зеркало из https://github.com/mozilla/pjs.git
Bug 596075 - Move First-Run Video To Be A Tab Pointing To A Mozilla-Hosted Web Page [r=dolske, a=blocking2.0:betaN+]
--HG-- extra : rebase_source : b05376dd45ebceaadd35b6f628ba28e47037f24e
This commit is contained in:
Родитель
c73af36ea8
Коммит
2c990d33f4
|
@ -1,252 +0,0 @@
|
||||||
/* ***** BEGIN LICENSE BLOCK *****
|
|
||||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
||||||
*
|
|
||||||
* The contents of this file are subject to the Mozilla Public License Version
|
|
||||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
||||||
* the License. You may obtain a copy of the License at
|
|
||||||
* http://www.mozilla.org/MPL/
|
|
||||||
*
|
|
||||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
||||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
||||||
* for the specific language governing rights and limitations under the
|
|
||||||
* License.
|
|
||||||
*
|
|
||||||
* The Original Code is infoitems.js.
|
|
||||||
*
|
|
||||||
* The Initial Developer of the Original Code is
|
|
||||||
* the Mozilla Foundation.
|
|
||||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
|
||||||
* the Initial Developer. All Rights Reserved.
|
|
||||||
*
|
|
||||||
* Contributor(s):
|
|
||||||
* Ian Gilman <ian@iangilman.com>
|
|
||||||
* Aza Raskin <aza@mozilla.com>
|
|
||||||
* Michael Yoshitaka Erlewine <mitcho@mitcho.com>
|
|
||||||
* Ehsan Akhgari <ehsan@mozilla.com>
|
|
||||||
*
|
|
||||||
* Alternatively, the contents of this file may be used under the terms of
|
|
||||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
||||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
||||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
||||||
* of those above. If you wish to allow use of your version of this file only
|
|
||||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
||||||
* use your version of this file under the terms of the MPL, indicate your
|
|
||||||
* decision by deleting the provisions above and replace them with the notice
|
|
||||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
||||||
* the provisions above, a recipient may use your version of this file under
|
|
||||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
||||||
*
|
|
||||||
* ***** END LICENSE BLOCK ***** */
|
|
||||||
|
|
||||||
// **********
|
|
||||||
// Title: infoitems.js
|
|
||||||
|
|
||||||
// ##########
|
|
||||||
// Class: InfoItem
|
|
||||||
// An <Item> in TabView used for displaying information, such as the welcome video.
|
|
||||||
// Note that it implements the <Subscribable> interface.
|
|
||||||
//
|
|
||||||
// ----------
|
|
||||||
// Constructor: InfoItem
|
|
||||||
//
|
|
||||||
// Parameters:
|
|
||||||
// bounds - a <Rect> for where the item should be located
|
|
||||||
// options - various options for this infoItem (see below)
|
|
||||||
//
|
|
||||||
// Possible options:
|
|
||||||
// locked - see <Item.locked>; default is {}
|
|
||||||
// dontPush - true if this infoItem shouldn't push away on creation; default is false
|
|
||||||
// immediately - place the item immediately, without animation
|
|
||||||
function InfoItem(bounds, options) {
|
|
||||||
try {
|
|
||||||
Utils.assertThrow(Utils.isRect(bounds), 'bounds');
|
|
||||||
|
|
||||||
if (typeof options == 'undefined')
|
|
||||||
options = {};
|
|
||||||
|
|
||||||
this._inited = false;
|
|
||||||
this.isAnInfoItem = true;
|
|
||||||
this.defaultSize = bounds.size();
|
|
||||||
this.locked = (options.locked ? Utils.copy(options.locked) : {});
|
|
||||||
this.bounds = new Rect(bounds);
|
|
||||||
this.isDragging = false;
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
var $container = iQ('<div>')
|
|
||||||
.addClass('info-item')
|
|
||||||
.css(this.bounds)
|
|
||||||
.appendTo('body');
|
|
||||||
|
|
||||||
this.$contents = iQ('<div>')
|
|
||||||
.appendTo($container);
|
|
||||||
|
|
||||||
var $close = iQ('<div>')
|
|
||||||
.addClass('close')
|
|
||||||
.click(function() {
|
|
||||||
self.close();
|
|
||||||
})
|
|
||||||
.appendTo($container);
|
|
||||||
|
|
||||||
// ___ locking
|
|
||||||
if (this.locked.bounds)
|
|
||||||
$container.css({cursor: 'default'});
|
|
||||||
|
|
||||||
if (this.locked.close)
|
|
||||||
$close.hide();
|
|
||||||
|
|
||||||
// ___ Superclass initialization
|
|
||||||
this._init($container[0]);
|
|
||||||
|
|
||||||
if (this.$debug)
|
|
||||||
this.$debug.css({zIndex: -1000});
|
|
||||||
|
|
||||||
// ___ Finish Up
|
|
||||||
if (!this.locked.bounds)
|
|
||||||
this.draggable();
|
|
||||||
|
|
||||||
// ___ Position
|
|
||||||
if (!options.dontPush)
|
|
||||||
this.snap(options.immediately);
|
|
||||||
|
|
||||||
this._inited = true;
|
|
||||||
this.save();
|
|
||||||
} catch(e) {
|
|
||||||
Utils.log(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
InfoItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
// Function: getStorageData
|
|
||||||
// Returns all of the info worth storing about this item.
|
|
||||||
getStorageData: function InfoItem_getStorageData() {
|
|
||||||
var data = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
data = {
|
|
||||||
bounds: this.getBounds(),
|
|
||||||
locked: Utils.copy(this.locked)
|
|
||||||
};
|
|
||||||
} catch(e) {
|
|
||||||
Utils.log(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
},
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
// Function: save
|
|
||||||
// Saves this item to persistent storage.
|
|
||||||
save: function InfoItem_save() {
|
|
||||||
try {
|
|
||||||
if (!this._inited) // too soon to save now
|
|
||||||
return;
|
|
||||||
|
|
||||||
var data = this.getStorageData();
|
|
||||||
|
|
||||||
} catch(e) {
|
|
||||||
Utils.log(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
// Function: setBounds
|
|
||||||
// Sets the bounds with the given <Rect>, animating unless "immediately" is false.
|
|
||||||
setBounds: function InfoItem_setBounds(rect, immediately) {
|
|
||||||
try {
|
|
||||||
Utils.assertThrow(Utils.isRect(rect), 'InfoItem.setBounds: rect must be a real rectangle!');
|
|
||||||
|
|
||||||
// ___ Determine what has changed
|
|
||||||
var css = {};
|
|
||||||
|
|
||||||
if (rect.left != this.bounds.left)
|
|
||||||
css.left = rect.left;
|
|
||||||
|
|
||||||
if (rect.top != this.bounds.top)
|
|
||||||
css.top = rect.top;
|
|
||||||
|
|
||||||
if (rect.width != this.bounds.width)
|
|
||||||
css.width = rect.width;
|
|
||||||
|
|
||||||
if (rect.height != this.bounds.height)
|
|
||||||
css.height = rect.height;
|
|
||||||
|
|
||||||
if (Utils.isEmptyObject(css))
|
|
||||||
return;
|
|
||||||
|
|
||||||
this.bounds = new Rect(rect);
|
|
||||||
Utils.assertThrow(Utils.isRect(this.bounds),
|
|
||||||
'InfoItem.setBounds: this.bounds must be a real rectangle!');
|
|
||||||
|
|
||||||
// ___ Update our representation
|
|
||||||
if (immediately) {
|
|
||||||
iQ(this.container).css(css);
|
|
||||||
} else {
|
|
||||||
TabItems.pausePainting();
|
|
||||||
iQ(this.container).animate(css, {
|
|
||||||
duration: 350,
|
|
||||||
easing: "tabviewBounce",
|
|
||||||
complete: function() {
|
|
||||||
TabItems.resumePainting();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this._updateDebugBounds();
|
|
||||||
this.setTrenches(rect);
|
|
||||||
this.save();
|
|
||||||
} catch(e) {
|
|
||||||
Utils.log(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
// Function: setZ
|
|
||||||
// Set the Z order for the item's container.
|
|
||||||
setZ: function InfoItem_setZ(value) {
|
|
||||||
try {
|
|
||||||
Utils.assertThrow(typeof value == 'number', 'value must be a number');
|
|
||||||
|
|
||||||
this.zIndex = value;
|
|
||||||
|
|
||||||
iQ(this.container).css({zIndex: value});
|
|
||||||
|
|
||||||
if (this.$debug)
|
|
||||||
this.$debug.css({zIndex: value + 1});
|
|
||||||
} catch(e) {
|
|
||||||
Utils.log(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
// Function: close
|
|
||||||
// Closes the item.
|
|
||||||
close: function InfoItem_close() {
|
|
||||||
try {
|
|
||||||
this._sendToSubscribers("close");
|
|
||||||
this.removeTrenches();
|
|
||||||
iQ(this.container).fadeOut(function() {
|
|
||||||
iQ(this).remove();
|
|
||||||
Items.unsquish();
|
|
||||||
});
|
|
||||||
|
|
||||||
} catch(e) {
|
|
||||||
Utils.log(e);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// ----------
|
|
||||||
// Function: html
|
|
||||||
// Sets the item's container's html to the specified value.
|
|
||||||
html: function InfoItem_html(value) {
|
|
||||||
try {
|
|
||||||
Utils.assertThrow(typeof value == 'string', 'value must be a string');
|
|
||||||
this.$contents.html(value);
|
|
||||||
} catch(e) {
|
|
||||||
Utils.log(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -52,8 +52,5 @@ XPCOMUtils.defineLazyGetter(this, "gPrivateBrowsing", function() {
|
||||||
#include tabitems.js
|
#include tabitems.js
|
||||||
#include drag.js
|
#include drag.js
|
||||||
#include trench.js
|
#include trench.js
|
||||||
#include infoitems.js
|
|
||||||
#include ui.js
|
#include ui.js
|
||||||
#include search.js
|
#include search.js
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -249,16 +249,19 @@ let UI = {
|
||||||
// Resets the Panorama view to have just one group with all tabs
|
// Resets the Panorama view to have just one group with all tabs
|
||||||
// and, if firstTime == true, add the welcome video/tab
|
// and, if firstTime == true, add the welcome video/tab
|
||||||
reset: function UI_reset(firstTime) {
|
reset: function UI_reset(firstTime) {
|
||||||
let padding = 10;
|
let padding = Trenches.defaultRadius;
|
||||||
let infoWidth = 350;
|
let welcomeWidth = 300;
|
||||||
let infoHeight = 232;
|
|
||||||
let pageBounds = Items.getPageBounds();
|
let pageBounds = Items.getPageBounds();
|
||||||
pageBounds.inset(padding, padding);
|
pageBounds.inset(padding, padding);
|
||||||
|
|
||||||
|
let $actions = iQ("#actions");
|
||||||
|
if ($actions)
|
||||||
|
pageBounds.width -= $actions.width();
|
||||||
|
|
||||||
// ___ make a fresh groupItem
|
// ___ make a fresh groupItem
|
||||||
let box = new Rect(pageBounds);
|
let box = new Rect(pageBounds);
|
||||||
box.width =
|
box.width = Math.min(box.width * 0.667,
|
||||||
Math.min(box.width * 0.667, pageBounds.width - (infoWidth + padding));
|
pageBounds.width - (welcomeWidth + padding));
|
||||||
box.height = box.height * 0.667;
|
box.height = box.height * 0.667;
|
||||||
|
|
||||||
GroupItems.groupItems.forEach(function(group) {
|
GroupItems.groupItems.forEach(function(group) {
|
||||||
|
@ -280,17 +283,18 @@ let UI = {
|
||||||
if (firstTime) {
|
if (firstTime) {
|
||||||
gPrefBranch.setBoolPref("experienced_first_run", true);
|
gPrefBranch.setBoolPref("experienced_first_run", true);
|
||||||
|
|
||||||
// ___ make info item
|
let url = gPrefBranch.getCharPref("welcome_url");
|
||||||
let video =
|
let newTab = gBrowser.loadOneTab(url, {inBackground: true});
|
||||||
"http://videos-cdn.mozilla.net/firefox4beta/tabcandy_howto.webm";
|
let newTabItem = newTab.tabItem;
|
||||||
let html =
|
let parent = newTabItem.parent;
|
||||||
"<div class='intro'>"
|
Utils.assert(parent, "should have a parent");
|
||||||
+ "<video src='" + video + "' width='100%' preload controls>"
|
|
||||||
+ "</div>";
|
newTabItem.parent.remove(newTabItem);
|
||||||
let infoBox = new Rect(box.right + padding, box.top,
|
let aspect = TabItems.tabHeight / TabItems.tabWidth;
|
||||||
infoWidth, infoHeight);
|
let welcomeBounds = new Rect(box.right + padding, box.top,
|
||||||
let infoItem = new InfoItem(infoBox);
|
welcomeWidth, welcomeWidth * aspect);
|
||||||
infoItem.html(html);
|
newTabItem.setBounds(welcomeBounds, true);
|
||||||
|
GroupItems.setActiveGroupItem(groupItem);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -35,15 +35,8 @@
|
||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
let newWin;
|
let newWin;
|
||||||
let prefService;
|
|
||||||
|
|
||||||
function test() {
|
function test() {
|
||||||
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||||
prefService =
|
|
||||||
Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).
|
|
||||||
getBranch("browser.panorama.");
|
|
||||||
// make sure we don't trigger the 'first run' behavior
|
|
||||||
prefService.setBoolPref("experienced_first_run", true);
|
|
||||||
|
|
||||||
waitForExplicitFinish();
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
@ -104,7 +97,6 @@ function test() {
|
||||||
is(contentWindow.GroupItems.getOrphanedTabs().length, 0, "No orphan tabs");
|
is(contentWindow.GroupItems.getOrphanedTabs().length, 0, "No orphan tabs");
|
||||||
|
|
||||||
// clean up and finish
|
// clean up and finish
|
||||||
prefService.setBoolPref("experienced_first_run", false);
|
|
||||||
newWin.close();
|
newWin.close();
|
||||||
|
|
||||||
finish();
|
finish();
|
||||||
|
|
|
@ -44,8 +44,10 @@ function test() {
|
||||||
|
|
||||||
ok(!TabView.isVisible(), "Main window TabView is hidden");
|
ok(!TabView.isVisible(), "Main window TabView is hidden");
|
||||||
|
|
||||||
|
ok(experienced(), "should start as experienced");
|
||||||
|
|
||||||
prefsBranch.setBoolPref("experienced_first_run", false);
|
prefsBranch.setBoolPref("experienced_first_run", false);
|
||||||
ok(!experienced(), "not experienced");
|
ok(!experienced(), "set to not experienced");
|
||||||
|
|
||||||
newWindowWithTabView(checkFirstRun, part2);
|
newWindowWithTabView(checkFirstRun, part2);
|
||||||
}
|
}
|
||||||
|
@ -58,11 +60,14 @@ function experienced() {
|
||||||
function checkFirstRun(win) {
|
function checkFirstRun(win) {
|
||||||
let contentWindow = win.document.getElementById("tab-view").contentWindow;
|
let contentWindow = win.document.getElementById("tab-view").contentWindow;
|
||||||
|
|
||||||
let infoItems = contentWindow.iQ(".info-item");
|
is(win.gBrowser.tabs.length, 2, "There should be two tabs");
|
||||||
is(infoItems.length, 1, "There should be an info item");
|
|
||||||
|
|
||||||
let groupItems = contentWindow.GroupItems.groupItems;
|
let groupItems = contentWindow.GroupItems.groupItems;
|
||||||
is(groupItems.length, 1, "There should be one group");
|
is(groupItems.length, 1, "There should be one group");
|
||||||
|
is(groupItems[0].getChildren().length, 1, "...with one child");
|
||||||
|
|
||||||
|
let orphanTabCount = contentWindow.GroupItems.getOrphanedTabs().length;
|
||||||
|
is(orphanTabCount, 1, "There should also be an orphaned tab");
|
||||||
|
|
||||||
ok(experienced(), "we're now experienced");
|
ok(experienced(), "we're now experienced");
|
||||||
}
|
}
|
||||||
|
@ -74,12 +79,19 @@ function part2() {
|
||||||
function checkNotFirstRun(win) {
|
function checkNotFirstRun(win) {
|
||||||
let contentWindow = win.document.getElementById("tab-view").contentWindow;
|
let contentWindow = win.document.getElementById("tab-view").contentWindow;
|
||||||
|
|
||||||
let infoItems = contentWindow.iQ(".info-item");
|
is(win.gBrowser.tabs.length, 1, "There should be one tab");
|
||||||
is(infoItems.length, 0, "There should be no info items");
|
|
||||||
|
let groupItems = contentWindow.GroupItems.groupItems;
|
||||||
|
is(groupItems.length, 1, "There should be one group");
|
||||||
|
is(groupItems[0].getChildren().length, 1, "...with one child");
|
||||||
|
|
||||||
|
let orphanTabCount = contentWindow.GroupItems.getOrphanedTabs().length;
|
||||||
|
is(orphanTabCount, 0, "There should also be no orphaned tabs");
|
||||||
}
|
}
|
||||||
|
|
||||||
function endGame() {
|
function endGame() {
|
||||||
ok(!TabView.isVisible(), "Main window TabView is still hidden");
|
ok(!TabView.isVisible(), "Main window TabView is still hidden");
|
||||||
|
ok(experienced(), "should finish as experienced");
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
pref("startup.homepage_override_url","http://www.mozilla.org/projects/%APP%/%VERSION%/whatsnew/");
|
pref("startup.homepage_override_url","http://www.mozilla.org/projects/%APP%/%VERSION%/whatsnew/");
|
||||||
pref("startup.homepage_welcome_url","http://www.mozilla.org/projects/%APP%/%VERSION%/firstrun/");
|
pref("startup.homepage_welcome_url","http://www.mozilla.org/projects/%APP%/%VERSION%/firstrun/");
|
||||||
|
pref("browser.panorama.welcome_url", "http://www.mozilla.com/firefox/panorama/");
|
||||||
// The time interval between checks for a new version (in seconds)
|
// The time interval between checks for a new version (in seconds)
|
||||||
// nightly=8 hours, official=24 hours
|
// nightly=8 hours, official=24 hours
|
||||||
pref("app.update.interval", 28800);
|
pref("app.update.interval", 28800);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
pref("startup.homepage_override_url","http://www.mozilla.org/projects/%APP%/%VERSION%/whatsnew/");
|
pref("startup.homepage_override_url","http://www.mozilla.org/projects/%APP%/%VERSION%/whatsnew/");
|
||||||
pref("startup.homepage_welcome_url","http://www.mozilla.org/projects/%APP%/%VERSION%/firstrun/");
|
pref("startup.homepage_welcome_url","http://www.mozilla.org/projects/%APP%/%VERSION%/firstrun/");
|
||||||
|
pref("browser.panorama.welcome_url", "http://www.mozilla.com/firefox/panorama/");
|
||||||
// The time interval between checks for a new version (in seconds)
|
// The time interval between checks for a new version (in seconds)
|
||||||
// nightly=8 hours, official=24 hours
|
// nightly=8 hours, official=24 hours
|
||||||
pref("app.update.interval", 28800);
|
pref("app.update.interval", 28800);
|
||||||
|
|
|
@ -360,6 +360,7 @@ user_pref("network.http.prompt-temp-redirect", false);
|
||||||
user_pref("media.cache_size", 100);
|
user_pref("media.cache_size", 100);
|
||||||
user_pref("security.warn_viewing_mixed", false);
|
user_pref("security.warn_viewing_mixed", false);
|
||||||
user_pref("app.update.enabled", false);
|
user_pref("app.update.enabled", false);
|
||||||
|
user_pref("browser.panorama.experienced_first_run", true); // Assume experienced
|
||||||
|
|
||||||
// Only load extensions from the application and user profile
|
// Only load extensions from the application and user profile
|
||||||
// AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
|
// AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
pref("startup.homepage_override_url","http://www.mozilla.com/%LOCALE%/%APP%/%VERSION%/whatsnew/");
|
pref("startup.homepage_override_url","http://www.mozilla.com/%LOCALE%/%APP%/%VERSION%/whatsnew/");
|
||||||
pref("startup.homepage_welcome_url","http://www.mozilla.com/%LOCALE%/%APP%/%VERSION%/firstrun/");
|
pref("startup.homepage_welcome_url","http://www.mozilla.com/%LOCALE%/%APP%/%VERSION%/firstrun/");
|
||||||
|
pref("browser.panorama.welcome_url", "http://www.mozilla.com/firefox/panorama/");
|
||||||
// Interval: Time between checks for a new version (in seconds)
|
// Interval: Time between checks for a new version (in seconds)
|
||||||
// nightly=6 hours, official=24 hours
|
// nightly=6 hours, official=24 hours
|
||||||
pref("app.update.interval", 86400);
|
pref("app.update.interval", 86400);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче