mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 14:45:29 +00:00
+ started work on the first run experience: everything goes into a single new group, and there is an info item as well
+ Added "reset" to the dev menu so we can test first run (since the reset button is currently AWOL) + Added Utils.assertThrow(), an assert that throws an exception
This commit is contained in:
parent
6f5d3f335b
commit
3392c9ea17
256
browser/base/content/tabcandy/app/infoitems.js
Normal file
256
browser/base/content/tabcandy/app/infoitems.js
Normal file
@ -0,0 +1,256 @@
|
||||
/* ***** 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
|
||||
* Ian Gilman <ian@iangilman.com>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* 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
|
||||
|
||||
(function(){
|
||||
|
||||
// ##########
|
||||
// Class: InfoItem
|
||||
// An <Item> in TabCandy 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 group (see below)
|
||||
//
|
||||
// Possible options:
|
||||
// locked - see <Item.locked>; default is {}
|
||||
// dontPush - true if this group shouldn't push away on creation; default is false
|
||||
window.InfoItem = function(bounds, options) {
|
||||
try {
|
||||
Utils.assertThrow('bounds', isRect(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');
|
||||
|
||||
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.get(0));
|
||||
|
||||
if(this.$debug)
|
||||
this.$debug.css({zIndex: -1000});
|
||||
|
||||
// ___ Finish Up
|
||||
if(!this.locked.bounds)
|
||||
this.draggable();
|
||||
|
||||
// ___ Position
|
||||
this.snap();
|
||||
|
||||
// ___ Push other objects away
|
||||
if(!options.dontPush)
|
||||
this.pushAway();
|
||||
|
||||
this._inited = true;
|
||||
this.save();
|
||||
} catch(e){
|
||||
Utils.log(e);
|
||||
}
|
||||
};
|
||||
|
||||
// ----------
|
||||
window.InfoItem.prototype = iQ.extend(new Item(), new Subscribable(), {
|
||||
// ----------
|
||||
// Function: getStorageData
|
||||
// Returns all of the info worth storing about this item.
|
||||
getStorageData: function() {
|
||||
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 persistant storage.
|
||||
save: function() {
|
||||
try {
|
||||
if (!this._inited) // too soon to save now
|
||||
return;
|
||||
|
||||
var data = this.getStorageData();
|
||||
/*
|
||||
if(Groups.groupStorageSanity(data))
|
||||
Storage.saveGroup(Utils.getCurrentWindow(), data);
|
||||
*/
|
||||
} catch(e) {
|
||||
Utils.log(e);
|
||||
}
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: setBounds
|
||||
// Sets the bounds with the given <Rect>, animating unless "immediately" is false.
|
||||
setBounds: function(rect, immediately) {
|
||||
try {
|
||||
Utils.assertThrow('Group.setBounds: rect must be a real rectangle!', isRect(rect));
|
||||
|
||||
// ___ 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(iQ.isEmptyObject(css))
|
||||
return;
|
||||
|
||||
this.bounds = new Rect(rect);
|
||||
Utils.assertThrow('Group.setBounds: this.bounds must be a real rectangle!', isRect(this.bounds));
|
||||
|
||||
// ___ Update our representation
|
||||
if(immediately) {
|
||||
iQ(this.container).css(css);
|
||||
} else {
|
||||
TabMirror.pausePainting();
|
||||
iQ(this.container).animate(css, {
|
||||
duration: 350,
|
||||
easing: 'tabcandyBounce',
|
||||
complete: function() {
|
||||
TabMirror.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(value) {
|
||||
try {
|
||||
Utils.assertThrow('value must be a number', typeof(value) == '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() {
|
||||
try {
|
||||
this._sendOnClose();
|
||||
this.removeTrenches();
|
||||
iQ(this.container).fadeOut(function() {
|
||||
iQ(this).remove();
|
||||
Items.unsquish();
|
||||
});
|
||||
|
||||
/* Storage.deleteGroup(Utils.getCurrentWindow(), this.id); */
|
||||
} catch(e) {
|
||||
Utils.log(e);
|
||||
}
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: html
|
||||
// Sets the item's container's html to the specified value.
|
||||
html: function(value) {
|
||||
try {
|
||||
Utils.assertThrow('value must be a string', typeof(value) == 'string');
|
||||
iQ(this.container).html(value);
|
||||
} catch(e) {
|
||||
Utils.log(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
@ -859,7 +859,7 @@ window.Items = {
|
||||
getTopLevelItems: function() {
|
||||
var items = [];
|
||||
|
||||
iQ('.tab, .group').each(function() {
|
||||
iQ('.tab, .group, .info-item').each(function() {
|
||||
var $this = iQ(this);
|
||||
var item = $this.data('item');
|
||||
if(item && !item.parent && !$this.hasClass('phantom'))
|
||||
|
@ -637,16 +637,39 @@ UIClass.prototype = {
|
||||
TabItems.init();
|
||||
|
||||
if(firstTime) {
|
||||
var padding = 10;
|
||||
var infoWidth = 300;
|
||||
var infoHeight = 200;
|
||||
var pageBounds = Items.getPageBounds();
|
||||
pageBounds.inset(padding, padding);
|
||||
|
||||
// ___ make a fresh group
|
||||
var box = new Rect(pageBounds);
|
||||
box.width = Math.min(box.width * 0.667, pageBounds.width - (infoWidth + padding));
|
||||
box.height = box.height * 0.667;
|
||||
var options = {
|
||||
bounds: box
|
||||
};
|
||||
|
||||
var group = new Group([], options);
|
||||
|
||||
let items = TabItems.getItems();
|
||||
iQ.each(items, function(index, item) {
|
||||
items.forEach(function(item) {
|
||||
if(item.parent)
|
||||
item.parent.remove(item);
|
||||
|
||||
group.add(item);
|
||||
});
|
||||
|
||||
let box = Items.getPageBounds();
|
||||
box.inset(10, 10);
|
||||
let options = {padding: 10};
|
||||
Items.arrange(items, box, options);
|
||||
|
||||
// ___ make info item
|
||||
var html = '<h1>Welcome to Firefox Tab Sets</h1>'
|
||||
+ '(more goes here)';
|
||||
|
||||
box.left = box.right + padding;
|
||||
box.width = infoWidth;
|
||||
box.height = infoHeight;
|
||||
var infoItem = new InfoItem(box);
|
||||
infoItem.html(html);
|
||||
}
|
||||
|
||||
// ___ resizing
|
||||
@ -924,6 +947,11 @@ UIClass.prototype = {
|
||||
code: function() {
|
||||
location.href = 'tabcandy.html';
|
||||
}
|
||||
}, {
|
||||
name: 'reset',
|
||||
code: function() {
|
||||
self.reset();
|
||||
}
|
||||
}, {
|
||||
name: 'code docs',
|
||||
code: function() {
|
||||
|
@ -601,6 +601,26 @@ var Utils = {
|
||||
}
|
||||
},
|
||||
|
||||
// Function: assertThrow
|
||||
// Throws label as an exception if condition is false.
|
||||
assertThrow: function(label, condition) {
|
||||
if(!condition) {
|
||||
var text;
|
||||
if(typeof(label) == 'undefined')
|
||||
text = 'badly formed assert';
|
||||
else
|
||||
text = 'tabcandy assert: ' + label;
|
||||
|
||||
if(typeof(printStackTrace) == 'function') {
|
||||
var calls = printStackTrace();
|
||||
calls.splice(0, 3); // Remove this call and the printStackTrace calls
|
||||
text += '\n' + calls.join('\n');
|
||||
}
|
||||
|
||||
throw text;
|
||||
}
|
||||
},
|
||||
|
||||
expandObject: function(obj) {
|
||||
var s = obj + ' = {';
|
||||
for(prop in obj) {
|
||||
|
@ -186,6 +186,20 @@ body {
|
||||
inset rgba(255, 255, 255, 0.6) -2px 0px 0px; */
|
||||
}
|
||||
|
||||
/* InfoItems
|
||||
----------------------------------*/
|
||||
|
||||
.info-item {
|
||||
position: absolute;
|
||||
cursor: move;
|
||||
border: 1px solid rgba(230,230,230,1);
|
||||
background-color: rgba(248,248,248,1);
|
||||
-moz-border-radius: 0.4em;
|
||||
-moz-box-shadow:
|
||||
inset rgba(255, 255, 255, 0.6) 0 0 0 2px,
|
||||
rgba(0,0,0, .2) 1px 1px 4px;
|
||||
}
|
||||
|
||||
/* Trenches
|
||||
----------------------------------*/
|
||||
|
||||
|
@ -12,4 +12,5 @@
|
||||
#include app/trench.js
|
||||
#include app/tabitems.js
|
||||
#include app/groups.js
|
||||
#include app/infoitems.js
|
||||
#include app/ui.js
|
||||
|
Loading…
Reference in New Issue
Block a user