Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/site/app/webroot
diff options
context:
space:
mode:
Diffstat (limited to 'site/app/webroot')
-rw-r--r--site/app/webroot/css/editors.css3
-rw-r--r--site/app/webroot/css/filebrowser.css2
-rw-r--r--site/app/webroot/css/localizers.css8
-rw-r--r--site/app/webroot/css/remora.css19
-rw-r--r--site/app/webroot/css/screen.css45
-rwxr-xr-xsite/app/webroot/css/stats/dropdowns.css24
-rw-r--r--site/app/webroot/img/box-pointer-top.pngbin0 -> 392 bytes
-rw-r--r--site/app/webroot/img/developers/admin_review.pngbin0 -> 702 bytes
-rw-r--r--site/app/webroot/img/developers/info-bw.pngbin0 -> 607 bytes
-rw-r--r--site/app/webroot/img/developers/info-color.pngbin0 -> 1166 bytes
-rw-r--r--site/app/webroot/img/favicons/delicious.gifbin0 -> 171 bytes
-rw-r--r--site/app/webroot/img/favicons/digg.gifbin0 -> 256 bytes
-rw-r--r--site/app/webroot/img/favicons/facebook.gifbin0 -> 121 bytes
-rw-r--r--site/app/webroot/img/favicons/friendfeed.gifbin0 -> 239 bytes
-rw-r--r--site/app/webroot/img/favicons/myspace.gifbin0 -> 268 bytes
-rw-r--r--site/app/webroot/img/favicons/reddit.gifbin0 -> 581 bytes
-rw-r--r--site/app/webroot/js/addons.js132
-rw-r--r--site/app/webroot/js/developers.js37
-rw-r--r--site/app/webroot/js/editors.js45
-rwxr-xr-xsite/app/webroot/js/stats/plot-selection.js8
-rw-r--r--site/app/webroot/js/stats/plot-tables.js6
-rwxr-xr-xsite/app/webroot/js/stats/plots.js195
-rw-r--r--site/app/webroot/services/install.php14
23 files changed, 477 insertions, 61 deletions
diff --git a/site/app/webroot/css/editors.css b/site/app/webroot/css/editors.css
index 396b600..4c11658 100644
--- a/site/app/webroot/css/editors.css
+++ b/site/app/webroot/css/editors.css
@@ -181,6 +181,9 @@ div.error_message {
border: 0;
vertical-align: middle;
}
+#subform div {
+ margin: 5px 0;
+}
#commentsbox {
padding: 5px;
}
diff --git a/site/app/webroot/css/filebrowser.css b/site/app/webroot/css/filebrowser.css
index 35f6d89..f94c1be 100644
--- a/site/app/webroot/css/filebrowser.css
+++ b/site/app/webroot/css/filebrowser.css
@@ -52,7 +52,7 @@
content: "\00BB \0020";
}
.fileList li.file:before {
- content: "\203A \0000";
+ content: "\203A \0020";
margin-right: 2px;
}
diff --git a/site/app/webroot/css/localizers.css b/site/app/webroot/css/localizers.css
index 6213973..ee81a39 100644
--- a/site/app/webroot/css/localizers.css
+++ b/site/app/webroot/css/localizers.css
@@ -46,6 +46,7 @@ table.translatedSection th {
table.translatedSection td {
padding: 5px;
font-size: 80%;
+ vertical-align: top;
}
table.translatedSection td.field {
font-weight: bold;
@@ -56,3 +57,10 @@ table.translatedSection td.enus {
table.translatedSection td.localized {
border-left: 1px solid gray;
}
+table.translatedSection input {
+ width: 100%;
+}
+table.translatedSection textarea {
+ width: 100%;
+ height: 8em;
+}
diff --git a/site/app/webroot/css/remora.css b/site/app/webroot/css/remora.css
index 57fa3e1..0c796e6 100644
--- a/site/app/webroot/css/remora.css
+++ b/site/app/webroot/css/remora.css
@@ -18,8 +18,8 @@
#cat-list li.selected a { background: #99CC66; }
/* Add-on Summary */
-#addon-summary .stats { position: absolute; left: 20px; top: 18em; margin: 1em 0; }
-#addon-summary { min-height: 225px; }
+#addon-summary .stats { position: absolute; left: 20px; top: 19em; margin: 1em 0; text-align: center; }
+#addon-summary { min-height: 255px; }
#addon-summary .privacypolicy { clear: both; padding-top: .5em; }
/* Details Page */
@@ -136,4 +136,19 @@ div.hsession { display: none; }
}
#tabbed-editor .ui-tabs-nav {
display: block;
+}
+
+
+/* FAQ styling */
+
+dl.faq dt {
+ margin: 1em 0 0 0;
+}
+
+dl.faq dd {
+ margin-top: 0.5em;
+}
+
+dl.faq dt:target {
+ color: #df731b;
} \ No newline at end of file
diff --git a/site/app/webroot/css/screen.css b/site/app/webroot/css/screen.css
index 62c4080..e20ff6e 100644
--- a/site/app/webroot/css/screen.css
+++ b/site/app/webroot/css/screen.css
@@ -4,6 +4,7 @@ Created by Craig Cook - focalcurve.com
on November 20, 2007
-----------------------------------------------------------------------------*/
+
/*** =Reset defaults ***/
html, body, div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
@@ -84,7 +85,7 @@ h4#moz a { display: block; height: 44px; width: 100px; padding-left: 10px;}
/* =User nav */
#nav-user { max-width: 900px; min-width: 770px;}
.html-ltr #nav-user { margin: -1.75em auto 0; padding: 0 50px;}
-.html-rtl #nav-user { margin: -1.75em auto 0; padding: 0 0 0 50px;}
+.html-rtl #nav-user { margin: 0em auto 0; padding: 0 0 0 50px;}
#nav-user li { display: inline;}
.html-ltr #nav-user li { padding-left: 1em; margin-right: .5em; }
@@ -385,6 +386,46 @@ form.asclosed {display: none;}
#addon-summary .rating { position: absolute; left: 20px; top: 180px; width: 200px; }
#addon-summary .stats { position: absolute; left: 20px; top: 180px; width: 200px; margin-top: 3.5em; }
+#addon-summary .link-sharing { position: absolute; left: 105px; /*padding-left: 25px; border-left: 1px solid #cecece;*/ top: 180px; font-size: 0.7em; }
+#addon-summary .link-sharing .badge { }
+#addon-summary .link-sharing .badge .button { display: block;color: #062445; background: #7cc11c url("../img/sprite.png?20081210") -800px -730px no-repeat; }
+#addon-summary .link-sharing .badge .button a { display: block; padding: 0 8px 8px 0; background: transparent url(../img/installbtn-edges.png) no-repeat scroll right bottom; }
+#addon-summary .link-sharing .badge .button a span { display: block; text-align: center; font-weight: bold; padding: 2px 0 0 2px; background: transparent url(../img/installbtn-edges-list.png) no-repeat scroll left top; }
+
+#addon-summary .link-sharing .share-button { padding: 0; margin: 0 }
+#addon-summary .link-sharing .share-button:after, .install-container:after {content:".";clear:both;display:block;visibility:hidden;height:0;overflow:hidden;}
+#addon-summary .link-sharing .share-button a { float: left; cursor: pointer; max-width: 290px; text-decoration: none; }
+#addon-summary .link-sharing .share-button a * { display: block; float: left; position: relative; }
+#addon-summary .link-sharing .share-button a span { padding: 0 0 0 6px; }
+#addon-summary .link-sharing .share-button a span span { padding: 0 0 8px 0; }
+#addon-summary .link-sharing .share-button a span span span { left: -6px; padding: 0 0 0 0; }
+#addon-summary .link-sharing .share-button a span span span strong { width: 90px; text-align: center; right: -6px; padding: 0 18px 0 6px; }
+#addon-summary .link-sharing .share-button a span span span strong img {padding: 0 6px 0 0;}
+
+#addon-summary .link-sharing .share-button a { color: #062445; background: #7cc11c url("../img/sprite.png?20081210") -800px -730px no-repeat; }
+#addon-summary .link-sharing .share-button a span { background: transparent url("../img/installbtn-edges.png") left bottom no-repeat; }
+#addon-summary .link-sharing .share-button a span span { background: transparent url("../img/installbtn-edges.png") right bottom no-repeat; }
+#addon-summary .link-sharing .share-button a span span span { background: transparent url("../img/installbtn-edges.png") left top no-repeat; }
+#addon-summary .link-sharing .share-button a span span span strong { background: transparent url("../img/installbtn-edges.png") right top no-repeat; }
+
+#addon-summary .link-sharing .share-button a:hover, .install-button a:focus, .install-button a:active { color: #0a3b73; background-color: #9dd34c; background-position: -800px -860px; }
+
+#addon-summary .link-sharing .badge .counter { display: block; position: relative; padding-right: 4px; text-align: center; top: -4px; }
+
+#addon-summary .link-sharing .choices { display: none; position: absolute; z-index: 999; left: -120px; top: 12px; width: 360px; background: transparent url(../img/box-pointer-top.png) center top no-repeat; padding-top: 12px; }
+#addon-summary .link-sharing .choices div { margin: 0; padding: 1em; background-color: #f8f8f8; border: 1px solid #657b86; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; }
+#addon-summary .link-sharing .choices ul { list-style: none; margin: 0; }
+#addon-summary .link-sharing .choices ul li { width: 50%; float: left; }
+#addon-summary .link-sharing .choices ul li p { padding: 0.25em; margin: 0 0.25em 0 0 }
+#addon-summary .link-sharing .choices ul li p a { font-weight: bold; display:block; height: 20px; text-decoration: none; padding-left: 22px; background: transparent url(../img/favicons/digg.gif) left top no-repeat }
+#addon-summary .link-sharing .choices ul li.digg p a { background-image: url(../img/favicons/digg.gif); }
+#addon-summary .link-sharing .choices ul li.facebook p a { background-image: url(../img/favicons/facebook.gif); }
+#addon-summary .link-sharing .choices ul li.delicious p a { background-image: url(../img/favicons/delicious.gif); }
+#addon-summary .link-sharing .choices ul li.myspace p a { background-image: url(../img/favicons/myspace.gif); }
+#addon-summary .link-sharing .choices ul li.friendfeed p a { background-image: url(../img/favicons/friendfeed.gif); }
+#addon-summary .link-sharing .choices ul li.reddit p a { background-image: url(../img/favicons/reddit.gif); }
+
+
.addon-cats { margin-left: 0; }
.addon-cats li { display: inline; padding-left: 1em; margin-right: .5em; }
.addon-cats li:first-child { padding-left: 0; }
@@ -906,6 +947,8 @@ form.asclosed {display: none;}
background-color: #000;
}
+
+
/* Background iframe styling for IE6. Prevents ActiveX bleed-through (<select> form elements, etc.) */
* iframe.jqm {
position: absolute;
diff --git a/site/app/webroot/css/stats/dropdowns.css b/site/app/webroot/css/stats/dropdowns.css
index fef396f..336ad95 100755
--- a/site/app/webroot/css/stats/dropdowns.css
+++ b/site/app/webroot/css/stats/dropdowns.css
@@ -214,9 +214,6 @@
.plot-dropdown.big-menu ul li.indented a {
padding-left: 23px;
}
-.plot-dropdown.group-by .selected {
- width: 98%;
-}
#options.plot-dropdown {
width: 35px;
@@ -232,6 +229,17 @@
margin-left: -120px;
}
+#group-by-selector {
+ width: 163px;
+ white-space: nowrap;
+}
+#group-by-selector .selected {
+ width: 98%;
+}
+#group-by-selector_group-by-selection-menu {
+ padding: 0 0.5em 0 0.5em;
+ width: auto;
+}
#plot-options #plot-selector-area {
@@ -251,6 +259,15 @@
float: right;
}
+#weeks-legend {
+ display: none;
+ border: 2px solid #D8DCDF;
+ -moz-border-radius: 6px;
+ -webkit-border-radius: 6px;
+ float: left;
+ margin-left: 160px;
+}
+
#summary-legend {
border: 2px solid #D8DCDF;
-moz-border-radius: 6px;
@@ -331,3 +348,4 @@
height: 150px;
border: none !important;
}
+
diff --git a/site/app/webroot/img/box-pointer-top.png b/site/app/webroot/img/box-pointer-top.png
new file mode 100644
index 0000000..d7f451c
--- /dev/null
+++ b/site/app/webroot/img/box-pointer-top.png
Binary files differ
diff --git a/site/app/webroot/img/developers/admin_review.png b/site/app/webroot/img/developers/admin_review.png
new file mode 100644
index 0000000..cff65d7
--- /dev/null
+++ b/site/app/webroot/img/developers/admin_review.png
Binary files differ
diff --git a/site/app/webroot/img/developers/info-bw.png b/site/app/webroot/img/developers/info-bw.png
new file mode 100644
index 0000000..ade8c8f
--- /dev/null
+++ b/site/app/webroot/img/developers/info-bw.png
Binary files differ
diff --git a/site/app/webroot/img/developers/info-color.png b/site/app/webroot/img/developers/info-color.png
new file mode 100644
index 0000000..1236c56
--- /dev/null
+++ b/site/app/webroot/img/developers/info-color.png
Binary files differ
diff --git a/site/app/webroot/img/favicons/delicious.gif b/site/app/webroot/img/favicons/delicious.gif
new file mode 100644
index 0000000..a136dd1
--- /dev/null
+++ b/site/app/webroot/img/favicons/delicious.gif
Binary files differ
diff --git a/site/app/webroot/img/favicons/digg.gif b/site/app/webroot/img/favicons/digg.gif
new file mode 100644
index 0000000..089f4f2
--- /dev/null
+++ b/site/app/webroot/img/favicons/digg.gif
Binary files differ
diff --git a/site/app/webroot/img/favicons/facebook.gif b/site/app/webroot/img/favicons/facebook.gif
new file mode 100644
index 0000000..90a8e02
--- /dev/null
+++ b/site/app/webroot/img/favicons/facebook.gif
Binary files differ
diff --git a/site/app/webroot/img/favicons/friendfeed.gif b/site/app/webroot/img/favicons/friendfeed.gif
new file mode 100644
index 0000000..edcc727
--- /dev/null
+++ b/site/app/webroot/img/favicons/friendfeed.gif
Binary files differ
diff --git a/site/app/webroot/img/favicons/myspace.gif b/site/app/webroot/img/favicons/myspace.gif
new file mode 100644
index 0000000..8e56437
--- /dev/null
+++ b/site/app/webroot/img/favicons/myspace.gif
Binary files differ
diff --git a/site/app/webroot/img/favicons/reddit.gif b/site/app/webroot/img/favicons/reddit.gif
new file mode 100644
index 0000000..8a4963f
--- /dev/null
+++ b/site/app/webroot/img/favicons/reddit.gif
Binary files differ
diff --git a/site/app/webroot/js/addons.js b/site/app/webroot/js/addons.js
index 6da858b..2f23003 100644
--- a/site/app/webroot/js/addons.js
+++ b/site/app/webroot/js/addons.js
@@ -260,10 +260,9 @@ function removeCompatibilityHint(versionID) {
* This function is used on the addon version page to create an element
* at the top of the page with the most recent compatible version of an addon
*/
-function createLatestVersionElement(get_latest_version_text) {
+function createLatestVersionElement(get_latest_version_text, app) {
var container = $("#latest-version-container");
-
- container.wrapInner("<p>" + get_latest_version_text + " (" + gLatestApplicationVersion + ")" + "</p>");
+ container.wrapInner("<p>" + sprintf(get_latest_version_text, app, gLatestApplicationVersion) + "</p>");
container.append(gLatestAddonVersion);
var installButton = $("#install-"+ gLatestVersionID);
var cloned = installButton.clone();
@@ -865,3 +864,130 @@ $.fn.collection = function(options) {
/*# AVOID COLLISIONS #*/
})(jQuery);
/*# AVOID COLLISIONS #*/
+
+/**
+ * jQuery rollover reveal widget
+ * lorchard@mozilla.com
+ *
+ * Example markup:
+ * <div id="foo">
+ * <a href="#" class="activator">Hover me</a>
+ * <div class="to-reveal">This content will appear</div>
+ * </div>
+ * <script>
+ * $('#foo').rolloverReveal({
+ * reveal_delay: 1000, dismiss_delay: 2000
+ * })
+ * </script>
+ *
+ * Whenever the activator element is hovered, the to-reveal content will appear
+ * after a short delay. If the mouse leaves the activator or revealed content,
+ * the content will disappear after a short delay unless the mouse returns.
+ *
+ * Clicking on a link within the revealed content will dismiss the content.
+ */
+;if(jQuery) (function($){
+
+ $.fn.rolloverReveal = function(options) {
+ var $cls = arguments.callee.support;
+ $.each(this, function() { new $cls(this, options) });
+ return this;
+ }
+
+ $.fn.rolloverReveal.support = function(el, options) {
+ this.init(el, options);
+ };
+
+ $.fn.rolloverReveal.support.prototype = function() {
+
+ var option_defaults = {
+ reveal_delay: 250,
+ dismiss_delay: 500
+ };
+
+ return {
+ // Delayed execution timers.
+ timers: {},
+
+ /** Set up the object instance and event handlers for this widget. */
+ init: function(el, options) {
+ var that = this;
+ this.options = $.extend({}, option_defaults, options);
+
+ // Assign a unique ID to the element if none found.
+ if (!el.id) el.id = 'el-' +
+ (new Date()).getTime() + '-' +
+ parseInt(1000 * Math.random());
+
+ this.root = '#'+el.id;
+ this.to_reveal = $(this.root_id).find('.to-reveal');
+
+ // Wire up the event handlers for significant elements of
+ // the widget.
+ $(this.root)
+ .find('.activator')
+ .click(function() { that.toggle(); return false; })
+ .mouseover(function() { that.schedule('reveal'); that.cancel('dismiss'); })
+ .mouseout(function() { that.cancel('reveal'); that.schedule('dismiss'); })
+ .end()
+ .find('.to-reveal')
+ .mouseover(function() { that.cancel('dismiss'); })
+ .mouseout(function() { that.schedule('dismiss'); })
+ .end()
+ .find('.to-reveal a')
+ .click(function() { that.dismiss(); return true; })
+ .mouseover(function() { that.cancel('dismiss'); })
+ .mouseout(function() { that.schedule('dismiss'); })
+ .end();
+ },
+
+ /** Reveal the hidden content */
+ reveal: function() {
+ this.to_reveal.show().addClass('revealed');
+ },
+
+ /** Determine whether the hidden content is revealed */
+ revealStatus: function() {
+ return this.to_reveal.hasClass('revealed');
+ },
+
+ /** Dismiss the hidden content */
+ dismiss: function() {
+ this.to_reveal.hide().removeClass('revealed');
+ },
+
+ /** Determine whether the hidden content is hidden */
+ dismissStatus: function() {
+ return !this.to_reveal.hasClass('revealed');
+ },
+
+ /** Toggle the hide/show of the content */
+ toggle: function() {
+ return (this.revealStatus()) ?
+ this.dismiss() : this.reveal();
+ },
+
+ /** Schedule delayed execution of the given action. */
+ schedule: function(action) {
+ var that = this;
+ // Skip if the action is already in effect.
+ if (this[action+'Status']()) return;
+ // De-bounce any existing running timer.
+ this.cancel(action);
+ // Schedule a call to the given action.
+ this.timers[action] = setTimeout(function() {
+ that[action]();
+ }, this.options[action + '_delay']);
+ },
+
+ /** Cancel delayed execution of the given action. */
+ cancel: function(action) {
+ if (this.timers[action])
+ clearTimeout(this.timers[action]);
+ },
+
+ EOF:null
+ };
+ }();
+
+})(jQuery);
diff --git a/site/app/webroot/js/developers.js b/site/app/webroot/js/developers.js
index e7ef203..0e02c86 100644
--- a/site/app/webroot/js/developers.js
+++ b/site/app/webroot/js/developers.js
@@ -55,7 +55,7 @@ var upload = {
return true;
}
else {
- alert('You must select a file to upload.');
+ alert(devcp_js_upload_alert);
return false;
}
}
@@ -85,10 +85,13 @@ function iframeLoaded() {
else if (upload.response.uploadtype == 'update') {
if (upload.response.status == addon_statuses.PUBLIC) {
$('#pending-message').hide();
- $('#new-file-status').text('Public');
+ $('#new-file-status').text(addons_status_public);
+ }
+ else if (upload.response.status == addon_statuses.SANDBOX) {
+ $('#new-file-status').text(addons_status_sandbox);
}
else if (upload.response.status == addon_statuses.PENDING) {
- $('#new-file-status').text('In Sandbox; Pending Review');
+ $('#new-file-status').text(addons_status_pending);
}
$('#new-file-status').addClass('status-' + upload.response.status);
$('#new-version-number').text(upload.response.version);
@@ -99,10 +102,10 @@ function iframeLoaded() {
else if (upload.response.uploadtype == 'file') {
if (upload.response.status == addon_statuses.PUBLIC) {
$('#pending-message').hide();
- $('#new-file-status').text('Public');
+ $('#new-file-status').text(addons_status_public);
}
else if (upload.response.status == addon_statuses.PENDING) {
- $('#new-file-status').text('In Sandbox; Pending Review');
+ $('#new-file-status').text(addons_status_pending);
}
$('#new-file-status').addClass('status-' + upload.response.status);
$('#queue-count').text(upload.response.queuecount);
@@ -150,22 +153,22 @@ var addon_edit_authors = {
addAuthor: function(user_id, author, role, visible, markChanges) {
var row = '<tr><td>';
- row += '<a class="down-arrow" href="#" onclick="addon_edit_authors.moveDownRow(this); return false;"><img src="' + imageURL + '/developers/arrow_down.png" alt="Move Down" title="Move Down" /></a>';
- row += '<a class="up-arrow" href="#" onclick="addon_edit_authors.moveUpRow(this); return false;"><img src="' + imageURL + '/developers/arrow_up.png" alt="Move Up" title="Move Up" /></a>';
+ row += '<a class="down-arrow" href="#" onclick="addon_edit_authors.moveDownRow(this); return false;"><img src="' + imageURL + '/developers/arrow_down.png" alt="' + devcp_js_img_move_down + '" title="' + devcp_js_img_move_down + '" /></a>';
+ row += '<a class="up-arrow" href="#" onclick="addon_edit_authors.moveUpRow(this); return false;"><img src="' + imageURL + '/developers/arrow_up.png" alt="' + devcp_js_img_move_up + '" title="' + devcp_js_img_move_up + '" /></a>';
row += '</td><td><a href="' + profileURL + '/' + user_id + '">' + author + '</a></td><td>';
row += '<select name="data[addons_users][' + user_id + '][role]">';
- row += '<option value="' + author_roles.OWNER + '" ' + (role == author_roles.OWNER ? ' selected="selected"' : '') + '>Owner</option>';
- row += '<option value="' + author_roles.DEV + '" ' + (role == author_roles.DEV ? ' selected="selected"' : '') + '>Developer</option>';
- row += '<option value="' + author_roles.VIEWER + '" ' + (role == author_roles.VIEWER ? ' selected="selected"' : '') + '>Viewer</option>';
+ row += '<option value="' + author_roles.OWNER + '" ' + (role == author_roles.OWNER ? ' selected="selected"' : '') + '>' + devcp_js_option_owner + '</option>';
+ row += '<option value="' + author_roles.DEV + '" ' + (role == author_roles.DEV ? ' selected="selected"' : '') + '>' + devcp_js_option_developer + '</option>';
+ row += '<option value="' + author_roles.VIEWER + '" ' + (role == author_roles.VIEWER ? ' selected="selected"' : '') + '>' + devcp_js_option_viewer + '</option>';
row += '</td><td>';
- row += '<input type="checkbox" name="data[addons_users][' + user_id + '][listed]" value="1" ' + (visible == true ? ' checked="checked"' : '') + ' title="List as author in public listings"/>';
+ row += '<input type="checkbox" name="data[addons_users][' + user_id + '][listed]" value="1" ' + (visible == true ? ' checked="checked"' : '') + ' title="' + devcp_js_input_list_author + '"/>';
row += '</td><td style="width: 25px;">';
row += '<div class="inline-delete-button uses-image">';
- row += '<a href="#" onclick="addon_edit_authors.deleteAuthor(this); return false;"><img src="' + imageURL + '/developers/delete.png" alt="Remove Author" title="Remove Author" /></a>';
+ row += '<a href="#" onclick="addon_edit_authors.deleteAuthor(this); return false;"><img src="' + imageURL + '/developers/delete.png" alt="' + devcp_js_remove_author + '" title="' + devcp_js_remove_author + '" /></a>';
row += '<div class="inline-delete-box">';
- row += '<p>Are you <b>sure</b> you wish to remove this author?</p><br />';
- row += '<p><a href="#" onclick="addon_edit_authors.confirmDelete(this); return false;" class="remove-button rounded">Remove Author</a>&nbsp;&nbsp;';
- row += '<a href="#" onclick="addon_edit_authors.cancelDelete(this); return false;" class="button rounded">Cancel</a></p>';
+ row += '<p>' + devcp_js_sure_remove + '</p><br/>';
+ row += '<p><a href="#" onclick="addon_edit_authors.confirmDelete(this); return false;" class="remove-button rounded">' + devcp_js_remove_author + '</a>&nbsp;&nbsp;';
+ row += '<a href="#" onclick="addon_edit_authors.cancelDelete(this); return false;" class="button rounded">' + devcp_js_a_cancel + '</a></p>';
row += '</div></div>';
row += '</td></tr>';
@@ -239,7 +242,7 @@ var addon_edit_authors = {
return true;
}
else {
- $('#add-error').html('Please enter the account email of the author you wish to add.');
+ $('#add-error').html(devcp_js_add_email);
$('#add-error').slideDown();
return false;
}
@@ -380,7 +383,7 @@ var versions_edit = {
newRow += '<input type="hidden" name="data[Application][' + application_id + '][new]" value="1"/></td>';
newRow += '<td>' + $('#app' + application_id + '-dropdowns').html() + '</td>';
newRow += '<td style="width: 25px;"><div class="inline-delete-button">';
- newRow += '<a href="#" onclick="versions_edit.confirmDelete(this); return false;"><img src="' + imageBase + '/delete.png" alt="Remove Application Compatibility" title="Remove Application Compatibility" /></a>';
+ newRow += '<a href="#" onclick="versions_edit.confirmDelete(this); return false;"><img src="' + imageBase + '/delete.png" alt="' + devcp_js_img_remove_compat + '" title="' + devcp_js_img_remove_compat + '" /></a>';
newRow += '</div></td>';
newRow += '</tr>';
diff --git a/site/app/webroot/js/editors.js b/site/app/webroot/js/editors.js
index d6e1bba..6a00292 100644
--- a/site/app/webroot/js/editors.js
+++ b/site/app/webroot/js/editors.js
@@ -26,7 +26,7 @@ function toggleFilters() {
* editors/review *
*************************************************/
//Array of possible actions
-var actions = ['public', 'sandbox', 'superreview'];
+var actions = ['public', 'sandbox', 'info', 'superreview'];
//Simulate radio button group for action icons
function selectAction(action) {
@@ -36,34 +36,33 @@ function selectAction(action) {
//Select action and deselect other actions
for (var i = 0; i < actions.length; i++) {
if (actions[i] == action) {
- color(actions[i]);
+ changeIcon(actions[i], 'color');
document.getElementById('details-' + actions[i]).style.display = '';
}
else {
- bw(actions[i]);
+ changeIcon(actions[i], 'bw');
document.getElementById('details-' + actions[i]).style.display = 'none';
}
}
+ // when rejecting, pre-select notification box
+ $('#subscribe input').attr('checked', (action=='sandbox'));
+ // no canned responses/app/os for info request
+ if (action=='info')
+ $('#canned,#testing').hide();
+ else
+ $('#canned,#testing').show();
+
$('#subform').show('medium');
}
-//Turn an icon colored
-function color(action) {
+//Turn an icon colored/bw
+function changeIcon(action, colorbw) {
var icon = document.getElementById(action + 'Icon');
var span = document.getElementById(action);
- icon.src = '../../../../img/developers/' + action + '-color.png';
- span.className = 'action_color';
-}
-
-//Turn an icon bw
-function bw(action) {
- var icon = document.getElementById(action + 'Icon');
- var span = document.getElementById(action);
-
- icon.src = '../../../../img/developers/' + action + '-bw.png';
- span.className = 'action_bw';
+ icon.src = icon.src.substring(0, icon.src.lastIndexOf('/')+1) + action + '-' + colorbw + '.png';
+ span.className = 'action_'+colorbw;
}
//Get number of selected files
@@ -95,7 +94,13 @@ function selectedFile() {
//Validate review form
function validateReview(type) {
- if (type == 'pending') {
+ //Make sure an action was selected
+ var action = document.getElementById('actionField').value;
+ if (action == '') {
+ errors += '- ' + localized['action'] + '\n';
+ }
+
+ if (type == 'pending' && action!='info') {
//Make sure at least one file is selected
var filesSelected = selectedFileCount();
@@ -107,15 +112,11 @@ function validateReview(type) {
var errors = '';
- //Make sure an action was selected
- if (document.getElementById('actionField').value == '') {
- errors += '- ' + localized['action'] + '\n';
- }
//Make sure comments were entered
if (document.getElementById('comments').value == '') {
errors += '- ' + localized['comments'] + '\n';
}
- if (type == 'pending') {
+ if (type == 'pending' && action!='info') {
//Make sure tested operating system was entered
if (document.getElementById('ApprovalOs').value == '') {
errors += '- ' + localized['os'] + '\n';
diff --git a/site/app/webroot/js/stats/plot-selection.js b/site/app/webroot/js/stats/plot-selection.js
index 5310f32..805e3b9 100755
--- a/site/app/webroot/js/stats/plot-selection.js
+++ b/site/app/webroot/js/stats/plot-selection.js
@@ -65,9 +65,15 @@ var plotSelection = {
menu.addItem({'value': 'date', 'name': localized['statistics_js_groupby_selector_date']}).select();
menu.addItem({'value': 'week', 'name': localized['statistics_js_groupby_selector_week']});
menu.addItem({'value': 'month', 'name': localized['statistics_js_groupby_selector_month']});
+ menu.addItem({'value': 'week_over_week', 'name':localized['statistics_js_groupby_selector_week_over_week']});
$('#group-by-selector').hide();
},
+
+ getGroupByValue: function() {
+ return (!this.dropdowns['group-by-selector']) ? 'date' :
+ this.dropdowns['group-by-selector'].selectedItem.value;
+ },
addAdditionalDropdown: function() {
var type = plotSelection.dropdowns['plot-selector'].selectedItem.value;
@@ -371,4 +377,4 @@ var plotSelection = {
}
});
}
-}; \ No newline at end of file
+};
diff --git a/site/app/webroot/js/stats/plot-tables.js b/site/app/webroot/js/stats/plot-tables.js
index 51833ad..106c3e6 100644
--- a/site/app/webroot/js/stats/plot-tables.js
+++ b/site/app/webroot/js/stats/plot-tables.js
@@ -61,6 +61,12 @@ var PlotsTables = (function() {
$('#stats-table-instance').remove();
},
+ week_over_week_count_onAddMany: function(source) {
+ // Clear any existing tables when week-over-week comes up
+ $('#stats-table').hide();
+ $('#stats-table-instance').remove();
+ },
+
defined_count_onAddMany: function(source) {
// Set the URL for the download link.
diff --git a/site/app/webroot/js/stats/plots.js b/site/app/webroot/js/stats/plots.js
index 464b2c3..48f792e 100755
--- a/site/app/webroot/js/stats/plots.js
+++ b/site/app/webroot/js/stats/plots.js
@@ -7,11 +7,7 @@ var Plots = {
determinePlot: function() {
var selected = plotSelection.dropdowns['plot-selector'].selectedItem.value;
-
- // HACK: The group-by selector doesn't exist when the plot-selector is first
- // instantiated, but this method is called at that point.
- var group_by = (!plotSelection.dropdowns['group-by-selector']) ? null :
- plotSelection.dropdowns['group-by-selector'].selectedItem.value;
+ var group_by = plotSelection.getGroupByValue();
// Remove current plot selections
plotSelection.removeAll();
@@ -156,11 +152,13 @@ var Plots = {
var plotType = plotSelection.dropdowns['plot-selector'].selectedItem.value;
if (plotType == 'summary') {
+ $('#weeks-legend').hide();
$('#summary-legend').show();
$('#summary-options').show();
$('#group-by-selector').hide();
}
else {
+ $('#weeks-legend').hide();
$('#summary-legend').hide();
$('#summary-options').hide();
$('#group-by-selector').show();
@@ -231,9 +229,22 @@ var Plots = {
// If there's a value for the group-by selector, add it as a
// parameter to the CSV URL to invoke it server-side.
- var group_by = plotSelection.dropdowns['group-by-selector'].selectedItem.value;
+ var group_by = plotSelection.getGroupByValue();
+
+ if ('week_over_week' == group_by) {
+ if ('updatepings' == type || 'downloads' == type) {
+ $('#weeks-legend').show();
+ return this.plotWeekOverWeek();
+ } else {
+ // HACK: Until I can figure out how to disable the Compare
+ // by: Week option for views not supported for it
+ group_by = 'week';
+ }
+ }
+
+ $('#weeks-legend').hide();
if (group_by) Plots.currentCSV += '?group_by=' + group_by;
-
+
this.dataSources = {
'count': new Timeplot.DefaultEventSource(),
'events-firefox': new Timeplot.DefaultEventSource(),
@@ -304,7 +315,7 @@ var Plots = {
this.plot();
},
-
+
plot: function() {
var timeGeometry = new Timeplot.DefaultTimeGeometry(this.timeGeometry);
var valueGeometry = new Timeplot.DefaultValueGeometry(this.valueGeometry);
@@ -328,6 +339,172 @@ var Plots = {
Plots.timeplot.loadXML(statsURL + 'xml/events/firefox', this.dataSources['events-firefox']);
Plots.timeplot.loadXML(statsURL + 'xml/events/addon/' + addonID, this.dataSources['events-addon']);
},
+
+ /**
+ * Construct a plot consisting of 2 different weeks' data overlaid on
+ * the same graph.
+ */
+ plotWeekOverWeek: function() {
+
+ var type = plotSelection.dropdowns['plot-selector'].selectedItem.value;
+ Plots.currentCSV = statsURL + 'csv/' + addonID + '/' + type;
+
+ this.dataSources = {
+ 'count': new Timeplot.DefaultEventSource(),
+ };
+
+ PlotsTables.addListeners('week_over_week', this.dataSources);
+
+ var date_parser = Timeline.NativeDateUnit.getParser('iso8601');
+
+ // Collect Mondays from the set of available dates.
+ var available_dates = plotSelection
+ .summary[ (type=='downloads') ? 'downloads' : 'updatepings' ]
+ .availableDates;
+ var dates = [];
+ var DAY_MONDAY = 1;
+ for (idx in available_dates) {
+ // The available dates data is a little weird - it's an object
+ // with numerical properties, instead of an array.
+ if (available_dates.hasOwnProperty(idx)) {
+ var date = date_parser(available_dates[idx]);
+ if (date.getDay() == DAY_MONDAY)
+ dates.push(available_dates[idx]);
+ }
+ }
+
+ // Set up empty ranges set.
+ var ranges = {
+ week1: { min: '', max: '' },
+ week2: { min: '', max: '' }
+ };
+
+ var WEEK = ( 1000 * 60 * 60 * 24 * 7 );
+
+ if ( $('#weeks-legend .template').length ) {
+
+ // The date selection dropdowns still contain unpopulated
+ // templates, so set up the defaults and populate the dropdowns
+
+ ranges['week2']['min'] = date_parser(dates[dates.length - 1]);
+ ranges['week2']['max'] = new Date(ranges['week2']['min'].getTime() + WEEK);
+ ranges['week1']['min'] = date_parser(dates[dates.length - 2]);
+ ranges['week1']['max'] = new Date(ranges['week1']['min'].getTime() + WEEK);
+
+ var weeks = ['week1', 'week2'];
+ for (var i=0, week; week=weeks[i]; i++) {
+
+ // Convert the selection template into a concrete element
+ var tmpl = $('#'+week+'-selection select.template');
+ if (!tmpl.length) continue;
+ tmpl.remove().removeClass('template');
+
+ // Convert the current min date to string for comparison.
+ var min_str = ranges[week]['min'].strftime('%Y-%m-%d');
+
+ // Now populate the selection element with options cloned
+ // and populated from available dates.
+ var t_opt = tmpl.find('option').remove();
+ for (var j=0,date; date=dates[j]; j++) {
+ var opt = t_opt.clone();
+
+ var dp = date.split('-');
+ opt.text([dp[1], dp[2], dp[0]].join('/'))
+ .attr('value', date)
+ .appendTo(tmpl);
+
+ if (date == min_str)
+ opt.attr('selected', 'selected');
+ }
+
+ // Finally inject the populated selector into the DOM and
+ // wire up an onChange handler to reload the plot.
+ tmpl.appendTo('#'+week+'-selection')
+ .change(function() { Plots.determinePlot() });
+ }
+
+ } else {
+
+ // The date selection dropdowns are populated, so set ranges
+ // from the selected values.
+
+ var weeks = ['week1', 'week2'];
+ for (var i=0, week; week=weeks[i]; i++) {
+ var opt = $('#'+week+'-selection select')[0];
+ var date = opt.options[opt.selectedIndex].value;
+ ranges[week]['min'] = date_parser(date);
+ ranges[week]['max'] = new Date(ranges[week]['min'].getTime() + WEEK);
+ }
+
+ }
+
+ // Assemble the time geometries from the selected time ranges.
+ this.timeGeometries = {
+ 'week1': {
+ 'min': ranges['week1']['min'],
+ 'max': ranges['week1']['max'],
+ 'gridColor': '#CC6666',
+ 'axisLabelsPlacement': 'bottom'
+ },
+ 'week2': {
+ 'min': ranges['week2']['min'],
+ 'max': ranges['week2']['max'],
+ 'gridColor': '#6666CC',
+ 'axisLabelsPlacement': 'top'
+ }
+ };
+
+ // Both time ranges share the same value geometry
+ this.valueGeometry = {
+ 'gridColor': '#000000',
+ 'axisLabelsPlacement': 'left',
+ 'min': 0
+ };
+
+ // Construct the plot info structures for each of the overlaid sets.
+ Plots.newTimeplot();
+ Plots.timeplot = Timeplot.create(document.getElementById(Plots.timeplot_id), [
+ Timeplot.createPlotInfo({
+ 'id': 'week1-plot',
+ 'dataSource':
+ new Timeplot.ColumnSource(this.dataSources['count'], 1),
+ 'timeGeometry':
+ new Timeplot.DefaultTimeGeometry(this.timeGeometries['week1']),
+ 'valueGeometry':
+ new Timeplot.DefaultValueGeometry(this.valueGeometry),
+ 'showValues': true,
+ 'dotColor': '#CC6666',
+ 'dotRadius': 3.0,
+ 'lineColor': '#CC6666',
+ 'lineWidth': 3.0,
+ 'fillColor': false
+ }),
+ Timeplot.createPlotInfo({
+ 'id': 'week2-plot',
+ 'dataSource':
+ new Timeplot.ColumnSource(this.dataSources['count'], 1),
+ 'timeGeometry':
+ new Timeplot.DefaultTimeGeometry(this.timeGeometries['week2']),
+ 'valueGeometry':
+ new Timeplot.DefaultValueGeometry(this.valueGeometry),
+ 'showValues': true,
+ 'dotColor': '#6666CC',
+ 'dotRadius': 3.0,
+ 'lineColor': '#6666CC',
+ 'lineWidth': 3.0,
+ 'fillColor': false
+ })
+ ]);
+
+ // Finally, queue up a load for the plot data.
+ Plots.timeplot.loadText(
+ Plots.currentCSV,
+ ",",
+ this.dataSources['count'],
+ parseFields
+ );
+
+ },
addPlot: function(plotName, column, color) {
if (plotName in this.plotInfo)
@@ -397,4 +574,4 @@ function parseFields(data) {
}
return data;
-} \ No newline at end of file
+}
diff --git a/site/app/webroot/services/install.php b/site/app/webroot/services/install.php
index 251b790..ba70ab4 100644
--- a/site/app/webroot/services/install.php
+++ b/site/app/webroot/services/install.php
@@ -60,6 +60,7 @@
*/
define('REGEX_MOZILLA', '/^https?:\/\/[^\/]*\.?mozilla\.(com|org)\/?.*/');
define('REGEX_LOCALHOST', '/https?:\/\/[^\/]*\.?localhost.*/');
+define('REGEX_PERSONAS', '/https?:\/\/[^\/]*\.?getpersonas\.com\/?.*/');
// If an add-on's referrers property is set, defaults will not be used unless specified
$default_referrers = array('document.referrer.match('.REGEX_MOZILLA.')',
@@ -140,8 +141,17 @@ $addons = array(
/* Other */
'personas' => array(
'name' => 'Personas for Firefox',
- 'xpi' => 'https://labs.mozilla.com/projects/personas/xpi/personas-latest.xpi',
- 'icon' => 'http://labs.mozilla.com/projects/personas/images/personas_32x32.png'
+ 'xpi' => 'https://addons.mozilla.org/en-US/firefox/downloads/latest/10900',
+ 'icon' => 'https://addons.mozilla.org/en-US/firefox/images/addon_icon/10900/1236031798',
+ 'referrers' => array_merge($default_referrers, array(
+ 'document.referrer.match('.REGEX_PERSONAS.')'
+ ))
+ ),
+
+ 'weave' => array(
+ 'name' => 'Weave',
+ 'xpi' => 'https://addons.mozilla.org/en-US/firefox/downloads/latest/10868',
+ 'icon' => 'https://addons.mozilla.org/en-US/firefox/images/addon_icon/10868/1236131155'
)
);