diff options
Diffstat (limited to 'application/palemoon/base')
73 files changed, 452 insertions, 9861 deletions
diff --git a/application/palemoon/base/content/abouthome/aboutHome.css b/application/palemoon/base/content/abouthome/aboutHome.css deleted file mode 100644 index 73c686202..000000000 --- a/application/palemoon/base/content/abouthome/aboutHome.css +++ /dev/null @@ -1,339 +0,0 @@ -%if 0 -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -%endif - -html { - font: message-box; - font-size: 100%; - background-color: hsl(0,0%,90%); - color: #000; - height: 100%; -} - -body { - margin: 0; - display: -moz-box; - -moz-box-orient: vertical; - width: 100%; - height: 100%; - background-image: url(chrome://browser/content/abouthome/noise.png), - linear-gradient(hsla(0,0%,100%,.7), hsla(0,0%,100%,.4)); -} - -input, -button { - font-size: inherit; - font-family: inherit; -} - -a { - color: -moz-nativehyperlinktext; - text-decoration: none; -} - -.spacer { - -moz-box-flex: 1; -} - -#topSection { - text-align: center; -} - -#brandLogo { - height: 192px; - width: 192px; - margin: 22px auto 31px; - background-image: url("chrome://branding/content/about-logo.png"); - background-size: 192px auto; - background-position: center center; - background-repeat: no-repeat; -} - -#searchForm { - width: 470px; -} - -#searchForm { - display: -moz-box; -} - -#searchLogoContainer { - display: -moz-box; - -moz-box-align: center; - padding-top: 2px; - -moz-padding-end: 8px; -} - -#searchLogoContainer[hidden] { - display: none; -} - -#searchEngineLogo { - display: inline-block; - height: 28px; - width: 70px; - min-width: 70px; -} - -#searchText { - -moz-box-flex: 1; - padding: 6px 8px; - background: hsla(0,0%,100%,.9) padding-box; - border: 1px solid; - border-color: hsla(210,54%,20%,.15) hsla(210,54%,20%,.17) hsla(210,54%,20%,.2); - box-shadow: 0 1px 0 hsla(210,65%,9%,.02) inset, - 0 0 2px hsla(210,65%,9%,.1) inset, - 0 1px 0 hsla(0,0%,100%,.2); - border-radius: 2.5px 0 0 2.5px; -} - -#searchText:-moz-dir(rtl) { - border-radius: 0 2.5px 2.5px 0; -} - -#searchText:focus, -#searchText[autofocus] { - border-color: hsla(206,100%,60%,.6) hsla(206,76%,52%,.6) hsla(204,100%,40%,.6); -} - -#searchSubmit { - -moz-margin-start: -1px; - background: linear-gradient(hsla(0,0%,100%,.8), hsla(0,0%,100%,.1)) padding-box; - padding: 0 9px; - border: 1px solid; - border-color: hsla(210,54%,20%,.15) hsla(210,54%,20%,.17) hsla(210,54%,20%,.2); - -moz-border-start: 1px solid transparent; - border-radius: 0 2.5px 2.5px 0; - box-shadow: 0 0 2px hsla(0,0%,100%,.5) inset, - 0 1px 0 hsla(0,0%,100%,.2); - cursor: pointer; - transition-property: background-color, border-color, box-shadow; - transition-duration: 150ms; -} - -#searchSubmit:-moz-dir(rtl) { - border-radius: 2.5px 0 0 2.5px; -} - -#searchText:focus + #searchSubmit, -#searchText + #searchSubmit:hover, -#searchText[autofocus] + #searchSubmit { - border-color: #59b5fc #45a3e7 #3294d5; - color: white; -} - -#searchText:focus + #searchSubmit, -#searchText[autofocus] + #searchSubmit { - background-image: linear-gradient(#4cb1ff, #1793e5); - box-shadow: 0 1px 0 hsla(0,0%,100%,.2) inset, - 0 0 0 1px hsla(0,0%,100%,.1) inset, - 0 1px 0 hsla(210,54%,20%,.03); -} - -#searchText + #searchSubmit:hover { - background-image: linear-gradient(#66bdff, #0d9eff); - box-shadow: 0 1px 0 hsla(0,0%,100%,.2) inset, - 0 0 0 1px hsla(0,0%,100%,.1) inset, - 0 1px 0 hsla(210,54%,20%,.03), - 0 0 4px hsla(206,100%,20%,.2); -} - -#searchText + #searchSubmit:hover:active { - box-shadow: 0 1px 1px hsla(211,79%,6%,.1) inset, - 0 0 1px hsla(211,79%,6%,.2) inset; - transition-duration: 0ms; -} - -#launcher { - display: -moz-box; - -moz-box-align: center; - -moz-box-pack: center; - width: 100%; - background-color: hsla(0,0%,0%,.03); - border-top: 1px solid hsla(0,0%,0%,.03); - box-shadow: 0 1px 2px hsla(0,0%,0%,.02) inset, - 0 -1px 0 hsla(0,0%,100%,.25); -} - -#launcher:not([session]), -body[narrow] #launcher[session] { - display: block; /* display separator and restore button on separate lines */ - text-align: center; - white-space: nowrap; /* prevent navigational buttons from wrapping */ -} - -.launchButton { - display: -moz-box; - -moz-box-orient: vertical; - margin: 16px 1px; - padding: 14px 6px; - min-width: 88px; - max-width: 176px; - max-height: 85px; - vertical-align: top; - white-space: normal; - background: transparent padding-box; - border: 1px solid transparent; - border-radius: 2.5px; - color: #525c66; - font-size: 75%; - cursor: pointer; - transition-property: background-color, border-color, box-shadow; - transition-duration: 150ms; -} - -body[narrow] #launcher[session] > .launchButton { - margin: 4px 1px; -} - -.launchButton:hover { - background-color: hsla(211,79%,6%,.03); - border-color: hsla(210,54%,20%,.15) hsla(210,54%,20%,.17) hsla(210,54%,20%,.2); -} - -.launchButton:hover:active { - background-image: linear-gradient(hsla(211,79%,6%,.02), hsla(211,79%,6%,.05)); - border-color: hsla(210,54%,20%,.2) hsla(210,54%,20%,.23) hsla(210,54%,20%,.25); - box-shadow: 0 1px 1px hsla(211,79%,6%,.05) inset, - 0 0 1px hsla(211,79%,6%,.1) inset; - transition-duration: 0ms; -} - -.launchButton[hidden], -#launcher:not([session]) > #restorePreviousSessionSeparator, -#launcher:not([session]) > #restorePreviousSession { - display: none; -} - -#restorePreviousSessionSeparator { - width: 3px; - height: 116px; - margin: 0 10px; - background-image: linear-gradient(hsla(0,0%,100%,0), hsla(0,0%,100%,.35), hsla(0,0%,100%,0)), - linear-gradient(hsla(211,79%,6%,0), hsla(211,79%,6%,.2), hsla(211,79%,6%,0)), - linear-gradient(hsla(0,0%,100%,0), hsla(0,0%,100%,.35), hsla(0,0%,100%,0)); - background-position: left top, center, right bottom; - background-size: 1px auto; - background-repeat: no-repeat; -} - -body[narrow] #restorePreviousSessionSeparator { - margin: 0 auto; - width: 512px; - height: 3px; - background-image: linear-gradient(to right, hsla(0,0%,100%,0), hsla(0,0%,100%,.35), hsla(0,0%,100%,0)), - linear-gradient(to right, hsla(211,79%,6%,0), hsla(211,79%,6%,.2), hsla(211,79%,6%,0)), - linear-gradient(to right, hsla(0,0%,100%,0), hsla(0,0%,100%,.35), hsla(0,0%,100%,0)); - background-size: auto 1px; -} - -#restorePreviousSession { - max-width: none; - font-size: 90%; -} - -body[narrow] #restorePreviousSession { - font-size: 80%; -} - -.launchButton::before { - display: block; - width: 32px; - height: 32px; - margin: 0 auto 6px; - line-height: 0; /* remove extra vertical space due to non-zero font-size */ -} - -#downloads::before { - content: url("chrome://browser/content/abouthome/downloads.png"); -} - -#bookmarks::before { - content: url("chrome://browser/content/abouthome/bookmarks.png"); -} - -#history::before { - content: url("chrome://browser/content/abouthome/history.png"); -} - -#addons::before { - content: url("chrome://browser/content/abouthome/addons.png"); -} - -#sync::before { - content: url("chrome://browser/content/abouthome/sync.png"); -} - -#settings::before { - content: url("chrome://browser/content/abouthome/settings.png"); -} - -#restorePreviousSession::before { - content: url("chrome://browser/content/abouthome/restore-large.png"); - height: 48px; - width: 48px; - display: inline-block; /* display on same line as text label */ - vertical-align: middle; - margin-bottom: 0; - -moz-margin-end: 8px; -} - -#restorePreviousSession:-moz-dir(rtl)::before { - transform: scaleX(-1); -} - -body[narrow] #restorePreviousSession::before { - content: url("chrome://browser/content/abouthome/restore.png"); - height: 32px; - width: 32px; -} - -/* [HiDPI] - * At resolutions above 1dppx, prefer downscaling the 2x Retina graphics - * rather than upscaling the original-size ones (bug 818940). - */ -@media not all and (max-resolution: 1dppx) { - #brandLogo { - background-image: url("chrome://branding/content/about-logo@2x.png"); - } - - .launchButton::before { - transform: scale(.5); - transform-origin: 0 0; - } - - #downloads::before { - content: url("chrome://browser/content/abouthome/downloads@2x.png"); - } - - #bookmarks::before { - content: url("chrome://browser/content/abouthome/bookmarks@2x.png"); - } - - #history::before { - content: url("chrome://browser/content/abouthome/history@2x.png"); - } - - #addons::before { - content: url("chrome://browser/content/abouthome/addons@2x.png"); - } - - #sync::before { - content: url("chrome://browser/content/abouthome/sync@2x.png"); - } - - #settings::before { - content: url("chrome://browser/content/abouthome/settings@2x.png"); - } - - #restorePreviousSession::before { - content: url("chrome://browser/content/abouthome/restore-large@2x.png"); - } - - body[narrow] #restorePreviousSession::before { - content: url("chrome://browser/content/abouthome/restore@2x.png"); - } -} - diff --git a/application/palemoon/base/content/abouthome/aboutHome.js b/application/palemoon/base/content/abouthome/aboutHome.js deleted file mode 100644 index 6ff8eee98..000000000 --- a/application/palemoon/base/content/abouthome/aboutHome.js +++ /dev/null @@ -1,227 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const SEARCH_ENGINES = { - "DuckDuckGo": { - image: "data:image/png;base64," + - "iVBORw0KGgoAAAANSUhEUgAAAIwAAAA4CAYAAAAvmxBdAAAVhUlEQVR4Xu3dd5SU1d3A8e/vPs/0" + - "2crussBSdkHEAgoomEQSUTAW3hRbfMUeUwgSj9FoorGXqDGxBHvMazRGE0KsBQuiEVRUEEEM0pfO" + - "1tndmZ32PPf3knDCUZAlIYsxOfM553f2v91/vnufOzP33BFV5TOnQFQ1snFN/YCVb88Z6S2dd1B8" + - "3Qf7lTSv6R9PNle4uXQEVNRxvUy4qL29pPeGRNXA5d6g4fOLhoyYN2C/oe8Vl5QmAoFAnm72GQqm" + - "oKO9vXj5e/NHtr48/fjq92eOq2xYOsixvuMpKFuhfJywjQMYI5oKF7evrR09t/LE7z3Ze9TYZyPx" + - "+FpjjPdfEkxBY0ND9ftP//7EkpceOLNm/cJh+J6rylYWcIwSiCHhuEo4ggRdMCLq+UomK5pJq2Y7" + - "BD8HqoIAAmKhPdKjuX7EMc9WnfCde/YZOfot13Xz/6HBFKi1pdmlCya23Dz5PPeDN/eygCqAqIn3" + - "ULduiAb2Ha3BfUYgJeUgBhxHRAwgoupbfF/wPcXL461bRX7xm5Jb8q7Yhno0lzUYMIANx9Lh0y99" + - "svjEc292YkXzAfufE0yBse0tX+qY+uNrOp/+9SGo5yggTlADQw72I4efQGDf4Wg6RW7xO5Jf8g7+" + - "ulVi21rRXAr8HKpWRBzFCSGRIpyKSnX6701wv0PU7Vunms2RmfO0ZGc/Z/zWjSKiAqJOdV1LyUVT" + - "7wkdcuQvENP8mQ+mQGPZt2ZelLj2nCl+Q30ZAqijoVFH+rGTJiHROJnXniE75znxN64yms8AKghd" + - "062DEZVIqQbq9tHwYcdpcL+DNDvvFUlNv1dsywYHA0jAjx512lslF956vkSL5n5Wgymwfq+O/7vx" + - "jvZfX/0/+FkXC27N3n7xlOvVlFdp8pFfSnbuC0bTbYKqIOw+BcSoKeut0WNPtZEjjtPOx++X1FMP" + - "GPysAXD777epxy1PXuj2qXsEsJ+hYArUy9e2Xn7GtPTLj44AFVVHY1/7tld0+g8l+cht2vnE/Y7N" + - "p0S2htJ9FEDUlPWxxZOusE5VjSRunIK3YbkrAhIpzlRMfeGy4P6jbwH8z0AwBZrPDWqacvQzmfkv" + - "D0ZETbxCS3/wC9/t1ZeWq78t3oZlDqiwp6nRyJiveMXnXEL7fdeTef1JV9UKKlp118wrQgeNvX5X" + - "0Rj2uMJjqOmik/6UmbclFkSdylrb4/qHfU0naTzvK463fqkLKijo1oGt0/3ESudrT7jNPznTxL8x" + - "iehXvuUhroJKw6RxV+aWzJ8MyL9vhSmIJm778fT2h244CiPqVg+0Pa64TzPzZtv2X18XUD8jAIiB" + - "3nWEK6rBDaHZTmyiCb+lGe1MoGpB6FZOWR+/7KJbbXb+n0lOv8tV64mJlnX2mr74ZKei11PshMue" + - "UmA6X3nyqrbf/uxIAKe4l5ZdcqdNz5vNllhc9TKCAIAaQ6puNLEzzqN86EhQRTs78BvWkX3/bTpf" + - "mkZm3p/RbAoM3cJrWe+03PB9yn881drOlJd85gHXT7VGG77/1TvK7n1pRThe/MGnuMIU+M2bj91w" + - "wrBHbUdDnEDUVlx2n29TbbT8/AIXLy18hAQiFJ8wmdD44wnvPwoxZvs9ENlFb9D2qxvIzH0BxNId" + - "VMGtGuBXXPNrm7j7OskueNkBKDnjkudKp1x7ItD5KQRToNavaLzgGy91vjr9ABAtPuUCL/LFo2m8" + - "8ETHJlsMwsek9zqEztMvRbw8TjBMqLSU4spKiquqicVjiAgANtVBx8O3kbjvOtTPgPCvUwjufZBX" + - "ftEt2njBScZv2+gYN5KvfvCN84N7H3DHpxBMQerNmZc3nHvU5ajnBGqHedW3Psam848jv+I9F2FH" + - "4qA4gIJvkHgZgeGHEvzSUZSMP4FQccnHVpvk0w+Seu73ZN57Hc11guFfo6JFX/+uFzpgNE1XnOUi" + - "KpEDvriy4p4XxrrB0Jo9GExB0+bNtanvjX/VX7mor6jR6rtmeOk3ZpJ46CZXRKWrx4MTK6fkrB8S" + - "n3AqTnkVuAFEgO0qU1Xw8ngbVpO462o6ZjyCGMu/RB3tOfUZr+03t5B5+/kAIhq7/g8/rTrqhEv3" + - "YDAFCx+889qiWyZfahVihx2fL598haw7ebRRmzbshCgEBgyj+rY/Eui/F/8UVVp+eTmt918HRvlX" + - "hOqGexWX3q4bvn2kg582nZW1awc9vuhL4Whs1R4IpqC1ubnXhm8d/mp45cK9cEK29/0v+22P3Elq" + - "xsMBhJ3Ssj7U/OYVwv0GsTvU99h03nGkXnsKEXabqqNVV96b75z9vCRf+kPAEWi5+P4fjvzfs2/e" + - "Ay+rC96f9fzYPqsX11mF2EGH+yYal9TMJ4wCKJ9ILAQmXbXbsWSyeVLpPGUX3ULm3Tfxk43sNrG0" + - "/eE+Uz7pMk29/Li1Nmeyj917QsexJ9xbVFzcDmDoFgWe5wWysx7/mvq+o1Y0NuEUOp6bpjaXEgV2" + - "Nuke/Sg6+n8B8H3LklWNzJq7gtXrW7BW6UpzopN7fj+X+6bNZdqCNuKnnof6oOzmqEr2w/cc9fMa" + - "2OsAtQoVq947YPVfFu/XzStMQWtTU1WPJXNHWwWnR28bHjZKWu+9AUVFlE+mkDxoPEXxCNYq055f" + - "yKamJGNHD0REUFVA2JlgwOGbJxxMLBKkrSNDONWTjkfvxG/dwO6yXobO2TMl+sVjNPPBO+pmM+FV" + - "s18cP3T0597oxmAKNqxYtm9R07oaayG0/0HqNW4mt26Vg4LyycSD7N6jcIFM3iMWDTH5lKEEXId/" + - "RFEsxN+VFkfQWDXxcceReHQqGHaPqnS+NctUXnyzlUBIfS8jzvzXxnieF3ZdN+PSLQo6PlhwcMxa" + - "Y30IH/h5Mu+/o9bLsCu58l4AhIMuR4/ZG9cx/LNS6RwbGzuorSkjfuTxtP7hLsBntwjkNq0T9TxM" + - "RV/1Ni2jdPUH+3q5XNFfgzF0hwLHXfmXA3wFcRwN7zuC9HvviKqC0uXkjYsCIrItlpa2TmbM/pCV" + - "a5tR1a5DTWWZ+MNHuPTWGbwwZxnBQfvi9hwAym6PptvFb20kWDsQtRBNbO6ZSyX7dNcjqUA1HG9a" + - "308VJF6qblVvydUvQa2KCjtlFGwqScazRAMOAIn2NOdc9kfqN7Ry8jEHcvyRQ6mrKWdn1m5KsHJd" + - "C9Fw4G97oKMO+SrBQUPIbVgBwu5RJbP8Qwn03UvVn4FR39H21kFUVi0wdIeCYDjRWKkKpqiHqlr1" + - "WpsEdvGfDLgNa2nPeADbVpctEeD7lufnLGXpqka6MnhAJRMnDKdf7zLO/NpIxA0QqKlF7XZ/a+uA" + - "bB0UdGcrjKrkN9QT6N0fFVEVcFJt3bXCFKiq6zdtKlYFJxoDL49NZ1GlawLRVYtozfhUFwFA76pi" + - "vvyFvXnpjWVUlcU4aP8auuI6hovPOQxVRUQAMOE4WFC2MmEI9YaiUUJ0X0F9yKyGxIuW3AZA+DgF" + - "v61ZnPJKRQEFL9FS3k3BFAjq4uWCqkAoiFormvdF6ZoKRFcupjnt8XfhUIDLJx3BN48/mMqyGPFY" + - "iF1jWyyqis21E6iGyF5CdD8hMkQI9gYJCFgAiB6oaN7Q8LAFYQeay6iJRFQFVMHx8+HuC6ZAsCoA" + - "iICqKICyS6H1S9mcaEf7Fm1bIYJBl9qacrqm4DWguTWgafDbIL8O0u9R/qWn6HGEgxMTAFC2soAB" + - "P6G0zrS0PKEggPIxqqBWQURQUO3mE3cF4uG6nirYnAeOYzGOURB2wSTb8NavJrNPLyIBh11jayTN" + - "v0TbHgevETQHeKAWALcYQEDZSkBEyayDtlmWttlKvpGthE8WDInN5nRbLMZ43RdMgS/hWEqh3E+m" + - "RNygEgqqtrNrCsFlC2g79OBdB6OKpl5G10+C7CpAQYRtRPgYB/x2JTlfScxSUksUzW4XirIDtWDi" + - "ZeolWrEWACQUaeuuYApEck5JeTNKX789gRhHnJJS8pvXIkKX1ED0w3m0ZM+muoguaXYxWj8R/CYQ" + - "AQSskmsCJw5OVEDA71BSi5S217b+9FOg2/ekXUcc6NmX/MZ1YFUQcGJFm7ormAIh41b1Wm+VAzXZ" + - "gteR0GDNYNJL39cthF0IL1tIUzIPFXStcy74jSAGAFWl/lpLxzuKBMCJAgb8JKgHOHyMKv8QMUZD" + - "g4aQnPMiKoCIOqU9VnZbMAWSD9UN+QDlWJvJSeYv7xMeOpzEzD8h7Fpw43Kam5rw+xXjGGGnIsPB" + - "REHTgGDTkF6tqANY8JJsgwEUAJSPPL0EULoWjGmgujfp5R8KgImVtG0JZhWAoVsUlIz/2jtqRUGl" + - "8903NDb8EMSEUNjlmM40/pplpHIeXZHwUKTHZMAFwIkJ1acZghWAgNqPjAIGnDhE66DHl4Wacw0D" + - "LjGE+8FOP7VQcCur1cSKNbe+XhSIjfjCMhONd+cepiBYO/hdU1TW6idbyjvemWuqzv2JBqr62OzG" + - "FQ67oh7BD9+l/YjDKA4H2CkJID0vJ1OfQJvvI1QjlI8zFB0sZJYr2U3gd4I44JZAsEoI9gS3FCQo" + - "CEpmDXgZ2PnLftkS+xc0/eH7+Ml2wUB05Ji54jipbgymwEQi6yNDhi1Mvv3KYdk1SyW3ZqUWjz3G" + - "Njw81QgqdEFVCS9ZQFPGUlNC10yUxBt9aLjXEttHKB4txIcKsf3lb+GgoApYthLAQm6j0vqK0vSs" + - "Jd8CIjuPsnjcMdoy7TeiqBjj+LERh7wIaDcGUyCO27klkGc7tgSDlzctT/7eVpx8Ng2/uwfVHLsS" + - "Wv0+ifYUWhVBROiKWh8vBe3v6t/GhCHYE6IDhUidEKoGEwIvCZl6SP1F6Vyh+B2AbB1lRyiEB+zl" + - "B/v0p+PtOQaBQJ8BqyN77/c2QDcHU1AybsLTm35184Vec0NVYsbjUn3uj6Ro9OFe++szAghdcho3" + - "0LlpI7naHoRcoStueSXKNvgZSK+GzlWKiO74ASMg0vV7LwCqRstPPlsTzz2Gl2wTMVB82DHPumXl" + - "mwvXfewB6vvO6h+c/mDLE787Ra1or8mXeMWHHcmHJx3uiPiGLqgE2XTlg3z+xK9THg3SlbZZM1h+" + - "1gTApzsFq+u8QQ8+ydKTxomX2OSYaFHH4N++OD42YvTcPbDCFIjj+JWnn3tX2ysvTMgnmoo3P3CH" + - "6XHyWfT46kS/6YmHBFTYCdEcgSXvksh+lfIoXQrVDsKUVOIlNrGdrhaRrlmjvS66yjb+7n7JNW9y" + - "cUR7njFlRmz4qPl78H6YgtiBo96s/t4lz6iKesmEs/6Gy2yvC66QQGU/q12djbEQWrqI5lSOXa8E" + - "fQgP2ptP+n1N8SCpoPPPnbBT0dIj/icfrhssmx+611GBQGXftupvnX8bIvk9G0xhlfGqTv/2jZEB" + - "+zQAND89zU0teFv7Xn6TlUDUdtEMwbVLaG9N4FslmW+gKbOGjN+5wzFNE45QPGY8WFAAC4niEHdM" + - "GMjJU0bw4Ji+GPsP9qIQqq6zfS6+Rtb85HzRXMqAY/v+6PpH3PKKN9mOc+WVV9K9CiQQ3Bzdd1iw" + - "afrDX1LNO8m359LzrO+pW1yh7W+/blAr7AjJWzoOPZaaAX2Yu/lWHls1ldc2z2VjOklJsILiQBwR" + - "wVefXDRAy1N/gnyWv4yu4s4zhzCztox2DAIctaABlF1y4mW29md32y2bdJqfneYCUnzI4cv6XnrD" + - "d8SYxKd1e0OBaqz+yose23j/z8cBFA3/gjfw9l/Lxjt+rg2P/soFX9iBQ+OP7mTUWWeyoOkaXtv0" + - "KqtTsDxpSfoVfLn34YzoU8bsxnksb23EeWMxxwRyvDGigqVJWJ5U2vLQvznNA3cuIJLz6YqEiuyA" + - "a27x1fOov+J8x+bTxo2Xdw6btfDUYK8+j32aN1AViKT6/eS6ye1zXn45tWR+Tce7r7v1V/zQ73/N" + - "L0R9z2+Y9oCzQzTWx/1wEa1pH8SwlWDE0JBp5oHVv2eB+jQnhdaUoWNQnIE1LmQUUP4uHzDkHEOY" + - "nQSjYCJFtt9lN/kmFmflxZMdm0sbxbGDpj50+5ZYngT49IMpPJqW7TP9pVPf/fy+T3qJTcUtM59y" + - "FPEGXHuLOOUV3oZ7fuGieeEjgsvfo7WjE9cN8FECOI5gEEQEgJyFVF7ZnhXBIqiyA1UIlFb5tdff" + - "ZlFY+aMpjt/ebFSh/yU/nV467pgrAf/fdItmgVtS9uqwF98620TK0mCl5aUn3OWTT6dq4tky8Of3" + - "eSZSZlXZJrC+nmRTC0aibE/4OFVFAWv4GMcqxirbUysaG3yAN+S3T2i+sYHlF37H8doajSr0Ovv7" + - "s/qce+E5QPbffO1qQah33+kH/nnhaYHKfq2qKm3vvOYu/to43LIKhr0415aOOTpvNaBWwSSayNav" + - "QrR0hzhcP86g6H4MjNUyuuJArjrwO9w06hGOesWl3+oOgr5iBEpSecJZH2vZOiqKG7N9Jl3k7f2b" + - "P7Hp/+7RlZed7/rpdqM4ts+5lz5be+2txyHS/hm62Lkg39x05AenfOWejoVv9hdUkIBWTzzHqznv" + - "YumYN1fX//JnJvXBItNy7k8lftpgZm28iRVJZXM2yoiKcXx3yERqi3qxvaY/Pcqyb09kc0WQRf3i" + - "lKY8Rq5IYBF1wnFKDxtva6ZcaHONTdRffZF0Ll/iYsAEI/m6a29/qPq0b56/LZbPVjAFNpMeuvrK" + - "i2/f+ODdY9TmHXwI1dT6vSedpz3GHyvJhfN1VUMSjhljFrb/UuLBfeRzPY+hX7w/O2PzORYePYbk" + - "orcQFRXXJVBdo+Vjj7QVx5+MuAHZcPdt2vTsYw54gkKopq55yN2/vano4M/dBmQBPqvBFKiWtc56" + - "4YJlF3x3Unb96nIEUKOR2sG28usnafmErxOoHUwwGkLEiCDCNgg70paXnmPNjVdr0fCRWjJmLOEB" + - "daRXraDxj7+j9dUXjc2kBFTEuH7VSWfOrbvqpkvc0rI/Awrw2Q+mwPgdHaPX3X3rj9dNvfEom0kF" + - "VAEVdYvLtGjoAVo85ggtGf05CfcbqMGqKjGhMB9pRwEBUN/Ha23R9OrlZFatlMRrL2v73NclXb/C" + - "qJ8XMQCyJaZD1g687hdTi0aMvh+Rlv/AL9gq0Hw+3PbWnMPX3n7jlLY5s8baXDYEgIIiagIh3NIe" + - "Gqqq1EBVb9zyCtxoXDFGbT5n/PaE5ho2mtzmjeSbW/A720R9X8SwTbimf33Pb5zxUO9vTv5VoKKq" + - "/r/gK/wKbDYTTi1eNHTzH393SvPzT0/IrF5Zp2KNCFtpF8cqBba/ndVEYqmKCcfP6Xn8xEeLRx78" + - "rFtS2oCIAvx3BVMgms/H8q3N+zc9/cTYphlPf/6vIWU3ru+jnufySUTULSpujwzca9mWPcy8skMP" + - "e6Xkc4fODlb32iyOk6cb/T/N+faHj8AX2gAAAABJRU5ErkJggg==" - } -}; - -// This global tracks if the page has been set up before, to prevent double inits -var gInitialized = false; -var gObserver = new MutationObserver(function (mutations) { - for (let mutation of mutations) { - if (mutation.attributeName == "searchEngineURL") { - setupSearchEngine(); - if (!gInitialized) { - gInitialized = true; - } - return; - } - } -}); - -window.addEventListener("pageshow", function () { - // Delay search engine setup, cause browser.js::BrowserOnAboutPageLoad runs - // later and may use asynchronous getters. - window.gObserver.observe(document.documentElement, { attributes: true }); - fitToWidth(); - window.addEventListener("resize", fitToWidth); -}); - -window.addEventListener("pagehide", function() { - window.gObserver.disconnect(); - window.removeEventListener("resize", fitToWidth); -}); - -function onSearchSubmit(aEvent) -{ - let searchTerms = document.getElementById("searchText").value; - let searchURL = document.documentElement.getAttribute("searchEngineURL"); - - if (searchURL && searchTerms.length > 0) { - // Send an event that a search was performed. This was originally - // added so Firefox Health Report could record that a search from - // about:home had occurred. - let engineName = document.documentElement.getAttribute("searchEngineName"); - let event = new CustomEvent("AboutHomeSearchEvent", {detail: engineName}); - document.dispatchEvent(event); - - const SEARCH_TOKEN = "_searchTerms_"; - let searchPostData = document.documentElement.getAttribute("searchEnginePostData"); - if (searchPostData) { - // Check if a post form already exists. If so, remove it. - const POST_FORM_NAME = "searchFormPost"; - let form = document.forms[POST_FORM_NAME]; - if (form) { - form.parentNode.removeChild(form); - } - - // Create a new post form. - form = document.body.appendChild(document.createElement("form")); - form.setAttribute("name", POST_FORM_NAME); - // Set the URL to submit the form to. - form.setAttribute("action", searchURL.replace(SEARCH_TOKEN, searchTerms)); - form.setAttribute("method", "post"); - - // Create new <input type=hidden> elements for search param. - searchPostData = searchPostData.split("&"); - for (let postVar of searchPostData) { - let [name, value] = postVar.split("="); - if (value == SEARCH_TOKEN) { - value = searchTerms; - } - let input = document.createElement("input"); - input.setAttribute("type", "hidden"); - input.setAttribute("name", name); - input.setAttribute("value", value); - form.appendChild(input); - } - // Submit the form. - form.submit(); - } else { - searchURL = searchURL.replace(SEARCH_TOKEN, encodeURIComponent(searchTerms)); - window.location.href = searchURL; - } - } - - aEvent.preventDefault(); -} - - -function setupSearchEngine() -{ - // The "autofocus" attribute doesn't focus the form element - // immediately when the element is first drawn, so the - // attribute is also used for styling when the page first loads. - let searchText = document.getElementById("searchText"); - searchText.addEventListener("blur", function searchText_onBlur() { - searchText.removeEventListener("blur", searchText_onBlur); - searchText.removeAttribute("autofocus"); - }); - - let searchEngineName = document.documentElement.getAttribute("searchEngineName"); - let searchEngineInfo = SEARCH_ENGINES[searchEngineName]; - let logoElt = document.getElementById("searchEngineLogo"); - - // Add search engine logo. - if (searchEngineInfo && searchEngineInfo.image) { - logoElt.parentNode.hidden = false; - logoElt.src = searchEngineInfo.image; - logoElt.alt = searchEngineName; - searchText.placeholder = ""; - } - else { - logoElt.parentNode.hidden = true; - searchText.placeholder = searchEngineName; - } - -} - -function fitToWidth() { - if (window.scrollMaxX) { - document.body.setAttribute("narrow", "true"); - } else if (document.body.hasAttribute("narrow")) { - document.body.removeAttribute("narrow"); - fitToWidth(); - } -} diff --git a/application/palemoon/base/content/abouthome/aboutHome.xhtml b/application/palemoon/base/content/abouthome/aboutHome.xhtml deleted file mode 100644 index cb3fa634a..000000000 --- a/application/palemoon/base/content/abouthome/aboutHome.xhtml +++ /dev/null @@ -1,60 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % htmlDTD - PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "DTD/xhtml1-strict.dtd"> - %htmlDTD; - <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd"> - %globalDTD; - <!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd"> - %aboutHomeDTD; - <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" > - %browserDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>&abouthome.pageTitle;</title> - - <link rel="icon" type="image/png" id="favicon" - href="chrome://branding/content/icon32.png"/> - <link rel="stylesheet" type="text/css" media="all" - href="chrome://browser/content/abouthome/aboutHome.css"/> - - <script type="text/javascript;version=1.8" - src="chrome://browser/content/abouthome/aboutHome.js"/> - </head> - - <body dir="&locale.dir;"> - <div class="spacer"/> - <div id="topSection"> - <div id="brandLogo"></div> - - <div id="searchContainer"> - <form name="searchForm" id="searchForm" onsubmit="onSearchSubmit(event)"> - <div id="searchLogoContainer"><img id="searchEngineLogo"/></div> - <input type="text" name="q" value="" id="searchText" maxlength="256" - autofocus="autofocus"/> - <input id="searchSubmit" type="submit" value="&abouthome.searchEngineButton.label;"/> - </form> - </div> - </div> - <div class="spacer"/> - - <div id="launcher"> - <button class="launchButton" id="downloads">&abouthome.downloadsButton.label;</button> - <button class="launchButton" id="bookmarks">&abouthome.bookmarksButton.label;</button> - <button class="launchButton" id="history">&abouthome.historyButton.label;</button> - <button class="launchButton" id="addons">&abouthome.addonsButton.label;</button> - <button class="launchButton" id="sync">&abouthome.syncButton.label;</button> - <button class="launchButton" id="settings">&abouthome.settingsButton.label;</button> - <div id="restorePreviousSessionSeparator"/> - <button class="launchButton" id="restorePreviousSession">&historyRestoreLastSession.label;</button> - </div> - </body> -</html> diff --git a/application/palemoon/base/content/abouthome/addons.png b/application/palemoon/base/content/abouthome/addons.png Binary files differdeleted file mode 100644 index 41519ce49..000000000 --- a/application/palemoon/base/content/abouthome/addons.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/addons@2x.png b/application/palemoon/base/content/abouthome/addons@2x.png Binary files differdeleted file mode 100644 index d4d04ee8c..000000000 --- a/application/palemoon/base/content/abouthome/addons@2x.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/bookmarks.png b/application/palemoon/base/content/abouthome/bookmarks.png Binary files differdeleted file mode 100644 index 5c7e194a6..000000000 --- a/application/palemoon/base/content/abouthome/bookmarks.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/bookmarks@2x.png b/application/palemoon/base/content/abouthome/bookmarks@2x.png Binary files differdeleted file mode 100644 index 7ede00744..000000000 --- a/application/palemoon/base/content/abouthome/bookmarks@2x.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/downloads.png b/application/palemoon/base/content/abouthome/downloads.png Binary files differdeleted file mode 100644 index 3d4d10e7a..000000000 --- a/application/palemoon/base/content/abouthome/downloads.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/downloads@2x.png b/application/palemoon/base/content/abouthome/downloads@2x.png Binary files differdeleted file mode 100644 index d384a22c6..000000000 --- a/application/palemoon/base/content/abouthome/downloads@2x.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/history.png b/application/palemoon/base/content/abouthome/history.png Binary files differdeleted file mode 100644 index ae742b1aa..000000000 --- a/application/palemoon/base/content/abouthome/history.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/history@2x.png b/application/palemoon/base/content/abouthome/history@2x.png Binary files differdeleted file mode 100644 index 696902e7c..000000000 --- a/application/palemoon/base/content/abouthome/history@2x.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/noise.png b/application/palemoon/base/content/abouthome/noise.png Binary files differdeleted file mode 100644 index 3467cf4d4..000000000 --- a/application/palemoon/base/content/abouthome/noise.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/restore-large.png b/application/palemoon/base/content/abouthome/restore-large.png Binary files differdeleted file mode 100644 index ef593e6e1..000000000 --- a/application/palemoon/base/content/abouthome/restore-large.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/restore-large@2x.png b/application/palemoon/base/content/abouthome/restore-large@2x.png Binary files differdeleted file mode 100644 index d5c71d0b0..000000000 --- a/application/palemoon/base/content/abouthome/restore-large@2x.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/restore.png b/application/palemoon/base/content/abouthome/restore.png Binary files differdeleted file mode 100644 index 5c3d6f437..000000000 --- a/application/palemoon/base/content/abouthome/restore.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/restore@2x.png b/application/palemoon/base/content/abouthome/restore@2x.png Binary files differdeleted file mode 100644 index 5acb63052..000000000 --- a/application/palemoon/base/content/abouthome/restore@2x.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/settings.png b/application/palemoon/base/content/abouthome/settings.png Binary files differdeleted file mode 100644 index 4b0c30990..000000000 --- a/application/palemoon/base/content/abouthome/settings.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/settings@2x.png b/application/palemoon/base/content/abouthome/settings@2x.png Binary files differdeleted file mode 100644 index c77cb9a92..000000000 --- a/application/palemoon/base/content/abouthome/settings@2x.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/snippet1.png b/application/palemoon/base/content/abouthome/snippet1.png Binary files differdeleted file mode 100644 index ce2ec55c2..000000000 --- a/application/palemoon/base/content/abouthome/snippet1.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/snippet1@2x.png b/application/palemoon/base/content/abouthome/snippet1@2x.png Binary files differdeleted file mode 100644 index f57cd0a82..000000000 --- a/application/palemoon/base/content/abouthome/snippet1@2x.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/snippet2.png b/application/palemoon/base/content/abouthome/snippet2.png Binary files differdeleted file mode 100644 index e0724fb6d..000000000 --- a/application/palemoon/base/content/abouthome/snippet2.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/snippet2@2x.png b/application/palemoon/base/content/abouthome/snippet2@2x.png Binary files differdeleted file mode 100644 index 40577f52f..000000000 --- a/application/palemoon/base/content/abouthome/snippet2@2x.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/sync.png b/application/palemoon/base/content/abouthome/sync.png Binary files differdeleted file mode 100644 index 11e40cc93..000000000 --- a/application/palemoon/base/content/abouthome/sync.png +++ /dev/null diff --git a/application/palemoon/base/content/abouthome/sync@2x.png b/application/palemoon/base/content/abouthome/sync@2x.png Binary files differdeleted file mode 100644 index 6354f5bf9..000000000 --- a/application/palemoon/base/content/abouthome/sync@2x.png +++ /dev/null diff --git a/application/palemoon/base/content/browser-sets.inc b/application/palemoon/base/content/browser-sets.inc index 25794a65c..78fce2670 100644 --- a/application/palemoon/base/content/browser-sets.inc +++ b/application/palemoon/base/content/browser-sets.inc @@ -32,6 +32,7 @@ <command id="cmd_printPreview" oncommand="PrintUtils.printPreview(PrintPreviewListener);"/> <command id="cmd_close" oncommand="BrowserCloseTabOrWindow()"/> <command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow()"/> + <command id="cmd_toggleMute" oncommand="gBrowser.selectedTab.toggleMuteAudio()"/> <command id="cmd_ToggleTabsOnTop" oncommand="TabsOnTop.toggle()"/> <command id="cmd_CustomizeToolbars" oncommand="BrowserCustomizeToolbar()"/> <command id="cmd_restartApplication" oncommand="restart(false);"/> @@ -212,6 +213,7 @@ <key id="printKb" key="&printCmd.commandkey;" command="cmd_print" modifiers="accel"/> <key id="key_close" key="&closeCmd.key;" command="cmd_close" modifiers="accel"/> <key id="key_closeWindow" key="&closeCmd.key;" command="cmd_closeWindow" modifiers="accel,shift"/> + <key id="key_toggleMute" key="&toggleMuteCmd.key;" command="cmd_toggleMute" modifiers="control"/> <key id="key_undo" key="&undoCmd.key;" modifiers="accel"/> diff --git a/application/palemoon/base/content/browser-tabPreviews.js b/application/palemoon/base/content/browser-tabPreviews.js index eaae78ba8..e0755b81d 100644 --- a/application/palemoon/base/content/browser-tabPreviews.js +++ b/application/palemoon/base/content/browser-tabPreviews.js @@ -940,6 +940,13 @@ var allTabs = { aPreview.setAttribute("image", aPreview._tab.image); else aPreview.removeAttribute("image"); + + aPreview.removeAttribute("soundplaying"); + aPreview.removeAttribute("muted"); + if (aPreview._tab.hasAttribute("muted")) + aPreview.setAttribute("muted", "true"); + else if (aPreview._tab.hasAttribute("soundplaying")) + aPreview.setAttribute("soundplaying", "true"); var thumbnail = tabPreviews.get(aPreview._tab); if (aPreview.firstChild) { diff --git a/application/palemoon/base/content/browser-tabPreviews.xml b/application/palemoon/base/content/browser-tabPreviews.xml index e957649e7..4f54321ea 100644 --- a/application/palemoon/base/content/browser-tabPreviews.xml +++ b/application/palemoon/base/content/browser-tabPreviews.xml @@ -42,7 +42,10 @@ <xul:hbox class="tabPreview-canvas" xbl:inherits="style=canvasstyle"> <children/> </xul:hbox> - <xul:label flex="1" xbl:inherits="value=label,crop" class="allTabs-preview-label plain"/> + <xul:hbox align="center"> + <xul:image xbl:inherits="soundplaying,muted" class="allTabs-endimage"/> + <xul:label flex="1" xbl:inherits="value=label,crop" class="allTabs-preview-label plain"/> + </xul:hbox> </xul:vbox> <xul:hbox class="allTabs-favicon-container"> <xul:image class="allTabs-favicon" xbl:inherits="src=image"/> diff --git a/application/palemoon/base/content/browser.js b/application/palemoon/base/content/browser.js index 4167f186c..eb4916e37 100644 --- a/application/palemoon/base/content/browser.js +++ b/application/palemoon/base/content/browser.js @@ -976,6 +976,7 @@ var gBrowserInit = { CombinedStopReload.init(); allTabs.readPref(); TabsOnTop.init(); + AudioIndicator.init(); gPrivateBrowsingUI.init(); TabsInTitlebar.init(); retrieveToolbarIconsizesFromTheme(); @@ -1364,6 +1365,8 @@ var gBrowserInit = { BookmarkingUI.uninit(); TabsOnTop.uninit(); + + AudioIndicator.uninit(); TabsInTitlebar.uninit(); @@ -2453,7 +2456,7 @@ function BrowserOnAboutPageLoad(doc) { docElt.setAttribute("searchEnginePostData", engine.postDataString || ""); docElt.setAttribute("searchEngineURL", engine.searchURL); } - updateSearchEngine(); + Services.search.init(updateSearchEngine); // Listen for the event that's triggered when the user changes search engine. // At this point we simply reload about:home to reflect the change. @@ -2478,7 +2481,7 @@ function BrowserOnAboutPageLoad(doc) { docElt.setAttribute("searchEnginePostData", engine.postDataString || ""); docElt.setAttribute("searchEngineURL", engine.searchURL); } - updateSearchEngine(); + Services.search.init(updateSearchEngine); // Listen for the event that's triggered when the user changes search engine. // At this point we simply reload about:newtab to reflect the change. @@ -3043,7 +3046,9 @@ const DOMLinkHandler = { /^(?:https?|ftp):/i.test(link.href) && !PrivateBrowsingUtils.isWindowPrivate(window)) { var engine = { title: link.title, href: link.href }; - BrowserSearch.addEngine(engine, link.ownerDocument); + Services.search.init(function () { + BrowserSearch.addEngine(engine, link.ownerDocument); + }); searchAdded = true; } } @@ -4597,6 +4602,42 @@ function setToolbarVisibility(toolbar, isVisible) { ToolbarIconColor.inferFromText(); } +var AudioIndicator = { + init: function () { + Services.prefs.addObserver(this._prefName, this, false); + this.syncUI(); + }, + + uninit: function () { + Services.prefs.removeObserver(this._prefName, this); + }, + + toggle: function () { + this.enabled = !Services.prefs.getBoolPref(this._prefName); + }, + + syncUI: function () { + document.getElementById("context_toggleMuteTab").setAttribute("hidden", this.enabled); + document.getElementById("key_toggleMute").setAttribute("disabled", this.enabled); + }, + + get enabled () { + return !Services.prefs.getBoolPref(this._prefName); + }, + + set enabled (val) { + Services.prefs.setBoolPref(this._prefName, !!val); + return val; + }, + + observe: function (subject, topic, data) { + if (topic == "nsPref:changed") + this.syncUI(); + }, + + _prefName: "browser.tabs.showAudioPlayingIcon" +} + var TabsOnTop = { init: function TabsOnTop_init() { Services.prefs.addObserver(this._prefName, this, false); @@ -7021,6 +7062,17 @@ function restoreLastSession() { var TabContextMenu = { contextTab: null, + _updateToggleMuteMenuItem(aTab, aConditionFn) { + ["muted", "soundplaying"].forEach(attr => { + if (!aConditionFn || aConditionFn(attr)) { + if (aTab.hasAttribute(attr)) { + aTab.toggleMuteMenuItem.setAttribute(attr, "true"); + } else { + aTab.toggleMuteMenuItem.removeAttribute(attr); + } + } + }); + }, updateContextMenu: function updateContextMenu(aPopupMenu) { this.contextTab = aPopupMenu.triggerNode.localName == "tab" ? aPopupMenu.triggerNode : gBrowser.selectedTab; @@ -7067,6 +7119,35 @@ var TabContextMenu = { bookmarkAllTabs.hidden = this.contextTab.pinned; if (!bookmarkAllTabs.hidden) PlacesCommandHook.updateBookmarkAllTabsCommand(); + + // Adjust the state of the toggle mute menu item. + let toggleMute = document.getElementById("context_toggleMuteTab"); + if (this.contextTab.hasAttribute("muted")) { + toggleMute.label = gNavigatorBundle.getString("unmuteTab.label"); + toggleMute.accessKey = gNavigatorBundle.getString("unmuteTab.accesskey"); + } else { + toggleMute.label = gNavigatorBundle.getString("muteTab.label"); + toggleMute.accessKey = gNavigatorBundle.getString("muteTab.accesskey"); + } + + this.contextTab.toggleMuteMenuItem = toggleMute; + this._updateToggleMuteMenuItem(this.contextTab); + + this.contextTab.addEventListener("TabAttrModified", this, false); + aPopupMenu.addEventListener("popuphiding", this, false); + }, + handleEvent(aEvent) { + switch (aEvent.type) { + case "popuphiding": + gBrowser.removeEventListener("TabAttrModified", this); + aEvent.target.removeEventListener("popuphiding", this); + break; + case "TabAttrModified": + let tab = aEvent.target; + this._updateToggleMuteMenuItem(tab, + attr => aEvent.detail.changed.indexOf(attr) >= 0); + break; + } } }; diff --git a/application/palemoon/base/content/browser.xul b/application/palemoon/base/content/browser.xul index 07ca54722..ce2a7c5a8 100644 --- a/application/palemoon/base/content/browser.xul +++ b/application/palemoon/base/content/browser.xul @@ -87,6 +87,7 @@ onpopuphidden="if (event.target == this) TabContextMenu.contextTab = null;"> <menuitem id="context_reloadTab" label="&reloadTab.label;" accesskey="&reloadTab.accesskey;" oncommand="gBrowser.reloadTab(TabContextMenu.contextTab);"/> + <menuitem id="context_toggleMuteTab" oncommand="TabContextMenu.contextTab.toggleMuteAudio();"/> <menuseparator/> <menuitem id="context_pinTab" label="&pinTab.label;" accesskey="&pinTab.accesskey;" diff --git a/application/palemoon/base/content/newtab/cells.js b/application/palemoon/base/content/newtab/cells.js deleted file mode 100644 index 47d4ef52d..000000000 --- a/application/palemoon/base/content/newtab/cells.js +++ /dev/null @@ -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, false); - }, this); -} - -Cell.prototype = { - /** - * The grid. - */ - _grid: null, - - /** - * The cell's DOM node. - */ - get node() { return this._node; }, - - /** - * The cell's offset in the grid. - */ - get index() { - let index = this._grid.cells.indexOf(this); - - // Cache this value, overwrite the getter. - Object.defineProperty(this, "index", {value: index, enumerable: true}); - - return index; - }, - - /** - * The previous cell in the grid. - */ - get previousSibling() { - let prev = this.node.previousElementSibling; - prev = prev && prev._newtabCell; - - // Cache this value, overwrite the getter. - Object.defineProperty(this, "previousSibling", {value: prev, enumerable: true}); - - return prev; - }, - - /** - * The next cell in the grid. - */ - get nextSibling() { - let next = this.node.nextElementSibling; - next = next && next._newtabCell; - - // Cache this value, overwrite the getter. - Object.defineProperty(this, "nextSibling", {value: next, enumerable: true}); - - return next; - }, - - /** - * The site contained in the cell, if any. - */ - get site() { - let firstChild = this.node.firstElementChild; - return firstChild && firstChild._newtabSite; - }, - - /** - * Checks whether the cell contains a pinned site. - * @return Whether the cell contains a pinned site. - */ - containsPinnedSite: function Cell_containsPinnedSite() { - let site = this.site; - return site && site.isPinned(); - }, - - /** - * Checks whether the cell contains a site (is empty). - * @return Whether the cell is empty. - */ - isEmpty: function Cell_isEmpty() { - return !this.site; - }, - - /** - * Handles all cell events. - */ - handleEvent: function Cell_handleEvent(aEvent) { - // We're not responding to external drag/drop events - // when our parent window is in private browsing mode. - if (inPrivateBrowsingMode() && !gDrag.draggedSite) - return; - - if (aEvent.type != "dragexit" && !gDrag.isValid(aEvent)) - return; - - switch (aEvent.type) { - case "dragenter": - aEvent.preventDefault(); - gDrop.enter(this, aEvent); - break; - case "dragover": - aEvent.preventDefault(); - break; - case "dragexit": - gDrop.exit(this, aEvent); - break; - case "drop": - aEvent.preventDefault(); - gDrop.drop(this, aEvent); - break; - } - } -}; diff --git a/application/palemoon/base/content/newtab/drag.js b/application/palemoon/base/content/newtab/drag.js deleted file mode 100644 index e3928ebd0..000000000 --- a/application/palemoon/base/content/newtab/drag.js +++ /dev/null @@ -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); - } -}; diff --git a/application/palemoon/base/content/newtab/dragDataHelper.js b/application/palemoon/base/content/newtab/dragDataHelper.js deleted file mode 100644 index 675ff2671..000000000 --- a/application/palemoon/base/content/newtab/dragDataHelper.js +++ /dev/null @@ -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}; - } -}; diff --git a/application/palemoon/base/content/newtab/drop.js b/application/palemoon/base/content/newtab/drop.js deleted file mode 100644 index 748652455..000000000 --- a/application/palemoon/base/content/newtab/drop.js +++ /dev/null @@ -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}); - } -}; diff --git a/application/palemoon/base/content/newtab/dropPreview.js b/application/palemoon/base/content/newtab/dropPreview.js deleted file mode 100644 index fd7587a35..000000000 --- a/application/palemoon/base/content/newtab/dropPreview.js +++ /dev/null @@ -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; - } -}; diff --git a/application/palemoon/base/content/newtab/dropTargetShim.js b/application/palemoon/base/content/newtab/dropTargetShim.js deleted file mode 100644 index 57a97fa00..000000000 --- a/application/palemoon/base/content/newtab/dropTargetShim.js +++ /dev/null @@ -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); - } -}; diff --git a/application/palemoon/base/content/newtab/grid.js b/application/palemoon/base/content/newtab/grid.js deleted file mode 100644 index db3d319c3..000000000 --- a/application/palemoon/base/content/newtab/grid.js +++ /dev/null @@ -1,179 +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 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 [for (cell of this.cells) cell.site]; - let aSites = []; - for (let cell of this.cells) { - aSites.push(cell.site); - } - return aSites; - }, - - // 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; - }); - }, - - /** - * 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) { - // Any specific events should go here. - }, - - /** - * 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 the grid. - */ - refresh() { - this._refreshGrid(); - }, - - /** - * Renders the grid, including cells and sites. - */ - _refreshGrid() { - let row = document.createElementNS(HTML_NAMESPACE, "div"); - row.classList.add("newtab-row"); - let cell = document.createElementNS(HTML_NAMESPACE, "div"); - cell.classList.add("newtab-cell"); - - // Clear the grid - this._node.innerHTML = ""; - - // Creates the structure of one row - for (let i = 0; i < gGridPrefs.gridColumns; i++) { - row.appendChild(cell.cloneNode(true)); - } - - // Creates the grid - for (let j = 0; j < gGridPrefs.gridRows; j++) { - this._node.appendChild(row.cloneNode(true)); - } - - // Create cell array. - let cellElements = this.node.querySelectorAll(".newtab-cell"); - let cells = Array.from(cellElements, (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; - }, - - /** - * 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"); - - // Create the site's inner HTML code. - site.innerHTML = - '<a class="newtab-link">' + - ' <span class="newtab-thumbnail placeholder"/>' + - ' <span class="newtab-thumbnail thumbnail"/>' + - ' <span class="newtab-title"/>' + - '</a>' + - '<input type="button" title="' + newTabString("pin") + '"' + - ' class="newtab-control newtab-control-pin"/>' + - '<input type="button" title="' + newTabString("block") + '"' + - ' class="newtab-control newtab-control-block"/>'; - - 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"); - } - -}; diff --git a/application/palemoon/base/content/newtab/newTab.css b/application/palemoon/base/content/newtab/newTab.css deleted file mode 100644 index 3c7cfa102..000000000 --- a/application/palemoon/base/content/newtab/newTab.css +++ /dev/null @@ -1,349 +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: #F9F9F9; - 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; -} - -#newtab-undo-container[undo-disabled] { - opacity: 0; - pointer-events: none; -} - -/* TOGGLE */ -#newtab-toggle { - position: absolute; - top: 12px; - right: 12px; -} - -#newtab-toggle:-moz-locale-dir(rtl) { - left: 12px; - 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: 6px; - 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: 5; -} - -#newtab-margin-top { - min-height: 10px; - max-height: 30px; - display: -moz-box; - -moz-box-flex: 1; - -moz-box-align: center; - -moz-box-pack: center; -} - -#newtab-margin-bottom { - min-height: 40px; - max-height: 80px; - -moz-box-flex: 1; -} - -.newtab-side-margin { - min-width: 40px; - max-width: 300px; - -moz-box-flex: 1; -} - -/* GRID */ -#newtab-grid { - display: -moz-box; - -moz-box-flex: 5; - -moz-box-orient: vertical; - min-width: 600px; - min-height: 400px; - transition: 175ms ease-out; - transition-property: opacity; -} - -#newtab-grid[page-disabled] { - opacity: 0; -} - -#newtab-grid[locked], -#newtab-grid[page-disabled] { - pointer-events: none; -} - -/* ROWS */ -.newtab-row { - display: -moz-box; - -moz-box-orient: horizontal; - -moz-box-direction: normal; - -moz-box-flex: 1; -} - -/* - * Thumbnail image sizes are determined in the preferences: - * toolkit.pageThumbs.minWidth - * toolkit.pageThumbs.minHeight - */ -/* CELLS */ -.newtab-cell { - display: -moz-box; - -moz-box-flex: 1; -} - -/* SITES */ -.newtab-site { - position: relative; - -moz-box-flex: 1; - transition: 150ms 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; -} - -.newtab-title { - 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 */ -#searchContainer { - display: -moz-box; - position: relative; - -moz-box-pack: center; - margin: 10px 0 15px; -} - -#searchContainer[page-disabled] { - opacity: 0; - pointer-events: none; -} - -#searchForm { - display: -moz-box; - position: relative; - height: 36px; - -moz-box-flex: 1; - max-width: 600px; /* 2 * (290 cell width + 10 cell margin) */ -} - -#searchEngineLogo { - border: 1px transparent; - padding: 2px 4px; - margin: 0; - width: 32px; - height: 32px; - position: absolute; -} - -#searchText { - -moz-box-flex: 1; - padding-top: 6px; - padding-bottom: 6px; - padding-inline-start: 42px; - padding-inline-end: 8px; - background: hsla(0,0%,100%,.9) padding-box; - border: 1px solid; - border-spacing: 0; - border-radius: 2px 0 0 2px; - border-color: hsla(210,54%,20%,.15) hsla(210,54%,20%,.17) hsla(210,54%,20%,.2); - box-shadow: 0 1px 0 hsla(210,65%,9%,.02) inset, - 0 0 2px hsla(210,65%,9%,.1) inset, - 0 1px 0 hsla(0,0%,100%,.2); - color: inherit; - unicode-bidi: plaintext; -} - -#searchText:dir(rtl) { - border-radius: 0 2px 2px 0; -} - -#searchText[aria-expanded="true"] { - border-radius: 2px 0 0 0; -} - -#searchText[aria-expanded="true"]:dir(rtl) { - border-radius: 0 2px 0 0; -} - -#searchText[keepfocus], -#searchText:focus { - border-color: hsla(216,100%,60%,.6) hsla(216,76%,52%,.6) hsla(214,100%,40%,.6); -} - -#searchSubmit { - margin-inline-start: -1px; - padding: 0; - border: 1px solid; - background-color: #e0e0e0; - color: black; - border-color: hsla(220,54%,20%,.15) hsla(220,54%,20%,.17) hsla(220,54%,20%,.2); - border-radius: 0 2px 2px 0; - box-shadow: 0 0 2px hsla(0,0%,100%,.5) inset, - 0 1px 0 hsla(0,0%,100%,.2); - cursor: pointer; - transition-property: background-color, border-color, box-shadow; - transition-duration: 150ms; - width: 50px; -} - -#searchSubmit:dir(rtl) { - border-radius: 2px 0 0 2px; -} - -#searchSubmit:hover { - background-color: hsl(220,54%,20%); - color: white; -} - -#searchText:focus + #searchSubmit, -#searchText + #searchSubmit:hover { - border-color: #5985fc #4573e7 #3264d5; -} - -#searchText:focus + #searchSubmit, -#searchText[keepfocus] + #searchSubmit { - box-shadow: 0 1px 0 hsla(0,0%,100%,.2) inset, - 0 0 0 1px hsla(0,0%,100%,.1) inset, - 0 1px 0 hsla(220,54%,20%,.03); -} - -#searchText + #searchSubmit:hover { - box-shadow: 0 1px 0 hsla(0,0%,100%,.2) inset, - 0 0 0 1px hsla(0,0%,100%,.1) inset, - 0 1px 0 hsla(220,54%,20%,.03), - 0 0 4px hsla(216,100%,20%,.2); -} - -#searchText + #searchSubmit:hover:active { - box-shadow: 0 1px 1px hsla(221,79%,6%,.1) inset, - 0 0 1px hsla(221,79%,6%,.2) inset; - transition-duration: 0ms; -} - -.contentSearchSuggestionTable { - font: message-box; - font-size: 16px; -} diff --git a/application/palemoon/base/content/newtab/newTab.js b/application/palemoon/base/content/newtab/newTab.js deleted file mode 100644 index 0022f21bb..000000000 --- a/application/palemoon/base/content/newtab/newTab.js +++ /dev/null @@ -1,69 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -"use strict"; - -var Cu = Components.utils; -var Ci = Components.interfaces; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/PageThumbs.jsm"); -Cu.import("resource://gre/modules/BackgroundPageThumbs.jsm"); -Cu.import("resource://gre/modules/NewTabUtils.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "Rect", - "resource://gre/modules/Geometry.jsm"); -XPCOMUtils.defineLazyModuleGetter(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 - -// Everything is loaded. Initialize the New Tab Page. -gPage.init(); diff --git a/application/palemoon/base/content/newtab/newTab.xhtml b/application/palemoon/base/content/newtab/newTab.xhtml deleted file mode 100644 index de000e723..000000000 --- a/application/palemoon/base/content/newtab/newTab.xhtml +++ /dev/null @@ -1,61 +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/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-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="searchContainer"> - <form name="searchForm" id="searchForm" onsubmit="onSearchSubmit(event)"> - <div id="searchLogoContainer"><img id="searchEngineLogo"/></div> - <input type="text" name="q" value="" id="searchText" maxlength="256"/> - <input id="searchSubmit" type="submit" value="&newtab.searchEngineButton.label;"/> - </form> - </div> - - <div id="newtab-horizontal-margin"> - <div class="newtab-side-margin"/> - <div id="newtab-grid"> - <!-- site grid --> - </div> - <div class="newtab-side-margin"/> - </div> - - <div id="newtab-margin-bottom"/> - <input id="newtab-toggle" type="button"/> - </div> -</body> -<script type="text/javascript;version=1.8" src="chrome://browser/content/newtab/newTab.js"/> -</html> diff --git a/application/palemoon/base/content/newtab/page.js b/application/palemoon/base/content/newtab/page.js deleted file mode 100644 index 7117d4527..000000000 --- a/application/palemoon/base/content/newtab/page.js +++ /dev/null @@ -1,292 +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. - addEventListener("unload", this, false); - - // Listen for toggle button clicks. - let button = document.getElementById("newtab-toggle"); - button.addEventListener("click", e => this.toggleEnabled(e)); - - // 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); - }, - - /** - * Listens for notifications specific to this page. - */ - observe: function Page_observe(aSubject, aTopic, aData) { - if (aTopic == "nsPref:changed") { - 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 = setTimeout(() => { - // Refresh if the grid is ready. - if (gGrid.ready) { - gGrid.refresh(); - } - - this._scheduleUpdateTimeout = null; - }, 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("searchSubmit").value = - document.body.getAttribute("dir") == "ltr" ? "\u25B6" : "\u25C0"; - - 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, false); - document.addEventListener("drop", this, false); -#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, #searchContainer"; - 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); - // compute page life-span and send telemetry probe: using milli-seconds will leave - // many low buckets empty. Instead we use half-second precision to make low end - // of histogram linear and not lose the change in user attention - let delta = Math.round((Date.now() - this._firstVisibleTime) / 500); - if (this._suggestedTilePresent) { - Services.telemetry.getHistogramById("NEWTAB_PAGE_LIFE_SPAN_SUGGESTED").add(delta); - } - else { - Services.telemetry.getHistogramById("NEWTAB_PAGE_LIFE_SPAN").add(delta); - } - }, - - /** - * Handles all page events. - */ - handleEvent: function Page_handleEvent(aEvent) { - switch (aEvent.type) { - case "load": - this.onPageVisibleAndLoaded(); - break; - case "unload": - this._handleUnloadEvent(); - 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) { - clearTimeout(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 () { - // Record another page impression. - Services.telemetry.getHistogramById("NEWTAB_PAGE_SHOWN").add(true); - - for (let site of gGrid.sites) { - if (site) { - // The site may need to modify and/or re-render itself if - // something changed after newtab was created by preloader. - // For example, the suggested tile endTime may have passed. - site.onFirstVisible(); - } - } - - // save timestamp to compute page life-span delta - this._firstVisibleTime = Date.now(); - - if (document.readyState == "complete") { - this.onPageVisibleAndLoaded(); - } else { - addEventListener("load", this); - } - }, - - onPageVisibleAndLoaded() { - // Send the index of the last visible tile. - this.reportLastVisibleTileIndex(); - // Maybe tell the user they can undo an initial automigration - this.maybeShowAutoMigrationUndoNotification(); - }, - - reportLastVisibleTileIndex() { - let cwu = window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils); - - let rect = cwu.getBoundsWithoutFlushing(gGrid.node); - let nodes = cwu.nodesFromRect(rect.left, rect.top, 0, rect.width, - rect.height, 0, true, false); - - let i = -1; - let lastIndex = -1; - let sites = gGrid.sites; - - for (let node of nodes) { - if (node.classList && node.classList.contains("newtab-cell")) { - if (sites[++i]) { - lastIndex = i; - if (sites[i].link.targetedSite) { - // record that suggested tile is shown to use suggested-tiles-histogram - this._suggestedTilePresent = true; - } - } - } - } - }, - - toggleEnabled: function(aEvent) { - gAllPages.enabled = !gAllPages.enabled; - event.stopPropagation(); - }, - - maybeShowAutoMigrationUndoNotification() { - // sendAsyncMessage("NewTab:MaybeShowAutoMigrationUndoNotification"); - }, -}; diff --git a/application/palemoon/base/content/newtab/search.js b/application/palemoon/base/content/newtab/search.js deleted file mode 100644 index 8bc959eee..000000000 --- a/application/palemoon/base/content/newtab/search.js +++ /dev/null @@ -1,134 +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 SEARCH_ENGINES = { - "DuckDuckGo": { - image: "data:image/png;base64," + - "iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAACT1BMVEXvISn/////9/fvUlr3ra3/" + - "zs7/7+/va2v/5+f/xsbvMTn/tbX/3t7/vb3vOUL3WmPvQkr/zgDvKTHvSlL3hIT3paX/1tbnISn3" + - "c3v3e3v3a3P3jIz3nJz/tb33c3PvKSn3lJT39/cAc73vSkr3e4Tv7+/3Yxj3pa3/tQj3jJT3nKX3" + - "Y2P/xs73hIzvQkL/vQjvQiHn5+f3hBD/ztbvMTH/vcb/3ucIc733lJz/pQilzufe7/fvMSHOzs73" + - "//cQrUpKvVprxmP3Y2vvShiUzmvWlJRzzmMYtUrvOTnn7/davVrWra3v9//nY2PvISGUxudztd7e" + - "3t7/76XvKSHea2v/xgDnOUK93vfW5/f/1t73Uhj/52ut3q2l3rXO784pjMZrrdb/rQjera3/5+/e" + - "paWMxufO79aEazkYrUr/nAj3jBD3axj3lBD///fehIRKpd7/1hCEYzk5vVL3//8ptVLW77UxtVLn" + - "SlLW1tZCvVp7vef/1gj/3invSkL//+fWtbXvpaX/3kr/97XvnJznWmMxjM5zvefOxsbWnKXWjIzG" + - "3u/ea3Pn997O5/fnQkqExuf3Whit1u/nUlrnxs7v5+d7zmuU1pT3exDOSjFjrVL/987/pUoQe8b/" + - "75T/3jFKxnO158bWKSl7zoRSxmtajEK1e0pzxlqcUjH/1iHOMSnOvb33cxDWnJx7td6EzmP/74xz" + - "azlrcznec3Pe771jxlpzczne78YpvVqEvWPn99YxvWOtSjHee3vG787OOTE5lEK1QjHv9+drzmve" + - "tbXO772q+r8wAAAFbUlEQVR4Xo2X84PzTBDHN3Zqu2fbemzbNl7atm3btvGHvTNJ2myuyd3NL2mT" + - "zmdnvjM76RImyGQlH5dCHBeSmscNmQkyfwBrZMLEY2aRF5cMSDYPEx+LZpUlAYRQbVEpnuc1je/M" + - "SbVwYoVFAbpE0IaLmiwqiVymmE3H84YuGs2mheCEhQH5qPUrje2ONxHKVIkXR2x2MxsMkDnLvftk" + - "2fSTQNCzSAgngwCCipkXxHiU+BsnCDFE8f6AQgnwaTGhkmDLymW8jPsBeIsth8iCpha618El1wgo" + - "4FOhWyWLWY+O8pbnAwTI29S1ElncJBmF4L0AGeJSdR4dUpt5w+DL0nAgoUuGGKKCBxDCOxrykaDb" + - "+yFQjhUylLlXpAB5jGnIqV6uvvWUcAAhLmDBXIAMrkXRdHQ+cerUiWefq1hRrAgg8LikUgdkQUAx" + - "6+2Ze0WLEO/1BQzrHCFNrAPAeDSD4q/Ln6R3p68MSYzDAUiwIEutJM0bHXE/gpEhJMxaAB3T6aT8" + - "mfkm+QBiMlwKFqAHvrHu9tvTOLrEdX4hFAkJWQB42qbVyam75ruv3zvF+wBCKJ0MAAV6SAy5+raA" + - "y+lb9tYBUw9sffKRJh+CDl2SAEAPquaC76swU1c+zlxbA9if/EIY78AcCBODDKjnVzDM0+sb57zq" + - "N14gdpbg4nraBaxm3NWpIDKNgJIIDTxEAKMyVM9/VrFcpijK52PbNhmk0RQORCA8dhGhIkDA+qPV" + - "Y/U8No2NHZsUfQCdzYTECSiRSRJKgxYAnK6+tnVrPYL7q2P7GNNnT0L3SQSS61AowK4BAExWq9XJ" + - "OmDT5D4GtUab7p92W1aD6AFBOjUKcONNKMG2o9vmScmhd+v5SCTS91StDLBwmHR5q0iiM4yv3X5g" + - "sD1i24tUHc0GQOrOihdw+ZV7drx+8I1IzfpaCQ1oSIGsbqEBdxy8KkLb8dYt7m7AFBpEJI8OUIAd" + - "Hve+wX509IqYgzLqxKMi5X+r6737wgHfMrZBKGwpQMWP0PN8/8qLn15cSRosEQeI3coxGrzRVfE2" + - "BEyTAMNpmbA3k2erPOyq+CUCPGvv3OmGykYBQhiYFbynDLu2uyW826qb7bSlv/VCe2R3vQqhIYQQ" + - "nLmSGKUAT1AqXn7V6p72iUsTThsNuhKUAeKMNFaiW2nG08H90IF1m6DywVdsHgA4bPgRGgAqUgBr" + - "DwxOtPcdv9RK6yklnaGKOXBMmN7RVCtJJMiUdG2s78dv9HbY7KrI9AQBOHwjaxaA6cKhRLXCHkpF" + - "PrAJYBz1su7LtSBQIjzozgI5AJDWsQ7gTJxETTHuEh5yW8kR5+1fvQBT5PDdWgPokE6GSuK3Aaby" + - "2KwNyGFIZ8/NfexVMAGXEfe8MA5QTVdrgGe2M9evev6FMwiAYr308nVzcx/SgHwSlswyLgDLHU0K" + - "tX5UZwCwZsM1b7516J1333v/g2UAuJoCNMsmZkEDZBXujCoOIfVJxQKsvXnDshvWfrEcAV9RAoqY" + - "rfdvHjY06R3tVmtjzQYsQ8ByC/C1O0dEzqkAGqELbiZ1W/RvBr51Ad9ZgO8dQCkh4/q5xvMC6hot" + - "sBl7rP1QT+HHQz9RGoSHhkyMgqEBdNPFWSWMY+1nBPxy+MjvZ2aZxB9n/zz3FwKiOTZfotb3AhhF" + - "xSUUNmGSjX+vWvPPYacVWJOkUilUT05ymEVb0JFHj9l/AVn+35b/jsx6YzNz8mja+iAEH7rYDntY" + - "Gaz3dizW080KWaeICx77kiG7lTKG6EEoPb0Wu0lZ9OA5whFH8GxHQjOMQls5HSs5t/glHX2FYtT/" + - "mGAs/fCtFU0vQJUSQYfvIBvVyukuLhbjuood/H6WCbD/AQSFvIO3JDxgAAAAAElFTkSuQmCC" - } -}; - -// This global tracks if the page has been set up before, to prevent double inits -var gInitialized = false; -var gObserver = new MutationObserver(function (mutations) { - for (let mutation of mutations) { - if (mutation.attributeName == "searchEngineURL") { - setupSearchEngine(); - if (!gInitialized) { - gInitialized = true; - } - return; - } - } -}); - -window.addEventListener("pageshow", function () { - window.gObserver.observe(document.documentElement, { attributes: true }); -}); - -window.addEventListener("pagehide", function() { - window.gObserver.disconnect(); -}); - -function onSearchSubmit(aEvent) { - let searchTerms = document.getElementById("searchText").value; - let searchURL = document.documentElement.getAttribute("searchEngineURL"); - - if (searchURL && searchTerms.length > 0) { - const SEARCH_TOKEN = "_searchTerms_"; - let searchPostData = document.documentElement.getAttribute("searchEnginePostData"); - if (searchPostData) { - // Check if a post form already exists. If so, remove it. - const POST_FORM_NAME = "searchFormPost"; - let form = document.forms[POST_FORM_NAME]; - if (form) { - form.parentNode.removeChild(form); - } - - // Create a new post form. - form = document.body.appendChild(document.createElement("form")); - form.setAttribute("name", POST_FORM_NAME); - // Set the URL to submit the form to. - form.setAttribute("action", searchURL.replace(SEARCH_TOKEN, searchTerms)); - form.setAttribute("method", "post"); - - // Create new <input type=hidden> elements for search param. - searchPostData = searchPostData.split("&"); - for (let postVar of searchPostData) { - let [name, value] = postVar.split("="); - if (value == SEARCH_TOKEN) { - value = searchTerms; - } - let input = document.createElement("input"); - input.setAttribute("type", "hidden"); - input.setAttribute("name", name); - input.setAttribute("value", value); - form.appendChild(input); - } - // Submit the form. - form.submit(); - } else { - searchURL = searchURL.replace(SEARCH_TOKEN, encodeURIComponent(searchTerms)); - window.location.href = searchURL; - } - } - - aEvent.preventDefault(); -} - - -function setupSearchEngine() { - let searchText = document.getElementById("searchText"); - let searchEngineName = document.documentElement.getAttribute("searchEngineName"); - let searchEngineInfo = SEARCH_ENGINES[searchEngineName]; - let logoElt = document.getElementById("searchEngineLogo"); - - // Add search engine logo. - if (searchEngineInfo && searchEngineInfo.image) { - logoElt.parentNode.hidden = false; - logoElt.src = searchEngineInfo.image; - logoElt.alt = searchEngineName; - searchText.placeholder = ""; - } else { - logoElt.parentNode.hidden = true; - searchText.placeholder = searchEngineName; - } -} diff --git a/application/palemoon/base/content/newtab/sites.js b/application/palemoon/base/content/newtab/sites.js deleted file mode 100644 index a368146bb..000000000 --- a/application/palemoon/base/content/newtab/sites.js +++ /dev/null @@ -1,365 +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). - * @return true if link changed type after pin - */ - pin: function Site_pin(aIndex) { - if (typeof aIndex == "undefined") - aIndex = this.cell.index; - - this._updateAttributes(true); - let changed = gPinnedLinks.pin(this._link, aIndex); - if (changed) { - // render site again - this._render(); - } - return changed; - }, - - /** - * 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; - }, - - _getSuggestedTileExplanation: function() { - let targetedName = `<strong> ${this.link.targetedName} </strong>`; - let targetedSite = `<strong> ${this.link.targetedSite} </strong>`; - if (this.link.explanation) { - return this._newTabString(this.link.explanation, [targetedName, targetedSite]); - } - return newTabString("suggested.button", [targetedName]); - }, - - /** - * Checks for and modifies link at campaign end time - */ - _checkLinkEndTime: function Site_checkLinkEndTime() { - if (this.link.endTime && this.link.endTime < Date.now()) { - let oldUrl = this.url; - // chop off the path part from url - this.link.url = Services.io.newURI(this.url, null, null).resolve("/"); - // clear supplied images - this triggers thumbnail download for new url - delete this.link.imageURI; - delete this.link.enhancedImageURI; - // remove endTime to avoid further time checks - delete this.link.endTime; - // clear enhanced-content image that may still exist in preloaded page - this._querySelector(".enhanced-content").style.backgroundImage = ""; - gPinnedLinks.replace(oldUrl, this.link); - } - }, - - /** - * Renders the site's data (fills the HTML fragment). - */ - _render: function Site_render() { - // first check for end time, as it may modify the link - this._checkLinkEndTime(); - // setup display variables - let url = this.url; - let 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(); - }, - - /** - * Called when the site's tab becomes visible for the first time. - * Since the newtab may be preloaded long before it's displayed, - * check for changed conditions and re-render if needed - */ - onFirstVisible: function Site_onFirstVisible() { - if (this.link.endTime && this.link.endTime < Date.now()) { - // site needs to change landing url and background image - this._render(); - } - else { - this.captureIfMissing(); - } - }, - - /** - * 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) { - BackgroundPageThumbs.captureIfMissing(this.url); - } - }, - - /** - * Refreshes the thumbnail for the site. - */ - refreshThumbnail: function Site_refreshThumbnail() { - let link = 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.style.backgroundImage = 'url("' + 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(); - } - }, - - _ignoreHoverEvents: function(element) { - element.addEventListener("mouseover", () => { - this.cell.node.setAttribute("ignorehover", "true"); - }); - element.addEventListener("mouseout", () => { - this.cell.node.removeAttribute("ignorehover"); - }); - }, - - /** - * Adds event handlers for the site and its buttons. - */ - _addEventHandlers: function Site_addEventHandlers() { - // Register drag-and-drop event handlers. - this._node.addEventListener("dragstart", this, false); - this._node.addEventListener("dragend", this, false); - this._node.addEventListener("mouseover", this, false); - }, - - /** - * 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, null, null); - try { - // This can throw for certain internal URLs, when they wind up in - // about:newtab. Be sure not to propagate the error. - sc.speculativeConnect(uri, null); - } catch (e) {} - }, - - /** - * Record interaction with site using telemetry. - */ - _recordSiteClicked: function Site_recordSiteClicked(aIndex) { - if (Services.prefs.prefHasUserValue("browser.newtabpage.rows") || - Services.prefs.prefHasUserValue("browser.newtabpage.columns") || - aIndex > 8) { - // We only want to get indices for the default configuration, everything - // else goes in the same bucket. - aIndex = 9; - } - Services.telemetry.getHistogramById("NEWTAB_PAGE_SITE_CLICKED") - .add(aIndex); - }, - - _toggleLegalText: function(buttonClass, explanationTextClass) { - let button = this._querySelector(buttonClass); - if (button.hasAttribute("active")) { - let explain = this._querySelector(explanationTextClass); - explain.parentNode.removeChild(explain); - - button.removeAttribute("active"); - } - }, - - /** - * Handles site click events. - */ - onClick: function Site_onClick(aEvent) { - let action; - let pinned = this.isPinned(); - let tileIndex = this.cell.index; - let {button, target} = aEvent; - - // Handle tile/thumbnail link click - if (target.classList.contains("newtab-link") || - target.parentElement.classList.contains("newtab-link")) { - // Record for primary and middle clicks - if (button == 0 || button == 1) { - this._recordSiteClicked(tileIndex); - action = "click"; - } - } - // Only handle primary clicks for the remaining targets - else if (button == 0) { - aEvent.preventDefault(); - if (target.classList.contains("newtab-control-block")) { - this.block(); - action = "block"; - } - else if (pinned && target.classList.contains("newtab-control-pin")) { - this.unpin(); - action = "unpin"; - } - else if (!pinned && target.classList.contains("newtab-control-pin")) { - if (this.pin()) { - // suggested link has changed - update rest of the pages - gAllPages.update(gPage); - } - action = "pin"; - } - } - }, - - /** - * Handles all site events. - */ - handleEvent: function Site_handleEvent(aEvent) { - switch (aEvent.type) { - case "mouseover": - this._node.removeEventListener("mouseover", this, false); - this._speculativeConnect(); - break; - case "dragstart": - gDrag.start(this, aEvent); - break; - case "dragend": - gDrag.end(this, aEvent); - break; - } - } -}; diff --git a/application/palemoon/base/content/newtab/transformations.js b/application/palemoon/base/content/newtab/transformations.js deleted file mode 100644 index f7db0ad84..000000000 --- a/application/palemoon/base/content/newtab/transformations.js +++ /dev/null @@ -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, null); - 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, null); - 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"); - } -}; diff --git a/application/palemoon/base/content/newtab/undo.js b/application/palemoon/base/content/newtab/undo.js deleted file mode 100644 index b856914d2..000000000 --- a/application/palemoon/base/content/newtab/undo.js +++ /dev/null @@ -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, false); - 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(function() { - gUpdater.updateGrid(); - this.hide(); - }.bind(this)); - } -}; - -gUndoDialog.init(); diff --git a/application/palemoon/base/content/newtab/updater.js b/application/palemoon/base/content/newtab/updater.js deleted file mode 100644 index 2bab74d70..000000000 --- a/application/palemoon/base/content/newtab/updater.js +++ /dev/null @@ -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.indexOf(aSite) != -1) - 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.parentNode.removeChild(node); - 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); - } -}; diff --git a/application/palemoon/base/content/pageinfo/feeds.js b/application/palemoon/base/content/pageinfo/feeds.js deleted file mode 100644 index 468d8c19d..000000000 --- a/application/palemoon/base/content/pageinfo/feeds.js +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -function initFeedTab() -{ - const feedTypes = { - "application/rss+xml": gBundle.getString("feedRss"), - "application/atom+xml": gBundle.getString("feedAtom"), - "text/xml": gBundle.getString("feedXML"), - "application/xml": gBundle.getString("feedXML"), - "application/rdf+xml": gBundle.getString("feedXML") - }; - - // get the feeds - var linkNodes = gDocument.getElementsByTagName("link"); - var length = linkNodes.length; - for (var i = 0; i < length; i++) { - var link = linkNodes[i]; - if (!link.href) - continue; - - var rel = link.rel && link.rel.toLowerCase(); - var rels = {}; - if (rel) { - for each (let relVal in rel.split(/\s+/)) - rels[relVal] = true; - } - - if (rels.feed || (link.type && rels.alternate && !rels.stylesheet)) { - var type = isValidFeed(link, gDocument.nodePrincipal, "feed" in rels); - if (type) { - type = feedTypes[type] || feedTypes["application/rss+xml"]; - addRow(link.title, type, link.href); - } - } - } - - var feedListbox = document.getElementById("feedListbox"); - document.getElementById("feedTab").hidden = feedListbox.getRowCount() == 0; -} - -function onSubscribeFeed() -{ - var listbox = document.getElementById("feedListbox"); - openUILinkIn(listbox.selectedItem.getAttribute("feedURL"), "current", - { ignoreAlt: true }); -} - -function addRow(name, type, url) -{ - var item = document.createElement("richlistitem"); - item.setAttribute("feed", "true"); - item.setAttribute("name", name); - item.setAttribute("type", type); - item.setAttribute("feedURL", url); - document.getElementById("feedListbox").appendChild(item); -} diff --git a/application/palemoon/base/content/pageinfo/feeds.xml b/application/palemoon/base/content/pageinfo/feeds.xml deleted file mode 100644 index 782c05a73..000000000 --- a/application/palemoon/base/content/pageinfo/feeds.xml +++ /dev/null @@ -1,40 +0,0 @@ -<?xml version="1.0"?> -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE bindings [ - <!ENTITY % pageInfoDTD SYSTEM "chrome://browser/locale/pageInfo.dtd"> - %pageInfoDTD; -]> - -<bindings id="feedBindings" - xmlns="http://www.mozilla.org/xbl" - xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:xbl="http://www.mozilla.org/xbl"> - - <binding id="feed" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem"> - <content> - <xul:vbox flex="1"> - <xul:hbox flex="1"> - <xul:textbox flex="1" readonly="true" xbl:inherits="value=name" - class="feedTitle"/> - <xul:label xbl:inherits="value=type"/> - </xul:hbox> - <xul:vbox> - <xul:vbox align="start"> - <xul:hbox> - <xul:label xbl:inherits="value=feedURL,tooltiptext=feedURL" class="text-link" flex="1" - onclick="openUILink(this.value, event);" crop="end"/> - </xul:hbox> - </xul:vbox> - </xul:vbox> - <xul:hbox flex="1" class="feed-subscribe"> - <xul:spacer flex="1"/> - <xul:button label="&feedSubscribe;" accesskey="&feedSubscribe.accesskey;" - oncommand="onSubscribeFeed()"/> - </xul:hbox> - </xul:vbox> - </content> - </binding> -</bindings> diff --git a/application/palemoon/base/content/pageinfo/pageInfo.css b/application/palemoon/base/content/pageinfo/pageInfo.css deleted file mode 100644 index 622b56bb5..000000000 --- a/application/palemoon/base/content/pageinfo/pageInfo.css +++ /dev/null @@ -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/. */ - - -#viewGroup > radio { - -moz-binding: url("chrome://browser/content/pageinfo/pageInfo.xml#viewbutton"); -} - -richlistitem[feed] { - -moz-binding: url("chrome://browser/content/pageinfo/feeds.xml#feed"); -} - -richlistitem[feed]:not([selected="true"]) .feed-subscribe { - display: none; -} - -groupbox[closed="true"] > .groupbox-body { - visibility: collapse; -} - -#thepreviewimage { - display: block; -/* This following entry can be removed when Bug 522850 is fixed. */ - min-width: 1px; -} diff --git a/application/palemoon/base/content/pageinfo/pageInfo.js b/application/palemoon/base/content/pageinfo/pageInfo.js deleted file mode 100644 index 600174ad9..000000000 --- a/application/palemoon/base/content/pageinfo/pageInfo.js +++ /dev/null @@ -1,1286 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Cu = Components.utils; -Cu.import("resource://gre/modules/LoadContextInfo.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -//******** define a js object to implement nsITreeView -function pageInfoTreeView(treeid, copycol) -{ - // copycol is the index number for the column that we want to add to - // the copy-n-paste buffer when the user hits accel-c - this.treeid = treeid; - this.copycol = copycol; - this.rows = 0; - this.tree = null; - this.data = [ ]; - this.selection = null; - this.sortcol = -1; - this.sortdir = false; -} - -pageInfoTreeView.prototype = { - set rowCount(c) { throw "rowCount is a readonly property"; }, - get rowCount() { return this.rows; }, - - setTree: function(tree) - { - this.tree = tree; - }, - - getCellText: function(row, column) - { - // row can be null, but js arrays are 0-indexed. - // colidx cannot be null, but can be larger than the number - // of columns in the array. In this case it's the fault of - // whoever typoed while calling this function. - return this.data[row][column.index] || ""; - }, - - setCellValue: function(row, column, value) - { - }, - - setCellText: function(row, column, value) - { - this.data[row][column.index] = value; - }, - - addRow: function(row) - { - this.rows = this.data.push(row); - this.rowCountChanged(this.rows - 1, 1); - if (this.selection.count == 0 && this.rowCount && !gImageElement) - this.selection.select(0); - }, - - rowCountChanged: function(index, count) - { - this.tree.rowCountChanged(index, count); - }, - - invalidate: function() - { - this.tree.invalidate(); - }, - - clear: function() - { - if (this.tree) - this.tree.rowCountChanged(0, -this.rows); - this.rows = 0; - this.data = [ ]; - }, - - handleCopy: function(row) - { - return (row < 0 || this.copycol < 0) ? "" : (this.data[row][this.copycol] || ""); - }, - - performActionOnRow: function(action, row) - { - if (action == "copy") { - var data = this.handleCopy(row) - this.tree.treeBody.parentNode.setAttribute("copybuffer", data); - } - }, - - onPageMediaSort : function(columnname) - { - var tree = document.getElementById(this.treeid); - var treecol = tree.columns.getNamedColumn(columnname); - - this.sortdir = - gTreeUtils.sort( - tree, - this, - this.data, - treecol.index, - function textComparator(a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()); }, - this.sortcol, - this.sortdir - ); - - this.sortcol = treecol.index; - }, - - getRowProperties: function(row) { return ""; }, - getCellProperties: function(row, column) { return ""; }, - getColumnProperties: function(column) { return ""; }, - isContainer: function(index) { return false; }, - isContainerOpen: function(index) { return false; }, - isSeparator: function(index) { return false; }, - isSorted: function() { }, - canDrop: function(index, orientation) { return false; }, - drop: function(row, orientation) { return false; }, - getParentIndex: function(index) { return 0; }, - hasNextSibling: function(index, after) { return false; }, - getLevel: function(index) { return 0; }, - getImageSrc: function(row, column) { }, - getProgressMode: function(row, column) { }, - getCellValue: function(row, column) { }, - toggleOpenState: function(index) { }, - cycleHeader: function(col) { }, - selectionChanged: function() { }, - cycleCell: function(row, column) { }, - isEditable: function(row, column) { return false; }, - isSelectable: function(row, column) { return false; }, - performAction: function(action) { }, - performActionOnCell: function(action, row, column) { } -}; - -// mmm, yummy. global variables. -var gWindow = null; -var gDocument = null; -var gImageElement = null; - -// column number to help using the data array -const COL_IMAGE_ADDRESS = 0; -const COL_IMAGE_TYPE = 1; -const COL_IMAGE_SIZE = 2; -const COL_IMAGE_ALT = 3; -const COL_IMAGE_COUNT = 4; -const COL_IMAGE_NODE = 5; -const COL_IMAGE_BG = 6; - -// column number to copy from, second argument to pageInfoTreeView's constructor -const COPYCOL_NONE = -1; -const COPYCOL_META_CONTENT = 1; -const COPYCOL_IMAGE = COL_IMAGE_ADDRESS; - -// one nsITreeView for each tree in the window -var gMetaView = new pageInfoTreeView('metatree', COPYCOL_META_CONTENT); -var gImageView = new pageInfoTreeView('imagetree', COPYCOL_IMAGE); - -gImageView.getCellProperties = function(row, col) { - var data = gImageView.data[row]; - var item = gImageView.data[row][COL_IMAGE_NODE]; - var props = ""; - if (!checkProtocol(data) || - item instanceof HTMLEmbedElement || - (item instanceof HTMLObjectElement && !item.type.startsWith("image/"))) - props += "broken"; - - if (col.element.id == "image-address") - props += " ltr"; - - return props; -}; - -gImageView.getCellText = function(row, column) { - var value = this.data[row][column.index]; - if (column.index == COL_IMAGE_SIZE) { - if (value == -1) { - return gStrings.unknown; - } else { - var kbSize = Number(Math.round(value / 1024 * 100) / 100); - return gBundle.getFormattedString("mediaFileSize", [kbSize]); - } - } - return value || ""; -}; - -gImageView.onPageMediaSort = function(columnname) { - var tree = document.getElementById(this.treeid); - var treecol = tree.columns.getNamedColumn(columnname); - - var comparator; - if (treecol.index == COL_IMAGE_SIZE || treecol.index == COL_IMAGE_COUNT) { - comparator = function numComparator(a, b) { return a - b; }; - } else { - comparator = function textComparator(a, b) { return a.toLowerCase().localeCompare(b.toLowerCase()); }; - } - - this.sortdir = - gTreeUtils.sort( - tree, - this, - this.data, - treecol.index, - comparator, - this.sortcol, - this.sortdir - ); - - this.sortcol = treecol.index; -}; - -var gImageHash = { }; - -// localized strings (will be filled in when the document is loaded) -// this isn't all of them, these are just the ones that would otherwise have been loaded inside a loop -var gStrings = { }; -var gBundle; - -const PERMISSION_CONTRACTID = "@mozilla.org/permissionmanager;1"; -const PREFERENCES_CONTRACTID = "@mozilla.org/preferences-service;1"; -const ATOM_CONTRACTID = "@mozilla.org/atom-service;1"; - -// a number of services I'll need later -// the cache services -const nsICacheStorageService = Components.interfaces.nsICacheStorageService; -const nsICacheStorage = Components.interfaces.nsICacheStorage; -const cacheService = Components.classes["@mozilla.org/netwerk/cache-storage-service;1"].getService(nsICacheStorageService); - -var loadContextInfo = LoadContextInfo.fromLoadContext( - window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) - .getInterface(Components.interfaces.nsIWebNavigation) - .QueryInterface(Components.interfaces.nsILoadContext), false); -var diskStorage = cacheService.diskCacheStorage(loadContextInfo, false); - -const nsICookiePermission = Components.interfaces.nsICookiePermission; -const nsIPermissionManager = Components.interfaces.nsIPermissionManager; - -const nsICertificateDialogs = Components.interfaces.nsICertificateDialogs; -const CERTIFICATEDIALOGS_CONTRACTID = "@mozilla.org/nsCertificateDialogs;1" - -// clipboard helper -function getClipboardHelper() { - try { - return Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper); - } catch(e) { - // do nothing, later code will handle the error - } -} -const gClipboardHelper = getClipboardHelper(); - -// Interface for image loading content -const nsIImageLoadingContent = Components.interfaces.nsIImageLoadingContent; - -// namespaces, don't need all of these yet... -const XLinkNS = "http://www.w3.org/1999/xlink"; -const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; -const XMLNS = "http://www.w3.org/XML/1998/namespace"; -const XHTMLNS = "http://www.w3.org/1999/xhtml"; -const XHTML2NS = "http://www.w3.org/2002/06/xhtml2" - -const XHTMLNSre = "^http\:\/\/www\.w3\.org\/1999\/xhtml$"; -const XHTML2NSre = "^http\:\/\/www\.w3\.org\/2002\/06\/xhtml2$"; -const XHTMLre = RegExp(XHTMLNSre + "|" + XHTML2NSre, ""); - -/* Overlays register functions here. - * These arrays are used to hold callbacks that Page Info will call at - * various stages. Use them by simply appending a function to them. - * For example, add a function to onLoadRegistry by invoking - * "onLoadRegistry.push(XXXLoadFunc);" - * The XXXLoadFunc should be unique to the overlay module, and will be - * invoked as "XXXLoadFunc();" - */ - -// These functions are called to build the data displayed in the Page -// Info window. The global variables gDocument and gWindow are set. -var onLoadRegistry = [ ]; - -// These functions are called to remove old data still displayed in -// the window when the document whose information is displayed -// changes. For example, at this time, the list of images of the Media -// tab is cleared. -var onResetRegistry = [ ]; - -// These are called once for each subframe of the target document and -// the target document itself. The frame is passed as an argument. -var onProcessFrame = [ ]; - -// These functions are called once for each element (in all subframes, if any) -// in the target document. The element is passed as an argument. -var onProcessElement = [ ]; - -// These functions are called once when all the elements in all of the target -// document (and all of its subframes, if any) have been processed -var onFinished = [ ]; - -// These functions are called once when the Page Info window is closed. -var onUnloadRegistry = [ ]; - -// These functions are called once when an image preview is shown. -var onImagePreviewShown = [ ]; - -/* Called when PageInfo window is loaded. Arguments are: - * window.arguments[0] - (optional) an object consisting of - * - doc: (optional) document to use for source. if not provided, - * the calling window's document will be used - * - initialTab: (optional) id of the inital tab to display - */ -function onLoadPageInfo() -{ - gBundle = document.getElementById("pageinfobundle"); - gStrings.unknown = gBundle.getString("unknown"); - gStrings.notSet = gBundle.getString("notset"); - gStrings.mediaImg = gBundle.getString("mediaImg"); - gStrings.mediaBGImg = gBundle.getString("mediaBGImg"); - gStrings.mediaBorderImg = gBundle.getString("mediaBorderImg"); - gStrings.mediaListImg = gBundle.getString("mediaListImg"); - gStrings.mediaCursor = gBundle.getString("mediaCursor"); - gStrings.mediaObject = gBundle.getString("mediaObject"); - gStrings.mediaEmbed = gBundle.getString("mediaEmbed"); - gStrings.mediaLink = gBundle.getString("mediaLink"); - gStrings.mediaInput = gBundle.getString("mediaInput"); - gStrings.mediaVideo = gBundle.getString("mediaVideo"); - gStrings.mediaAudio = gBundle.getString("mediaAudio"); - - var args = "arguments" in window && - window.arguments.length >= 1 && - window.arguments[0]; - - if (!args || !args.doc) { - gWindow = window.opener.content; - gDocument = gWindow.document; - } - - // init media view - var imageTree = document.getElementById("imagetree"); - imageTree.view = gImageView; - - /* Select the requested tab, if the name is specified */ - loadTab(args); - Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService) - .notifyObservers(window, "page-info-dialog-loaded", null); - - // Make sure the page info window gets focus even if a doorhanger might - // otherwise (async) steal it. - window.focus(); -} - -function loadPageInfo() -{ - var titleFormat = gWindow != gWindow.top ? "pageInfo.frame.title" - : "pageInfo.page.title"; - document.title = gBundle.getFormattedString(titleFormat, [gDocument.location]); - - document.getElementById("main-window").setAttribute("relatedUrl", gDocument.location); - - // do the easy stuff first - makeGeneralTab(); - - // and then the hard stuff - makeTabs(gDocument, gWindow); - - initFeedTab(); - onLoadPermission(gDocument.nodePrincipal); - - /* Call registered overlay init functions */ - onLoadRegistry.forEach(function(func) { func(); }); -} - -function resetPageInfo(args) -{ - /* Reset Meta tags part */ - gMetaView.clear(); - - /* Reset Media tab */ - var mediaTab = document.getElementById("mediaTab"); - if (!mediaTab.hidden) { - Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService) - .removeObserver(imagePermissionObserver, "perm-changed"); - mediaTab.hidden = true; - } - gImageView.clear(); - gImageHash = {}; - - /* Reset Feeds Tab */ - var feedListbox = document.getElementById("feedListbox"); - while (feedListbox.firstChild) - feedListbox.removeChild(feedListbox.firstChild); - - /* Call registered overlay reset functions */ - onResetRegistry.forEach(function(func) { func(); }); - - /* Rebuild the data */ - loadTab(args); -} - -function onUnloadPageInfo() -{ - // Remove the observer, only if there is at least 1 image. - if (!document.getElementById("mediaTab").hidden) { - Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService) - .removeObserver(imagePermissionObserver, "perm-changed"); - } - - /* Call registered overlay unload functions */ - onUnloadRegistry.forEach(function(func) { func(); }); -} - -function doHelpButton() -{ - const helpTopics = { - "generalPanel": "pageinfo_general", - "mediaPanel": "pageinfo_media", - "feedPanel": "pageinfo_feed", - "permPanel": "pageinfo_permissions", - "securityPanel": "pageinfo_security" - }; - - var deck = document.getElementById("mainDeck"); - var helpdoc = helpTopics[deck.selectedPanel.id] || "pageinfo_general"; - openHelpLink(helpdoc); -} - -function showTab(id) -{ - var deck = document.getElementById("mainDeck"); - var pagel = document.getElementById(id + "Panel"); - deck.selectedPanel = pagel; -} - -function loadTab(args) -{ - if (args && args.doc) { - gDocument = args.doc; - gWindow = gDocument.defaultView; - } - - gImageElement = args && args.imageElement; - - /* Load the page info */ - loadPageInfo(); - - var initialTab = (args && args.initialTab) || "generalTab"; - var radioGroup = document.getElementById("viewGroup"); - initialTab = document.getElementById(initialTab) || document.getElementById("generalTab"); - radioGroup.selectedItem = initialTab; - radioGroup.selectedItem.doCommand(); - radioGroup.focus(); -} - -function onClickMore() -{ - var radioGrp = document.getElementById("viewGroup"); - var radioElt = document.getElementById("securityTab"); - radioGrp.selectedItem = radioElt; - showTab('security'); -} - -function toggleGroupbox(id) -{ - var elt = document.getElementById(id); - if (elt.hasAttribute("closed")) { - elt.removeAttribute("closed"); - if (elt.flexWhenOpened) - elt.flex = elt.flexWhenOpened; - } - else { - elt.setAttribute("closed", "true"); - if (elt.flex) { - elt.flexWhenOpened = elt.flex; - elt.flex = 0; - } - } -} - -function openCacheEntry(key, cb) -{ - var checkCacheListener = { - onCacheEntryCheck: function(entry, appCache) { - return Components.interfaces.nsICacheEntryOpenCallback.ENTRY_WANTED; - }, - onCacheEntryAvailable: function(entry, isNew, appCache, status) { - cb(entry); - }, - get mainThreadOnly() { return true; } - }; - diskStorage.asyncOpenURI(Services.io.newURI(key, null, null), "", nsICacheStorage.OPEN_READONLY, checkCacheListener); -} - -function makeGeneralTab() -{ - var title = (gDocument.title) ? gBundle.getFormattedString("pageTitle", [gDocument.title]) : gBundle.getString("noPageTitle"); - document.getElementById("titletext").value = title; - - var url = gDocument.location.toString(); - setItemValue("urltext", url); - - var referrer = ("referrer" in gDocument && gDocument.referrer); - setItemValue("refertext", referrer); - - var mode = ("compatMode" in gDocument && gDocument.compatMode == "BackCompat") ? "generalQuirksMode" : "generalStrictMode"; - document.getElementById("modetext").value = gBundle.getString(mode); - - // find out the mime type - var mimeType = gDocument.contentType; - setItemValue("typetext", mimeType); - - // get the document characterset - var encoding = gDocument.characterSet; - document.getElementById("encodingtext").value = encoding; - - // get the meta tags - var metaNodes = gDocument.getElementsByTagName("meta"); - var length = metaNodes.length; - - var metaGroup = document.getElementById("metaTags"); - if (!length) - metaGroup.collapsed = true; - else { - var metaTagsCaption = document.getElementById("metaTagsCaption"); - if (length == 1) - metaTagsCaption.label = gBundle.getString("generalMetaTag"); - else - metaTagsCaption.label = gBundle.getFormattedString("generalMetaTags", [length]); - var metaTree = document.getElementById("metatree"); - metaTree.view = gMetaView; - - for (var i = 0; i < length; i++) - gMetaView.addRow([metaNodes[i].name || metaNodes[i].httpEquiv, metaNodes[i].content]); - - metaGroup.collapsed = false; - } - - // get the date of last modification - var modifiedText = formatDate(gDocument.lastModified, gStrings.notSet); - document.getElementById("modifiedtext").value = modifiedText; - - // get cache info - var cacheKey = url.replace(/#.*$/, ""); - openCacheEntry(cacheKey, function(cacheEntry) { - var sizeText; - if (cacheEntry) { - var pageSize = cacheEntry.dataSize; - var kbSize = formatNumber(Math.round(pageSize / 1024 * 100) / 100); - sizeText = gBundle.getFormattedString("generalSize", [kbSize, formatNumber(pageSize)]); - } - setItemValue("sizetext", sizeText); - }); - - securityOnLoad(); -} - -//******** Generic Build-a-tab -// Assumes the views are empty. Only called once to build the tabs, and -// does so by farming the task off to another thread via setTimeout(). -// The actual work is done with a TreeWalker that calls doGrab() once for -// each element node in the document. - -var gFrameList = [ ]; - -function makeTabs(aDocument, aWindow) -{ - goThroughFrames(aDocument, aWindow); - processFrames(); -} - -function goThroughFrames(aDocument, aWindow) -{ - gFrameList.push(aDocument); - if (aWindow && aWindow.frames.length > 0) { - var num = aWindow.frames.length; - for (var i = 0; i < num; i++) - goThroughFrames(aWindow.frames[i].document, aWindow.frames[i]); // recurse through the frames - } -} - -function processFrames() -{ - if (gFrameList.length) { - var doc = gFrameList[0]; - onProcessFrame.forEach(function(func) { func(doc); }); - var iterator = doc.createTreeWalker(doc, NodeFilter.SHOW_ELEMENT, grabAll); - gFrameList.shift(); - setTimeout(doGrab, 10, iterator); - onFinished.push(selectImage); - } - else - onFinished.forEach(function(func) { func(); }); -} - -function doGrab(iterator) -{ - for (var i = 0; i < 500; ++i) - if (!iterator.nextNode()) { - processFrames(); - return; - } - - setTimeout(doGrab, 10, iterator); -} - -function addImage(url, type, alt, elem, isBg) -{ - if (!url) - return; - - if (!gImageHash.hasOwnProperty(url)) - gImageHash[url] = { }; - if (!gImageHash[url].hasOwnProperty(type)) - gImageHash[url][type] = { }; - if (!gImageHash[url][type].hasOwnProperty(alt)) { - gImageHash[url][type][alt] = gImageView.data.length; - var row = [url, type, -1, alt, 1, elem, isBg]; - gImageView.addRow(row); - - // Fill in cache data asynchronously - openCacheEntry(url, function(cacheEntry) { - // The data at row[2] corresponds to the data size. - if (cacheEntry) { - row[2] = cacheEntry.dataSize; - // Invalidate the row to trigger a repaint. - gImageView.tree.invalidateRow(gImageView.data.indexOf(row)); - } - }); - - // Add the observer, only once. - if (gImageView.data.length == 1) { - document.getElementById("mediaTab").hidden = false; - Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService) - .addObserver(imagePermissionObserver, "perm-changed", false); - } - } - else { - var i = gImageHash[url][type][alt]; - gImageView.data[i][COL_IMAGE_COUNT]++; - if (elem == gImageElement) - gImageView.data[i][COL_IMAGE_NODE] = elem; - } -} - -function grabAll(elem) -{ - // check for images defined in CSS (e.g. background, borders), any node may have multiple - var computedStyle = elem.ownerDocument.defaultView.getComputedStyle(elem, ""); - - if (computedStyle) { - var addImgFunc = function (label, val) { - if (val.primitiveType == CSSPrimitiveValue.CSS_URI) { - addImage(val.getStringValue(), label, gStrings.notSet, elem, true); - } - else if (val.primitiveType == CSSPrimitiveValue.CSS_STRING) { - // This is for -moz-image-rect. - // TODO: Reimplement once bug 714757 is fixed - var strVal = val.getStringValue(); - if (strVal.search(/^.*url\(\"?/) > -1) { - url = strVal.replace(/^.*url\(\"?/,"").replace(/\"?\).*$/,""); - addImage(url, label, gStrings.notSet, elem, true); - } - } - else if (val.cssValueType == CSSValue.CSS_VALUE_LIST) { - // recursively resolve multiple nested CSS value lists - for (var i = 0; i < val.length; i++) - addImgFunc(label, val.item(i)); - } - }; - - addImgFunc(gStrings.mediaBGImg, computedStyle.getPropertyCSSValue("background-image")); - addImgFunc(gStrings.mediaBorderImg, computedStyle.getPropertyCSSValue("border-image-source")); - addImgFunc(gStrings.mediaListImg, computedStyle.getPropertyCSSValue("list-style-image")); - addImgFunc(gStrings.mediaCursor, computedStyle.getPropertyCSSValue("cursor")); - } - - // one swi^H^H^Hif-else to rule them all - if (elem instanceof HTMLImageElement) - addImage(elem.src, gStrings.mediaImg, - (elem.hasAttribute("alt")) ? elem.alt : gStrings.notSet, elem, false); - else if (elem instanceof SVGImageElement) { - try { - // Note: makeURLAbsolute will throw if either the baseURI is not a valid URI - // or the URI formed from the baseURI and the URL is not a valid URI - var href = makeURLAbsolute(elem.baseURI, elem.href.baseVal); - addImage(href, gStrings.mediaImg, "", elem, false); - } catch (e) { } - } - else if (elem instanceof HTMLVideoElement) { - addImage(elem.currentSrc, gStrings.mediaVideo, "", elem, false); - } - else if (elem instanceof HTMLAudioElement) { - addImage(elem.currentSrc, gStrings.mediaAudio, "", elem, false); - } - else if (elem instanceof HTMLLinkElement) { - if (elem.rel && /\bicon\b/i.test(elem.rel)) - addImage(elem.href, gStrings.mediaLink, "", elem, false); - } - else if (elem instanceof HTMLInputElement || elem instanceof HTMLButtonElement) { - if (elem.type.toLowerCase() == "image") - addImage(elem.src, gStrings.mediaInput, - (elem.hasAttribute("alt")) ? elem.alt : gStrings.notSet, elem, false); - } - else if (elem instanceof HTMLObjectElement) - addImage(elem.data, gStrings.mediaObject, getValueText(elem), elem, false); - else if (elem instanceof HTMLEmbedElement) - addImage(elem.src, gStrings.mediaEmbed, "", elem, false); - - onProcessElement.forEach(function(func) { func(elem); }); - - return NodeFilter.FILTER_ACCEPT; -} - -//******** Link Stuff -function openURL(target) -{ - var url = target.parentNode.childNodes[2].value; - window.open(url, "_blank", "chrome"); -} - -function onBeginLinkDrag(event,urlField,descField) -{ - if (event.originalTarget.localName != "treechildren") - return; - - var tree = event.target; - if (!("treeBoxObject" in tree)) - tree = tree.parentNode; - - var row = tree.treeBoxObject.getRowAt(event.clientX, event.clientY); - if (row == -1) - return; - - // Adding URL flavor - var col = tree.columns[urlField]; - var url = tree.view.getCellText(row, col); - col = tree.columns[descField]; - var desc = tree.view.getCellText(row, col); - - var dt = event.dataTransfer; - dt.setData("text/x-moz-url", url + "\n" + desc); - dt.setData("text/url-list", url); - dt.setData("text/plain", url); -} - -//******** Image Stuff -function getSelectedRows(tree) -{ - var start = { }; - var end = { }; - var numRanges = tree.view.selection.getRangeCount(); - - var rowArray = [ ]; - for (var t = 0; t < numRanges; t++) { - tree.view.selection.getRangeAt(t, start, end); - for (var v = start.value; v <= end.value; v++) - rowArray.push(v); - } - - return rowArray; -} - -function getSelectedRow(tree) -{ - var rows = getSelectedRows(tree); - return (rows.length == 1) ? rows[0] : -1; -} - -function selectSaveFolder(aCallback) -{ - const nsILocalFile = Components.interfaces.nsILocalFile; - const nsIFilePicker = Components.interfaces.nsIFilePicker; - let titleText = gBundle.getString("mediaSelectFolder"); - let fp = Components.classes["@mozilla.org/filepicker;1"]. - createInstance(nsIFilePicker); - let fpCallback = function fpCallback_done(aResult) { - if (aResult == nsIFilePicker.returnOK) { - aCallback(fp.file.QueryInterface(nsILocalFile)); - } else { - aCallback(null); - } - }; - - fp.init(window, titleText, nsIFilePicker.modeGetFolder); - fp.appendFilters(nsIFilePicker.filterAll); - try { - let prefs = Components.classes[PREFERENCES_CONTRACTID]. - getService(Components.interfaces.nsIPrefBranch); - let initialDir = prefs.getComplexValue("browser.download.dir", nsILocalFile); - if (initialDir) { - fp.displayDirectory = initialDir; - } - } catch (ex) { - } - fp.open(fpCallback); -} - -function saveMedia() -{ - var tree = document.getElementById("imagetree"); - var rowArray = getSelectedRows(tree); - if (rowArray.length == 1) { - var row = rowArray[0]; - var item = gImageView.data[row][COL_IMAGE_NODE]; - var url = gImageView.data[row][COL_IMAGE_ADDRESS]; - - if (url) { - var titleKey = "SaveImageTitle"; - - if (item instanceof HTMLVideoElement) - titleKey = "SaveVideoTitle"; - else if (item instanceof HTMLAudioElement) - titleKey = "SaveAudioTitle"; - - saveURL(url, null, titleKey, false, false, makeURI(item.baseURI), gDocument); - } - } else { - selectSaveFolder(function(aDirectory) { - if (aDirectory) { - var saveAnImage = function(aURIString, aChosenData, aBaseURI) { - internalSave(aURIString, null, null, null, null, false, "SaveImageTitle", - aChosenData, aBaseURI, gDocument); - }; - - for (var i = 0; i < rowArray.length; i++) { - var v = rowArray[i]; - var dir = aDirectory.clone(); - var item = gImageView.data[v][COL_IMAGE_NODE]; - var uriString = gImageView.data[v][COL_IMAGE_ADDRESS]; - var uri = makeURI(uriString); - - try { - uri.QueryInterface(Components.interfaces.nsIURL); - dir.append(decodeURIComponent(uri.fileName)); - } catch(ex) { - /* data: uris */ - } - - if (i == 0) { - saveAnImage(uriString, new AutoChosen(dir, uri), makeURI(item.baseURI)); - } else { - // This delay is a hack which prevents the download manager - // from opening many times. See bug 377339. - setTimeout(saveAnImage, 200, uriString, new AutoChosen(dir, uri), - makeURI(item.baseURI)); - } - } - } - }); - } -} - -function onBlockImage() -{ - var permissionManager = Components.classes[PERMISSION_CONTRACTID] - .getService(nsIPermissionManager); - - var checkbox = document.getElementById("blockImage"); - var uri = makeURI(document.getElementById("imageurltext").value); - if (checkbox.checked) - permissionManager.add(uri, "image", nsIPermissionManager.DENY_ACTION); - else - permissionManager.remove(uri, "image"); -} - -function onImageSelect() -{ - var previewBox = document.getElementById("mediaPreviewBox"); - var mediaSaveBox = document.getElementById("mediaSaveBox"); - var splitter = document.getElementById("mediaSplitter"); - var tree = document.getElementById("imagetree"); - var count = tree.view.selection.count; - if (count == 0) { - previewBox.collapsed = true; - mediaSaveBox.collapsed = true; - splitter.collapsed = true; - tree.flex = 1; - } - else if (count > 1) { - splitter.collapsed = true; - previewBox.collapsed = true; - mediaSaveBox.collapsed = false; - tree.flex = 1; - } - else { - mediaSaveBox.collapsed = true; - splitter.collapsed = false; - previewBox.collapsed = false; - tree.flex = 0; - makePreview(getSelectedRows(tree)[0]); - } -} - -function makePreview(row) -{ - var imageTree = document.getElementById("imagetree"); - var item = gImageView.data[row][COL_IMAGE_NODE]; - var url = gImageView.data[row][COL_IMAGE_ADDRESS]; - var isBG = gImageView.data[row][COL_IMAGE_BG]; - var isAudio = false; - - setItemValue("imageurltext", url); - - var imageText; - if (!isBG && - !(item instanceof SVGImageElement) && - !(gDocument instanceof ImageDocument)) { - imageText = item.title || item.alt; - - if (!imageText && !(item instanceof HTMLImageElement)) - imageText = getValueText(item); - } - setItemValue("imagetext", imageText); - - setItemValue("imagelongdesctext", item.longDesc); - - // get cache info - var cacheKey = url.replace(/#.*$/, ""); - openCacheEntry(cacheKey, function(cacheEntry) { - // find out the file size - var sizeText; - if (cacheEntry) { - var imageSize = cacheEntry.dataSize; - var kbSize = Math.round(imageSize / 1024 * 100) / 100; - sizeText = gBundle.getFormattedString("generalSize", - [formatNumber(kbSize), formatNumber(imageSize)]); - } - else - sizeText = gBundle.getString("mediaUnknownNotCached"); - setItemValue("imagesizetext", sizeText); - - var mimeType; - var numFrames = 1; - if (item instanceof HTMLObjectElement || - item instanceof HTMLEmbedElement || - item instanceof HTMLLinkElement) - mimeType = item.type; - - if (!mimeType && !isBG && item instanceof nsIImageLoadingContent) { - var imageRequest = item.getRequest(nsIImageLoadingContent.CURRENT_REQUEST); - if (imageRequest) { - mimeType = imageRequest.mimeType; - var image = imageRequest.image; - if (image) - numFrames = image.numFrames; - } - } - - if (!mimeType) - mimeType = getContentTypeFromHeaders(cacheEntry); - - // if we have a data url, get the MIME type from the url - if (!mimeType && url.startsWith("data:")) { - let dataMimeType = /^data:(image\/[^;,]+)/i.exec(url); - if (dataMimeType) - mimeType = dataMimeType[1].toLowerCase(); - } - - var imageType; - if (mimeType) { - // We found the type, try to display it nicely - let imageMimeType = /^image\/(.*)/i.exec(mimeType); - if (imageMimeType) { - imageType = imageMimeType[1].toUpperCase(); - if (numFrames > 1) - imageType = gBundle.getFormattedString("mediaAnimatedImageType", - [imageType, numFrames]); - else - imageType = gBundle.getFormattedString("mediaImageType", [imageType]); - } - else { - // the MIME type doesn't begin with image/, display the raw type - imageType = mimeType; - } - } - else { - // We couldn't find the type, fall back to the value in the treeview - imageType = gImageView.data[row][COL_IMAGE_TYPE]; - } - setItemValue("imagetypetext", imageType); - - var imageContainer = document.getElementById("theimagecontainer"); - var oldImage = document.getElementById("thepreviewimage"); - - var isProtocolAllowed = checkProtocol(gImageView.data[row]); - - var newImage = new Image; - newImage.id = "thepreviewimage"; - var physWidth = 0, physHeight = 0; - var width = 0, height = 0; - - if ((item instanceof HTMLLinkElement || item instanceof HTMLInputElement || - item instanceof HTMLImageElement || - item instanceof SVGImageElement || - (item instanceof HTMLObjectElement && mimeType && mimeType.startsWith("image/")) || isBG) && isProtocolAllowed) { - newImage.setAttribute("src", url); - physWidth = newImage.width || 0; - physHeight = newImage.height || 0; - - // "width" and "height" attributes must be set to newImage, - // even if there is no "width" or "height attribute in item; - // otherwise, the preview image cannot be displayed correctly. - if (!isBG) { - newImage.width = ("width" in item && item.width) || newImage.naturalWidth; - newImage.height = ("height" in item && item.height) || newImage.naturalHeight; - } - else { - // the Width and Height of an HTML tag should not be used for its background image - // (for example, "table" can have "width" or "height" attributes) - newImage.width = newImage.naturalWidth; - newImage.height = newImage.naturalHeight; - } - - if (item instanceof SVGImageElement) { - newImage.width = item.width.baseVal.value; - newImage.height = item.height.baseVal.value; - } - - width = newImage.width; - height = newImage.height; - - document.getElementById("theimagecontainer").collapsed = false - document.getElementById("brokenimagecontainer").collapsed = true; - } - else if (item instanceof HTMLVideoElement && isProtocolAllowed) { - newImage = document.createElementNS("http://www.w3.org/1999/xhtml", "video"); - newImage.id = "thepreviewimage"; - newImage.src = url; - newImage.controls = true; - width = physWidth = item.videoWidth; - height = physHeight = item.videoHeight; - - document.getElementById("theimagecontainer").collapsed = false; - document.getElementById("brokenimagecontainer").collapsed = true; - } - else if (item instanceof HTMLAudioElement && isProtocolAllowed) { - newImage = new Audio; - newImage.id = "thepreviewimage"; - newImage.src = url; - newImage.controls = true; - isAudio = true; - - document.getElementById("theimagecontainer").collapsed = false; - document.getElementById("brokenimagecontainer").collapsed = true; - } - else { - // fallback image for protocols not allowed (e.g., javascript:) - // or elements not [yet] handled (e.g., object, embed). - document.getElementById("brokenimagecontainer").collapsed = false; - document.getElementById("theimagecontainer").collapsed = true; - } - - var imageSize = ""; - if (url && !isAudio) { - if (width != physWidth || height != physHeight) { - imageSize = gBundle.getFormattedString("mediaDimensionsScaled", - [formatNumber(physWidth), - formatNumber(physHeight), - formatNumber(width), - formatNumber(height)]); - } - else { - imageSize = gBundle.getFormattedString("mediaDimensions", - [formatNumber(width), - formatNumber(height)]); - } - } - setItemValue("imagedimensiontext", imageSize); - - makeBlockImage(url); - - imageContainer.removeChild(oldImage); - imageContainer.appendChild(newImage); - - onImagePreviewShown.forEach(function(func) { func(); }); - }); -} - -function makeBlockImage(url) -{ - var permissionManager = Components.classes[PERMISSION_CONTRACTID] - .getService(nsIPermissionManager); - var prefs = Components.classes[PREFERENCES_CONTRACTID] - .getService(Components.interfaces.nsIPrefBranch); - - var checkbox = document.getElementById("blockImage"); - var imagePref = prefs.getIntPref("permissions.default.image"); - if (!(/^https?:/.test(url)) || imagePref == 2) - // We can't block the images from this host because either is is not - // for http(s) or we don't load images at all - checkbox.hidden = true; - else { - var uri = makeURI(url); - if (uri.host) { - checkbox.hidden = false; - checkbox.label = gBundle.getFormattedString("mediaBlockImage", [uri.host]); - var perm = permissionManager.testPermission(uri, "image"); - checkbox.checked = perm == nsIPermissionManager.DENY_ACTION; - } - else - checkbox.hidden = true; - } -} - -var imagePermissionObserver = { - observe: function (aSubject, aTopic, aData) - { - if (document.getElementById("mediaPreviewBox").collapsed) - return; - - if (aTopic == "perm-changed") { - var permission = aSubject.QueryInterface(Components.interfaces.nsIPermission); - if (permission.type == "image") { - var imageTree = document.getElementById("imagetree"); - var row = getSelectedRow(imageTree); - var item = gImageView.data[row][COL_IMAGE_NODE]; - var url = gImageView.data[row][COL_IMAGE_ADDRESS]; - if (permission.matchesURI(makeURI(url), true)) { - makeBlockImage(url); - } - } - } - } -} - -function getContentTypeFromHeaders(cacheEntryDescriptor) -{ - if (!cacheEntryDescriptor) - return null; - - return (/^Content-Type:\s*(.*?)\s*(?:\;|$)/mi - .exec(cacheEntryDescriptor.getMetaDataElement("response-head")))[1]; -} - -//******** Other Misc Stuff -// Modified from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html -// parse a node to extract the contents of the node -function getValueText(node) -{ - var valueText = ""; - - // form input elements don't generally contain information that is useful to our callers, so return nothing - if (node instanceof HTMLInputElement || - node instanceof HTMLSelectElement || - node instanceof HTMLTextAreaElement) - return valueText; - - // otherwise recurse for each child - var length = node.childNodes.length; - for (var i = 0; i < length; i++) { - var childNode = node.childNodes[i]; - var nodeType = childNode.nodeType; - - // text nodes are where the goods are - if (nodeType == Node.TEXT_NODE) - valueText += " " + childNode.nodeValue; - // and elements can have more text inside them - else if (nodeType == Node.ELEMENT_NODE) { - // images are special, we want to capture the alt text as if the image weren't there - if (childNode instanceof HTMLImageElement) - valueText += " " + getAltText(childNode); - else - valueText += " " + getValueText(childNode); - } - } - - return stripWS(valueText); -} - -// Copied from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html -// traverse the tree in search of an img or area element and grab its alt tag -function getAltText(node) -{ - var altText = ""; - - if (node.alt) - return node.alt; - var length = node.childNodes.length; - for (var i = 0; i < length; i++) - if ((altText = getAltText(node.childNodes[i]) != undefined)) // stupid js warning... - return altText; - return ""; -} - -// Copied from the Links Panel v2.3, http://segment7.net/mozilla/links/links.html -// strip leading and trailing whitespace, and replace multiple consecutive whitespace characters with a single space -function stripWS(text) -{ - var middleRE = /\s+/g; - var endRE = /(^\s+)|(\s+$)/g; - - text = text.replace(middleRE, " "); - return text.replace(endRE, ""); -} - -function setItemValue(id, value) -{ - var item = document.getElementById(id); - if (value) { - item.parentNode.collapsed = false; - item.value = value; - } - else - item.parentNode.collapsed = true; -} - -function formatNumber(number) -{ - return (+number).toLocaleString(); // coerce number to a numeric value before calling toLocaleString() -} - -function formatDate(datestr, unknown) -{ - // scriptable date formatter, for pretty printing dates - var dateService = Components.classes["@mozilla.org/intl/scriptabledateformat;1"] - .getService(Components.interfaces.nsIScriptableDateFormat); - - var date = new Date(datestr); - if (!date.valueOf()) - return unknown; - - return dateService.FormatDateTime("", dateService.dateFormatLong, - dateService.timeFormatSeconds, - date.getFullYear(), date.getMonth()+1, date.getDate(), - date.getHours(), date.getMinutes(), date.getSeconds()); -} - -function doCopy() -{ - if (!gClipboardHelper) - return; - - var elem = document.commandDispatcher.focusedElement; - - if (elem && "treeBoxObject" in elem) { - var view = elem.view; - var selection = view.selection; - var text = [], tmp = ''; - var min = {}, max = {}; - - var count = selection.getRangeCount(); - - for (var i = 0; i < count; i++) { - selection.getRangeAt(i, min, max); - - for (var row = min.value; row <= max.value; row++) { - view.performActionOnRow("copy", row); - - tmp = elem.getAttribute("copybuffer"); - if (tmp) - text.push(tmp); - elem.removeAttribute("copybuffer"); - } - } - gClipboardHelper.copyString(text.join("\n"), document); - } -} - -function doSelectAll() -{ - var elem = document.commandDispatcher.focusedElement; - - if (elem && "treeBoxObject" in elem) - elem.view.selection.selectAll(); -} - -function selectImage() -{ - if (!gImageElement) - return; - - var tree = document.getElementById("imagetree"); - for (var i = 0; i < tree.view.rowCount; i++) { - if (gImageElement == gImageView.data[i][COL_IMAGE_NODE] && - !gImageView.data[i][COL_IMAGE_BG]) { - tree.view.selection.select(i); - tree.treeBoxObject.ensureRowIsVisible(i); - tree.focus(); - return; - } - } -} - -function checkProtocol(img) -{ - var url = img[COL_IMAGE_ADDRESS]; - return /^data:image\//i.test(url) || - /^(https?|ftp|file|about|chrome|resource):/.test(url); -} diff --git a/application/palemoon/base/content/pageinfo/pageInfo.xml b/application/palemoon/base/content/pageinfo/pageInfo.xml deleted file mode 100644 index 20d330046..000000000 --- a/application/palemoon/base/content/pageinfo/pageInfo.xml +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.0"?> -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - - -<bindings id="pageInfoBindings" - xmlns="http://www.mozilla.org/xbl" - xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:xbl="http://www.mozilla.org/xbl"> - - <!-- based on preferences.xml paneButton --> - <binding id="viewbutton" extends="chrome://global/content/bindings/radio.xml#radio"> - <content> - <xul:image class="viewButtonIcon" xbl:inherits="src"/> - <xul:label class="viewButtonLabel" xbl:inherits="value=label"/> - </content> - <implementation implements="nsIAccessibleProvider"> - <property name="accessibleType" readonly="true"> - <getter> - <![CDATA[ - return Components.interfaces.nsIAccessibleProvider.XULListitem; - ]]> - </getter> - </property> - </implementation> - </binding> - -</bindings> diff --git a/application/palemoon/base/content/pageinfo/pageInfo.xul b/application/palemoon/base/content/pageinfo/pageInfo.xul deleted file mode 100644 index e3a61d31e..000000000 --- a/application/palemoon/base/content/pageinfo/pageInfo.xul +++ /dev/null @@ -1,507 +0,0 @@ -<?xml version="1.0"?> -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -<?xml-stylesheet href="chrome://browser/content/pageinfo/pageInfo.css" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/pageInfo.css" type="text/css"?> - -<!DOCTYPE window [ - <!ENTITY % pageInfoDTD SYSTEM "chrome://browser/locale/pageInfo.dtd"> - %pageInfoDTD; -]> - -#ifdef XP_MACOSX -<?xul-overlay href="chrome://browser/content/macBrowserOverlay.xul"?> -#endif - -<window id="main-window" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - windowtype="Browser:page-info" - onload="onLoadPageInfo()" - onunload="onUnloadPageInfo()" - align="stretch" - screenX="10" screenY="10" - width="&pageInfoWindow.width;" height="&pageInfoWindow.height;" - persist="screenX screenY width height sizemode"> - - <script type="application/javascript" src="chrome://global/content/globalOverlay.js"/> - <script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/> - <script type="application/javascript" src="chrome://global/content/treeUtils.js"/> - <script type="application/javascript" src="chrome://browser/content/pageinfo/pageInfo.js"/> - <script type="application/javascript" src="chrome://browser/content/pageinfo/feeds.js"/> - <script type="application/javascript" src="chrome://browser/content/pageinfo/permissions.js"/> - <script type="application/javascript" src="chrome://browser/content/pageinfo/security.js"/> - <script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/> - - <stringbundleset id="pageinfobundleset"> - <stringbundle id="pageinfobundle" src="chrome://browser/locale/pageInfo.properties"/> - <stringbundle id="pkiBundle" src="chrome://pippki/locale/pippki.properties"/> - <stringbundle id="browserBundle" src="chrome://browser/locale/browser.properties"/> - </stringbundleset> - - <commandset id="pageInfoCommandSet"> - <command id="cmd_close" oncommand="window.close();"/> - <command id="cmd_help" oncommand="doHelpButton();"/> - <command id="cmd_copy" oncommand="doCopy();"/> - <command id="cmd_selectall" oncommand="doSelectAll();"/> - - <!-- permissions tab --> - <command id="cmd_imageDef" oncommand="onCheckboxClick('image');"/> - <command id="cmd_popupDef" oncommand="onCheckboxClick('popup');"/> - <command id="cmd_cookieDef" oncommand="onCheckboxClick('cookie');"/> - <command id="cmd_desktop-notificationDef" oncommand="onCheckboxClick('desktop-notification');"/> - <command id="cmd_installDef" oncommand="onCheckboxClick('install');"/> - <command id="cmd_geoDef" oncommand="onCheckboxClick('geo');"/> - <command id="cmd_pluginsDef" oncommand="onCheckboxClick('plugins');"/> - <command id="cmd_imageToggle" oncommand="onRadioClick('image');"/> - <command id="cmd_popupToggle" oncommand="onRadioClick('popup');"/> - <command id="cmd_cookieToggle" oncommand="onRadioClick('cookie');"/> - <command id="cmd_desktop-notificationToggle" oncommand="onRadioClick('desktop-notification');"/> - <command id="cmd_installToggle" oncommand="onRadioClick('install');"/> - <command id="cmd_geoToggle" oncommand="onRadioClick('geo');"/> - <command id="cmd_pluginsToggle" oncommand="onPluginRadioClick(event);"/> - </commandset> - - <keyset id="pageInfoKeySet"> - <key key="&closeWindow.key;" modifiers="accel" command="cmd_close"/> - <key keycode="VK_ESCAPE" command="cmd_close"/> -#ifdef XP_MACOSX - <key key="." modifiers="meta" command="cmd_close"/> -#else - <key keycode="VK_F1" command="cmd_help"/> -#endif - <key key="©.key;" modifiers="accel" command="cmd_copy"/> - <key key="&selectall.key;" modifiers="accel" command="cmd_selectall"/> - <key key="&selectall.key;" modifiers="alt" command="cmd_selectall"/> - </keyset> - - <menupopup id="picontext"> - <menuitem id="menu_selectall" label="&selectall.label;" command="cmd_selectall" accesskey="&selectall.accesskey;"/> - <menuitem id="menu_copy" label="©.label;" command="cmd_copy" accesskey="©.accesskey;"/> - </menupopup> - - <windowdragbox id="topBar" class="viewGroupWrapper"> - <radiogroup id="viewGroup" class="chromeclass-toolbar" orient="horizontal"> - <radio id="generalTab" label="&generalTab;" accesskey="&generalTab.accesskey;" - oncommand="showTab('general');"/> - <radio id="mediaTab" label="&mediaTab;" accesskey="&mediaTab.accesskey;" - oncommand="showTab('media');" hidden="true"/> - <radio id="feedTab" label="&feedTab;" accesskey="&feedTab.accesskey;" - oncommand="showTab('feed');" hidden="true"/> - <radio id="permTab" label="&permTab;" accesskey="&permTab.accesskey;" - oncommand="showTab('perm');"/> - <radio id="securityTab" label="&securityTab;" accesskey="&securityTab.accesskey;" - oncommand="showTab('security');"/> - <!-- Others added by overlay --> - </radiogroup> - </windowdragbox> - - <deck id="mainDeck" flex="1"> - <!-- General page information --> - <vbox id="generalPanel"> - <textbox class="header" readonly="true" id="titletext"/> - <grid id="generalGrid"> - <columns> - <column/> - <column class="gridSeparator"/> - <column flex="1"/> - </columns> - <rows id="generalRows"> - <row id="generalURLRow"> - <label control="urltext" value="&generalURL;"/> - <separator/> - <textbox readonly="true" id="urltext"/> - </row> - <row id="generalSeparatorRow1"> - <separator class="thin"/> - </row> - <row id="generalTypeRow"> - <label control="typetext" value="&generalType;"/> - <separator/> - <textbox readonly="true" id="typetext"/> - </row> - <row id="generalModeRow"> - <label control="modetext" value="&generalMode;"/> - <separator/> - <textbox readonly="true" crop="end" id="modetext"/> - </row> - <row id="generalEncodingRow"> - <label control="encodingtext" value="&generalEncoding;"/> - <separator/> - <textbox readonly="true" id="encodingtext"/> - </row> - <row id="generalSizeRow"> - <label control="sizetext" value="&generalSize;"/> - <separator/> - <textbox readonly="true" id="sizetext"/> - </row> - <row id="generalReferrerRow"> - <label control="refertext" value="&generalReferrer;"/> - <separator/> - <textbox readonly="true" id="refertext"/> - </row> - <row id="generalSeparatorRow2"> - <separator class="thin"/> - </row> - <row id="generalModifiedRow"> - <label control="modifiedtext" value="&generalModified;"/> - <separator/> - <textbox readonly="true" id="modifiedtext"/> - </row> - </rows> - </grid> - <separator class="thin"/> - <groupbox id="metaTags" flex="1" class="collapsable treebox"> - <caption id="metaTagsCaption" onclick="toggleGroupbox('metaTags');"/> - <tree id="metatree" flex="1" hidecolumnpicker="true" contextmenu="picontext"> - <treecols> - <treecol id="meta-name" label="&generalMetaName;" - persist="width" flex="1" - onclick="gMetaView.onPageMediaSort('meta-name');"/> - <splitter class="tree-splitter"/> - <treecol id="meta-content" label="&generalMetaContent;" - persist="width" flex="4" - onclick="gMetaView.onPageMediaSort('meta-content');"/> - </treecols> - <treechildren id="metatreechildren" flex="1"/> - </tree> - </groupbox> - <groupbox id="securityBox"> - <caption id="securityBoxCaption" label="&securityHeader;"/> - <description id="general-security-identity" class="header"/> - <description id="general-security-privacy" class="header"/> - <hbox id="securityDetailsButtonBox" align="right"> - <button id="security-view-details" label="&generalSecurityDetails;" - accesskey="&generalSecurityDetails.accesskey;" - oncommand="onClickMore();"/> - </hbox> - </groupbox> - </vbox> - - <!-- Media information --> - <vbox id="mediaPanel"> - <tree id="imagetree" onselect="onImageSelect();" contextmenu="picontext" - ondragstart="onBeginLinkDrag(event,'image-address','image-alt')"> - <treecols> - <treecol sortSeparators="true" primary="true" persist="width" flex="10" - width="10" id="image-address" label="&mediaAddress;" - onclick="gImageView.onPageMediaSort('image-address');"/> - <splitter class="tree-splitter"/> - <treecol sortSeparators="true" persist="hidden width" flex="2" - width="2" id="image-type" label="&mediaType;" - onclick="gImageView.onPageMediaSort('image-type');"/> - <splitter class="tree-splitter"/> - <treecol sortSeparators="true" hidden="true" persist="hidden width" flex="2" - width="2" id="image-size" label="&mediaSize;" value="size" - onclick="gImageView.onPageMediaSort('image-size');"/> - <splitter class="tree-splitter"/> - <treecol sortSeparators="true" hidden="true" persist="hidden width" flex="4" - width="4" id="image-alt" label="&mediaAltHeader;" - onclick="gImageView.onPageMediaSort('image-alt');"/> - <splitter class="tree-splitter"/> - <treecol sortSeparators="true" hidden="true" persist="hidden width" flex="1" - width="1" id="image-count" label="&mediaCount;" - onclick="gImageView.onPageMediaSort('image-count');"/> - </treecols> - <treechildren id="imagetreechildren" flex="1"/> - </tree> - <splitter orient="vertical" id="mediaSplitter"/> - <vbox flex="1" id="mediaPreviewBox" collapsed="true"> - <grid id="mediaGrid"> - <columns> - <column id="mediaLabelColumn"/> - <column class="gridSeparator"/> - <column flex="1"/> - </columns> - <rows id="mediaRows"> - <row id="mediaLocationRow"> - <label control="imageurltext" value="&mediaLocation;"/> - <separator/> - <textbox readonly="true" id="imageurltext"/> - </row> - <row id="mediaTypeRow"> - <label control="imagetypetext" value="&generalType;"/> - <separator/> - <textbox readonly="true" id="imagetypetext"/> - </row> - <row id="mediaSizeRow"> - <label control="imagesizetext" value="&generalSize;"/> - <separator/> - <textbox readonly="true" id="imagesizetext"/> - </row> - <row id="mediaDimensionRow"> - <label control="imagedimensiontext" value="&mediaDimension;"/> - <separator/> - <textbox readonly="true" id="imagedimensiontext"/> - </row> - <row id="mediaTextRow"> - <label control="imagetext" value="&mediaText;"/> - <separator/> - <textbox readonly="true" id="imagetext"/> - </row> - <row id="mediaLongdescRow"> - <label control="imagelongdesctext" value="&mediaLongdesc;"/> - <separator/> - <textbox readonly="true" id="imagelongdesctext"/> - </row> - </rows> - </grid> - <hbox id="imageSaveBox" align="end"> - <vbox id="blockImageBox"> - <checkbox id="blockImage" hidden="true" oncommand="onBlockImage()" - accesskey="&mediaBlockImage.accesskey;"/> - <label control="thepreviewimage" value="&mediaPreview;" class="header"/> - </vbox> - <spacer id="imageSaveBoxSpacer" flex="1"/> - <button label="&mediaSaveAs;" accesskey="&mediaSaveAs.accesskey;" - icon="save" id="imagesaveasbutton" - oncommand="saveMedia();"/> - </hbox> - <vbox id="imagecontainerbox" class="inset iframe" flex="1" pack="center"> - <hbox id="theimagecontainer" pack="center"> - <image id="thepreviewimage"/> - </hbox> - <hbox id="brokenimagecontainer" pack="center" collapsed="true"> - <image id="brokenimage" src="resource://gre-resources/broken-image.png"/> - </hbox> - </vbox> - </vbox> - <hbox id="mediaSaveBox" collapsed="true"> - <spacer id="mediaSaveBoxSpacer" flex="1"/> - <button label="&mediaSaveAs;" accesskey="&mediaSaveAs2.accesskey;" - icon="save" id="mediasaveasbutton" - oncommand="saveMedia();"/> - </hbox> - </vbox> - - <!-- Feeds --> - <vbox id="feedPanel"> - <richlistbox id="feedListbox" flex="1"/> - </vbox> - - <!-- Permissions --> - <vbox id="permPanel"> - <hbox id="permHostBox"> - <label value="&permissionsFor;" control="hostText" /> - <textbox id="hostText" class="header" readonly="true" - crop="end" flex="1"/> - </hbox> - - <vbox id="permList" flex="1"> - <vbox class="permission" id="permImageRow"> - <label class="permissionLabel" id="permImageLabel" - value="&permImage;" control="imageRadioGroup"/> - <hbox id="permImageBox" role="group" aria-labelledby="permImageLabel"> - <checkbox id="imageDef" command="cmd_imageDef" label="&permUseDefault;"/> - <spacer flex="1"/> - <radiogroup id="imageRadioGroup" orient="horizontal"> - <radio id="image#1" command="cmd_imageToggle" label="&permAllow;"/> - <radio id="image#2" command="cmd_imageToggle" label="&permBlock;"/> - </radiogroup> - </hbox> - </vbox> - <vbox class="permission" id="permPopupRow"> - <label class="permissionLabel" id="permPopupLabel" - value="&permPopup;" control="popupRadioGroup"/> - <hbox id="permPopupBox" role="group" aria-labelledby="permPopupLabel"> - <checkbox id="popupDef" command="cmd_popupDef" label="&permUseDefault;"/> - <spacer flex="1"/> - <radiogroup id="popupRadioGroup" orient="horizontal"> - <radio id="popup#1" command="cmd_popupToggle" label="&permAllow;"/> - <radio id="popup#2" command="cmd_popupToggle" label="&permBlock;"/> - </radiogroup> - </hbox> - </vbox> - <vbox class="permission" id="permCookieRow"> - <label class="permissionLabel" id="permCookieLabel" - value="&permCookie;" control="cookieRadioGroup"/> - <hbox id="permCookieBox" role="group" aria-labelledby="permCookieLabel"> - <checkbox id="cookieDef" command="cmd_cookieDef" label="&permUseDefault;"/> - <spacer flex="1"/> - <radiogroup id="cookieRadioGroup" orient="horizontal"> - <radio id="cookie#1" command="cmd_cookieToggle" label="&permAllow;"/> - <radio id="cookie#8" command="cmd_cookieToggle" label="&permAllowSession;"/> - <radio id="cookie#9" command="cmd_cookieToggle" label="&permAllowFirstPartyOnly;"/> - <radio id="cookie#2" command="cmd_cookieToggle" label="&permBlock;"/> - </radiogroup> - </hbox> - </vbox> - <vbox class="permission" id="permNotificationRow"> - <label class="permissionLabel" id="permNotificationLabel" - value="&permNotifications;" control="desktop-notificationRadioGroup"/> - <hbox role="group" aria-labelledby="permNotificationLabel"> - <checkbox id="desktop-notificationDef" command="cmd_desktop-notificationDef" label="&permUseDefault;"/> - <spacer flex="1"/> - <radiogroup id="desktop-notificationRadioGroup" orient="horizontal"> - <radio id="desktop-notification#0" command="cmd_desktop-notificationToggle" label="&permAskAlways;"/> - <radio id="desktop-notification#1" command="cmd_desktop-notificationToggle" label="&permAllow;"/> - <radio id="desktop-notification#2" command="cmd_desktop-notificationToggle" label="&permBlock;"/> - </radiogroup> - </hbox> - </vbox> - <vbox class="permission" id="permInstallRow"> - <label class="permissionLabel" id="permInstallLabel" - value="&permInstall;" control="installRadioGroup"/> - <hbox id="permInstallBox" role="group" aria-labelledby="permInstallLabel"> - <checkbox id="installDef" command="cmd_installDef" label="&permUseDefault;"/> - <spacer flex="1"/> - <radiogroup id="installRadioGroup" orient="horizontal"> - <radio id="install#1" command="cmd_installToggle" label="&permAllow;"/> - <radio id="install#2" command="cmd_installToggle" label="&permBlock;"/> - </radiogroup> - </hbox> - </vbox> - <vbox class="permission" id="permGeoRow" > - <label class="permissionLabel" id="permGeoLabel" - value="&permGeo;" control="geoRadioGroup"/> - <hbox id="permGeoBox" role="group" aria-labelledby="permGeoLabel"> - <checkbox id="geoDef" command="cmd_geoDef" label="&permAskAlways;"/> - <spacer flex="1"/> - <radiogroup id="geoRadioGroup" orient="horizontal"> - <radio id="geo#1" command="cmd_geoToggle" label="&permAllow;"/> - <radio id="geo#2" command="cmd_geoToggle" label="&permBlock;"/> - </radiogroup> - </hbox> - </vbox> - <vbox class="permission" id="permPluginsRow"> - <label class="permissionLabel" id="permPluginsLabel" - value="&permPlugins;" control="pluginsRadioGroup"/> - <hbox id="permPluginTemplate" role="group" aria-labelledby="permPluginsLabel" align="baseline"> - <label class="permPluginTemplateLabel"/> - <spacer flex="1"/> - <radiogroup class="permPluginTemplateRadioGroup" orient="horizontal" command="cmd_pluginsToggle"> - <radio class="permPluginTemplateRadioDefault" label="&permUseDefault;"/> - <radio class="permPluginTemplateRadioAsk" label="&permAskAlways;"/> - <radio class="permPluginTemplateRadioAllow" label="&permAllow;"/> - <radio class="permPluginTemplateRadioBlock" label="&permBlock;"/> - </radiogroup> - </hbox> - </vbox> - </vbox> - </vbox> - - <!-- Security & Privacy --> - <vbox id="securityPanel"> - <!-- Identity Section --> - <groupbox id="security-identity-groupbox" flex="1"> - <caption id="security-identity" label="&securityView.identity.header;"/> - <grid id="security-identity-grid" flex="1"> - <columns> - <column/> - <column flex="1"/> - </columns> - <rows id="security-identity-rows"> - <!-- Domain --> - <row id="security-identity-domain-row"> - <label id="security-identity-domain-label" - class="fieldLabel" - value="&securityView.identity.domain;" - control="security-identity-domain-value"/> - <textbox id="security-identity-domain-value" - class="fieldValue" readonly="true"/> - </row> - <!-- Owner --> - <row id="security-identity-owner-row"> - <label id="security-identity-owner-label" - class="fieldLabel" - value="&securityView.identity.owner;" - control="security-identity-owner-value"/> - <textbox id="security-identity-owner-value" - class="fieldValue" readonly="true"/> - </row> - <!-- Verifier --> - <row id="security-identity-verifier-row"> - <label id="security-identity-verifier-label" - class="fieldLabel" - value="&securityView.identity.verifier;" - control="security-identity-verifier-value"/> - <textbox id="security-identity-verifier-value" - class="fieldValue" readonly="true" /> - </row> - </rows> - </grid> - <spacer flex="1"/> - <!-- Cert button --> - <hbox id="security-view-cert-box" pack="end"> - <button id="security-view-cert" label="&securityView.certView;" - accesskey="&securityView.accesskey;" - oncommand="security.viewCert();"/> - </hbox> - </groupbox> - - <!-- Privacy & History section --> - <groupbox id="security-privacy-groupbox" flex="1"> - <caption id="security-privacy" label="&securityView.privacy.header;" /> - <grid id="security-privacy-grid"> - <columns> - <column flex="1"/> - <column flex="1"/> - </columns> - <rows id="security-privacy-rows"> - <!-- History --> - <row id="security-privacy-history-row"> - <label id="security-privacy-history-label" - control="security-privacy-history-value" - class="fieldLabel">&securityView.privacy.history;</label> - <textbox id="security-privacy-history-value" - class="fieldValue" - value="&securityView.unknown;" - readonly="true"/> - </row> - <!-- Cookies --> - <row id="security-privacy-cookies-row"> - <label id="security-privacy-cookies-label" - control="security-privacy-cookies-value" - class="fieldLabel">&securityView.privacy.cookies;</label> - <hbox id="security-privacy-cookies-box" align="center"> - <textbox id="security-privacy-cookies-value" - class="fieldValue" - value="&securityView.unknown;" - flex="1" - readonly="true"/> - <button id="security-view-cookies" - label="&securityView.privacy.viewCookies;" - accesskey="&securityView.privacy.viewCookies.accessKey;" - oncommand="security.viewCookies();"/> - </hbox> - </row> - <!-- Passwords --> - <row id="security-privacy-passwords-row"> - <label id="security-privacy-passwords-label" - control="security-privacy-passwords-value" - class="fieldLabel">&securityView.privacy.passwords;</label> - <hbox id="security-privacy-passwords-box" align="center"> - <textbox id="security-privacy-passwords-value" - class="fieldValue" - value="&securityView.unknown;" - flex="1" - readonly="true"/> - <button id="security-view-password" - label="&securityView.privacy.viewPasswords;" - accesskey="&securityView.privacy.viewPasswords.accessKey;" - oncommand="security.viewPasswords();"/> - </hbox> - </row> - </rows> - </grid> - </groupbox> - - <!-- Technical Details section --> - <groupbox id="security-technical-groupbox" flex="1"> - <caption id="security-technical" label="&securityView.technical.header;" /> - <vbox id="security-technical-box" flex="1"> - <label id="security-technical-shortform" class="fieldValue"/> - <description id="security-technical-longform1" class="fieldLabel"/> - <description id="security-technical-longform2" class="fieldLabel"/> - </vbox> - </groupbox> - </vbox> - <!-- Others added by overlay --> - </deck> - -#ifdef XP_MACOSX -#include ../browserMountPoints.inc -#endif - -</window> diff --git a/application/palemoon/base/content/pageinfo/permissions.js b/application/palemoon/base/content/pageinfo/permissions.js deleted file mode 100644 index 4f8382f66..000000000 --- a/application/palemoon/base/content/pageinfo/permissions.js +++ /dev/null @@ -1,341 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const UNKNOWN = nsIPermissionManager.UNKNOWN_ACTION; // 0 -const ALLOW = nsIPermissionManager.ALLOW_ACTION; // 1 -const DENY = nsIPermissionManager.DENY_ACTION; // 2 -const SESSION = nsICookiePermission.ACCESS_SESSION; // 8 - -const IMAGE_DENY = 2; - -const COOKIE_DENY = 2; -const COOKIE_SESSION = 2; - -var gPermURI; -var gPermPrincipal; -var gPrefs; -var gUsageRequest; - -var gPermObj = { - image: function getImageDefaultPermission() - { - if (gPrefs.getIntPref("permissions.default.image") == IMAGE_DENY) { - return DENY; - } - return ALLOW; - }, - popup: function getPopupDefaultPermission() - { - if (gPrefs.getBoolPref("dom.disable_open_during_load")) { - return DENY; - } - return ALLOW; - }, - cookie: function getCookieDefaultPermission() - { - if (gPrefs.getIntPref("network.cookie.cookieBehavior") == COOKIE_DENY) { - return DENY; - } - if (gPrefs.getIntPref("network.cookie.lifetimePolicy") == COOKIE_SESSION) { - return SESSION; - } - return ALLOW; - }, - "desktop-notification": function getNotificationDefaultPermission() - { - if (!gPrefs.getBoolPref("dom.webnotifications.enabled")) { - return DENY; - } - return UNKNOWN; - }, - install: function getInstallDefaultPermission() - { - if (Services.prefs.getBoolPref("xpinstall.whitelist.required")) { - return DENY; - } - return ALLOW; - }, - geo: function getGeoDefaultPermissions() - { - if (!gPrefs.getBoolPref("geo.enabled")) { - return DENY; - } - return ALLOW; - }, - plugins: function getPluginsDefaultPermissions() - { - return UNKNOWN; - }, -}; - -var permissionObserver = { - observe: function (aSubject, aTopic, aData) - { - if (aTopic == "perm-changed") { - var permission = aSubject.QueryInterface( - Components.interfaces.nsIPermission); - if (permission.matchesURI(gPermURI, true)) { - if (permission.type in gPermObj) - initRow(permission.type); - else if (permission.type.startsWith("plugin")) - setPluginsRadioState(); - } - } - } -}; - -function onLoadPermission(principal) -{ - gPrefs = Components.classes[PREFERENCES_CONTRACTID] - .getService(Components.interfaces.nsIPrefBranch); - - var uri = gDocument.documentURIObject; - var permTab = document.getElementById("permTab"); - if (/^https?$/.test(uri.scheme)) { - gPermURI = uri; - gPermPrincipal = principal; - var hostText = document.getElementById("hostText"); - hostText.value = gPermURI.prePath; - - for (var i in gPermObj) - initRow(i); - var os = Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService); - os.addObserver(permissionObserver, "perm-changed", false); - onUnloadRegistry.push(onUnloadPermission); - permTab.hidden = false; - } - else - permTab.hidden = true; -} - -function onUnloadPermission() -{ - var os = Components.classes["@mozilla.org/observer-service;1"] - .getService(Components.interfaces.nsIObserverService); - os.removeObserver(permissionObserver, "perm-changed"); - - if (gUsageRequest) { - gUsageRequest.cancel(); - gUsageRequest = null; - } -} - -function initRow(aPartId) -{ - if (aPartId == "plugins") { - initPluginsRow(); - return; - } - - var permissionManager = Components.classes[PERMISSION_CONTRACTID] - .getService(nsIPermissionManager); - - var checkbox = document.getElementById(aPartId + "Def"); - var command = document.getElementById("cmd_" + aPartId + "Toggle"); - // Desktop Notification, Geolocation and PointerLock permission consumers - // use testExactPermission, not testPermission. - var perm; - if (aPartId == "desktop-notification" || aPartId == "geo" || aPartId == "pointerLock") - perm = permissionManager.testExactPermission(gPermURI, aPartId); - else - perm = permissionManager.testPermission(gPermURI, aPartId); - - if (perm) { - checkbox.checked = false; - command.removeAttribute("disabled"); - } - else { - checkbox.checked = true; - command.setAttribute("disabled", "true"); - perm = gPermObj[aPartId](); - } - setRadioState(aPartId, perm); -} - -function onCheckboxClick(aPartId) -{ - var permissionManager = Components.classes[PERMISSION_CONTRACTID] - .getService(nsIPermissionManager); - - var command = document.getElementById("cmd_" + aPartId + "Toggle"); - var checkbox = document.getElementById(aPartId + "Def"); - if (checkbox.checked) { - permissionManager.remove(gPermURI, aPartId); - command.setAttribute("disabled", "true"); - var perm = gPermObj[aPartId](); - setRadioState(aPartId, perm); - } - else { - onRadioClick(aPartId); - command.removeAttribute("disabled"); - } -} - -function onPluginRadioClick(aEvent) { - onRadioClick(aEvent.originalTarget.getAttribute("id").split('#')[0]); -} - -function onRadioClick(aPartId) -{ - var permissionManager = Components.classes[PERMISSION_CONTRACTID] - .getService(nsIPermissionManager); - - var radioGroup = document.getElementById(aPartId + "RadioGroup"); - var id = radioGroup.selectedItem.id; - var permission = id.split('#')[1]; - if (permission == UNKNOWN) { - permissionManager.remove(gPermURI, aPartId); - } else { - permissionManager.add(gPermURI, aPartId, permission); - } -} - -function setRadioState(aPartId, aValue) -{ - var radio = document.getElementById(aPartId + "#" + aValue); - radio.radioGroup.selectedItem = radio; -} - -// XXX copied this from browser-plugins.js - is there a way to share? -function makeNicePluginName(aName) { - if (aName == "Shockwave Flash") - return "Adobe Flash"; - - // Clean up the plugin name by stripping off any trailing version numbers - // or "plugin". EG, "Foo Bar Plugin 1.23_02" --> "Foo Bar" - // Do this by first stripping the numbers, etc. off the end, and then - // removing "Plugin" (and then trimming to get rid of any whitespace). - // (Otherwise, something like "Java(TM) Plug-in 1.7.0_07" gets mangled) - let newName = aName.replace(/[\s\d\.\-\_\(\)]+$/, "").replace(/\bplug-?in\b/i, "").trim(); - return newName; -} - -function fillInPluginPermissionTemplate(aPermissionString, aPluginObject) { - let permPluginTemplate = document.getElementById("permPluginTemplate") - .cloneNode(true); - permPluginTemplate.setAttribute("permString", aPermissionString); - permPluginTemplate.setAttribute("tooltiptext", aPluginObject.description); - let attrs = []; - attrs.push([".permPluginTemplateLabel", "value", aPluginObject.name]); - attrs.push([".permPluginTemplateRadioGroup", "id", aPermissionString + "RadioGroup"]); - attrs.push([".permPluginTemplateRadioDefault", "id", aPermissionString + "#0"]); - let permPluginTemplateRadioAsk = ".permPluginTemplateRadioAsk"; - if (Services.prefs.getBoolPref("plugins.click_to_play") || - aPluginObject.vulnerable) { - attrs.push([permPluginTemplateRadioAsk, "id", aPermissionString + "#3"]); - } else { - permPluginTemplate.querySelector(permPluginTemplateRadioAsk) - .setAttribute("disabled", "true"); - } - attrs.push([".permPluginTemplateRadioAllow", "id", aPermissionString + "#1"]); - attrs.push([".permPluginTemplateRadioBlock", "id", aPermissionString + "#2"]); - - for (let attr of attrs) { - permPluginTemplate.querySelector(attr[0]).setAttribute(attr[1], attr[2]); - } - - return permPluginTemplate; -} - -function clearPluginPermissionTemplate() { - let permPluginTemplate = document.getElementById("permPluginTemplate"); - permPluginTemplate.hidden = true; - permPluginTemplate.removeAttribute("permString"); - permPluginTemplate.removeAttribute("tooltiptext"); - document.querySelector(".permPluginTemplateLabel").removeAttribute("value"); - document.querySelector(".permPluginTemplateRadioGroup").removeAttribute("id"); - document.querySelector(".permPluginTemplateRadioAsk").removeAttribute("id"); - document.querySelector(".permPluginTemplateRadioAllow").removeAttribute("id"); - document.querySelector(".permPluginTemplateRadioBlock").removeAttribute("id"); -} - -function initPluginsRow() { - let vulnerableLabel = document.getElementById("browserBundle") - .getString("pluginActivateVulnerable.label"); - let pluginHost = Components.classes["@mozilla.org/plugin/host;1"] - .getService(Components.interfaces.nsIPluginHost); - let tags = pluginHost.getPluginTags(); - - let permissionMap = new Map(); - - for (let plugin of tags) { - if (plugin.disabled) { - continue; - } - for (let mimeType of plugin.getMimeTypes()) { - if (mimeType == "application/x-shockwave-flash" && plugin.name != "Shockwave Flash") { - continue; - } - let permString = pluginHost.getPermissionStringForType(mimeType); - if (!permissionMap.has(permString)) { - let name = makeNicePluginName(plugin.name) + " " + plugin.version; - let vulnerable = false; - if (permString.startsWith("plugin-vulnerable:")) { - name += " \u2014 " + vulnerableLabel; - vulnerable = true; - } - permissionMap.set(permString, { - "name": name, - "description": plugin.description, - "vulnerable": vulnerable - }); - } - } - } - - // Tycho: - // let entries = [ - // { - // "permission": item[0], - // "obj": item[1], - // } - // for (item of permissionMap) - // ]; - let entries = []; - for (let item of permissionMap) { - entries.push({ - "permission": item[0], - "obj": item[1] - }); - } - entries.sort(function(a, b) { - return ((a.obj.name < b.obj.name) ? -1 : (a.obj.name == b.obj.name ? 0 : 1)); - }); - - // Tycho: - // let permissionEntries = [ - // fillInPluginPermissionTemplate(p.permission, p.obj) for (p of entries) - // ]; - let permissionEntries = []; - entries.forEach(function (p) { - permissionEntries.push(fillInPluginPermissionTemplate(p.permission, p.obj)); - }); - - let permPluginsRow = document.getElementById("permPluginsRow"); - clearPluginPermissionTemplate(); - if (permissionEntries.length < 1) { - permPluginsRow.hidden = true; - return; - } - - for (let permissionEntry of permissionEntries) { - permPluginsRow.appendChild(permissionEntry); - } - - setPluginsRadioState(); -} - -function setPluginsRadioState() { - var permissionManager = Components.classes[PERMISSION_CONTRACTID] - .getService(nsIPermissionManager); - let box = document.getElementById("permPluginsRow"); - for (let permissionEntry of box.childNodes) { - if (permissionEntry.hasAttribute("permString")) { - let permString = permissionEntry.getAttribute("permString"); - let permission = permissionManager.testPermission(gPermURI, permString); - setRadioState(permString, permission); - } - } -} diff --git a/application/palemoon/base/content/pageinfo/security.js b/application/palemoon/base/content/pageinfo/security.js deleted file mode 100644 index e791ab92a..000000000 --- a/application/palemoon/base/content/pageinfo/security.js +++ /dev/null @@ -1,378 +0,0 @@ -/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var security = { - // Display the server certificate (static) - viewCert : function () { - var cert = security._cert; - viewCertHelper(window, cert); - }, - - _getSecurityInfo : function() { - const nsIX509Cert = Components.interfaces.nsIX509Cert; - const nsIX509CertDB = Components.interfaces.nsIX509CertDB; - const nsX509CertDB = "@mozilla.org/security/x509certdb;1"; - const nsISSLStatusProvider = Components.interfaces.nsISSLStatusProvider; - const nsISSLStatus = Components.interfaces.nsISSLStatus; - - // We don't have separate info for a frame, return null until further notice - // (see bug 138479) - if (gWindow != gWindow.top) - return null; - - var hName = null; - try { - hName = gWindow.location.host; - } - catch (exception) { } - - var ui = security._getSecurityUI(); - if (!ui) - return null; - - var isBroken = - (ui.state & Components.interfaces.nsIWebProgressListener.STATE_IS_BROKEN); - var isMixed = - (ui.state & (Components.interfaces.nsIWebProgressListener.STATE_LOADED_MIXED_ACTIVE_CONTENT | - Components.interfaces.nsIWebProgressListener.STATE_LOADED_MIXED_DISPLAY_CONTENT)); - var isInsecure = - (ui.state & Components.interfaces.nsIWebProgressListener.STATE_IS_INSECURE); - var isEV = - (ui.state & Components.interfaces.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL); - ui.QueryInterface(nsISSLStatusProvider); - var status = ui.SSLStatus; - - if (!isInsecure && status) { - status.QueryInterface(nsISSLStatus); - var cert = status.serverCert; - var issuerName = - this.mapIssuerOrganization(cert.issuerOrganization) || cert.issuerName; - - var retval = { - hostName : hName, - cAName : issuerName, - encryptionAlgorithm : undefined, - encryptionStrength : undefined, - encryptionSuite : undefined, - version: undefined, - isBroken : isBroken, - isMixed : isMixed, - isEV : isEV, - cert : cert, - fullLocation : gWindow.location - }; - - var version; - try { - retval.encryptionAlgorithm = status.cipherName; - retval.encryptionStrength = status.secretKeyLength; - retval.encryptionSuite = status.cipherSuite; - version = status.protocolVersion; - } - catch (e) { - } - - switch (version) { - case nsISSLStatus.SSL_VERSION_3: - retval.version = "SSL 3"; - break; - case nsISSLStatus.TLS_VERSION_1: - retval.version = "TLS 1.0"; - break; - case nsISSLStatus.TLS_VERSION_1_1: - retval.version = "TLS 1.1"; - break; - case nsISSLStatus.TLS_VERSION_1_2: - retval.version = "TLS 1.2" - break; - case nsISSLStatus.TLS_VERSION_1_3: - retval.version = "TLS 1.3" - break; - } - - return retval; - } else { - return { - hostName : hName, - cAName : "", - encryptionAlgorithm : "", - encryptionStrength : 0, - encryptionSuite : "", - version: "", - isBroken : isBroken, - isMixed : isMixed, - isEV : isEV, - cert : null, - fullLocation : gWindow.location - }; - } - }, - - // Find the secureBrowserUI object (if present) - _getSecurityUI : function() { - if (window.opener.gBrowser) - return window.opener.gBrowser.securityUI; - return null; - }, - - // Interface for mapping a certificate issuer organization to - // the value to be displayed. - // Bug 82017 - this implementation should be moved to pipnss C++ code - mapIssuerOrganization: function(name) { - if (!name) return null; - - if (name == "RSA Data Security, Inc.") return "Verisign, Inc."; - - // No mapping required - return name; - }, - - /** - * Open the cookie manager window - */ - viewCookies : function() - { - var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] - .getService(Components.interfaces.nsIWindowMediator); - var win = wm.getMostRecentWindow("Browser:Cookies"); - var eTLDService = Components.classes["@mozilla.org/network/effective-tld-service;1"]. - getService(Components.interfaces.nsIEffectiveTLDService); - - var eTLD; - var uri = gDocument.documentURIObject; - try { - eTLD = eTLDService.getBaseDomain(uri); - } - catch (e) { - // getBaseDomain will fail if the host is an IP address or is empty - eTLD = uri.asciiHost; - } - - if (win) { - win.gCookiesWindow.setFilter(eTLD); - win.focus(); - } - else - window.openDialog("chrome://browser/content/preferences/cookies.xul", - "Browser:Cookies", "", {filterString : eTLD}); - }, - - /** - * Open the login manager window - */ - viewPasswords : function() - { - var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] - .getService(Components.interfaces.nsIWindowMediator); - var win = wm.getMostRecentWindow("Toolkit:PasswordManager"); - if (win) { - win.setFilter(this._getSecurityInfo().hostName); - win.focus(); - } - else - window.openDialog("chrome://passwordmgr/content/passwordManager.xul", - "Toolkit:PasswordManager", "", - {filterString : this._getSecurityInfo().hostName}); - }, - - _cert : null -}; - -function securityOnLoad() { - var info = security._getSecurityInfo(); - if (!info) { - document.getElementById("securityTab").hidden = true; - document.getElementById("securityBox").collapsed = true; - return; - } - else { - document.getElementById("securityTab").hidden = false; - document.getElementById("securityBox").collapsed = false; - } - - const pageInfoBundle = document.getElementById("pageinfobundle"); - - /* Set Identity section text */ - setText("security-identity-domain-value", info.hostName); - - var owner, verifier, generalPageIdentityString; - if (info.cert && !info.isBroken) { - // Try to pull out meaningful values. Technically these fields are optional - // so we'll employ fallbacks where appropriate. The EV spec states that Org - // fields must be specified for subject and issuer so that case is simpler. - if (info.isEV) { - owner = info.cert.organization; - verifier = security.mapIssuerOrganization(info.cAName); - generalPageIdentityString = pageInfoBundle.getFormattedString("generalSiteIdentity", - [owner, verifier]); - } - else { - // Technically, a non-EV cert might specify an owner in the O field or not, - // depending on the CA's issuing policies. However we don't have any programmatic - // way to tell those apart, and no policy way to establish which organization - // vetting standards are good enough (that's what EV is for) so we default to - // treating these certs as domain-validated only. - owner = pageInfoBundle.getString("securityNoOwner"); - verifier = security.mapIssuerOrganization(info.cAName || - info.cert.issuerCommonName || - info.cert.issuerName); - generalPageIdentityString = owner; - } - } - else { - // We don't have valid identity credentials. - owner = pageInfoBundle.getString("securityNoOwner"); - verifier = pageInfoBundle.getString("notset"); - generalPageIdentityString = owner; - } - - setText("security-identity-owner-value", owner); - setText("security-identity-verifier-value", verifier); - setText("general-security-identity", generalPageIdentityString); - - /* Manage the View Cert button*/ - var viewCert = document.getElementById("security-view-cert"); - if (info.cert) { - security._cert = info.cert; - viewCert.collapsed = false; - } - else - viewCert.collapsed = true; - - /* Set Privacy & History section text */ - var yesStr = pageInfoBundle.getString("yes"); - var noStr = pageInfoBundle.getString("no"); - - var uri = gDocument.documentURIObject; - setText("security-privacy-cookies-value", - hostHasCookies(uri) ? yesStr : noStr); - setText("security-privacy-passwords-value", - realmHasPasswords(uri) ? yesStr : noStr); - - var visitCount = previousVisitCount(info.hostName); - if(visitCount > 1) { - setText("security-privacy-history-value", - pageInfoBundle.getFormattedString("securityNVisits", [visitCount.toLocaleString()])); - } - else if (visitCount == 1) { - setText("security-privacy-history-value", - pageInfoBundle.getString("securityOneVisit")); - } - else { - setText("security-privacy-history-value", noStr); - } - - /* Set the Technical Detail section messages */ - const pkiBundle = document.getElementById("pkiBundle"); - var hdr; - var msg1; - var msg2; - - if (info.isBroken) { - if (info.isMixed) { - hdr = pkiBundle.getString("pageInfo_MixedContent"); - } else { - hdr = pkiBundle.getFormattedString("pageInfo_BrokenEncryption", - [info.encryptionAlgorithm, - info.encryptionStrength + "", - info.version]); - } - msg1 = pkiBundle.getString("pageInfo_Privacy_Broken1"); - msg2 = pkiBundle.getString("pageInfo_Privacy_None2"); - } - else if (info.encryptionStrength > 0) { - hdr = pkiBundle.getFormattedString("pageInfo_EncryptionWithBitsAndProtocol", - [info.encryptionAlgorithm, - info.encryptionStrength + "", - info.version]); - msg1 = pkiBundle.getString("pageInfo_Privacy_Encrypted1"); - msg2 = pkiBundle.getString("pageInfo_Privacy_Encrypted2"); - security._cert = info.cert; - } - else { - hdr = pkiBundle.getString("pageInfo_NoEncryption"); - if (info.hostName != null) - msg1 = pkiBundle.getFormattedString("pageInfo_Privacy_None1", [info.hostName]); - else - msg1 = pkiBundle.getString("pageInfo_Privacy_None3"); - msg2 = pkiBundle.getString("pageInfo_Privacy_None2"); - } - setText("security-technical-shortform", hdr); - setText("security-technical-longform1", msg1); - setText("security-technical-longform2", msg2); - setText("general-security-privacy", hdr); -} - -function setText(id, value) -{ - var element = document.getElementById(id); - if (!element) - return; - if (element.localName == "textbox" || element.localName == "label") - element.value = value; - else { - if (element.hasChildNodes()) - element.removeChild(element.firstChild); - var textNode = document.createTextNode(value); - element.appendChild(textNode); - } -} - -function viewCertHelper(parent, cert) -{ - if (!cert) - return; - - var cd = Components.classes[CERTIFICATEDIALOGS_CONTRACTID].getService(nsICertificateDialogs); - cd.viewCert(parent, cert); -} - -/** - * Return true iff we have cookies for uri - */ -function hostHasCookies(uri) { - var cookieManager = Components.classes["@mozilla.org/cookiemanager;1"] - .getService(Components.interfaces.nsICookieManager2); - - return cookieManager.countCookiesFromHost(uri.asciiHost) > 0; -} - -/** - * Return true iff realm (proto://host:port) (extracted from uri) has - * saved passwords - */ -function realmHasPasswords(uri) { - var passwordManager = Components.classes["@mozilla.org/login-manager;1"] - .getService(Components.interfaces.nsILoginManager); - return passwordManager.countLogins(uri.prePath, "", "") > 0; -} - -/** - * Return the number of previous visits recorded for host before today. - * - * @param host - the domain name to look for in history - */ -function previousVisitCount(host, endTimeReference) { - if (!host) - return false; - - var historyService = Components.classes["@mozilla.org/browser/nav-history-service;1"] - .getService(Components.interfaces.nsINavHistoryService); - - var options = historyService.getNewQueryOptions(); - options.resultType = options.RESULTS_AS_VISIT; - - // Search for visits to this host before today - var query = historyService.getNewQuery(); - query.endTimeReference = query.TIME_RELATIVE_TODAY; - query.endTime = 0; - query.domain = host; - - var result = historyService.executeQuery(query, options); - result.root.containerOpen = true; - var cc = result.root.childCount; - result.root.containerOpen = false; - return cc; -} diff --git a/application/palemoon/base/content/sync/aboutSyncTabs-bindings.xml b/application/palemoon/base/content/sync/aboutSyncTabs-bindings.xml deleted file mode 100644 index e6108209a..000000000 --- a/application/palemoon/base/content/sync/aboutSyncTabs-bindings.xml +++ /dev/null @@ -1,46 +0,0 @@ -<?xml version="1.0"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<bindings id="tabBindings" - xmlns="http://www.mozilla.org/xbl" - xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:xbl="http://www.mozilla.org/xbl"> - - <binding id="tab-listing" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem"> - <content> - <xul:hbox flex="1"> - <xul:vbox pack="start"> - <xul:image class="tabIcon" - xbl:inherits="src=icon"/> - </xul:vbox> - <xul:vbox pack="start" flex="1"> - <xul:label xbl:inherits="value=title,selected" - crop="end" flex="1" class="title"/> - <xul:label xbl:inherits="value=url,selected" - crop="end" flex="1" class="url"/> - </xul:vbox> - </xul:hbox> - </content> - <handlers> - <handler event="dblclick" button="0"> - <![CDATA[ - RemoteTabViewer.openSelected(); - ]]> - </handler> - </handlers> - </binding> - - <binding id="client-listing" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem"> - <content> - <xul:hbox pack="start" align="center" onfocus="event.target.blur()" onselect="return false;"> - <xul:image/> - <xul:label xbl:inherits="value=clientName" - class="clientName" - crop="center" flex="1"/> - </xul:hbox> - </content> - </binding> -</bindings> diff --git a/application/palemoon/base/content/sync/aboutSyncTabs.css b/application/palemoon/base/content/sync/aboutSyncTabs.css deleted file mode 100644 index 5a353175b..000000000 --- a/application/palemoon/base/content/sync/aboutSyncTabs.css +++ /dev/null @@ -1,11 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -richlistitem[type="tab"] { - -moz-binding: url(chrome://browser/content/sync/aboutSyncTabs-bindings.xml#tab-listing); -} - -richlistitem[type="client"] { - -moz-binding: url(chrome://browser/content/sync/aboutSyncTabs-bindings.xml#client-listing); -} diff --git a/application/palemoon/base/content/sync/aboutSyncTabs.js b/application/palemoon/base/content/sync/aboutSyncTabs.js deleted file mode 100644 index 410494b5b..000000000 --- a/application/palemoon/base/content/sync/aboutSyncTabs.js +++ /dev/null @@ -1,313 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Cu = Components.utils; - -Cu.import("resource://services-common/utils.js"); -Cu.import("resource://services-sync/main.js"); -Cu.import("resource:///modules/PlacesUIUtils.jsm"); -Cu.import("resource://gre/modules/PlacesUtils.jsm", this); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -var RemoteTabViewer = { - _tabsList: null, - - init: function () { - Services.obs.addObserver(this, "weave:service:login:finish", false); - Services.obs.addObserver(this, "weave:engine:sync:finish", false); - - this._tabsList = document.getElementById("tabsList"); - - this.buildList(true); - }, - - uninit: function () { - Services.obs.removeObserver(this, "weave:service:login:finish"); - Services.obs.removeObserver(this, "weave:engine:sync:finish"); - }, - - createItem: function(attrs) { - let item = document.createElement("richlistitem"); - - // Copy the attributes from the argument into the item - for (let attr in attrs) { - item.setAttribute(attr, attrs[attr]); - } - - if (attrs["type"] == "tab") { - item.label = attrs.title != "" ? attrs.title : attrs.url; - } - - return item; - }, - - filterTabs: function(event) { - let val = event.target.value.toLowerCase(); - let numTabs = this._tabsList.getRowCount(); - let clientTabs = 0; - let currentClient = null; - - for (let i = 0; i < numTabs; i++) { - let item = this._tabsList.getItemAtIndex(i); - let hide = false; - if (item.getAttribute("type") == "tab") { - if (!item.getAttribute("url").toLowerCase().includes(val) && - !item.getAttribute("title").toLowerCase().includes(val)) { - hide = true; - } else { - clientTabs++; - } - } - else if (item.getAttribute("type") == "client") { - if (currentClient) { - if (clientTabs == 0) { - currentClient.hidden = true; - } - } - currentClient = item; - clientTabs = 0; - } - item.hidden = hide; - } - if (clientTabs == 0) { - currentClient.hidden = true; - } - }, - - openSelected: function() { - let items = this._tabsList.selectedItems; - let urls = []; - for (let i = 0;i < items.length;i++) { - if (items[i].getAttribute("type") == "tab") { - urls.push(items[i].getAttribute("url")); - let index = this._tabsList.getIndexOfItem(items[i]); - this._tabsList.removeItemAt(index); - } - } - if (urls.length) { - getTopWin().gBrowser.loadTabs(urls); - this._tabsList.clearSelection(); - } - }, - - bookmarkSingleTab: function() { - let item = this._tabsList.selectedItems[0]; - let uri = Weave.Utils.makeURI(item.getAttribute("url")); - let title = item.getAttribute("title"); - PlacesUIUtils.showBookmarkDialog({ action: "add" - , type: "bookmark" - , uri: uri - , title: title - , hiddenRows: [ "description" - , "location" - , "loadInSidebar" - , "keyword" ] - }, window.top); - }, - - bookmarkSelectedTabs: function() { - let items = this._tabsList.selectedItems; - let URIs = []; - for (let i = 0;i < items.length;i++) { - if (items[i].getAttribute("type") == "tab") { - let uri = Weave.Utils.makeURI(items[i].getAttribute("url")); - if (!uri) { - continue; - } - - URIs.push(uri); - } - } - if (URIs.length) { - PlacesUIUtils.showBookmarkDialog({ action: "add" - , type: "folder" - , URIList: URIs - , hiddenRows: [ "description" ] - }, window.top); - } - }, - - getIcon: function (iconUri, defaultIcon) { - try { - let iconURI = Weave.Utils.makeURI(iconUri); - return PlacesUtils.favicons.getFaviconLinkForIcon(iconURI).spec; - } catch (ex) { - // Do nothing. - } - - // Just give the provided default icon or the system's default. - return defaultIcon || PlacesUtils.favicons.defaultFavicon.spec; - }, - - _waitingForBuildList: false, - - _buildListRequested: false, - - buildList: function (force) { - if (this._waitingForBuildList) { - this._buildListRequested = true; - return; - } - - this._waitingForBuildList = true; - this._buildListRequested = false; - - this._clearTabList(); - - if (Weave.Service.isLoggedIn && this._refetchTabs(force)) { - this._generateWeaveTabList(); - } else { - //XXXzpao We should say something about not being logged in & not having data - // or tell the appropriate condition. (bug 583344) - } - - function complete() { - this._waitingForBuildList = false; - if (this._buildListRequested) { - CommonUtils.nextTick(this.buildList, this); - } - } - - complete(); - }, - - _clearTabList: function () { - let list = this._tabsList; - - // Clear out existing richlistitems - let count = list.getRowCount(); - if (count > 0) { - for (let i = count - 1; i >= 0; i--) { - list.removeItemAt(i); - } - } - }, - - _generateWeaveTabList: function () { - let engine = Weave.Service.engineManager.get("tabs"); - let list = this._tabsList; - - let seenURLs = new Set(); - let localURLs = engine.getOpenURLs(); - - for (let [guid, client] in Iterator(engine.getAllClients())) { - // Create the client node, but don't add it in-case we don't show any tabs - let appendClient = true; - - client.tabs.forEach(function({title, urlHistory, icon}) { - let url = urlHistory[0]; - if (!url || localURLs.has(url) || seenURLs.has(url)) { - return; - } - seenURLs.add(url); - - if (appendClient) { - let attrs = { - type: "client", - clientName: client.clientName, - class: Weave.Service.clientsEngine.isMobile(client.id) ? "mobile" : "desktop" - }; - let clientEnt = this.createItem(attrs); - list.appendChild(clientEnt); - appendClient = false; - clientEnt.disabled = true; - } - let attrs = { - type: "tab", - title: title || url, - url: url, - icon: this.getIcon(icon), - } - let tab = this.createItem(attrs); - list.appendChild(tab); - }, this); - } - }, - - adjustContextMenu: function(event) { - let mode = "all"; - switch (this._tabsList.selectedItems.length) { - case 0: - break; - case 1: - mode = "single" - break; - default: - mode = "multiple"; - break; - } - - let menu = document.getElementById("tabListContext"); - let el = menu.firstChild; - while (el) { - let showFor = el.getAttribute("showFor"); - if (showFor) { - el.hidden = showFor != mode && showFor != "all"; - } - - el = el.nextSibling; - } - }, - - _refetchTabs: function(force) { - if (!force) { - // Don't bother refetching tabs if we already did so recently - let lastFetch = 0; - try { - lastFetch = Services.prefs.getIntPref("services.sync.lastTabFetch"); - } - catch (e) { - /* Just use the default value of 0 */ - } - - let now = Math.floor(Date.now() / 1000); - if (now - lastFetch < 30) { - return false; - } - } - - // if Clients hasn't synced yet this session, we need to sync it as well. - if (Weave.Service.clientsEngine.lastSync == 0) { - Weave.Service.clientsEngine.sync(); - } - - // Force a sync only for the tabs engine - let engine = Weave.Service.engineManager.get("tabs"); - engine.lastModified = null; - engine.sync(); - Services.prefs.setIntPref("services.sync.lastTabFetch", - Math.floor(Date.now() / 1000)); - - return true; - }, - - observe: function(subject, topic, data) { - switch (topic) { - case "weave:service:login:finish": - this.buildList(true); - break; - case "weave:engine:sync:finish": - if (subject == "tabs") { - this.buildList(false); - } - break; - } - }, - - handleClick: function(event) { - if (event.target.getAttribute("type") != "tab") { - return; - } - - - if (event.button == 1) { - let url = event.target.getAttribute("url"); - openUILink(url, event); - let index = this._tabsList.getIndexOfItem(event.target); - this._tabsList.removeItemAt(index); - } - } -} - diff --git a/application/palemoon/base/content/sync/aboutSyncTabs.xul b/application/palemoon/base/content/sync/aboutSyncTabs.xul deleted file mode 100644 index a4aa0032f..000000000 --- a/application/palemoon/base/content/sync/aboutSyncTabs.xul +++ /dev/null @@ -1,68 +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/. --> - -<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/aboutSyncTabs.css" type="text/css"?> -<?xml-stylesheet href="chrome://browser/content/sync/aboutSyncTabs.css" type="text/css"?> - -<!DOCTYPE window [ - <!ENTITY % aboutSyncTabsDTD SYSTEM "chrome://browser/locale/aboutSyncTabs.dtd"> - %aboutSyncTabsDTD; -]> - -<window id="tabs-display" - onload="RemoteTabViewer.init()" - onunload="RemoteTabViewer.uninit()" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:html="http://www.w3.org/1999/xhtml" - title="&tabs.otherDevices.label;"> - <script type="application/javascript;version=1.8" src="chrome://browser/content/sync/aboutSyncTabs.js"/> - <script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/> - <html:head> - <html:link rel="icon" href="chrome://browser/skin/sync-16.png"/> - </html:head> - - <popupset id="contextmenus"> - <menupopup id="tabListContext"> - <menuitem label="&tabs.context.openTab.label;" - accesskey="&tabs.context.openTab.accesskey;" - oncommand="RemoteTabViewer.openSelected()" - showFor="single"/> - <menuitem label="&tabs.context.bookmarkSingleTab.label;" - accesskey="&tabs.context.bookmarkSingleTab.accesskey;" - oncommand="RemoteTabViewer.bookmarkSingleTab(event)" - showFor="single"/> - <menuitem label="&tabs.context.openMultipleTabs.label;" - accesskey="&tabs.context.openMultipleTabs.accesskey;" - oncommand="RemoteTabViewer.openSelected()" - showFor="multiple"/> - <menuitem label="&tabs.context.bookmarkMultipleTabs.label;" - accesskey="&tabs.context.bookmarkMultipleTabs.accesskey;" - oncommand="RemoteTabViewer.bookmarkSelectedTabs()" - showFor="multiple"/> - <menuseparator/> - <menuitem label="&tabs.context.refreshList.label;" - accesskey="&tabs.context.refreshList.accesskey;" - oncommand="RemoteTabViewer.buildList()" - showFor="all"/> - </menupopup> - </popupset> - <richlistbox context="tabListContext" id="tabsList" seltype="multiple" - align="center" flex="1" - onclick="RemoteTabViewer.handleClick(event)" - oncontextmenu="RemoteTabViewer.adjustContextMenu(event)"> - <hbox id="headers" align="center"> - <label id="tabsListHeading" - value="&tabs.otherDevices.label;"/> - <spacer flex="1"/> - <textbox type="search" - emptytext="&tabs.searchText.label;" - oncommand="RemoteTabViewer.filterTabs(event)"/> - </hbox> - - </richlistbox> -</window> - diff --git a/application/palemoon/base/content/sync/addDevice.js b/application/palemoon/base/content/sync/addDevice.js deleted file mode 100644 index 0390d4397..000000000 --- a/application/palemoon/base/content/sync/addDevice.js +++ /dev/null @@ -1,157 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Ci = Components.interfaces; -var Cc = Components.classes; -var Cu = Components.utils; - -Cu.import("resource://services-sync/main.js"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -const PIN_PART_LENGTH = 4; - -const ADD_DEVICE_PAGE = 0; -const SYNC_KEY_PAGE = 1; -const DEVICE_CONNECTED_PAGE = 2; - -var gSyncAddDevice = { - - init: function init() { - this.pin1.setAttribute("maxlength", PIN_PART_LENGTH); - this.pin2.setAttribute("maxlength", PIN_PART_LENGTH); - this.pin3.setAttribute("maxlength", PIN_PART_LENGTH); - - this.nextFocusEl = {pin1: this.pin2, - pin2: this.pin3, - pin3: this.wizard.getButton("next")}; - - this.throbber = document.getElementById("pairDeviceThrobber"); - this.errorRow = document.getElementById("errorRow"); - - // Kick off a sync. That way the server will have the most recent data from - // this computer and it will show up immediately on the new device. - Weave.Service.scheduler.scheduleNextSync(0); - }, - - onPageShow: function onPageShow() { - this.wizard.getButton("back").hidden = true; - - switch (this.wizard.pageIndex) { - case ADD_DEVICE_PAGE: - this.onTextBoxInput(); - this.wizard.canRewind = false; - this.wizard.getButton("next").hidden = false; - this.pin1.focus(); - break; - case SYNC_KEY_PAGE: - this.wizard.canAdvance = false; - this.wizard.canRewind = true; - this.wizard.getButton("back").hidden = false; - this.wizard.getButton("next").hidden = true; - document.getElementById("weavePassphrase").value = - Weave.Utils.hyphenatePassphrase(Weave.Service.identity.syncKey); - break; - case DEVICE_CONNECTED_PAGE: - this.wizard.canAdvance = true; - this.wizard.canRewind = false; - this.wizard.getButton("cancel").hidden = true; - break; - } - }, - - onWizardAdvance: function onWizardAdvance() { - switch (this.wizard.pageIndex) { - case ADD_DEVICE_PAGE: - this.startTransfer(); - return false; - case DEVICE_CONNECTED_PAGE: - window.close(); - return false; - } - return true; - }, - - startTransfer: function startTransfer() { - this.errorRow.hidden = true; - // When onAbort is called, Weave may already be gone. - const JPAKE_ERROR_USERABORT = Weave.JPAKE_ERROR_USERABORT; - - let self = this; - let jpakeclient = this._jpakeclient = new Weave.JPAKEClient({ - onPaired: function onPaired() { - let credentials = {account: Weave.Service.identity.account, - password: Weave.Service.identity.basicPassword, - synckey: Weave.Service.identity.syncKey, - serverURL: Weave.Service.serverURL}; - jpakeclient.sendAndComplete(credentials); - }, - onComplete: function onComplete() { - delete self._jpakeclient; - self.wizard.pageIndex = DEVICE_CONNECTED_PAGE; - - // Schedule a Sync for soonish to fetch the data uploaded by the - // device with which we just paired. - Weave.Service.scheduler.scheduleNextSync(Weave.Service.scheduler.activeInterval); - }, - onAbort: function onAbort(error) { - delete self._jpakeclient; - - // Aborted by user, ignore. - if (error == JPAKE_ERROR_USERABORT) { - return; - } - - self.errorRow.hidden = false; - self.throbber.hidden = true; - self.pin1.value = self.pin2.value = self.pin3.value = ""; - self.pin1.disabled = self.pin2.disabled = self.pin3.disabled = false; - self.pin1.focus(); - } - }); - this.throbber.hidden = false; - this.pin1.disabled = this.pin2.disabled = this.pin3.disabled = true; - this.wizard.canAdvance = false; - - let pin = this.pin1.value + this.pin2.value + this.pin3.value; - let expectDelay = false; - jpakeclient.pairWithPIN(pin, expectDelay); - }, - - onWizardBack: function onWizardBack() { - if (this.wizard.pageIndex != SYNC_KEY_PAGE) - return true; - - this.wizard.pageIndex = ADD_DEVICE_PAGE; - return false; - }, - - onWizardCancel: function onWizardCancel() { - if (this._jpakeclient) { - this._jpakeclient.abort(); - delete this._jpakeclient; - } - return true; - }, - - onTextBoxInput: function onTextBoxInput(textbox) { - if (textbox && textbox.value.length == PIN_PART_LENGTH) - this.nextFocusEl[textbox.id].focus(); - - this.wizard.canAdvance = (this.pin1.value.length == PIN_PART_LENGTH - && this.pin2.value.length == PIN_PART_LENGTH - && this.pin3.value.length == PIN_PART_LENGTH); - }, - - goToSyncKeyPage: function goToSyncKeyPage() { - this.wizard.pageIndex = SYNC_KEY_PAGE; - } - -}; -// onWizardAdvance() and onPageShow() are run before init() so we'll set -// these up as lazy getters. -["wizard", "pin1", "pin2", "pin3"].forEach(function (id) { - XPCOMUtils.defineLazyGetter(gSyncAddDevice, id, function() { - return document.getElementById(id); - }); -}); diff --git a/application/palemoon/base/content/sync/addDevice.xul b/application/palemoon/base/content/sync/addDevice.xul deleted file mode 100644 index f2371aad0..000000000 --- a/application/palemoon/base/content/sync/addDevice.xul +++ /dev/null @@ -1,129 +0,0 @@ -<?xml version="1.0"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/syncSetup.css" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/syncCommon.css" type="text/css"?> - -<!DOCTYPE window [ -<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> -<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> -<!ENTITY % syncSetupDTD SYSTEM "chrome://browser/locale/syncSetup.dtd"> -%brandDTD; -%syncBrandDTD; -%syncSetupDTD; -]> -<wizard xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:html="http://www.w3.org/1999/xhtml" - id="wizard" - title="&pairDevice.title.label;" - windowtype="Sync:AddDevice" - persist="screenX screenY" - onwizardnext="return gSyncAddDevice.onWizardAdvance();" - onwizardback="return gSyncAddDevice.onWizardBack();" - onwizardcancel="gSyncAddDevice.onWizardCancel();" - onload="gSyncAddDevice.init();"> - - <script type="application/javascript" - src="chrome://browser/content/sync/addDevice.js"/> - <script type="application/javascript" - src="chrome://browser/content/sync/utils.js"/> - <script type="application/javascript" - src="chrome://browser/content/utilityOverlay.js"/> - <script type="application/javascript" - src="chrome://global/content/printUtils.js"/> - - <wizardpage id="addDevicePage" - label="&pairDevice.title.label;" - onpageshow="gSyncAddDevice.onPageShow();"> - <description> - &pairDevice.dialog.description.label; - <label class="text-link" - value="&addDevice.showMeHow.label;" - href="http://www.palemoon.org/sync/help/easy-setup.shtml"/> - </description> - <separator class="groove-thin"/> - <description> - &addDevice.dialog.enterCode.label; - </description> - <separator class="groove-thin"/> - <vbox align="center"> - <textbox id="pin1" - class="pin" - oninput="gSyncAddDevice.onTextBoxInput(this);" - onfocus="this.select();" - /> - <textbox id="pin2" - class="pin" - oninput="gSyncAddDevice.onTextBoxInput(this);" - onfocus="this.select();" - /> - <textbox id="pin3" - class="pin" - oninput="gSyncAddDevice.onTextBoxInput(this);" - onfocus="this.select();" - /> - </vbox> - <separator class="groove-thin"/> - <vbox id="pairDeviceThrobber" align="center" hidden="true"> - <image/> - </vbox> - <hbox id="errorRow" pack="center" hidden="true"> - <image class="statusIcon" status="error"/> - <label class="status" - value="&addDevice.dialog.tryAgain.label;"/> - </hbox> - <spacer flex="3"/> - <label class="text-link" - value="&addDevice.dontHaveDevice.label;" - onclick="gSyncAddDevice.goToSyncKeyPage();"/> - </wizardpage> - - <!-- Need a non-empty label here, otherwise we get a default label on Mac --> - <wizardpage id="syncKeyPage" - label=" " - onpageshow="gSyncAddDevice.onPageShow();"> - <description> - &addDevice.dialog.recoveryKey.label; - </description> - <spacer/> - - <groupbox> - <label value="&recoveryKeyEntry.label;" - accesskey="&recoveryKeyEntry.accesskey;" - control="weavePassphrase"/> - <textbox id="weavePassphrase" - readonly="true"/> - </groupbox> - - <groupbox align="center"> - <description>&recoveryKeyBackup.description;</description> - <hbox> - <button id="printSyncKeyButton" - label="&button.syncKeyBackup.print.label;" - accesskey="&button.syncKeyBackup.print.accesskey;" - oncommand="gSyncUtils.passphrasePrint('weavePassphrase');"/> - <button id="saveSyncKeyButton" - label="&button.syncKeyBackup.save.label;" - accesskey="&button.syncKeyBackup.save.accesskey;" - oncommand="gSyncUtils.passphraseSave('weavePassphrase');"/> - </hbox> - </groupbox> - </wizardpage> - - <wizardpage id="deviceConnectedPage" - label="&addDevice.dialog.connected.label;" - onpageshow="gSyncAddDevice.onPageShow();"> - <vbox align="center"> - <image id="successPageIcon"/> - </vbox> - <separator/> - <description class="normal"> - &addDevice.dialog.successful.label; - </description> - </wizardpage> - -</wizard> diff --git a/application/palemoon/base/content/sync/genericChange.js b/application/palemoon/base/content/sync/genericChange.js deleted file mode 100644 index df6639178..000000000 --- a/application/palemoon/base/content/sync/genericChange.js +++ /dev/null @@ -1,234 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Ci = Components.interfaces; -var Cc = Components.classes; - -Components.utils.import("resource://services-sync/main.js"); -Components.utils.import("resource://gre/modules/Services.jsm"); - -var Change = { - _dialog: null, - _dialogType: null, - _status: null, - _statusIcon: null, - _firstBox: null, - _secondBox: null, - - get _passphraseBox() { - delete this._passphraseBox; - return this._passphraseBox = document.getElementById("passphraseBox"); - }, - - get _currentPasswordInvalid() { - return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED; - }, - - get _updatingPassphrase() { - return this._dialogType == "UpdatePassphrase"; - }, - - onLoad: function Change_onLoad() { - /* Load labels */ - let introText = document.getElementById("introText"); - let introText2 = document.getElementById("introText2"); - let warningText = document.getElementById("warningText"); - - // load some other elements & info from the window - this._dialog = document.getElementById("change-dialog"); - this._dialogType = window.arguments[0]; - this._duringSetup = window.arguments[1]; - this._status = document.getElementById("status"); - this._statusIcon = document.getElementById("statusIcon"); - this._statusRow = document.getElementById("statusRow"); - this._firstBox = document.getElementById("textBox1"); - this._secondBox = document.getElementById("textBox2"); - - this._dialog.getButton("finish").disabled = true; - this._dialog.getButton("back").hidden = true; - - this._stringBundle = - Services.strings.createBundle("chrome://browser/locale/syncGenericChange.properties"); - - switch (this._dialogType) { - case "UpdatePassphrase": - case "ResetPassphrase": - document.getElementById("textBox1Row").hidden = true; - document.getElementById("textBox2Row").hidden = true; - document.getElementById("passphraseLabel").value - = this._str("new.recoverykey.label"); - document.getElementById("passphraseSpacer").hidden = false; - - if (this._updatingPassphrase) { - document.getElementById("passphraseHelpBox").hidden = false; - document.title = this._str("new.recoverykey.title"); - introText.textContent = this._str("new.recoverykey.introText"); - this._dialog.getButton("finish").label - = this._str("new.recoverykey.acceptButton"); - } - else { - document.getElementById("generatePassphraseButton").hidden = false; - document.getElementById("passphraseBackupButtons").hidden = false; - let pp = Weave.Service.identity.syncKey; - if (Weave.Utils.isPassphrase(pp)) - pp = Weave.Utils.hyphenatePassphrase(pp); - this._passphraseBox.value = pp; - this._passphraseBox.focus(); - document.title = this._str("change.recoverykey.title"); - introText.textContent = this._str("change.synckey.introText2"); - warningText.textContent = this._str("change.recoverykey.warningText"); - this._dialog.getButton("finish").label - = this._str("change.recoverykey.acceptButton"); - if (this._duringSetup) { - this._dialog.getButton("finish").disabled = false; - } - } - break; - case "ChangePassword": - document.getElementById("passphraseRow").hidden = true; - let box1label = document.getElementById("textBox1Label"); - let box2label = document.getElementById("textBox2Label"); - box1label.value = this._str("new.password.label"); - - if (this._currentPasswordInvalid) { - document.title = this._str("new.password.title"); - introText.textContent = this._str("new.password.introText"); - this._dialog.getButton("finish").label - = this._str("new.password.acceptButton"); - document.getElementById("textBox2Row").hidden = true; - } - else { - document.title = this._str("change.password.title"); - box2label.value = this._str("new.password.confirm"); - introText.textContent = this._str("change.password3.introText"); - warningText.textContent = this._str("change.password.warningText"); - this._dialog.getButton("finish").label - = this._str("change.password.acceptButton"); - } - break; - } - document.getElementById("change-page") - .setAttribute("label", document.title); - }, - - _clearStatus: function _clearStatus() { - this._status.value = ""; - this._statusIcon.removeAttribute("status"); - }, - - _updateStatus: function Change__updateStatus(str, state) { - this._updateStatusWithString(this._str(str), state); - }, - - _updateStatusWithString: function Change__updateStatusWithString(string, state) { - this._statusRow.hidden = false; - this._status.value = string; - this._statusIcon.setAttribute("status", state); - - let error = state == "error"; - this._dialog.getButton("cancel").disabled = !error; - this._dialog.getButton("finish").disabled = !error; - document.getElementById("printSyncKeyButton").disabled = !error; - document.getElementById("saveSyncKeyButton").disabled = !error; - - if (state == "success") - window.setTimeout(window.close, 1500); - }, - - onDialogAccept: function() { - switch (this._dialogType) { - case "UpdatePassphrase": - case "ResetPassphrase": - return this.doChangePassphrase(); - break; - case "ChangePassword": - return this.doChangePassword(); - break; - } - }, - - doGeneratePassphrase: function () { - let passphrase = Weave.Utils.generatePassphrase(); - this._passphraseBox.value = Weave.Utils.hyphenatePassphrase(passphrase); - this._dialog.getButton("finish").disabled = false; - }, - - doChangePassphrase: function Change_doChangePassphrase() { - let pp = Weave.Utils.normalizePassphrase(this._passphraseBox.value); - if (this._updatingPassphrase) { - Weave.Service.identity.syncKey = pp; - if (Weave.Service.login()) { - this._updateStatus("change.recoverykey.success", "success"); - Weave.Service.persistLogin(); - Weave.Service.scheduler.delayedAutoConnect(0); - } - else { - this._updateStatus("new.passphrase.status.incorrect", "error"); - } - } - else { - this._updateStatus("change.recoverykey.label", "active"); - - if (Weave.Service.changePassphrase(pp)) - this._updateStatus("change.recoverykey.success", "success"); - else - this._updateStatus("change.recoverykey.error", "error"); - } - - return false; - }, - - doChangePassword: function Change_doChangePassword() { - if (this._currentPasswordInvalid) { - Weave.Service.identity.basicPassword = this._firstBox.value; - if (Weave.Service.login()) { - this._updateStatus("change.password.status.success", "success"); - Weave.Service.persistLogin(); - } - else { - this._updateStatus("new.password.status.incorrect", "error"); - } - } - else { - this._updateStatus("change.password.status.active", "active"); - - if (Weave.Service.changePassword(this._firstBox.value)) - this._updateStatus("change.password.status.success", "success"); - else - this._updateStatus("change.password.status.error", "error"); - } - - return false; - }, - - validate: function (event) { - let valid = false; - let errorString = ""; - - if (this._dialogType == "ChangePassword") { - if (this._currentPasswordInvalid) - [valid, errorString] = gSyncUtils.validatePassword(this._firstBox); - else - [valid, errorString] = gSyncUtils.validatePassword(this._firstBox, this._secondBox); - } - else { - //Pale Moon: Enforce minimum length of 8 for allowed custom passphrase - //and don't restrict it to "out of sync" situations only. People who - //go to this page generally know what they are doing ;) - valid = this._passphraseBox.value.length >= 8; - } - - if (errorString == "") - this._clearStatus(); - else - this._updateStatusWithString(errorString, "error"); - - this._statusRow.hidden = valid; - this._dialog.getButton("finish").disabled = !valid; - }, - - _str: function Change__string(str) { - return this._stringBundle.GetStringFromName(str); - } -}; diff --git a/application/palemoon/base/content/sync/genericChange.xul b/application/palemoon/base/content/sync/genericChange.xul deleted file mode 100644 index 3c0b2cd6c..000000000 --- a/application/palemoon/base/content/sync/genericChange.xul +++ /dev/null @@ -1,123 +0,0 @@ -<?xml version="1.0"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/syncSetup.css" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/syncCommon.css" type="text/css"?> - -<!DOCTYPE window [ -<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> -<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> -<!ENTITY % syncSetupDTD SYSTEM "chrome://browser/locale/syncSetup.dtd"> -%brandDTD; -%syncBrandDTD; -%syncSetupDTD; -]> -<wizard xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:html="http://www.w3.org/1999/xhtml" - id="change-dialog" - windowtype="Weave:ChangeSomething" - persist="screenX screenY" - onwizardnext="Change.onLoad()" - onwizardfinish="return Change.onDialogAccept();"> - - <script type="application/javascript" - src="chrome://browser/content/sync/genericChange.js"/> - <script type="application/javascript" - src="chrome://browser/content/sync/utils.js"/> - <script type="application/javascript" - src="chrome://global/content/printUtils.js"/> - - <wizardpage id="change-page" - label=""> - - <description id="introText"> - </description> - - <separator class="thin"/> - - <groupbox> - <grid> - <columns> - <column align="right"/> - <column flex="3"/> - <column flex="1"/> - </columns> - <rows> - <row id="textBox1Row" align="center"> - <label id="textBox1Label" control="textBox1"/> - <textbox id="textBox1" type="password" oninput="Change.validate()"/> - <spacer/> - </row> - <row id="textBox2Row" align="center"> - <label id="textBox2Label" control="textBox2"/> - <textbox id="textBox2" type="password" oninput="Change.validate()"/> - <spacer/> - </row> - </rows> - </grid> - - <vbox id="passphraseRow"> - <hbox flex="1"> - <label id="passphraseLabel" control="passphraseBox"/> - <spacer flex="1"/> - <label id="generatePassphraseButton" - hidden="true" - value="&syncGenerateNewKey.label;" - class="text-link inline-link" - onclick="event.stopPropagation(); - Change.doGeneratePassphrase();"/> - </hbox> - <textbox id="passphraseBox" - flex="1" - onfocus="this.select()" - oninput="Change.validate()"/> - </vbox> - - <vbox id="feedback" pack="center"> - <hbox id="statusRow" align="center"> - <image id="statusIcon" class="statusIcon"/> - <label id="status" class="status" value=" "/> - </hbox> - </vbox> - </groupbox> - - <separator class="thin"/> - - <hbox id="passphraseBackupButtons" - hidden="true" - pack="center"> - <button id="printSyncKeyButton" - label="&button.syncKeyBackup.print.label;" - accesskey="&button.syncKeyBackup.print.accesskey;" - oncommand="gSyncUtils.passphrasePrint('passphraseBox');"/> - <button id="saveSyncKeyButton" - label="&button.syncKeyBackup.save.label;" - accesskey="&button.syncKeyBackup.save.accesskey;" - oncommand="gSyncUtils.passphraseSave('passphraseBox');"/> - </hbox> - - <vbox id="passphraseHelpBox" - hidden="true"> - <description> - &existingRecoveryKey.description; - <label class="text-link" - href="http://www.palemoon.org/sync/help/recoverykey.shtml"> - &addDevice.showMeHow.label; - </label> - </description> - </vbox> - - <spacer id="passphraseSpacer" - flex="1" - hidden="true"/> - - <description id="warningText" class="data"> - </description> - - <spacer flex="1"/> - </wizardpage> -</wizard> diff --git a/application/palemoon/base/content/sync/key.xhtml b/application/palemoon/base/content/sync/key.xhtml deleted file mode 100644 index 92abf0ee6..000000000 --- a/application/palemoon/base/content/sync/key.xhtml +++ /dev/null @@ -1,54 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"> - %htmlDTD; - <!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> - %syncBrandDTD; - <!ENTITY % syncKeyDTD SYSTEM "chrome://browser/locale/syncKey.dtd"> - %syncKeyDTD; - <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd" > - %globalDTD; -]> -<html xmlns="http://www.w3.org/1999/xhtml"> -<head> - <title>&syncKey.page.title;</title> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> - <meta name="robots" content="noindex"/> - <style type="text/css"> - #synckey { font-size: 150% } - footer { font-size: 70% } - /* Bug 575675: Need to have an a:visited rule in a chrome document. */ - a:visited { color: purple; } - </style> -</head> - -<body dir="&locale.dir;"> -<h1>&syncKey.page.title;</h1> - -<p id="synckey" dir="ltr">SYNCKEY</p> - -<p>&syncKey.page.description2;</p> - -<div id="column1"> - <h2>&syncKey.keepItSecret.heading;</h2> - <p>&syncKey.keepItSecret.description;</p> -</div> - -<div id="column2"> - <h2>&syncKey.keepItSafe.heading;</h2> - <p><em>&syncKey.keepItSafe1.description;</em>&syncKey.keepItSafe2.description;<em>&syncKey.keepItSafe3.description;</em>&syncKey.keepItSafe4a.description;</p> -</div> - -<p>&syncKey.findOutMore1.label;<a href="http://www.palemoon.org/sync/">http://www.palemoon.org/sync/</a>&syncKey.findOutMore2.label;</p> - -<footer> - &syncKey.footer1.label;<a id="tosLink" href="termsURL">termsURL</a>&syncKey.footer2.label;<a id="ppLink" href="privacyURL">privacyURL</a>&syncKey.footer3.label; -</footer> - -</body> -</html> diff --git a/application/palemoon/base/content/sync/notification.xml b/application/palemoon/base/content/sync/notification.xml deleted file mode 100644 index 7a2b77382..000000000 --- a/application/palemoon/base/content/sync/notification.xml +++ /dev/null @@ -1,129 +0,0 @@ -<?xml version="1.0"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE bindings [ -<!ENTITY % notificationDTD SYSTEM "chrome://global/locale/notification.dtd"> -%notificationDTD; -]> - -<bindings id="notificationBindings" - xmlns="http://www.mozilla.org/xbl" - xmlns:xbl="http://www.mozilla.org/xbl" - xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> - - <binding id="notificationbox" extends="chrome://global/content/bindings/notification.xml#notificationbox"> - <content> - <xul:vbox xbl:inherits="hidden=notificationshidden"> - <xul:spacer/> - <children includes="notification"/> - </xul:vbox> - <children/> - </content> - - <implementation> - <constructor><![CDATA[ - let temp = {}; - Cu.import("resource://services-common/observers.js", temp); - temp.Observers.add("weave:notification:added", this.onNotificationAdded, this); - temp.Observers.add("weave:notification:removed", this.onNotificationRemoved, this); - - for each (var notification in Weave.Notifications.notifications) - this._appendNotification(notification); - ]]></constructor> - - <destructor><![CDATA[ - let temp = {}; - Cu.import("resource://services-common/observers.js", temp); - temp.Observers.remove("weave:notification:added", this.onNotificationAdded, this); - temp.Observers.remove("weave:notification:removed", this.onNotificationRemoved, this); - ]]></destructor> - - <method name="onNotificationAdded"> - <parameter name="subject"/> - <parameter name="data"/> - <body><![CDATA[ - this._appendNotification(subject); - ]]></body> - </method> - - <method name="onNotificationRemoved"> - <parameter name="subject"/> - <parameter name="data"/> - <body><![CDATA[ - // If the view of the notification hasn't been removed yet, remove it. - var notifications = this.allNotifications; - for each (var notification in notifications) { - if (notification.notification == subject) { - notification.close(); - break; - } - } - ]]></body> - </method> - - <method name="_appendNotification"> - <parameter name="notification"/> - <body><![CDATA[ - var node = this.appendNotification(notification.description, - notification.title, - notification.iconURL, - notification.priority, - notification.buttons); - node.notification = notification; - ]]></body> - </method> - - </implementation> - </binding> - - <binding id="notification" extends="chrome://global/content/bindings/notification.xml#notification"> - <content> - <xul:hbox class="notification-inner outset" flex="1" xbl:inherits="type"> - <xul:toolbarbutton ondblclick="event.stopPropagation();" - class="messageCloseButton close-icon tabbable" - xbl:inherits="hidden=hideclose" - tooltiptext="&closeNotification.tooltip;" - oncommand="document.getBindingParent(this).close()"/> - <xul:hbox anonid="details" align="center" flex="1"> - <xul:image anonid="messageImage" class="messageImage" xbl:inherits="src=image"/> - <xul:description anonid="messageText" class="messageText" xbl:inherits="xbl:text=label"/> - - <!-- The children are the buttons defined by the notification. --> - <xul:hbox oncommand="document.getBindingParent(this)._doButtonCommand(event);"> - <children/> - </xul:hbox> - </xul:hbox> - </xul:hbox> - </content> - <implementation> - <!-- Note: this used to be a field, but for some reason it kept getting - - reset to its default value for TabNotification elements. - - As a property, that doesn't happen, even though the property stores - - its value in a JS property |_notification| that is not defined - - in XBL as a field or property. Maybe this is wrong, but it works. - --> - <property name="notification" - onget="return this._notification" - onset="this._notification = val; return val;"/> - <method name="close"> - <body><![CDATA[ - Weave.Notifications.remove(this.notification); - - // We should be able to call the base class's close method here - // to remove the notification element from the notification box, - // but we can't because of bug 373652, so instead we copied its code - // and execute it below. - var control = this.control; - if (control) - control.removeNotification(this); - else - this.hidden = true; - ]]></body> - </method> - </implementation> - </binding> - -</bindings> diff --git a/application/palemoon/base/content/sync/progress.js b/application/palemoon/base/content/sync/progress.js deleted file mode 100644 index 101160fa8..000000000 --- a/application/palemoon/base/content/sync/progress.js +++ /dev/null @@ -1,71 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://services-sync/main.js"); - -var gProgressBar; -var gCounter = 0; - -function onLoad(event) { - Services.obs.addObserver(onEngineSync, "weave:engine:sync:finish", false); - Services.obs.addObserver(onEngineSync, "weave:engine:sync:error", false); - Services.obs.addObserver(onServiceSync, "weave:service:sync:finish", false); - Services.obs.addObserver(onServiceSync, "weave:service:sync:error", false); - - gProgressBar = document.getElementById('uploadProgressBar'); - - if (Services.prefs.getPrefType("services.sync.firstSync") != Ci.nsIPrefBranch.PREF_INVALID) { - gProgressBar.hidden = false; - } - else { - gProgressBar.hidden = true; - } -} - -function onUnload(event) { - cleanUpObservers(); -} - -function cleanUpObservers() { - try { - Services.obs.removeObserver(onEngineSync, "weave:engine:sync:finish"); - Services.obs.removeObserver(onEngineSync, "weave:engine:sync:error"); - Services.obs.removeObserver(onServiceSync, "weave:service:sync:finish"); - Services.obs.removeObserver(onServiceSync, "weave:service:sync:error"); - } - catch (e) { - // may be double called by unload & exit. Ignore. - } -} - -function onEngineSync(subject, topic, data) { - // The Clients engine syncs first. At this point we don't necessarily know - // yet how many engines will be enabled, so we'll ignore the Clients engine - // and evaluate how many engines are enabled when the first "real" engine - // syncs. - if (data == "clients") { - return; - } - - if (!gCounter && - Services.prefs.getPrefType("services.sync.firstSync") != Ci.nsIPrefBranch.PREF_INVALID) { - gProgressBar.max = Weave.Service.engineManager.getEnabled().length; - } - - gCounter += 1; - gProgressBar.setAttribute("value", gCounter); -} - -function onServiceSync(subject, topic, data) { - // To address the case where 0 engines are synced, we will fill the - // progress bar so the user knows that the sync has finished. - gProgressBar.setAttribute("value", gProgressBar.max); - cleanUpObservers(); -} - -function closeTab() { - window.close(); -} diff --git a/application/palemoon/base/content/sync/progress.xhtml b/application/palemoon/base/content/sync/progress.xhtml deleted file mode 100644 index d403cb20d..000000000 --- a/application/palemoon/base/content/sync/progress.xhtml +++ /dev/null @@ -1,55 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<!DOCTYPE html [ - <!ENTITY % htmlDTD - PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" - "DTD/xhtml1-strict.dtd"> - %htmlDTD; - <!ENTITY % syncProgressDTD - SYSTEM "chrome://browser/locale/syncProgress.dtd"> - %syncProgressDTD; - <!ENTITY % syncSetupDTD - SYSTEM "chrome://browser/locale/syncSetup.dtd"> - %syncSetupDTD; - <!ENTITY % globalDTD - SYSTEM "chrome://global/locale/global.dtd"> - %globalDTD; -]> - -<html xmlns="http://www.w3.org/1999/xhtml"> - <head> - <title>&syncProgress.pageTitle;</title> - - <link rel="stylesheet" type="text/css" media="all" - href="chrome://browser/skin/syncProgress.css"/> - - <link rel="icon" type="image/png" id="favicon" - href="chrome://browser/skin/sync-16.png"/> - - <script type="text/javascript;version=1.8" - src="chrome://browser/content/sync/progress.js"/> - </head> - <body onload="onLoad(event)" onunload="onUnload(event)" dir="&locale.dir;"> - <title>&setup.successPage.title;</title> - <div id="floatingBox" class="main-content"> - <div id="title"> - <h1>&setup.successPage.title;</h1> - </div> - <div id="successLogo"> - <img id="brandSyncLogo" src="chrome://browser/skin/sync-128.png" alt="&syncProgress.logoAltText;" /> - </div> - <div id="loadingText"> - <p id="blurb">&syncProgress.textBlurb; </p> - </div> - <div id="progressBar"> - <progress id="uploadProgressBar" value="0"/> - </div> - <div id="bottomRow"> - <button id="closeButton" onclick="closeTab()">&syncProgress.closeButton; </button> - </div> - </div> - </body> -</html> diff --git a/application/palemoon/base/content/sync/quota.js b/application/palemoon/base/content/sync/quota.js deleted file mode 100644 index 1285a8d54..000000000 --- a/application/palemoon/base/content/sync/quota.js +++ /dev/null @@ -1,279 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const Ci = Components.interfaces; -const Cc = Components.classes; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://services-sync/main.js"); -Cu.import("resource://gre/modules/DownloadUtils.jsm"); - -var gSyncQuota = { - - init: function init() { - this.bundle = document.getElementById("quotaStrings"); - let caption = document.getElementById("treeCaption"); - caption.firstChild.nodeValue = this.bundle.getString("quota.treeCaption.label"); - - gUsageTreeView.init(); - this.tree = document.getElementById("usageTree"); - this.tree.view = gUsageTreeView; - - this.loadData(); - }, - - loadData: function loadData() { - this._usage_req = Weave.Service.getStorageInfo(Weave.INFO_COLLECTION_USAGE, - function (error, usage) { - delete gSyncQuota._usage_req; - // displayUsageData handles null values, so no need to check 'error'. - gUsageTreeView.displayUsageData(usage); - }); - - let usageLabel = document.getElementById("usageLabel"); - let bundle = this.bundle; - - this._quota_req = Weave.Service.getStorageInfo(Weave.INFO_QUOTA, - function (error, quota) { - delete gSyncQuota._quota_req; - - if (error) { - usageLabel.value = bundle.getString("quota.usageError.label"); - return; - } - let used = gSyncQuota.convertKB(quota[0]); - if (!quota[1]) { - // No quota on the server. - usageLabel.value = bundle.getFormattedString( - "quota.usageNoQuota.label", used); - return; - } - let percent = Math.round(100 * quota[0] / quota[1]); - let total = gSyncQuota.convertKB(quota[1]); - usageLabel.value = bundle.getFormattedString( - "quota.usagePercentage.label", [percent].concat(used).concat(total)); - }); - }, - - onCancel: function onCancel() { - if (this._usage_req) { - this._usage_req.abort(); - } - if (this._quota_req) { - this._quota_req.abort(); - } - return true; - }, - - onAccept: function onAccept() { - let engines = gUsageTreeView.getEnginesToDisable(); - for each (let engine in engines) { - Weave.Service.engineManager.get(engine).enabled = false; - } - if (engines.length) { - // The 'Weave' object will disappear once the window closes. - let Service = Weave.Service; - Weave.Utils.nextTick(function() { Service.sync(); }); - } - return this.onCancel(); - }, - - convertKB: function convertKB(value) { - return DownloadUtils.convertByteUnits(value * 1024); - } - -}; - -var gUsageTreeView = { - - _ignored: {keys: true, - meta: true, - clients: true}, - - /* - * Internal data structures underlaying the tree. - */ - _collections: [], - _byname: {}, - - init: function init() { - let retrievingLabel = gSyncQuota.bundle.getString("quota.retrieving.label"); - for each (let engine in Weave.Service.engineManager.getEnabled()) { - if (this._ignored[engine.name]) - continue; - - // Some engines use the same pref, which means they can only be turned on - // and off together. We need to combine them here as well. - let existing = this._byname[engine.prefName]; - if (existing) { - existing.engines.push(engine.name); - continue; - } - - let obj = {name: engine.prefName, - title: this._collectionTitle(engine), - engines: [engine.name], - enabled: true, - sizeLabel: retrievingLabel}; - this._collections.push(obj); - this._byname[engine.prefName] = obj; - } - }, - - _collectionTitle: function _collectionTitle(engine) { - try { - return gSyncQuota.bundle.getString( - "collection." + engine.prefName + ".label"); - } catch (ex) { - return engine.Name; - } - }, - - /* - * Process the quota information as returned by info/collection_usage. - */ - displayUsageData: function displayUsageData(data) { - for each (let coll in this._collections) { - coll.size = 0; - // If we couldn't retrieve any data, just blank out the label. - if (!data) { - coll.sizeLabel = ""; - continue; - } - - for each (let engineName in coll.engines) - coll.size += data[engineName] || 0; - let sizeLabel = ""; - sizeLabel = gSyncQuota.bundle.getFormattedString( - "quota.sizeValueUnit.label", gSyncQuota.convertKB(coll.size)); - coll.sizeLabel = sizeLabel; - } - let sizeColumn = this.treeBox.columns.getNamedColumn("size"); - this.treeBox.invalidateColumn(sizeColumn); - }, - - /* - * Handle click events on the tree. - */ - onTreeClick: function onTreeClick(event) { - if (event.button == 2) - return; - - let cell = this.treeBox.getCellAt(event.clientX, event.clientY); - if (cell.col && cell.col.id == "enabled") - this.toggle(cell.row); - }, - - /* - * Toggle enabled state of an engine. - */ - toggle: function toggle(row) { - // Update the tree - let collection = this._collections[row]; - collection.enabled = !collection.enabled; - this.treeBox.invalidateRow(row); - - // Display which ones will be removed - let freeup = 0; - let toremove = []; - for each (collection in this._collections) { - if (collection.enabled) - continue; - toremove.push(collection.name); - freeup += collection.size; - } - - let caption = document.getElementById("treeCaption"); - if (!toremove.length) { - caption.className = ""; - caption.firstChild.nodeValue = gSyncQuota.bundle.getString( - "quota.treeCaption.label"); - return; - } - - // Tycho: toremove = [this._byname[coll].title for each (coll in toremove)]; - let toremovetitles = []; - for (let coll in toremove) { - toremovetitles.push(this._byname[coll].title); - } - - toremovetitles = toremovetitles.join(gSyncQuota.bundle.getString("quota.list.separator")); - caption.firstChild.nodeValue = gSyncQuota.bundle.getFormattedString( - "quota.removal.label", [toremovetitles]); - if (freeup) - caption.firstChild.nodeValue += gSyncQuota.bundle.getFormattedString( - "quota.freeup.label", gSyncQuota.convertKB(freeup)); - caption.className = "captionWarning"; - }, - - /* - * Return a list of engines (or rather their pref names) that should be - * disabled. - */ - getEnginesToDisable: function getEnginesToDisable() { - // Tycho: return [coll.name for each (coll in this._collections) if (!coll.enabled)]; - let engines = []; - for each (let coll in this._collections) { - if (!coll.enabled) { - engines.push(coll.name); - } - } - return engines; - }, - - // nsITreeView - - get rowCount() { - return this._collections.length; - }, - - getRowProperties: function(index) { return ""; }, - getCellProperties: function(row, col) { return ""; }, - getColumnProperties: function(col) { return ""; }, - isContainer: function(index) { return false; }, - isContainerOpen: function(index) { return false; }, - isContainerEmpty: function(index) { return false; }, - isSeparator: function(index) { return false; }, - isSorted: function() { return false; }, - canDrop: function(index, orientation, dataTransfer) { return false; }, - drop: function(row, orientation, dataTransfer) {}, - getParentIndex: function(rowIndex) {}, - hasNextSibling: function(rowIndex, afterIndex) { return false; }, - getLevel: function(index) { return 0; }, - getImageSrc: function(row, col) {}, - - getCellValue: function(row, col) { - return this._collections[row].enabled; - }, - - getCellText: function getCellText(row, col) { - let collection = this._collections[row]; - switch (col.id) { - case "collection": - return collection.title; - case "size": - return collection.sizeLabel; - default: - return ""; - } - }, - - setTree: function setTree(tree) { - this.treeBox = tree; - }, - - toggleOpenState: function(index) {}, - cycleHeader: function(col) {}, - selectionChanged: function() {}, - cycleCell: function(row, col) {}, - isEditable: function(row, col) { return false; }, - isSelectable: function (row, col) { return false; }, - setCellValue: function(row, col, value) {}, - setCellText: function(row, col, value) {}, - performAction: function(action) {}, - performActionOnRow: function(action, row) {}, - performActionOnCell: function(action, row, col) {} - -}; diff --git a/application/palemoon/base/content/sync/quota.xul b/application/palemoon/base/content/sync/quota.xul deleted file mode 100644 index 99e6ed78b..000000000 --- a/application/palemoon/base/content/sync/quota.xul +++ /dev/null @@ -1,65 +0,0 @@ -<?xml version="1.0"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/syncQuota.css"?> - -<!DOCTYPE dialog [ -<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> -<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> -<!ENTITY % syncQuotaDTD SYSTEM "chrome://browser/locale/syncQuota.dtd"> -%brandDTD; -%syncBrandDTD; -%syncQuotaDTD; -]> -<dialog id="quotaDialog" - windowtype="Sync:ViewQuota" - persist="screenX screenY width height" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:html="http://www.w3.org/1999/xhtml" - onload="gSyncQuota.init()" - buttons="accept,cancel" - title=""a.dialogTitle.label;" - ondialogcancel="return gSyncQuota.onCancel();" - ondialogaccept="return gSyncQuota.onAccept();"> - - <script type="application/javascript" - src="chrome://browser/content/sync/quota.js"/> - - <stringbundleset id="stringbundleset"> - <stringbundle id="quotaStrings" - src="chrome://browser/locale/syncQuota.properties"/> - </stringbundleset> - - <vbox flex="1"> - <label id="usageLabel" - value=""a.retrievingInfo.label;"/> - <separator/> - <tree id="usageTree" - seltype="single" - hidecolumnpicker="true" - onclick="gUsageTreeView.onTreeClick(event);" - flex="1"> - <treecols> - <treecol id="enabled" - type="checkbox" - fixed="true"/> - <splitter class="tree-splitter"/> - <treecol id="collection" - label=""a.typeColumn.label;" - flex="1"/> - <splitter class="tree-splitter"/> - <treecol id="size" - label=""a.sizeColumn.label;" - flex="1"/> - </treecols> - <treechildren flex="1"/> - </tree> - <separator/> - <description id="treeCaption"> </description> - </vbox> - -</dialog> diff --git a/application/palemoon/base/content/sync/setup.js b/application/palemoon/base/content/sync/setup.js deleted file mode 100644 index e8d67a5f6..000000000 --- a/application/palemoon/base/content/sync/setup.js +++ /dev/null @@ -1,1071 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -var Ci = Components.interfaces; -var Cc = Components.classes; -var Cr = Components.results; -var Cu = Components.utils; - -// page consts - -const PAIR_PAGE = 0; -const INTRO_PAGE = 1; -const NEW_ACCOUNT_START_PAGE = 2; -const EXISTING_ACCOUNT_CONNECT_PAGE = 3; -const EXISTING_ACCOUNT_LOGIN_PAGE = 4; -const OPTIONS_PAGE = 5; -const OPTIONS_CONFIRM_PAGE = 6; - -// Broader than we'd like, but after this changed from api-secure.recaptcha.net -// we had no choice. At least we only do this for the duration of setup. -// See discussion in Bugs 508112 and 653307. -const RECAPTCHA_DOMAIN = "https://www.google.com"; - -const PIN_PART_LENGTH = 4; - -Cu.import("resource://services-sync/main.js"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/PlacesUtils.jsm"); -Cu.import("resource://gre/modules/PluralForm.jsm"); - - -function setVisibility(element, visible) { - element.style.visibility = visible ? "visible" : "hidden"; -} - -var gSyncSetup = { - QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports, - Ci.nsIWebProgressListener, - Ci.nsISupportsWeakReference]), - - captchaBrowser: null, - wizard: null, - _disabledSites: [], - - status: { - password: false, - email: false, - server: false - }, - - get _remoteSites() [Weave.Service.serverURL, RECAPTCHA_DOMAIN], - - get _usingMainServers() { - if (this._settingUpNew) - return document.getElementById("server").selectedIndex == 0; - return document.getElementById("existingServer").selectedIndex == 0; - }, - - init: function () { - let obs = [ - ["weave:service:change-passphrase", "onResetPassphrase"], - ["weave:service:login:start", "onLoginStart"], - ["weave:service:login:error", "onLoginEnd"], - ["weave:service:login:finish", "onLoginEnd"]]; - - // Add the observers now and remove them on unload - let self = this; - let addRem = function(add) { - obs.forEach(function([topic, func]) { - //XXXzpao This should use Services.obs.* but Weave's Obs does nice handling - // of `this`. Fix in a followup. (bug 583347) - if (add) - Weave.Svc.Obs.add(topic, self[func], self); - else - Weave.Svc.Obs.remove(topic, self[func], self); - }); - }; - addRem(true); - window.addEventListener("unload", function() addRem(false), false); - - window.setTimeout(function () { - // Force Service to be loaded so that engines are registered. - // See Bug 670082. - Weave.Service; - }, 0); - - this.captchaBrowser = document.getElementById("captcha"); - - this.wizardType = null; - if (window.arguments && window.arguments[0]) { - this.wizardType = window.arguments[0]; - } - switch (this.wizardType) { - case null: - this.wizard.pageIndex = INTRO_PAGE; - // Fall through! - case "pair": - this.captchaBrowser.addProgressListener(this); - Weave.Svc.Prefs.set("firstSync", "notReady"); - break; - case "reset": - this._resettingSync = true; - this.wizard.pageIndex = OPTIONS_PAGE; - break; - } - - this.wizard.getButton("extra1").label = - this._stringBundle.GetStringFromName("button.syncOptions.label"); - - // Remember these values because the options pages change them temporarily. - this._nextButtonLabel = this.wizard.getButton("next").label; - this._nextButtonAccesskey = this.wizard.getButton("next") - .getAttribute("accesskey"); - this._backButtonLabel = this.wizard.getButton("back").label; - this._backButtonAccesskey = this.wizard.getButton("back") - .getAttribute("accesskey"); - }, - - startNewAccountSetup: function () { - if (!Weave.Utils.ensureMPUnlocked()) - return false; - this._settingUpNew = true; - this.wizard.pageIndex = NEW_ACCOUNT_START_PAGE; - }, - - useExistingAccount: function () { - if (!Weave.Utils.ensureMPUnlocked()) - return false; - this._settingUpNew = false; - if (this.wizardType == "pair") { - // We're already pairing, so there's no point in pairing again. - // Go straight to the manual login page. - this.wizard.pageIndex = EXISTING_ACCOUNT_LOGIN_PAGE; - } else { - this.wizard.pageIndex = EXISTING_ACCOUNT_CONNECT_PAGE; - } - }, - - resetPassphrase: function resetPassphrase() { - // Apply the existing form fields so that - // Weave.Service.changePassphrase() has the necessary credentials. - Weave.Service.identity.account = document.getElementById("existingAccountName").value; - Weave.Service.identity.basicPassword = document.getElementById("existingPassword").value; - - // Generate a new passphrase so that Weave.Service.login() will - // actually do something. - let passphrase = Weave.Utils.generatePassphrase(); - Weave.Service.identity.syncKey = passphrase; - - // Only open the dialog if username + password are actually correct. - Weave.Service.login(); - if ([Weave.LOGIN_FAILED_INVALID_PASSPHRASE, - Weave.LOGIN_FAILED_NO_PASSPHRASE, - Weave.LOGIN_SUCCEEDED].indexOf(Weave.Status.login) == -1) { - return; - } - - // Hide any errors about the passphrase, we know it's not right. - let feedback = document.getElementById("existingPassphraseFeedbackRow"); - feedback.hidden = true; - let el = document.getElementById("existingPassphrase"); - el.value = Weave.Utils.hyphenatePassphrase(passphrase); - - // changePassphrase() will sync, make sure we set the "firstSync" pref - // according to the user's pref. - Weave.Svc.Prefs.reset("firstSync"); - this.setupInitialSync(); - gSyncUtils.resetPassphrase(true); - }, - - onResetPassphrase: function () { - document.getElementById("existingPassphrase").value = - Weave.Utils.hyphenatePassphrase(Weave.Service.identity.syncKey); - this.checkFields(); - this.wizard.advance(); - }, - - onLoginStart: function () { - this.toggleLoginFeedback(false); - }, - - onLoginEnd: function () { - this.toggleLoginFeedback(true); - }, - - sendCredentialsAfterSync: function () { - let send = function() { - Services.obs.removeObserver("weave:service:sync:finish", send); - Services.obs.removeObserver("weave:service:sync:error", send); - let credentials = {account: Weave.Service.identity.account, - password: Weave.Service.identity.basicPassword, - synckey: Weave.Service.identity.syncKey, - serverURL: Weave.Service.serverURL}; - this._jpakeclient.sendAndComplete(credentials); - }.bind(this); - Services.obs.addObserver("weave:service:sync:finish", send, false); - Services.obs.addObserver("weave:service:sync:error", send, false); - }, - - toggleLoginFeedback: function (stop) { - document.getElementById("login-throbber").hidden = stop; - let password = document.getElementById("existingPasswordFeedbackRow"); - let server = document.getElementById("existingServerFeedbackRow"); - let passphrase = document.getElementById("existingPassphraseFeedbackRow"); - - if (!stop || (Weave.Status.login == Weave.LOGIN_SUCCEEDED)) { - password.hidden = server.hidden = passphrase.hidden = true; - return; - } - - let feedback; - switch (Weave.Status.login) { - case Weave.LOGIN_FAILED_NETWORK_ERROR: - case Weave.LOGIN_FAILED_SERVER_ERROR: - feedback = server; - break; - case Weave.LOGIN_FAILED_LOGIN_REJECTED: - case Weave.LOGIN_FAILED_NO_USERNAME: - case Weave.LOGIN_FAILED_NO_PASSWORD: - feedback = password; - break; - case Weave.LOGIN_FAILED_INVALID_PASSPHRASE: - feedback = passphrase; - break; - } - this._setFeedbackMessage(feedback, false, Weave.Status.login); - }, - - setupInitialSync: function () { - let action = document.getElementById("mergeChoiceRadio").selectedItem.id; - switch (action) { - case "resetClient": - // if we're not resetting sync, we don't need to explicitly - // call resetClient - if (!this._resettingSync) - return; - // otherwise, fall through - case "wipeClient": - case "wipeRemote": - Weave.Svc.Prefs.set("firstSync", action); - break; - } - }, - - // fun with validation! - checkFields: function () { - this.wizard.canAdvance = this.readyToAdvance(); - }, - - readyToAdvance: function () { - switch (this.wizard.pageIndex) { - case INTRO_PAGE: - return false; - case NEW_ACCOUNT_START_PAGE: - for (let i in this.status) { - if (!this.status[i]) - return false; - } - if (this._usingMainServers) - return document.getElementById("tos").checked; - - return true; - case EXISTING_ACCOUNT_LOGIN_PAGE: - let hasUser = document.getElementById("existingAccountName").value != ""; - let hasPass = document.getElementById("existingPassword").value != ""; - let hasKey = document.getElementById("existingPassphrase").value != ""; - - if (hasUser && hasPass && hasKey) { - if (this._usingMainServers) - return true; - - if (this._validateServer(document.getElementById("existingServer"))) { - return true; - } - } - return false; - } - // Default, e.g. wizard's special page -1 etc. - return true; - }, - - onPINInput: function onPINInput(textbox) { - if (textbox && textbox.value.length == PIN_PART_LENGTH) { - this.nextFocusEl[textbox.id].focus(); - } - this.wizard.canAdvance = (this.pin1.value.length == PIN_PART_LENGTH && - this.pin2.value.length == PIN_PART_LENGTH && - this.pin3.value.length == PIN_PART_LENGTH); - }, - - onEmailInput: function () { - // Check account validity when the user stops typing for 1 second. - if (this._checkAccountTimer) - window.clearTimeout(this._checkAccountTimer); - this._checkAccountTimer = window.setTimeout(function () { - gSyncSetup.checkAccount(); - }, 1000); - }, - - checkAccount: function() { - delete this._checkAccountTimer; - let value = Weave.Utils.normalizeAccount( - document.getElementById("weaveEmail").value); - if (!value) { - this.status.email = false; - this.checkFields(); - return; - } - - let re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - let feedback = document.getElementById("emailFeedbackRow"); - let valid = re.test(value); - - let str = ""; - if (!valid) { - str = "invalidEmail.label"; - } else { - let availCheck = Weave.Service.checkAccount(value); - valid = availCheck == "available"; - if (!valid) { - if (availCheck == "notAvailable") - str = "usernameNotAvailable.label"; - else - str = availCheck; - } - } - - this._setFeedbackMessage(feedback, valid, str); - this.status.email = valid; - if (valid) - Weave.Service.identity.account = value; - this.checkFields(); - }, - - onPasswordChange: function () { - let password = document.getElementById("weavePassword"); - let pwconfirm = document.getElementById("weavePasswordConfirm"); - let [valid, errorString] = gSyncUtils.validatePassword(password, pwconfirm); - - let feedback = document.getElementById("passwordFeedbackRow"); - this._setFeedback(feedback, valid, errorString); - - this.status.password = valid; - this.checkFields(); - }, - - onPageShow: function() { - switch (this.wizard.pageIndex) { - case PAIR_PAGE: - this.wizard.getButton("back").hidden = true; - this.wizard.getButton("extra1").hidden = true; - this.onPINInput(); - this.pin1.focus(); - break; - case INTRO_PAGE: - // We may not need the captcha in the Existing Account branch of the - // wizard. However, we want to preload it to avoid any flickering while - // the Create Account page is shown. - this.loadCaptcha(); - this.wizard.getButton("next").hidden = true; - this.wizard.getButton("back").hidden = true; - this.wizard.getButton("extra1").hidden = true; - this.checkFields(); - break; - case NEW_ACCOUNT_START_PAGE: - this.wizard.getButton("extra1").hidden = false; - this.wizard.getButton("next").hidden = false; - this.wizard.getButton("back").hidden = false; - this.onServerCommand(); - this.wizard.canRewind = true; - this.checkFields(); - break; - case EXISTING_ACCOUNT_CONNECT_PAGE: - Weave.Svc.Prefs.set("firstSync", "existingAccount"); - this.wizard.getButton("next").hidden = false; - this.wizard.getButton("back").hidden = false; - this.wizard.getButton("extra1").hidden = false; - this.wizard.canAdvance = false; - this.wizard.canRewind = true; - this.startEasySetup(); - break; - case EXISTING_ACCOUNT_LOGIN_PAGE: - this.wizard.getButton("next").hidden = false; - this.wizard.getButton("back").hidden = false; - this.wizard.getButton("extra1").hidden = false; - this.wizard.canRewind = true; - this.checkFields(); - break; - case OPTIONS_PAGE: - this.wizard.canRewind = false; - this.wizard.canAdvance = true; - if (!this._resettingSync) { - this.wizard.getButton("next").label = - this._stringBundle.GetStringFromName("button.syncOptionsDone.label"); - this.wizard.getButton("next").removeAttribute("accesskey"); - } - this.wizard.getButton("next").hidden = false; - this.wizard.getButton("back").hidden = true; - this.wizard.getButton("cancel").hidden = !this._resettingSync; - this.wizard.getButton("extra1").hidden = true; - document.getElementById("syncComputerName").value = Weave.Service.clientsEngine.localName; - document.getElementById("syncOptions").collapsed = this._resettingSync; - document.getElementById("mergeOptions").collapsed = this._settingUpNew; - break; - case OPTIONS_CONFIRM_PAGE: - this.wizard.canRewind = true; - this.wizard.canAdvance = true; - this.wizard.getButton("back").label = - this._stringBundle.GetStringFromName("button.syncOptionsCancel.label"); - this.wizard.getButton("back").removeAttribute("accesskey"); - this.wizard.getButton("back").hidden = this._resettingSync; - this.wizard.getButton("next").hidden = false; - this.wizard.getButton("finish").hidden = true; - break; - } - }, - - onWizardAdvance: function () { - // Check pageIndex so we don't prompt before the Sync setup wizard appears. - // This is a fallback in case the Master Password gets locked mid-wizard. - if ((this.wizard.pageIndex >= 0) && - !Weave.Utils.ensureMPUnlocked()) { - return false; - } - - switch (this.wizard.pageIndex) { - case PAIR_PAGE: - this.startPairing(); - return false; - case NEW_ACCOUNT_START_PAGE: - // If the user selects Next (e.g. by hitting enter) when we haven't - // executed the delayed checks yet, execute them immediately. - if (this._checkAccountTimer) { - this.checkAccount(); - } - if (this._checkServerTimer) { - this.checkServer(); - } - if (!this.wizard.canAdvance) { - return false; - } - - let doc = this.captchaBrowser.contentDocument; - let getField = function getField(field) { - let node = doc.getElementById("recaptcha_" + field + "_field"); - return node && node.value; - }; - - // Display throbber - let feedback = document.getElementById("captchaFeedback"); - let image = feedback.firstChild; - let label = image.nextSibling; - image.setAttribute("status", "active"); - label.value = this._stringBundle.GetStringFromName("verifying.label"); - setVisibility(feedback, true); - - let password = document.getElementById("weavePassword").value; - let email = Weave.Utils.normalizeAccount( - document.getElementById("weaveEmail").value); - let challenge = getField("challenge"); - let response = getField("response"); - - let error = Weave.Service.createAccount(email, password, - challenge, response); - - if (error == null) { - Weave.Service.identity.account = email; - Weave.Service.identity.basicPassword = password; - Weave.Service.identity.syncKey = Weave.Utils.generatePassphrase(); - this._handleNoScript(false); - Weave.Svc.Prefs.set("firstSync", "newAccount"); - this.wizardFinish(); - return false; - } - - image.setAttribute("status", "error"); - label.value = Weave.Utils.getErrorString(error); - return false; - case EXISTING_ACCOUNT_LOGIN_PAGE: - Weave.Service.identity.account = Weave.Utils.normalizeAccount( - document.getElementById("existingAccountName").value); - Weave.Service.identity.basicPassword = - document.getElementById("existingPassword").value; - let pp = document.getElementById("existingPassphrase").value; - Weave.Service.identity.syncKey = Weave.Utils.normalizePassphrase(pp); - if (Weave.Service.login()) { - this.wizardFinish(); - } - return false; - case OPTIONS_PAGE: - let desc = document.getElementById("mergeChoiceRadio").selectedIndex; - // No confirmation needed on new account setup or merge option - // with existing account. - if (this._settingUpNew || (!this._resettingSync && desc == 0)) - return this.returnFromOptions(); - return this._handleChoice(); - case OPTIONS_CONFIRM_PAGE: - if (this._resettingSync) { - this.wizardFinish(); - return false; - } - return this.returnFromOptions(); - } - return true; - }, - - onWizardBack: function () { - switch (this.wizard.pageIndex) { - case NEW_ACCOUNT_START_PAGE: - case EXISTING_ACCOUNT_LOGIN_PAGE: - this.wizard.pageIndex = INTRO_PAGE; - return false; - case EXISTING_ACCOUNT_CONNECT_PAGE: - this.abortEasySetup(); - this.wizard.pageIndex = INTRO_PAGE; - return false; - case EXISTING_ACCOUNT_LOGIN_PAGE: - // If we were already pairing on entry, we went straight to the manual - // login page. If subsequently we go back, return to the page that lets - // us choose whether we already have an account. - if (this.wizardType == "pair") { - this.wizard.pageIndex = INTRO_PAGE; - return false; - } - return true; - case OPTIONS_CONFIRM_PAGE: - // Backing up from the confirmation page = resetting first sync to merge. - document.getElementById("mergeChoiceRadio").selectedIndex = 0; - return this.returnFromOptions(); - } - return true; - }, - - wizardFinish: function () { - this.setupInitialSync(); - - if (this.wizardType == "pair") { - this.completePairing(); - } - - if (!this._resettingSync) { - function isChecked(element) { - return document.getElementById(element).hasAttribute("checked"); - } - - let prefs = ["engine.bookmarks", "engine.passwords", "engine.history", - "engine.tabs", "engine.prefs", "engine.addons"]; - for (let i = 0;i < prefs.length;i++) { - Weave.Svc.Prefs.set(prefs[i], isChecked(prefs[i])); - } - - // XXX: Addons syncing is currently not operational; - // Make doubly-sure to always disable addons syncing pref - Weave.Svc.Prefs.set("engine.addons", false); - - this._handleNoScript(false); - if (Weave.Svc.Prefs.get("firstSync", "") == "notReady") - Weave.Svc.Prefs.reset("firstSync"); - - Weave.Service.persistLogin(); - Weave.Svc.Obs.notify("weave:service:setup-complete"); - - gSyncUtils.openFirstSyncProgressPage(); - } - Weave.Utils.nextTick(Weave.Service.sync, Weave.Service); - window.close(); - }, - - onWizardCancel: function () { - if (this._resettingSync) - return; - - this.abortEasySetup(); - this._handleNoScript(false); - Weave.Service.startOver(); - }, - - onSyncOptions: function () { - this._beforeOptionsPage = this.wizard.pageIndex; - this.wizard.pageIndex = OPTIONS_PAGE; - }, - - returnFromOptions: function() { - this.wizard.getButton("next").label = this._nextButtonLabel; - this.wizard.getButton("next").setAttribute("accesskey", - this._nextButtonAccesskey); - this.wizard.getButton("back").label = this._backButtonLabel; - this.wizard.getButton("back").setAttribute("accesskey", - this._backButtonAccesskey); - this.wizard.getButton("cancel").hidden = false; - this.wizard.getButton("extra1").hidden = false; - this.wizard.pageIndex = this._beforeOptionsPage; - return false; - }, - - startPairing: function startPairing() { - this.pairDeviceErrorRow.hidden = true; - // When onAbort is called, Weave may already be gone. - const JPAKE_ERROR_USERABORT = Weave.JPAKE_ERROR_USERABORT; - - let self = this; - let jpakeclient = this._jpakeclient = new Weave.JPAKEClient({ - onPaired: function onPaired() { - self.wizard.pageIndex = INTRO_PAGE; - }, - onComplete: function onComplete() { - // This method will never be called since SendCredentialsController - // will take over after the wizard completes. - }, - onAbort: function onAbort(error) { - delete self._jpakeclient; - - // Aborted by user, ignore. The window is almost certainly going to close - // or is already closed. - if (error == JPAKE_ERROR_USERABORT) { - return; - } - - self.pairDeviceErrorRow.hidden = false; - self.pairDeviceThrobber.hidden = true; - self.pin1.value = self.pin2.value = self.pin3.value = ""; - self.pin1.disabled = self.pin2.disabled = self.pin3.disabled = false; - if (self.wizard.pageIndex == PAIR_PAGE) { - self.pin1.focus(); - } - } - }); - this.pairDeviceThrobber.hidden = false; - this.pin1.disabled = this.pin2.disabled = this.pin3.disabled = true; - this.wizard.canAdvance = false; - - let pin = this.pin1.value + this.pin2.value + this.pin3.value; - let expectDelay = true; - jpakeclient.pairWithPIN(pin, expectDelay); - }, - - completePairing: function completePairing() { - if (!this._jpakeclient) { - // The channel was aborted while we were setting up the account - // locally. XXX TODO should we do anything here, e.g. tell - // the user on the last wizard page that it's ok, they just - // have to pair again? - return; - } - let controller = new Weave.SendCredentialsController(this._jpakeclient, - Weave.Service); - this._jpakeclient.controller = controller; - }, - - startEasySetup: function () { - // Don't do anything if we have a client already (e.g. we went to - // Sync Options and just came back). - if (this._jpakeclient) - return; - - // When onAbort is called, Weave may already be gone - const JPAKE_ERROR_USERABORT = Weave.JPAKE_ERROR_USERABORT; - - let self = this; - this._jpakeclient = new Weave.JPAKEClient({ - displayPIN: function displayPIN(pin) { - document.getElementById("easySetupPIN1").value = pin.slice(0, 4); - document.getElementById("easySetupPIN2").value = pin.slice(4, 8); - document.getElementById("easySetupPIN3").value = pin.slice(8); - }, - - onPairingStart: function onPairingStart() {}, - - onComplete: function onComplete(credentials) { - Weave.Service.identity.account = credentials.account; - Weave.Service.identity.basicPassword = credentials.password; - Weave.Service.identity.syncKey = credentials.synckey; - Weave.Service.serverURL = credentials.serverURL; - gSyncSetup.wizardFinish(); - }, - - onAbort: function onAbort(error) { - delete self._jpakeclient; - - // Ignore if wizard is aborted. - if (error == JPAKE_ERROR_USERABORT) - return; - - // Automatically go to manual setup if we couldn't acquire a channel. - if (error == Weave.JPAKE_ERROR_CHANNEL) { - self.wizard.pageIndex = EXISTING_ACCOUNT_LOGIN_PAGE; - return; - } - - // Restart on all other errors. - self.startEasySetup(); - } - }); - this._jpakeclient.receiveNoPIN(); - }, - - abortEasySetup: function () { - document.getElementById("easySetupPIN1").value = ""; - document.getElementById("easySetupPIN2").value = ""; - document.getElementById("easySetupPIN3").value = ""; - if (!this._jpakeclient) - return; - - this._jpakeclient.abort(); - delete this._jpakeclient; - }, - - manualSetup: function () { - this.abortEasySetup(); - this.wizard.pageIndex = EXISTING_ACCOUNT_LOGIN_PAGE; - }, - - // _handleNoScript is needed because it blocks the captcha. So we temporarily - // allow the necessary sites so that we can verify the user is in fact a human. - // This was done with the help of Giorgio (NoScript author). See bug 508112. - _handleNoScript: function (addExceptions) { - // if NoScript isn't installed, or is disabled, bail out. - let ns = Cc["@maone.net/noscript-service;1"]; - if (ns == null) - return; - - ns = ns.getService().wrappedJSObject; - if (addExceptions) { - this._remoteSites.forEach(function(site) { - site = ns.getSite(site); - if (!ns.isJSEnabled(site)) { - this._disabledSites.push(site); // save status - ns.setJSEnabled(site, true); // allow site - } - }, this); - } - else { - this._disabledSites.forEach(function(site) { - ns.setJSEnabled(site, false); - }); - this._disabledSites = []; - } - }, - - onExistingServerCommand: function () { - let control = document.getElementById("existingServer"); - if (control.selectedIndex == 0) { - control.removeAttribute("editable"); - Weave.Svc.Prefs.reset("serverURL"); - } else { - control.setAttribute("editable", "true"); - // Force a style flush to ensure that the binding is attached. - control.clientTop; - control.value = ""; - control.inputField.focus(); - } - document.getElementById("existingServerFeedbackRow").hidden = true; - this.checkFields(); - }, - - onExistingServerInput: function () { - // Check custom server validity when the user stops typing for 1 second. - if (this._existingServerTimer) - window.clearTimeout(this._existingServerTimer); - this._existingServerTimer = window.setTimeout(function () { - gSyncSetup.checkFields(); - }, 1000); - }, - - onServerCommand: function () { - setVisibility(document.getElementById("TOSRow"), this._usingMainServers); - let control = document.getElementById("server"); - if (!this._usingMainServers) { - control.setAttribute("editable", "true"); - // Force a style flush to ensure that the binding is attached. - control.clientTop; - control.value = ""; - control.inputField.focus(); - // checkServer() will call checkAccount() and checkFields(). - this.checkServer(); - return; - } - control.removeAttribute("editable"); - Weave.Svc.Prefs.reset("serverURL"); - if (this._settingUpNew) { - this.loadCaptcha(); - } - this.checkAccount(); - this.status.server = true; - document.getElementById("serverFeedbackRow").hidden = true; - this.checkFields(); - }, - - onServerInput: function () { - // Check custom server validity when the user stops typing for 1 second. - if (this._checkServerTimer) - window.clearTimeout(this._checkServerTimer); - this._checkServerTimer = window.setTimeout(function () { - gSyncSetup.checkServer(); - }, 1000); - }, - - checkServer: function () { - delete this._checkServerTimer; - let el = document.getElementById("server"); - let valid = false; - let feedback = document.getElementById("serverFeedbackRow"); - let str = ""; - if (el.value) { - valid = this._validateServer(el); - let str = valid ? "" : "serverInvalid.label"; - this._setFeedbackMessage(feedback, valid, str); - } - else - this._setFeedbackMessage(feedback, true); - - // Recheck account against the new server. - if (valid) - this.checkAccount(); - - this.status.server = valid; - this.checkFields(); - }, - - _validateServer: function (element) { - let valid = false; - let val = element.value; - if (!val) - return false; - - let uri = Weave.Utils.makeURI(val); - - if (!uri) - uri = Weave.Utils.makeURI("https://" + val); - - if (uri && this._settingUpNew) { - function isValid(uri) { - Weave.Service.serverURL = uri.spec; - let check = Weave.Service.checkAccount("a"); - return (check == "available" || check == "notAvailable"); - } - - if (uri.schemeIs("http")) { - uri.scheme = "https"; - if (isValid(uri)) - valid = true; - else - // setting the scheme back to http - uri.scheme = "http"; - } - if (!valid) - valid = isValid(uri); - - if (valid) { - this.loadCaptcha(); - } - } - else if (uri) { - valid = true; - Weave.Service.serverURL = uri.spec; - } - - if (valid) - element.value = Weave.Service.serverURL; - else - Weave.Svc.Prefs.reset("serverURL"); - - return valid; - }, - - _handleChoice: function () { - let desc = document.getElementById("mergeChoiceRadio").selectedIndex; - document.getElementById("chosenActionDeck").selectedIndex = desc; - switch (desc) { - case 1: - if (this._case1Setup) - break; - - let places_db = PlacesUtils.history - .QueryInterface(Ci.nsPIPlacesDatabase) - .DBConnection; - if (Weave.Service.engineManager.get("history").enabled) { - let daysOfHistory = 0; - let stm = places_db.createStatement( - "SELECT ROUND(( " + - "strftime('%s','now','localtime','utc') - " + - "( " + - "SELECT visit_date FROM moz_historyvisits " + - "ORDER BY visit_date ASC LIMIT 1 " + - ")/1000000 " + - ")/86400) AS daysOfHistory "); - - if (stm.step()) - daysOfHistory = stm.getInt32(0); - // Support %S for historical reasons (see bug 600141) - document.getElementById("historyCount").value = - PluralForm.get(daysOfHistory, - this._stringBundle.GetStringFromName("historyDaysCount.label")) - .replace("%S", daysOfHistory) - .replace("#1", daysOfHistory); - } else { - document.getElementById("historyCount").hidden = true; - } - - if (Weave.Service.engineManager.get("bookmarks").enabled) { - let bookmarks = 0; - let stm = places_db.createStatement( - "SELECT count(*) AS bookmarks " + - "FROM moz_bookmarks b " + - "LEFT JOIN moz_bookmarks t ON " + - "b.parent = t.id WHERE b.type = 1 AND t.parent <> :tag"); - stm.params.tag = PlacesUtils.tagsFolderId; - if (stm.executeStep()) - bookmarks = stm.row.bookmarks; - // Support %S for historical reasons (see bug 600141) - document.getElementById("bookmarkCount").value = - PluralForm.get(bookmarks, - this._stringBundle.GetStringFromName("bookmarksCount.label")) - .replace("%S", bookmarks) - .replace("#1", bookmarks); - } else { - document.getElementById("bookmarkCount").hidden = true; - } - - if (Weave.Service.engineManager.get("passwords").enabled) { - let logins = Services.logins.getAllLogins({}); - // Support %S for historical reasons (see bug 600141) - document.getElementById("passwordCount").value = - PluralForm.get(logins.length, - this._stringBundle.GetStringFromName("passwordsCount.label")) - .replace("%S", logins.length) - .replace("#1", logins.length); - } else { - document.getElementById("passwordCount").hidden = true; - } - - if (!Weave.Service.engineManager.get("prefs").enabled) { - document.getElementById("prefsWipe").hidden = true; - } - - let addonsEngine = Weave.Service.engineManager.get("addons"); - if (addonsEngine.enabled) { - let ids = addonsEngine._store.getAllIDs(); - let blessedcount = 0; - for each (let i in ids) { - if (i) { - blessedcount++; - } - } - // bug 600141 does not apply, as this does not have to support existing strings - document.getElementById("addonCount").value = - PluralForm.get(blessedcount, - this._stringBundle.GetStringFromName("addonsCount.label")) - .replace("#1", blessedcount); - } else { - document.getElementById("addonCount").hidden = true; - } - - this._case1Setup = true; - break; - case 2: - if (this._case2Setup) - break; - let count = 0; - function appendNode(label) { - let box = document.getElementById("clientList"); - let node = document.createElement("label"); - node.setAttribute("value", label); - node.setAttribute("class", "data indent"); - box.appendChild(node); - } - - for each (let name in Weave.Service.clientsEngine.stats.names) { - // Don't list the current client - if (name == Weave.Service.clientsEngine.localName) - continue; - - // Only show the first several client names - if (++count <= 5) - appendNode(name); - } - if (count > 5) { - // Support %S for historical reasons (see bug 600141) - let label = - PluralForm.get(count - 5, - this._stringBundle.GetStringFromName("additionalClientCount.label")) - .replace("%S", count - 5) - .replace("#1", count - 5); - appendNode(label); - } - this._case2Setup = true; - break; - } - - return true; - }, - - // sets class and string on a feedback element - // if no property string is passed in, we clear label/style - _setFeedback: function (element, success, string) { - element.hidden = success || !string; - let classname = success ? "success" : "error"; - let image = element.getElementsByAttribute("class", "statusIcon")[0]; - image.setAttribute("status", classname); - let label = element.getElementsByAttribute("class", "status")[0]; - label.value = string; - }, - - // shim - _setFeedbackMessage: function (element, success, string) { - let str = ""; - if (string) { - try { - str = this._stringBundle.GetStringFromName(string); - } catch(e) {} - - if (!str) - str = Weave.Utils.getErrorString(string); - } - this._setFeedback(element, success, str); - }, - - loadCaptcha: function loadCaptcha() { - let captchaURI = Weave.Service.miscAPI + "captcha_html"; - // First check for NoScript and whitelist the right sites. - this._handleNoScript(true); - if (this.captchaBrowser.currentURI.spec != captchaURI) { - this.captchaBrowser.loadURI(captchaURI); - } - }, - - onStateChange: function(webProgress, request, stateFlags, status) { - // We're only looking for the end of the frame load - if ((stateFlags & Ci.nsIWebProgressListener.STATE_STOP) == 0) - return; - if ((stateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) == 0) - return; - if ((stateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW) == 0) - return; - - // If we didn't find a captcha, assume it's not needed and don't show it. - let responseStatus = request.QueryInterface(Ci.nsIHttpChannel).responseStatus; - setVisibility(this.captchaBrowser, responseStatus != 404); - //XXX TODO we should really log any responseStatus other than 200 - }, - onProgressChange: function() {}, - onStatusChange: function() {}, - onSecurityChange: function() {}, - onLocationChange: function () {} -}; - -// Define lazy getters for various XUL elements. -// -// onWizardAdvance() and onPageShow() are run before init(), so we'll even -// define things that will almost certainly be used (like 'wizard') as a lazy -// getter here. -["wizard", - "pin1", - "pin2", - "pin3", - "pairDeviceErrorRow", - "pairDeviceThrobber"].forEach(function (id) { - XPCOMUtils.defineLazyGetter(gSyncSetup, id, function() { - return document.getElementById(id); - }); -}); -XPCOMUtils.defineLazyGetter(gSyncSetup, "nextFocusEl", function () { - return {pin1: this.pin2, - pin2: this.pin3, - pin3: this.wizard.getButton("next")}; -}); -XPCOMUtils.defineLazyGetter(gSyncSetup, "_stringBundle", function() { - return Services.strings.createBundle("chrome://browser/locale/syncSetup.properties"); -}); diff --git a/application/palemoon/base/content/sync/setup.xul b/application/palemoon/base/content/sync/setup.xul deleted file mode 100644 index cf2cc77e4..000000000 --- a/application/palemoon/base/content/sync/setup.xul +++ /dev/null @@ -1,491 +0,0 @@ -<?xml version="1.0"?> - -<!-- This Source Code Form is subject to the terms of the Mozilla Public - - License, v. 2.0. If a copy of the MPL was not distributed with this - - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/syncSetup.css" type="text/css"?> -<?xml-stylesheet href="chrome://browser/skin/syncCommon.css" type="text/css"?> - -<!DOCTYPE window [ -<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd"> -<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd"> -<!ENTITY % syncSetupDTD SYSTEM "chrome://browser/locale/syncSetup.dtd"> -%brandDTD; -%syncBrandDTD; -%syncSetupDTD; -]> -<wizard id="wizard" - title="&accountSetupTitle.label;" - windowtype="Weave:AccountSetup" - persist="screenX screenY" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - xmlns:html="http://www.w3.org/1999/xhtml" - onwizardnext="return gSyncSetup.onWizardAdvance()" - onwizardback="return gSyncSetup.onWizardBack()" - onwizardcancel="gSyncSetup.onWizardCancel()" - onload="gSyncSetup.init()"> - - <script type="application/javascript" - src="chrome://browser/content/sync/setup.js"/> - <script type="application/javascript" - src="chrome://browser/content/sync/utils.js"/> - <script type="application/javascript" - src="chrome://browser/content/utilityOverlay.js"/> - <script type="application/javascript" - src="chrome://global/content/printUtils.js"/> - - <wizardpage id="addDevicePage" - label="&pairDevice.title.label;" - onpageshow="gSyncSetup.onPageShow()"> - <description> - &pairDevice.dialog.description.label; - <label class="text-link" - value="&addDevice.showMeHow.label;" - href="http://www.palemoon.org/sync/help/easy-setup.shtml"/> - </description> - <separator class="groove-thin"/> - <description> - &addDevice.dialog.enterCode.label; - </description> - <separator class="groove-thin"/> - <vbox align="center"> - <textbox id="pin1" - class="pin" - oninput="gSyncSetup.onPINInput(this);" - onfocus="this.select();" - /> - <textbox id="pin2" - class="pin" - oninput="gSyncSetup.onPINInput(this);" - onfocus="this.select();" - /> - <textbox id="pin3" - class="pin" - oninput="gSyncSetup.onPINInput(this);" - onfocus="this.select();" - /> - </vbox> - <separator class="groove-thin"/> - <vbox id="pairDeviceThrobber" align="center" hidden="true"> - <image/> - </vbox> - <hbox id="pairDeviceErrorRow" pack="center" hidden="true"> - <image class="statusIcon" status="error"/> - <label class="status" - value="&addDevice.dialog.tryAgain.label;"/> - </hbox> - </wizardpage> - - <wizardpage id="pickSetupType" - label="&syncBrand.fullName.label;" - onpageshow="gSyncSetup.onPageShow()"> - <vbox align="center" flex="1"> - <description style="padding: 0 7em;"> - &setup.pickSetupType.description2; - </description> - <spacer flex="3"/> - <button id="newAccount" - class="accountChoiceButton" - label="&button.createNewAccount.label;" - oncommand="gSyncSetup.startNewAccountSetup()" - align="center"/> - <spacer flex="1"/> - </vbox> - <separator class="groove"/> - <vbox align="center" flex="1"> - <spacer flex="1"/> - <button id="existingAccount" - class="accountChoiceButton" - label="&button.haveAccount.label;" - oncommand="gSyncSetup.useExistingAccount()"/> - <spacer flex="3"/> - </vbox> - </wizardpage> - - <wizardpage label="&setup.newAccountDetailsPage.title.label;" - id="newAccountStart" - onextra1="gSyncSetup.onSyncOptions()" - onpageshow="gSyncSetup.onPageShow();"> - <grid> - <columns> - <column/> - <column class="inputColumn" flex="1"/> - </columns> - <rows> - <row id="emailRow" align="center"> - <label value="&setup.emailAddress.label;" - accesskey="&setup.emailAddress.accesskey;" - control="weaveEmail"/> - <textbox id="weaveEmail" - oninput="gSyncSetup.onEmailInput()"/> - </row> - <row id="emailFeedbackRow" align="center" hidden="true"> - <spacer/> - <hbox> - <image class="statusIcon"/> - <label class="status" value=" "/> - </hbox> - </row> - <row id="passwordRow" align="center"> - <label value="&setup.choosePassword.label;" - accesskey="&setup.choosePassword.accesskey;" - control="weavePassword"/> - <textbox id="weavePassword" - type="password" - onchange="gSyncSetup.onPasswordChange()"/> - </row> - <row id="confirmRow" align="center"> - <label value="&setup.confirmPassword.label;" - accesskey="&setup.confirmPassword.accesskey;" - control="weavePasswordConfirm"/> - <textbox id="weavePasswordConfirm" - type="password" - onchange="gSyncSetup.onPasswordChange()"/> - </row> - <row id="passwordFeedbackRow" align="center" hidden="true"> - <spacer/> - <hbox> - <image class="statusIcon"/> - <label class="status" value=" "/> - </hbox> - </row> - <row align="center"> - <label control="server" - value="&server.label;"/> - <menulist id="server" - oncommand="gSyncSetup.onServerCommand()" - oninput="gSyncSetup.onServerInput()"> - <menupopup> - <menuitem label="&serverType.default.label;" - value="main"/> - <menuitem label="&serverType.custom2.label;" - value="custom"/> - </menupopup> - </menulist> - </row> - <row id="serverFeedbackRow" align="center" hidden="true"> - <spacer/> - <hbox> - <image class="statusIcon"/> - <label class="status" value=" "/> - </hbox> - </row> - <row id="TOSRow" align="center"> - <spacer/> - <hbox align="center"> - <checkbox id="tos" - accesskey="&setup.tosAgree1.accesskey;" - oncommand="this.focus(); gSyncSetup.checkFields();"/> - <description id="tosDesc" - flex="1" - onclick="document.getElementById('tos').focus(); - document.getElementById('tos').click()"> - &setup.tosAgree1.label; - <label class="text-link inline-link" - onclick="event.stopPropagation();gSyncUtils.openToS();"> - &setup.tosLink.label; - </label> - &setup.tosAgree2.label; - <label class="text-link inline-link" - onclick="event.stopPropagation();gSyncUtils.openPrivacyPolicy();"> - &setup.ppLink.label; - </label> - &setup.tosAgree3.label; - </description> - </hbox> - </row> - </rows> - </grid> - <spacer flex="1"/> - <vbox flex="1" align="center"> - <browser height="150" - width="500" - id="captcha" - type="content" - disablehistory="true"/> - <spacer flex="1"/> - <hbox id="captchaFeedback"> - <image class="statusIcon"/> - <label class="status" value=" "/> - </hbox> - </vbox> - </wizardpage> - - <wizardpage id="addDevice" - label="&pairDevice.title.label;" - onextra1="gSyncSetup.onSyncOptions()" - onpageshow="gSyncSetup.onPageShow()"> - <description> - &pairDevice.setup.description.label; - <label class="text-link" - value="&addDevice.showMeHow.label;" - href="http://www.palemoon.org/sync/help/easy-setup.shtml"/> - </description> - <label value="&addDevice.setup.enterCode.label;" - control="easySetupPIN1"/> - <spacer flex="1"/> - <vbox align="center" flex="1"> - <textbox id="easySetupPIN1" - class="pin" - value="" - readonly="true" - /> - <textbox id="easySetupPIN2" - class="pin" - value="" - readonly="true" - /> - <textbox id="easySetupPIN3" - class="pin" - value="" - readonly="true" - /> - </vbox> - <spacer flex="3"/> - <label class="text-link" - value="&addDevice.dontHaveDevice.label;" - onclick="gSyncSetup.manualSetup();"/> - </wizardpage> - - <wizardpage id="existingAccount" - label="&setup.signInPage.title.label;" - onextra1="gSyncSetup.onSyncOptions()" - onpageshow="gSyncSetup.onPageShow()"> - <grid> - <columns> - <column/> - <column class="inputColumn" flex="1"/> - </columns> - <rows> - <row id="existingAccountRow" align="center"> - <label id="existingAccountLabel" - value="&signIn.account2.label;" - accesskey="&signIn.account2.accesskey;" - control="existingAccount"/> - <textbox id="existingAccountName" - oninput="gSyncSetup.checkFields(event)" - onchange="gSyncSetup.checkFields(event)"/> - </row> - <row id="existingPasswordRow" align="center"> - <label id="existingPasswordLabel" - value="&signIn.password.label;" - accesskey="&signIn.password.accesskey;" - control="existingPassword"/> - <textbox id="existingPassword" - type="password" - onkeyup="gSyncSetup.checkFields(event)" - onchange="gSyncSetup.checkFields(event)"/> - </row> - <row id="existingPasswordFeedbackRow" align="center" hidden="true"> - <spacer/> - <hbox> - <image class="statusIcon"/> - <label class="status" value=" "/> - </hbox> - </row> - <row align="center"> - <spacer/> - <label class="text-link" - value="&resetPassword.label;" - onclick="gSyncUtils.resetPassword(); return false;"/> - </row> - <row align="center"> - <label control="existingServer" - value="&server.label;"/> - <menulist id="existingServer" - oncommand="gSyncSetup.onExistingServerCommand()" - oninput="gSyncSetup.onExistingServerInput()"> - <menupopup> - <menuitem label="&serverType.default.label;" - value="main"/> - <menuitem label="&serverType.custom2.label;" - value="custom"/> - </menupopup> - </menulist> - </row> - <row id="existingServerFeedbackRow" align="center" hidden="true"> - <spacer/> - <hbox> - <image class="statusIcon"/> - <vbox> - <label class="status" value=" "/> - </vbox> - </hbox> - </row> - </rows> - </grid> - - <groupbox> - <label id="existingPassphraseLabel" - value="&signIn.recoveryKey.label;" - accesskey="&signIn.recoveryKey.accesskey;" - control="existingPassphrase"/> - <textbox id="existingPassphrase" - oninput="gSyncSetup.checkFields()"/> - <hbox id="login-throbber" hidden="true"> - <image/> - <label value="&verifying.label;"/> - </hbox> - <vbox align="left" id="existingPassphraseFeedbackRow" hidden="true"> - <hbox> - <image class="statusIcon"/> - <label class="status" value=" "/> - </hbox> - </vbox> - </groupbox> - - <vbox id="passphraseHelpBox"> - <description> - &existingRecoveryKey.description; - <label class="text-link" - href="http://www.palemoon.org/sync/help/recoverykey.shtml"> - &addDevice.showMeHow.label; - </label> - <spacer id="passphraseHelpSpacer"/> - <label class="text-link" - onclick="gSyncSetup.resetPassphrase(); return false;"> - &resetSyncKey.label; - </label> - </description> - </vbox> - </wizardpage> - - <wizardpage id="syncOptionsPage" - label="&setup.optionsPage.title;" - onpageshow="gSyncSetup.onPageShow()"> - <groupbox id="syncOptions"> - <grid> - <columns> - <column/> - <column flex="1" style="-moz-margin-end: 2px"/> - </columns> - <rows> - <row align="center"> - <label value="&syncDeviceName.label;" - accesskey="&syncDeviceName.accesskey;" - control="syncComputerName"/> - <textbox id="syncComputerName" flex="1" - onchange="gSyncUtils.changeName(this)"/> - </row> - <row> - <label value="&syncMy.label;" /> - <vbox> - <checkbox label="&engine.addons.label;" - accesskey="&engine.addons.accesskey;" - id="engine.addons" - checked="false" - hidden="true"/> - <checkbox label="&engine.bookmarks.label;" - accesskey="&engine.bookmarks.accesskey;" - id="engine.bookmarks" - checked="true"/> - <checkbox label="&engine.passwords.label;" - accesskey="&engine.passwords.accesskey;" - id="engine.passwords" - checked="true"/> - <checkbox label="&engine.prefs.label;" - accesskey="&engine.prefs.accesskey;" - id="engine.prefs" - checked="true"/> - <checkbox label="&engine.history.label;" - accesskey="&engine.history.accesskey;" - id="engine.history" - checked="true"/> - <checkbox label="&engine.tabs.label;" - accesskey="&engine.tabs.accesskey;" - id="engine.tabs" - checked="true"/> - </vbox> - </row> - </rows> - </grid> - </groupbox> - - <groupbox id="mergeOptions"> - <radiogroup id="mergeChoiceRadio" pack="start"> - <grid> - <columns> - <column/> - <column flex="1"/> - </columns> - <rows flex="1"> - <row align="center"> - <radio id="resetClient" - class="mergeChoiceButton" - aria-labelledby="resetClientLabel"/> - <label id="resetClientLabel" control="resetClient"> - <html:strong>&choice2.merge.recommended.label;</html:strong> - &choice2a.merge.main.label; - </label> - </row> - <row align="center"> - <radio id="wipeClient" - class="mergeChoiceButton" - aria-labelledby="wipeClientLabel"/> - <label id="wipeClientLabel" - control="wipeClient"> - &choice2a.client.main.label; - </label> - </row> - <row align="center"> - <radio id="wipeRemote" - class="mergeChoiceButton" - aria-labelledby="wipeRemoteLabel"/> - <label id="wipeRemoteLabel" - control="wipeRemote"> - &choice2a.server.main.label; - </label> - </row> - </rows> - </grid> - </radiogroup> - </groupbox> - </wizardpage> - - <wizardpage id="syncOptionsConfirm" - label="&setup.optionsConfirmPage.title;" - onpageshow="gSyncSetup.onPageShow()"> - <deck id="chosenActionDeck"> - <vbox id="chosenActionMerge" class="confirm"> - <description class="normal"> - &confirm.merge2.label; - </description> - </vbox> - <vbox id="chosenActionWipeClient" class="confirm"> - <description class="normal"> - &confirm.client3.label; - </description> - <separator class="thin"/> - <vbox id="dataList"> - <label class="data indent" id="bookmarkCount"/> - <label class="data indent" id="historyCount"/> - <label class="data indent" id="passwordCount"/> - <label class="data indent" id="addonCount"/> - <label class="data indent" id="prefsWipe" - value="&engine.prefs.label;"/> - </vbox> - <separator class="thin"/> - <description class="normal"> - &confirm.client2.moreinfo.label; - </description> - </vbox> - <vbox id="chosenActionWipeServer" class="confirm"> - <description class="normal"> - &confirm.server2.label; - </description> - <separator class="thin"/> - <vbox id="clientList"> - </vbox> - </vbox> - </deck> - </wizardpage> - <!-- In terms of the wizard flow shown to the user, the 'syncOptionsConfirm' - page above is not the last wizard page. To prevent the wizard binding from - assuming that it is, we're inserting this dummy page here. This also means - that the wizard needs to always be closed manually via wizardFinish(). --> - <wizardpage> - </wizardpage> -</wizard> - diff --git a/application/palemoon/base/content/sync/utils.js b/application/palemoon/base/content/sync/utils.js deleted file mode 100644 index d41ecf18a..000000000 --- a/application/palemoon/base/content/sync/utils.js +++ /dev/null @@ -1,218 +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/. */ - -// Equivalent to 0o600 permissions; used for saved Sync Recovery Key. -// This constant can be replaced when the equivalent values are available to -// chrome JS; see Bug 433295 and Bug 757351. -const PERMISSIONS_RWUSR = 0x180; - -// Weave should always exist before before this file gets included. -var gSyncUtils = { - get bundle() { - delete this.bundle; - return this.bundle = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties"); - }, - - // opens in a new window if we're in a modal prefwindow world, in a new tab otherwise - _openLink: function (url) { - let thisDocEl = document.documentElement, - openerDocEl = window.opener && window.opener.document.documentElement; - if (thisDocEl.id == "accountSetup" && window.opener && - openerDocEl.id == "BrowserPreferences" && !openerDocEl.instantApply) - openUILinkIn(url, "window"); - else if (thisDocEl.id == "BrowserPreferences" && !thisDocEl.instantApply) - openUILinkIn(url, "window"); - else if (document.documentElement.id == "change-dialog") - Services.wm.getMostRecentWindow("navigator:browser") - .openUILinkIn(url, "tab"); - else - openUILinkIn(url, "tab"); - }, - - changeName: function changeName(input) { - // Make sure to update to a modified name, e.g., empty-string -> default - Weave.Service.clientsEngine.localName = input.value; - input.value = Weave.Service.clientsEngine.localName; - }, - - openChange: function openChange(type, duringSetup) { - // Just re-show the dialog if it's already open - let openedDialog = Services.wm.getMostRecentWindow("Sync:" + type); - if (openedDialog != null) { - openedDialog.focus(); - return; - } - - // Open up the change dialog - let changeXUL = "chrome://browser/content/sync/genericChange.xul"; - let changeOpt = "centerscreen,chrome,resizable=no"; - Services.ww.activeWindow.openDialog(changeXUL, "", changeOpt, - type, duringSetup); - }, - - changePassword: function () { - if (Weave.Utils.ensureMPUnlocked()) - this.openChange("ChangePassword"); - }, - - resetPassphrase: function (duringSetup) { - if (Weave.Utils.ensureMPUnlocked()) - this.openChange("ResetPassphrase", duringSetup); - }, - - updatePassphrase: function () { - if (Weave.Utils.ensureMPUnlocked()) - this.openChange("UpdatePassphrase"); - }, - - resetPassword: function () { - this._openLink(Weave.Service.pwResetURL); - }, - - openToS: function () { - this._openLink(Weave.Svc.Prefs.get("termsURL")); - }, - - openPrivacyPolicy: function () { - this._openLink(Weave.Svc.Prefs.get("privacyURL")); - }, - - openFirstSyncProgressPage: function () { - this._openLink("about:sync-progress"); - }, - - /** - * Prepare an invisible iframe with the passphrase backup document. - * Used by both the print and saving methods. - * - * @param elid : ID of the form element containing the passphrase. - * @param callback : Function called once the iframe has loaded. - */ - _preparePPiframe: function(elid, callback) { - let pp = document.getElementById(elid).value; - - // Create an invisible iframe whose contents we can print. - let iframe = document.createElement("iframe"); - iframe.setAttribute("src", "chrome://browser/content/sync/key.xhtml"); - iframe.collapsed = true; - document.documentElement.appendChild(iframe); - iframe.contentWindow.addEventListener("load", function() { - iframe.contentWindow.removeEventListener("load", arguments.callee, false); - - // Insert the Sync Key into the page. - let el = iframe.contentDocument.getElementById("synckey"); - el.firstChild.nodeValue = pp; - - // Insert the TOS and Privacy Policy URLs into the page. - let termsURL = Weave.Svc.Prefs.get("termsURL"); - el = iframe.contentDocument.getElementById("tosLink"); - el.setAttribute("href", termsURL); - el.firstChild.nodeValue = termsURL; - - let privacyURL = Weave.Svc.Prefs.get("privacyURL"); - el = iframe.contentDocument.getElementById("ppLink"); - el.setAttribute("href", privacyURL); - el.firstChild.nodeValue = privacyURL; - - callback(iframe); - }, false); - }, - - /** - * Print passphrase backup document. - * - * @param elid : ID of the form element containing the passphrase. - */ - passphrasePrint: function(elid) { - this._preparePPiframe(elid, function(iframe) { - let webBrowserPrint = iframe.contentWindow - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebBrowserPrint); - let printSettings = PrintUtils.getPrintSettings(); - - // Display no header/footer decoration except for the date. - printSettings.headerStrLeft - = printSettings.headerStrCenter - = printSettings.headerStrRight - = printSettings.footerStrLeft - = printSettings.footerStrCenter = ""; - printSettings.footerStrRight = "&D"; - - try { - webBrowserPrint.print(printSettings, null); - } catch (ex) { - // print()'s return codes are expressed as exceptions. Ignore. - } - }); - }, - - /** - * Save passphrase backup document to disk as HTML file. - * - * @param elid : ID of the form element containing the passphrase. - */ - passphraseSave: function(elid) { - let dialogTitle = this.bundle.GetStringFromName("save.recoverykey.title"); - let defaultSaveName = this.bundle.GetStringFromName("save.recoverykey.defaultfilename"); - this._preparePPiframe(elid, function(iframe) { - let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); - let fpCallback = function fpCallback_done(aResult) { - if (aResult == Ci.nsIFilePicker.returnOK || - aResult == Ci.nsIFilePicker.returnReplace) { - let stream = Cc["@mozilla.org/network/file-output-stream;1"]. - createInstance(Ci.nsIFileOutputStream); - stream.init(fp.file, -1, PERMISSIONS_RWUSR, 0); - - let serializer = new XMLSerializer(); - let output = serializer.serializeToString(iframe.contentDocument); - output = output.replace(/<!DOCTYPE (.|\n)*?]>/, - '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ' + - '"DTD/xhtml1-strict.dtd">'); - output = Weave.Utils.encodeUTF8(output); - stream.write(output, output.length); - } - }; - - fp.init(window, dialogTitle, Ci.nsIFilePicker.modeSave); - fp.appendFilters(Ci.nsIFilePicker.filterHTML); - fp.defaultString = defaultSaveName; - fp.open(fpCallback); - return false; - }); - }, - - /** - * validatePassword - * - * @param el1 : the first textbox element in the form - * @param el2 : the second textbox element, if omitted it's an update form - * - * returns [valid, errorString] - */ - validatePassword: function (el1, el2) { - let valid = false; - let val1 = el1.value; - let val2 = el2 ? el2.value : ""; - let error = ""; - - if (!el2) - valid = val1.length >= Weave.MIN_PASS_LENGTH; - else if (val1 && val1 == Weave.Service.identity.username) - error = "change.password.pwSameAsUsername"; - else if (val1 && val1 == Weave.Service.identity.account) - error = "change.password.pwSameAsEmail"; - else if (val1 && val1 == Weave.Service.identity.basicPassword) - error = "change.password.pwSameAsPassword"; - else if (val1 && val2) { - if (val1 == val2 && val1.length >= Weave.MIN_PASS_LENGTH) - valid = true; - else if (val1.length < Weave.MIN_PASS_LENGTH) - error = "change.password.tooShort"; - else if (val1 != val2) - error = "change.password.mismatch"; - } - let errorString = error ? Weave.Utils.getErrorString(error) : ""; - return [valid, errorString]; - } -}; diff --git a/application/palemoon/base/content/tabbrowser.css b/application/palemoon/base/content/tabbrowser.css index 94d6dbb2e..43536b27a 100644 --- a/application/palemoon/base/content/tabbrowser.css +++ b/application/palemoon/base/content/tabbrowser.css @@ -45,10 +45,19 @@ tabpanels { } .tab-throbber:not([busy]), -.tab-throbber[busy] + .tab-icon-image { +.tab-throbber[busy] + .tab-icon-image, +.tab-icon-sound:not([soundplaying]):not([muted]):not([blocked]), +.tab-icon-sound[pinned], +.tab-icon-overlay { display: none; } +.tab-icon-overlay[soundplaying][pinned], +.tab-icon-overlay[muted][pinned], +.tab-icon-overlay[blocked][pinned] { + display: -moz-box; +} + .closing-tabs-spacer { pointer-events: none; } diff --git a/application/palemoon/base/content/tabbrowser.xml b/application/palemoon/base/content/tabbrowser.xml index dc6cb0a9d..988cae55c 100644 --- a/application/palemoon/base/content/tabbrowser.xml +++ b/application/palemoon/base/content/tabbrowser.xml @@ -438,6 +438,22 @@ </body> </method> + <method name="getTabFromAudioEvent"> + <parameter name="aEvent"/> + <body> + <![CDATA[ + if (!Services.prefs.getBoolPref("browser.tabs.showAudioPlayingIcon") || + !aEvent.isTrusted) { + return null; + } + + var browser = aEvent.originalTarget; + var tab = this.getTabForBrowser(browser); + return tab; + ]]> + </body> + </method> + <method name="_callProgressListeners"> <parameter name="aBrowser"/> <parameter name="aMethod"/> @@ -616,7 +632,7 @@ if (this.mTab.hasAttribute("busy")) { this.mTab.removeAttribute("busy"); - this.mTabBrowser._tabAttrModified(this.mTab); + this.mTabBrowser._tabAttrModified(this.mTab, ["busy"]); if (!this.mTab.selected) this.mTab.setAttribute("unread", "true"); } @@ -686,6 +702,8 @@ let topLevel = aWebProgress.isTopLevel; if (topLevel) { + let isSameDocument = + !!(aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT); // We need to clear the typed value // if the document failed to load, to make sure the urlbar reflects the // failed URI (particularly for SSL errors). However, don't clear the value @@ -696,6 +714,19 @@ aLocation.spec != "about:blank")) this.mBrowser.userTypedValue = null; + // If the browser was playing audio, we should remove the playing state. + if (this.mTab.hasAttribute("soundplaying") && !isSameDocument) { + clearTimeout(this.mTab._soundPlayingAttrRemovalTimer); + this.mTab._soundPlayingAttrRemovalTimer = 0; + this.mTab.removeAttribute("soundplaying"); + this.mTabBrowser._tabAttrModified(this.mTab, ["soundplaying"]); + } + + // If the browser was previously muted, we should restore the muted state. + if (this.mTab.hasAttribute("muted")) { + this.mTab.linkedBrowser.mute(); + } + // Don't clear the favicon if this onLocationChange was // triggered by a pushState or a replaceState. See bug 550565. if (!gMultiProcessBrowser) { @@ -800,13 +831,40 @@ "-moz-resolution=" + size + "," + size; } if (sizedIconUrl != aTab.getAttribute("image")) { - if (browser.mIconURL) //PMed + if (browser.mIconURL) aTab.setAttribute("image", sizedIconUrl); else aTab.removeAttribute("image"); - this._tabAttrModified(aTab); + this._tabAttrModified(aTab, ["image"]); } + if (Services.prefs.getBoolPref("browser.chrome.favicons.process")) { + let favImage = new Image; + favImage.src = browser.mIconURL; + var tabBrowser = this; + favImage.onload = function () { + try { + // Draw the icon on a hidden canvas + var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas"); + var tabImg = document.getAnonymousElementByAttribute(aTab, "anonid", "tab-icon"); + var w = tabImg.boxObject.width; + var h = tabImg.boxObject.height; + canvas.width = w; + canvas.height = h; + var ctx = canvas.getContext('2d'); + ctx.drawImage(favImage, 0, 0, w, h); + icon = canvas.toDataURL(); + browser.mIconURL = icon; + aTab.setAttribute("image", icon); + } + catch (e) { + console.warn("Processing of favicon failed."); + // Canvas failed: icon remains as it was + } + tabBrowser._callProgressListeners(browser, "onLinkIconAvailable", [browser.mIconURL]); + } + } + this._callProgressListeners(browser, "onLinkIconAvailable", [browser.mIconURL]); ]]> </body> @@ -1116,8 +1174,8 @@ }); this.mCurrentTab.dispatchEvent(event); - this._tabAttrModified(oldTab); - this._tabAttrModified(this.mCurrentTab); + this._tabAttrModified(oldTab, ["selected"]); + this._tabAttrModified(this.mCurrentTab, ["selected"]); // Adjust focus oldBrowser._urlbarFocused = (gURLBar && gURLBar.focused); @@ -1187,14 +1245,18 @@ <method name="_tabAttrModified"> <parameter name="aTab"/> + <parameter name="aChanged"/> <body><![CDATA[ if (aTab.closing) return; - // This event should be dispatched when any of these attributes change: - // label, crop, busy, image, selected - var event = document.createEvent("Events"); - event.initEvent("TabAttrModified", true, false); + let event = new CustomEvent("TabAttrModified", { + bubbles: true, + cancelable: false, + detail: { + changed: aChanged, + } + }); aTab.dispatchEvent(event); ]]></body> </method> @@ -1205,7 +1267,7 @@ <![CDATA[ aTab.label = this.mStringBundle.getString("tabs.connecting"); aTab.crop = "end"; - this._tabAttrModified(aTab); + this._tabAttrModified(aTab, ["label", "crop"]); ]]> </body> </method> @@ -1250,7 +1312,7 @@ aTab.label = title; aTab.crop = crop; - this._tabAttrModified(aTab); + this._tabAttrModified(aTab, ["label", "crop"]); if (aTab.selected) this.updateTitlebar(); @@ -2239,6 +2301,14 @@ var remoteBrowser = aOtherTab.ownerDocument.defaultView.gBrowser; var isPending = aOtherTab.hasAttribute("pending"); + // Expedite the removal of the icon if it was already scheduled. + if (aOtherTab._soundPlayingAttrRemovalTimer) { + clearTimeout(aOtherTab._soundPlayingAttrRemovalTimer); + aOtherTab._soundPlayingAttrRemovalTimer = 0; + aOtherTab.removeAttribute("soundplaying"); + remoteBrowser._tabAttrModified(aOtherTab, ["soundplaying"]); + } + // First, start teardown of the other browser. Make sure to not // fire the beforeunload event in the process. Close the other // window if this was its last tab. @@ -2248,6 +2318,18 @@ let ourBrowser = this.getBrowserForTab(aOurTab); let otherBrowser = aOtherTab.linkedBrowser; + let modifiedAttrs = []; + if (aOtherTab.hasAttribute("muted")) { + aOurTab.setAttribute("muted", "true"); + aOurTab.muteReason = aOtherTab.muteReason; + ourBrowser.mute(); + modifiedAttrs.push("muted"); + } + if (aOtherTab.hasAttribute("soundplaying")) { + aOurTab.setAttribute("soundplaying", "true"); + modifiedAttrs.push("soundplaying"); + } + // If the other tab is pending (i.e. has not been restored, yet) // then do not switch docShells but retrieve the other tab's state // and apply it to our tab. @@ -2266,7 +2348,7 @@ var isBusy = aOtherTab.hasAttribute("busy"); if (isBusy) { aOurTab.setAttribute("busy", "true"); - this._tabAttrModified(aOurTab); + modifiedAttrs.push("busy"); if (aOurTab.selected) this.mIsBusy = true; } @@ -2286,6 +2368,10 @@ // of replaceTabWithWindow), notify onLocationChange, etc. if (aOurTab.selected) this.updateCurrentBrowser(true); + + if (modifiedAttrs.length) { + this._tabAttrModified(aOurTab, modifiedAttrs); + } ]]> </body> </method> @@ -3084,9 +3170,25 @@ event.preventDefault(); return; } - event.target.setAttribute("label", tab.mOverCloseButton ? - tab.getAttribute("closetabtext") : - tab.getAttribute("label")); + + var stringID, label; + if (tab.mOverCloseButton) { + stringID = "tabs.closeTab"; + } else if (tab._overPlayingIcon) { + if (tab.linkedBrowser.audioBlocked) { + stringID = "tabs.unblockAudio.tooltip"; + } else { + stringID = tab.linkedBrowser.audioMuted ? + "tabs.unmuteAudio.tooltip" : + "tabs.muteAudio.tooltip"; + } + } else { + label = tab.getAttribute("label"); + } + if (stringID && !label) { + label = this.mStringBundle.getString(stringID); + } + event.target.setAttribute("label", label); ]]></body> </method> @@ -3300,6 +3402,7 @@ ]]> </getter> </property> + <field name="_soundPlayingAttrRemovalTimer">0</field> </implementation> <handlers> @@ -3347,6 +3450,78 @@ tab.setAttribute("titlechanged", "true"); ]]> </handler> + <handler event="DOMAudioPlaybackStarted"> + <![CDATA[ + var tab = getTabFromAudioEvent(event) + if (!tab) { + return; + } + + clearTimeout(tab._soundPlayingAttrRemovalTimer); + tab._soundPlayingAttrRemovalTimer = 0; + + let modifiedAttrs = []; + if (tab.hasAttribute("soundplaying-scheduledremoval")) { + tab.removeAttribute("soundplaying-scheduledremoval"); + modifiedAttrs.push("soundplaying-scheduledremoval"); + } + + if (!tab.hasAttribute("soundplaying")) { + tab.setAttribute("soundplaying", true); + modifiedAttrs.push("soundplaying"); + } + + this._tabAttrModified(tab, modifiedAttrs); + ]]> + </handler> + <handler event="DOMAudioPlaybackStopped"> + <![CDATA[ + var tab = getTabFromAudioEvent(event) + if (!tab) { + return; + } + + if (tab.hasAttribute("soundplaying")) { + let removalDelay = Services.prefs.getIntPref("browser.tabs.delayHidingAudioPlayingIconMS"); + + tab.style.setProperty("--soundplaying-removal-delay", `${removalDelay - 300}ms`); + tab.setAttribute("soundplaying-scheduledremoval", "true"); + this._tabAttrModified(tab, ["soundplaying-scheduledremoval"]); + + tab._soundPlayingAttrRemovalTimer = setTimeout(() => { + tab.removeAttribute("soundplaying-scheduledremoval"); + tab.removeAttribute("soundplaying"); + this._tabAttrModified(tab, ["soundplaying", "soundplaying-scheduledremoval"]); + }, removalDelay); + } + ]]> + </handler> + <handler event="DOMAudioPlaybackBlockStarted"> + <![CDATA[ + var tab = getTabFromAudioEvent(event) + if (!tab) { + return; + } + + if (!tab.hasAttribute("blocked")) { + tab.setAttribute("blocked", true); + this._tabAttrModified(tab, ["blocked"]); + } + ]]> + </handler> + <handler event="DOMAudioPlaybackBlockStopped"> + <![CDATA[ + var tab = getTabFromAudioEvent(event) + if (!tab) { + return; + } + + if (tab.hasAttribute("blocked")) { + tab.removeAttribute("blocked"); + this._tabAttrModified(tab, ["blocked"]); + } + ]]> + </handler> </handlers> </binding> @@ -4758,10 +4933,18 @@ class="tab-icon-image" role="presentation" anonid="tab-icon"/> + <xul:image xbl:inherits="busy,soundplaying,soundplaying-scheduledremoval,pinned,muted,blocked,selected" + anonid="overlay-icon" + class="tab-icon-overlay" + role="presentation"/> <xul:label flex="1" xbl:inherits="value=label,crop,accesskey,fadein,pinned,selected" class="tab-text tab-label" role="presentation"/> + <xul:image xbl:inherits="soundplaying,soundplaying-scheduledremoval,pinned,muted,blocked,selected" + anonid="soundplaying-icon" + class="tab-icon-sound" + role="presentation"/> <xul:toolbarbutton anonid="close-button" xbl:inherits="fadein,pinned,selected" class="tab-close-button close-icon"/> @@ -4782,9 +4965,59 @@ </property> <field name="mOverCloseButton">false</field> + <property name="_overPlayingIcon" readonly="true"> + <getter><![CDATA[ + let iconVisible = this.hasAttribute("soundplaying") || + this.hasAttribute("muted") || + this.hasAttribute("blocked"); + let soundPlayingIcon = + document.getAnonymousElementByAttribute(this, "anonid", "soundplaying-icon"); + let overlayIcon = + document.getAnonymousElementByAttribute(this, "anonid", "overlay-icon"); + + return soundPlayingIcon && soundPlayingIcon.matches(":hover") || + (overlayIcon && overlayIcon.matches(":hover") && iconVisible); + ]]></getter> + </property> <field name="mCorrespondingMenuitem">null</field> <field name="closing">false</field> <field name="lastAccessed">0</field> + + <method name="toggleMuteAudio"> + <parameter name="aMuteReason"/> + <body> + <![CDATA[ + let tabContainer = this.parentNode; + let browser = this.linkedBrowser; + let modifiedAttrs = []; + if (browser.audioBlocked) { + this.removeAttribute("blocked"); + modifiedAttrs.push("blocked"); + + // We don't want sound icon flickering between "blocked", "none" and + // "sound-playing", here adding the "soundplaying" is to keep the + // transition smoothly. + if (!this.hasAttribute("soundplaying")) { + this.setAttribute("soundplaying", true); + modifiedAttrs.push("soundplaying"); + } + + browser.resumeMedia(); + } else { + if (browser.audioMuted) { + browser.unmute(); + this.removeAttribute("muted"); + } else { + browser.mute(); + this.setAttribute("muted", "true"); + } + this.muteReason = aMuteReason || null; + modifiedAttrs.push("muted"); + } + tabContainer.tabbrowser._tabAttrModified(this, modifiedAttrs); + ]]> + </body> + </method> </implementation> <handlers> @@ -4843,7 +5076,8 @@ if (this.selected) { this.style.MozUserFocus = 'ignore'; this.clientTop; // just using this to flush style updates - } else if (this.mOverCloseButton) { + } else if (this.mOverCloseButton || + this._overPlayingIcon) { // Prevent tabbox.xml from selecting the tab. event.stopPropagation(); } @@ -4852,6 +5086,17 @@ <handler event="mouseup"> this.style.MozUserFocus = ''; </handler> + <handler event="click"> + <![CDATA[ + if (event.button != 0) { + return; + } + + if (this._overPlayingIcon) { + this.toggleMuteAudio(); + } + ]]> + </handler> </handlers> </binding> @@ -4957,6 +5202,24 @@ aMenuitem.setAttribute("selected", "true"); else aMenuitem.removeAttribute("selected"); + + function addEndImage() { + let endImage = document.createElement("image"); + endImage.setAttribute("class", "allTabs-endimage"); + let endImageContainer = document.createElement("hbox"); + endImageContainer.setAttribute("align", "center"); + endImageContainer.setAttribute("pack", "center"); + endImageContainer.appendChild(endImage); + aMenuitem.appendChild(endImageContainer); + return endImage; + } + + if (aMenuitem.firstChild) + aMenuitem.firstChild.remove(); + if (aTab.hasAttribute("muted")) + addEndImage().setAttribute("muted", "true"); + else if (aTab.hasAttribute("soundplaying")) + addEndImage().setAttribute("soundplaying", "true"); ]]></body> </method> </implementation> diff --git a/application/palemoon/base/jar.mn b/application/palemoon/base/jar.mn index d8c3f4b21..8931c0260 100644 --- a/application/palemoon/base/jar.mn +++ b/application/palemoon/base/jar.mn @@ -2,135 +2,81 @@ # 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/. browser.jar: -% content browser %content/browser/ contentaccessible=yes +% content browser %content/browser/ contentaccessible=yes #ifdef XP_MACOSX -% overlay chrome://mozapps/content/downloads/downloads.xul chrome://browser/content/downloadManagerOverlay.xul -% overlay chrome://global/content/console.xul chrome://browser/content/jsConsoleOverlay.xul -% overlay chrome://mozapps/content/update/updates.xul chrome://browser/content/softwareUpdateOverlay.xul +% overlay chrome://mozapps/content/downloads/downloads.xul chrome://browser/content/downloadManagerOverlay.xul +% overlay chrome://global/content/console.xul chrome://browser/content/jsConsoleOverlay.xul +% overlay chrome://mozapps/content/update/updates.xul chrome://browser/content/softwareUpdateOverlay.xul #endif #ifdef XP_WIN -% overlay chrome://browser/content/browser.xul chrome://browser/content/win6BrowserOverlay.xul os=WINNT osversion>=6 +% overlay chrome://browser/content/browser.xul chrome://browser/content/win6BrowserOverlay.xul os=WINNT osversion>=6 #endif -% overlay chrome://global/content/viewSource.xul chrome://browser/content/viewSourceOverlay.xul -% overlay chrome://global/content/viewPartialSource.xul chrome://browser/content/viewSourceOverlay.xul -% style chrome://global/content/customizeToolbar.xul chrome://browser/content/browser.css -% style chrome://global/content/customizeToolbar.xul chrome://browser/skin/ -* content/browser/aboutDialog.xul (content/aboutDialog.xul) -* content/browser/aboutDialog.js (content/aboutDialog.js) - content/browser/aboutDialog.css (content/aboutDialog.css) - content/browser/aboutRobots.xhtml (content/aboutRobots.xhtml) - content/browser/abouthome/aboutHome.xhtml (content/abouthome/aboutHome.xhtml) - content/browser/abouthome/aboutHome.js (content/abouthome/aboutHome.js) -* content/browser/abouthome/aboutHome.css (content/abouthome/aboutHome.css) - content/browser/abouthome/noise.png (content/abouthome/noise.png) - content/browser/abouthome/snippet1.png (content/abouthome/snippet1.png) - content/browser/abouthome/snippet2.png (content/abouthome/snippet2.png) - content/browser/abouthome/downloads.png (content/abouthome/downloads.png) - content/browser/abouthome/bookmarks.png (content/abouthome/bookmarks.png) - content/browser/abouthome/history.png (content/abouthome/history.png) - content/browser/abouthome/addons.png (content/abouthome/addons.png) - content/browser/abouthome/sync.png (content/abouthome/sync.png) - content/browser/abouthome/settings.png (content/abouthome/settings.png) - content/browser/abouthome/restore.png (content/abouthome/restore.png) - content/browser/abouthome/restore-large.png (content/abouthome/restore-large.png) - content/browser/abouthome/snippet1@2x.png (content/abouthome/snippet1@2x.png) - content/browser/abouthome/snippet2@2x.png (content/abouthome/snippet2@2x.png) - content/browser/abouthome/downloads@2x.png (content/abouthome/downloads@2x.png) - content/browser/abouthome/bookmarks@2x.png (content/abouthome/bookmarks@2x.png) - content/browser/abouthome/history@2x.png (content/abouthome/history@2x.png) - content/browser/abouthome/addons@2x.png (content/abouthome/addons@2x.png) - content/browser/abouthome/sync@2x.png (content/abouthome/sync@2x.png) - content/browser/abouthome/settings@2x.png (content/abouthome/settings@2x.png) - content/browser/abouthome/restore@2x.png (content/abouthome/restore@2x.png) - content/browser/abouthome/restore-large@2x.png (content/abouthome/restore-large@2x.png) - content/browser/aboutRobots-icon.png (content/aboutRobots-icon.png) - content/browser/aboutRobots-widget-left.png (content/aboutRobots-widget-left.png) - content/browser/autorecovery.js (content/autorecovery.js) - content/browser/autorecovery.xul (content/autorecovery.xul) -* content/browser/browser.css (content/browser.css) - content/browser/browser-menudragging.xul (content/browser-menudragging.xul) - content/browser/browser-menudragging.js (content/browser-menudragging.js) - content/browser/browser-title.css (content/browser-title.css) -* content/browser/browser.js (content/browser.js) -* content/browser/browser.xul (content/browser.xul) +% overlay chrome://global/content/viewSource.xul chrome://browser/content/viewSourceOverlay.xul +% overlay chrome://global/content/viewPartialSource.xul chrome://browser/content/viewSourceOverlay.xul +% style chrome://global/content/customizeToolbar.xul chrome://browser/content/browser.css +% style chrome://global/content/customizeToolbar.xul chrome://browser/skin/ +* content/browser/aboutDialog.xul (content/aboutDialog.xul) +* content/browser/aboutDialog.js (content/aboutDialog.js) + content/browser/aboutDialog.css (content/aboutDialog.css) + content/browser/aboutRobots.xhtml (content/aboutRobots.xhtml) + content/browser/aboutRobots-icon.png (content/aboutRobots-icon.png) + content/browser/aboutRobots-widget-left.png (content/aboutRobots-widget-left.png) + content/browser/autorecovery.js (content/autorecovery.js) + content/browser/autorecovery.xul (content/autorecovery.xul) +* content/browser/browser.css (content/browser.css) + content/browser/browser-menudragging.xul (content/browser-menudragging.xul) + content/browser/browser-menudragging.js (content/browser-menudragging.js) + content/browser/browser-title.css (content/browser-title.css) +* content/browser/browser.js (content/browser.js) +* content/browser/browser.xul (content/browser.xul) #ifdef MOZ_DEVTOOLS - content/browser/browser-devtools-theme.js (content/browser-devtools-theme.js) + content/browser/browser-devtools-theme.js (content/browser-devtools-theme.js) #endif -* content/browser/browser-tabPreviews.xml (content/browser-tabPreviews.xml) - content/browser/content.js (content/content.js) - content/browser/padlock.xul (content/padlock.xul) - content/browser/padlock.js (content/padlock.js) - content/browser/padlock.css (content/padlock.css) - content/browser/padlock_mod_ev.png (content/padlock_mod_ev.png) - content/browser/padlock_mod_https.png (content/padlock_mod_https.png) - content/browser/padlock_mod_low.png (content/padlock_mod_low.png) - content/browser/padlock_mod_broken.png (content/padlock_mod_broken.png) - content/browser/padlock_classic_ev.png (content/padlock_classic_ev.png) - content/browser/padlock_classic_https.png (content/padlock_classic_https.png) - content/browser/padlock_classic_low.png (content/padlock_classic_low.png) - content/browser/padlock_classic_broken.png (content/padlock_classic_broken.png) - content/browser/palemoon.xhtml (content/palemoon.xhtml) - 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/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) - content/browser/pageinfo/pageInfo.xml (content/pageinfo/pageInfo.xml) - content/browser/pageinfo/feeds.js (content/pageinfo/feeds.js) - content/browser/pageinfo/feeds.xml (content/pageinfo/feeds.xml) - content/browser/pageinfo/permissions.js (content/pageinfo/permissions.js) - content/browser/pageinfo/security.js (content/pageinfo/security.js) -#ifdef MOZ_SERVICES_SYNC - content/browser/sync/aboutSyncTabs.xul (content/sync/aboutSyncTabs.xul) - content/browser/sync/aboutSyncTabs.js (content/sync/aboutSyncTabs.js) - content/browser/sync/aboutSyncTabs.css (content/sync/aboutSyncTabs.css) - content/browser/sync/aboutSyncTabs-bindings.xml (content/sync/aboutSyncTabs-bindings.xml) - content/browser/sync/setup.xul (content/sync/setup.xul) - content/browser/sync/addDevice.js (content/sync/addDevice.js) - content/browser/sync/addDevice.xul (content/sync/addDevice.xul) - content/browser/sync/setup.js (content/sync/setup.js) - content/browser/sync/genericChange.xul (content/sync/genericChange.xul) - content/browser/sync/genericChange.js (content/sync/genericChange.js) - content/browser/sync/key.xhtml (content/sync/key.xhtml) - content/browser/sync/notification.xml (content/sync/notification.xml) - content/browser/sync/quota.xul (content/sync/quota.xul) - content/browser/sync/quota.js (content/sync/quota.js) - content/browser/sync/utils.js (content/sync/utils.js) - content/browser/sync/progress.js (content/sync/progress.js) - content/browser/sync/progress.xhtml (content/sync/progress.xhtml) -#endif - content/browser/openLocation.js (content/openLocation.js) - content/browser/openLocation.xul (content/openLocation.xul) - content/browser/safeMode.css (content/safeMode.css) - content/browser/safeMode.js (content/safeMode.js) -* content/browser/safeMode.xul (content/safeMode.xul) -* content/browser/sanitize.js (content/sanitize.js) -* content/browser/sanitize.xul (content/sanitize.xul) -* content/browser/sanitizeDialog.js (content/sanitizeDialog.js) - content/browser/sanitizeDialog.css (content/sanitizeDialog.css) - content/browser/autocomplete.css (content/autocomplete.css) -* content/browser/autocomplete.xml (content/autocomplete.xml) - content/browser/tabbrowser.css (content/tabbrowser.css) -* content/browser/tabbrowser.xml (content/tabbrowser.xml) -* content/browser/urlbarBindings.xml (content/urlbarBindings.xml) -* content/browser/utilityOverlay.js (content/utilityOverlay.js) - content/browser/web-panels.js (content/web-panels.js) -* content/browser/web-panels.xul (content/web-panels.xul) -* content/browser/baseMenuOverlay.xul (content/baseMenuOverlay.xul) -* content/browser/nsContextMenu.js (content/nsContextMenu.js) +* content/browser/browser-tabPreviews.xml (content/browser-tabPreviews.xml) + content/browser/content.js (content/content.js) + content/browser/padlock.xul (content/padlock.xul) + content/browser/padlock.js (content/padlock.js) + content/browser/padlock.css (content/padlock.css) + content/browser/padlock_mod_ev.png (content/padlock_mod_ev.png) + content/browser/padlock_mod_https.png (content/padlock_mod_https.png) + content/browser/padlock_mod_low.png (content/padlock_mod_low.png) + content/browser/padlock_mod_broken.png (content/padlock_mod_broken.png) + content/browser/padlock_classic_ev.png (content/padlock_classic_ev.png) + content/browser/padlock_classic_https.png (content/padlock_classic_https.png) + content/browser/padlock_classic_low.png (content/padlock_classic_low.png) + content/browser/padlock_classic_broken.png (content/padlock_classic_broken.png) + content/browser/palemoon.xhtml (content/palemoon.xhtml) + content/browser/openLocation.js (content/openLocation.js) + content/browser/openLocation.xul (content/openLocation.xul) + content/browser/safeMode.css (content/safeMode.css) + content/browser/safeMode.js (content/safeMode.js) +* content/browser/safeMode.xul (content/safeMode.xul) +* content/browser/sanitize.js (content/sanitize.js) +* content/browser/sanitize.xul (content/sanitize.xul) +* content/browser/sanitizeDialog.js (content/sanitizeDialog.js) + content/browser/sanitizeDialog.css (content/sanitizeDialog.css) + content/browser/autocomplete.css (content/autocomplete.css) +* content/browser/autocomplete.xml (content/autocomplete.xml) + content/browser/tabbrowser.css (content/tabbrowser.css) +* content/browser/tabbrowser.xml (content/tabbrowser.xml) +* content/browser/urlbarBindings.xml (content/urlbarBindings.xml) +* content/browser/utilityOverlay.js (content/utilityOverlay.js) + content/browser/web-panels.js (content/web-panels.js) +* content/browser/web-panels.xul (content/web-panels.xul) +* content/browser/baseMenuOverlay.xul (content/baseMenuOverlay.xul) +* content/browser/nsContextMenu.js (content/nsContextMenu.js) # XXX: We should exclude this one as well (bug 71895) -* content/browser/hiddenWindow.xul (content/hiddenWindow.xul) +* content/browser/hiddenWindow.xul (content/hiddenWindow.xul) #ifdef XP_MACOSX -* content/browser/macBrowserOverlay.xul (content/macBrowserOverlay.xul) -* content/browser/downloadManagerOverlay.xul (content/downloadManagerOverlay.xul) -* content/browser/jsConsoleOverlay.xul (content/jsConsoleOverlay.xul) -* content/browser/softwareUpdateOverlay.xul (content/softwareUpdateOverlay.xul) +* content/browser/macBrowserOverlay.xul (content/macBrowserOverlay.xul) +* content/browser/downloadManagerOverlay.xul (content/downloadManagerOverlay.xul) +* content/browser/jsConsoleOverlay.xul (content/jsConsoleOverlay.xul) +* content/browser/softwareUpdateOverlay.xul (content/softwareUpdateOverlay.xul) #endif -* content/browser/viewSourceOverlay.xul (content/viewSourceOverlay.xul) +* content/browser/viewSourceOverlay.xul (content/viewSourceOverlay.xul) #ifdef XP_WIN - content/browser/win6BrowserOverlay.xul (content/win6BrowserOverlay.xul) + content/browser/win6BrowserOverlay.xul (content/win6BrowserOverlay.xul) #endif # the following files are browser-specific overrides -* content/browser/license.html (/toolkit/content/license.html) +* content/browser/license.html (/toolkit/content/license.html) % override chrome://global/content/license.html chrome://browser/content/license.html |