mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
First commit.
This commit is contained in:
commit
f90716db0f
BIN
browser/base/content/tabcandy/.DS_Store
vendored
Normal file
BIN
browser/base/content/tabcandy/.DS_Store
vendored
Normal file
Binary file not shown.
191
browser/base/content/tabcandy/app/ui.js
Normal file
191
browser/base/content/tabcandy/app/ui.js
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
(function(){
|
||||||
|
|
||||||
|
$.expr[':'].icontains = function(obj, index, meta, stack){
|
||||||
|
return (obj.textContent || obj.innerText || jQuery(obj).text() || '').toLowerCase().indexOf(meta[3].toLowerCase()) >= 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
Navbar = {
|
||||||
|
get el(){
|
||||||
|
var win = Utils.activeWindow;
|
||||||
|
var navbar = win.gBrowser.ownerDocument.getElementById("navigator-toolbox");
|
||||||
|
return navbar;
|
||||||
|
},
|
||||||
|
show: function(){ this.el.collapsed = false; },
|
||||||
|
hide: function(){ this.el.collapsed = true;}
|
||||||
|
}
|
||||||
|
|
||||||
|
var Tabbar = {
|
||||||
|
get el(){ return window.Tabs[0].raw.parentNode; },
|
||||||
|
hide: function(){ this.el.collapsed = true },
|
||||||
|
show: function(){ this.el.collapsed = false }
|
||||||
|
}
|
||||||
|
|
||||||
|
var Page = {
|
||||||
|
init: function(){
|
||||||
|
var isDragging = false;
|
||||||
|
|
||||||
|
var zIndex = 100;
|
||||||
|
function mod($div){
|
||||||
|
$div.draggable({
|
||||||
|
start:function(){ isDragging = true; },
|
||||||
|
stop: function(){
|
||||||
|
isDragging = false;
|
||||||
|
$(this).css({zIndex: zIndex});
|
||||||
|
zIndex += 1;
|
||||||
|
},
|
||||||
|
zIndex: 999,
|
||||||
|
}).mouseup(function(e){
|
||||||
|
if( e.target.className == "close" ){
|
||||||
|
$(this).find("canvas").data("link").tab.close(); }
|
||||||
|
else {
|
||||||
|
if( !isDragging ){
|
||||||
|
Navbar.show();
|
||||||
|
$(this).find("canvas").data("link").tab.focus();
|
||||||
|
} else {
|
||||||
|
$(this).find("canvas").data("link").tab.raw.pos = $(this).position();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("<div class='close'>x</div>").appendTo($div)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
window.TabMirror.customize(mod);
|
||||||
|
|
||||||
|
Utils.homeTab.raw.maxWidth = 60;
|
||||||
|
Utils.homeTab.raw.minWidth = 60;
|
||||||
|
|
||||||
|
Tabs.onClose(function(){
|
||||||
|
Utils.homeTab.focus();
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
|
||||||
|
$("#tabbar").toggle(
|
||||||
|
function(){Tabbar.hide()},
|
||||||
|
function(){Tabbar.show()}
|
||||||
|
)
|
||||||
|
|
||||||
|
Page.initSearch();
|
||||||
|
},
|
||||||
|
|
||||||
|
initSearch: function(){
|
||||||
|
$search = $(".search input");
|
||||||
|
$search.val("").focus();
|
||||||
|
$search.keydown(function(evt){
|
||||||
|
|
||||||
|
if( evt.which == 13 ){
|
||||||
|
|
||||||
|
Navbar.show();
|
||||||
|
|
||||||
|
if ($(".tab:not(.unhighlight)").length == 1) {
|
||||||
|
$(".tab:not(.unhighlight)").find("canvas").data("link").tab.focus();
|
||||||
|
} else {
|
||||||
|
Tabs.open( "http://google.com/search?q=" + $search.val() ).focus();
|
||||||
|
}
|
||||||
|
$search.val("")
|
||||||
|
$(".tab .name").parent().removeClass("unhighlight");
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$search.keyup(function(evt){
|
||||||
|
var $found = $(".tab .name:not(:icontains(" + $search.val() + "))").parent();
|
||||||
|
if( $search.val().length > 1 ){
|
||||||
|
$found.addClass("unhighlight");
|
||||||
|
$(".tab .name:icontains(" + $search.val() + ")").parent().removeClass("unhighlight");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$(".tab .name").parent().removeClass("unhighlight");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log( $found.length );
|
||||||
|
if ( $found.length == 1 ) {
|
||||||
|
$found.animate({top:0, left:0})
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Utils.homeTab.onFocus(function(){
|
||||||
|
$search.val("").focus();
|
||||||
|
Navbar.hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(window).blur(function(){
|
||||||
|
Navbar.show();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function ArrangeClass(name, func){ this.init(name, func); };
|
||||||
|
ArrangeClass.prototype = {
|
||||||
|
init: function(name, func){
|
||||||
|
this.$el = this._create(name);
|
||||||
|
this.arrange = func;
|
||||||
|
if(func) this.$el.click(func);
|
||||||
|
},
|
||||||
|
|
||||||
|
_create: function(name){
|
||||||
|
return $("<a href='#'/>").text(name).appendTo("#actions");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var anim = new ArrangeClass("Anim", function(){
|
||||||
|
if( $("canvas:visible").eq(9).height() < 300 )
|
||||||
|
$("canvas:visible").eq(9).data("link").animate({height:500}, 500);
|
||||||
|
else
|
||||||
|
$("canvas:visible").eq(9).data("link").animate({height:120}, 500);
|
||||||
|
|
||||||
|
$("canvas:visible").eq(9).css({zIndex:99999});
|
||||||
|
})
|
||||||
|
|
||||||
|
var grid = new ArrangeClass("Grid", function(){
|
||||||
|
var x = 10;
|
||||||
|
var y = 100;
|
||||||
|
$(".tab:visible").each(function(i){
|
||||||
|
$el = $(this);
|
||||||
|
|
||||||
|
var oldPos = $el.find("canvas").data("link").tab.raw.pos;
|
||||||
|
if( oldPos ){
|
||||||
|
$el.css({top:oldPos.top, left:oldPos.left});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$el.css({top: y,left: x});
|
||||||
|
x += $el.width() + 10;
|
||||||
|
if( x > window.innerWidth - $el.width() ){
|
||||||
|
x = 10;
|
||||||
|
y += $el.height() + 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var Arrange = {
|
||||||
|
init: function(){
|
||||||
|
grid.arrange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function UIClass(){ this.init(); };
|
||||||
|
UIClass.prototype = {
|
||||||
|
navbar: Navbar,
|
||||||
|
tabbar: Tabbar,
|
||||||
|
init: function(){
|
||||||
|
Page.init();
|
||||||
|
Arrange.init();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var UI = new UIClass();
|
||||||
|
window.UI = UI;
|
||||||
|
window.aza = ArrangeClass
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
218
browser/base/content/tabcandy/core/mirror.js
Normal file
218
browser/base/content/tabcandy/core/mirror.js
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
(function(){
|
||||||
|
|
||||||
|
const Cc = Components.classes;
|
||||||
|
const Ci = Components.interfaces;
|
||||||
|
const Cu = Components.utils;
|
||||||
|
const Cr = Components.results;
|
||||||
|
|
||||||
|
function _isIframe(doc){
|
||||||
|
var win = doc.defaultView;
|
||||||
|
return win.parent != win;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var TabCanvas = function(tab, canvas){ this.init(tab, canvas) }
|
||||||
|
TabCanvas.prototype = {
|
||||||
|
init: function(tab, canvas){
|
||||||
|
this.tab = tab;
|
||||||
|
this.canvas = canvas;
|
||||||
|
this.window = window;
|
||||||
|
|
||||||
|
this.RATE_LIMIT = 250; // To refresh the thumbnail any faster than this. In ms.
|
||||||
|
this.lastDraw = null;
|
||||||
|
|
||||||
|
$(canvas).data("link", this);
|
||||||
|
|
||||||
|
var w = $(canvas).width();
|
||||||
|
var h = $(canvas).height();
|
||||||
|
$(canvas).attr({width:w, height:h});
|
||||||
|
|
||||||
|
this.paint(null);
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
var paintIt = function(evt){self.onPaint(evt) };
|
||||||
|
|
||||||
|
// Don't mirror chrome tabs.
|
||||||
|
if( window.location.protocol == "chrome:" ) return;
|
||||||
|
|
||||||
|
|
||||||
|
tab.contentWindow.addEventListener("MozAfterPaint", paintIt, false);
|
||||||
|
$(window).unload(function(){
|
||||||
|
tab.contentWindow.removeEventListener("MozAfterPaint", paintIt, false);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
paint: function(evt){
|
||||||
|
var $ = this.window.$;
|
||||||
|
if( $ == null ) return;
|
||||||
|
var $canvas = $(this.canvas);
|
||||||
|
var ctx = this.canvas.getContext("2d");
|
||||||
|
|
||||||
|
var w = $canvas.width();
|
||||||
|
var h = $canvas.height();
|
||||||
|
|
||||||
|
var fromWin = this.tab.contentWindow;
|
||||||
|
if( fromWin == null || fromWin.location.protocol == "chrome:") return;
|
||||||
|
var scaler = w/fromWin.innerWidth;
|
||||||
|
|
||||||
|
// TODO: Potentially only redraw the dirty rect? (Is it worth it?)
|
||||||
|
var now = new Date();
|
||||||
|
if( this.lastDraw == null || now - this.lastDraw > this.RATE_LIMIT ){
|
||||||
|
var startTime = new Date();
|
||||||
|
ctx.save();
|
||||||
|
ctx.scale(scaler, scaler);
|
||||||
|
ctx.drawWindow( fromWin, fromWin.scrollX, fromWin.scrollY, w/scaler, h/scaler, "#fff" );
|
||||||
|
ctx.restore();
|
||||||
|
var elapsed = (new Date()) - startTime;
|
||||||
|
Utils.logger.log( this.window.location.host + " " + elapsed );
|
||||||
|
this.lastDraw = new Date();
|
||||||
|
}
|
||||||
|
ctx.restore();
|
||||||
|
},
|
||||||
|
|
||||||
|
onPaint: function(evt){
|
||||||
|
this.paint(evt);
|
||||||
|
},
|
||||||
|
|
||||||
|
animate: function(options, duration){
|
||||||
|
var self = this;
|
||||||
|
if( duration == null ) duration = 0;
|
||||||
|
|
||||||
|
var $canvas = $(this.canvas);
|
||||||
|
var w = $canvas.width();
|
||||||
|
var h = $canvas.height();
|
||||||
|
|
||||||
|
var newW = (w/h)*options.height;
|
||||||
|
var newH = options.height;
|
||||||
|
|
||||||
|
$canvas.width(w);
|
||||||
|
$canvas.height(h);
|
||||||
|
$canvas.animate({width:newW, height:newH}, duration, function(){
|
||||||
|
$canvas.attr("width", newW);
|
||||||
|
$canvas.attr("height", newH);
|
||||||
|
self.paint(null);
|
||||||
|
} );
|
||||||
|
this.paint(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var TabMirror = function( ){ this.init() }
|
||||||
|
TabMirror.prototype = {
|
||||||
|
init: function(){
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
// When a tab is updated, update the mirror
|
||||||
|
Tabs.onReady( function(evt){
|
||||||
|
self.update(evt.tab);
|
||||||
|
});
|
||||||
|
|
||||||
|
// When a tab is closed, unlink.
|
||||||
|
Tabs.onClose( function(){
|
||||||
|
self.unlink(this);
|
||||||
|
});
|
||||||
|
|
||||||
|
// For each tab, create the link.
|
||||||
|
Tabs.forEach(function(tab){
|
||||||
|
self.link(tab);
|
||||||
|
});
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
_getEl: function(tab){
|
||||||
|
mirror = null;
|
||||||
|
$(".tab").each(function(){
|
||||||
|
if( $(this).data("tab") == tab ){
|
||||||
|
mirror = this;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return mirror;
|
||||||
|
},
|
||||||
|
|
||||||
|
_customize: function(func){
|
||||||
|
// pass
|
||||||
|
// This gets set by add-ons/extensions to MirrorTab
|
||||||
|
},
|
||||||
|
|
||||||
|
_createEl: function(tab){
|
||||||
|
var div = $("<div class='tab'><span class='name'> </span><img class='fav'/><canvas class='thumb'/></div>")
|
||||||
|
.data("tab", tab)
|
||||||
|
.appendTo("body");
|
||||||
|
|
||||||
|
if( tab.url.match("chrome:") ){
|
||||||
|
div.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._customize(div);
|
||||||
|
|
||||||
|
function updateAttributes(){
|
||||||
|
var iconUrl = tab.raw.linkedBrowser.mIconURL;
|
||||||
|
var label = tab.raw.label;
|
||||||
|
$fav = $('.fav', div)
|
||||||
|
$name = $('.name', div);
|
||||||
|
|
||||||
|
if(iconUrl != $fav.attr("src")) $fav.attr("src", iconUrl);
|
||||||
|
if( $name.text() != label ) $name.text(label);
|
||||||
|
}
|
||||||
|
|
||||||
|
var timer = setInterval( updateAttributes, 500 );
|
||||||
|
div.data("timer", timer);
|
||||||
|
|
||||||
|
this._updateEl(tab);
|
||||||
|
},
|
||||||
|
|
||||||
|
_updateEl: function(tab){
|
||||||
|
var el = this._getEl(tab);
|
||||||
|
|
||||||
|
new TabCanvas(tab, $('.thumb', el).get(0) );
|
||||||
|
},
|
||||||
|
|
||||||
|
update: function(tab){
|
||||||
|
var doc = tab.contentDocument;
|
||||||
|
this.link(tab);
|
||||||
|
|
||||||
|
if( !_isIframe(doc) ){
|
||||||
|
this._updateEl(tab);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
link: function(tab){
|
||||||
|
// Don't add duplicates
|
||||||
|
var dup = this._getEl(tab)
|
||||||
|
if( dup ) return false;
|
||||||
|
|
||||||
|
/*// Don't do anything that starts with a chrome URL
|
||||||
|
if( tab.contentWindow.location.protocol == "chrome:" ){
|
||||||
|
return false;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Add the tab to the page
|
||||||
|
this._createEl(tab);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
unlink: function(tab){
|
||||||
|
$(".tab").each(function(){
|
||||||
|
if( $(this).data("tab") == tab ){
|
||||||
|
clearInterval( $(this).data("timer") );
|
||||||
|
$(this).remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
new TabMirror()
|
||||||
|
window.TabMirror = {}
|
||||||
|
window.TabMirror.customize = function(func){
|
||||||
|
// Apply the custom handlers to all existing elements
|
||||||
|
// TODO: Make this modular: so that it only exists in one place.
|
||||||
|
// No breaking DRY!
|
||||||
|
func($("div.tab"));
|
||||||
|
|
||||||
|
// Apply it to all future elements.
|
||||||
|
TabMirror.prototype._customize = func;
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
551
browser/base/content/tabcandy/core/tabs.js
Normal file
551
browser/base/content/tabcandy/core/tabs.js
Normal file
@ -0,0 +1,551 @@
|
|||||||
|
(function(){
|
||||||
|
|
||||||
|
|
||||||
|
const Cc = Components.classes;
|
||||||
|
const Ci = Components.interfaces;
|
||||||
|
const Cu = Components.utils;
|
||||||
|
const Cr = Components.results;
|
||||||
|
|
||||||
|
|
||||||
|
var XULApp = {
|
||||||
|
appWindowType: "navigator:browser",
|
||||||
|
tabStripForWindow: function(aWindow) {
|
||||||
|
return aWindow.document.getElementById("content").mStrip;
|
||||||
|
},
|
||||||
|
openTab: function(aUrl, aInBackground) {
|
||||||
|
var window = this.mostRecentAppWindow;
|
||||||
|
var tabbrowser = window.getBrowser();
|
||||||
|
var tab = tabbrowser.addTab(aUrl);
|
||||||
|
if (!aInBackground)
|
||||||
|
tabbrowser.selectedTab = tab;
|
||||||
|
},
|
||||||
|
getBrowserFromContentWindow: function(aMainWindow, aWindow) {
|
||||||
|
var browsers = aMainWindow.gBrowser.browsers;
|
||||||
|
for (var i = 0; i < browsers.length; i++) {
|
||||||
|
if (browsers[i].contentWindow == aWindow)
|
||||||
|
return browsers[i];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function Dictionary() {
|
||||||
|
var keys = [];
|
||||||
|
var values = [];
|
||||||
|
|
||||||
|
this.set = function set(key, value) {
|
||||||
|
var id = keys.indexOf(key);
|
||||||
|
if (id == -1) {
|
||||||
|
keys.push(key);
|
||||||
|
values.push(value);
|
||||||
|
} else
|
||||||
|
values[id] = value;
|
||||||
|
};
|
||||||
|
|
||||||
|
this.get = function get(key, defaultValue) {
|
||||||
|
if (defaultValue === undefined)
|
||||||
|
defaultValue = null;
|
||||||
|
var id = keys.indexOf(key);
|
||||||
|
if (id == -1)
|
||||||
|
return defaultValue;
|
||||||
|
return values[id];
|
||||||
|
};
|
||||||
|
|
||||||
|
this.remove = function remove(key) {
|
||||||
|
var id = keys.indexOf(key);
|
||||||
|
if (id == -1)
|
||||||
|
throw new Error("object not in dictionary: " + key);
|
||||||
|
keys.splice(id, 1);
|
||||||
|
values.splice(id, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
var readOnlyKeys = new ImmutableArray(keys);
|
||||||
|
var readOnlyValues = new ImmutableArray(values);
|
||||||
|
|
||||||
|
this.__defineGetter__("keys", function() { return readOnlyKeys; });
|
||||||
|
this.__defineGetter__("values", function() { return readOnlyValues; });
|
||||||
|
this.__defineGetter__("length", function() { return keys.length; });
|
||||||
|
}
|
||||||
|
|
||||||
|
function ImmutableArray(baseArray) {
|
||||||
|
var self = this;
|
||||||
|
var UNSUPPORTED_MUTATOR_METHODS = ["pop", "push", "reverse", "shift",
|
||||||
|
"sort", "splice", "unshift"];
|
||||||
|
UNSUPPORTED_MUTATOR_METHODS.forEach(
|
||||||
|
function(methodName) {
|
||||||
|
self[methodName] = function() {
|
||||||
|
throw new Error("Mutator method '" + methodName + "()' is " +
|
||||||
|
"unsupported on this object.");
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
self.toString = function() { return "[ImmutableArray]"; };
|
||||||
|
|
||||||
|
self.__proto__ = baseArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
function WindowWatcher() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
var observer = {
|
||||||
|
observe: function(window, event) {
|
||||||
|
if (event == "domwindowopened") {
|
||||||
|
if (self.onWindowOpened)
|
||||||
|
self.onWindowOpened(window);
|
||||||
|
} else
|
||||||
|
if (self.onWindowClosed)
|
||||||
|
self.onWindowClosed(window);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"]
|
||||||
|
.getService(Ci.nsIWindowWatcher);
|
||||||
|
ww.registerNotification(observer);
|
||||||
|
|
||||||
|
Extension.addUnloadMethod(
|
||||||
|
this,
|
||||||
|
function() {
|
||||||
|
ww.unregisterNotification(observer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// When this object is instantiated, the given onLoad() is called for
|
||||||
|
// all browser windows, and subsequently for all newly-opened browser
|
||||||
|
// windows. When a browser window closes, onUnload() is called.
|
||||||
|
// onUnload() is also called once for each browser window when the
|
||||||
|
// extension is unloaded.
|
||||||
|
|
||||||
|
function BrowserWatcher(options) {
|
||||||
|
var pendingHandlers = [];
|
||||||
|
|
||||||
|
function makeSafeFunc(func) {
|
||||||
|
function safeFunc(window) {
|
||||||
|
try {
|
||||||
|
func(window);
|
||||||
|
} catch (e) {
|
||||||
|
Utils.logger.log(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return safeFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addUnloader(chromeWindow, func) {
|
||||||
|
function onUnload() {
|
||||||
|
chromeWindow.removeEventListener("unload", onUnload, false);
|
||||||
|
pendingHandlers.splice(pendingHandlers.indexOf(onUnload), 1);
|
||||||
|
func(chromeWindow);
|
||||||
|
}
|
||||||
|
pendingHandlers.push(onUnload);
|
||||||
|
chromeWindow.addEventListener("unload", onUnload, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadAndBind(chromeWindow) {
|
||||||
|
if (options.onLoad)
|
||||||
|
(makeSafeFunc(options.onLoad))(chromeWindow);
|
||||||
|
if (options.onUnload)
|
||||||
|
addUnloader(chromeWindow, makeSafeFunc(options.onUnload));
|
||||||
|
}
|
||||||
|
|
||||||
|
var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
|
||||||
|
.getService(Ci.nsIWindowMediator);
|
||||||
|
|
||||||
|
var enumerator = wm.getEnumerator(XULApp.appWindowType);
|
||||||
|
|
||||||
|
while (enumerator.hasMoreElements()) {
|
||||||
|
var chromeWindow = enumerator.getNext();
|
||||||
|
if (chromeWindow.gIsDoneLoading)
|
||||||
|
loadAndBind(chromeWindow);
|
||||||
|
else
|
||||||
|
onWindowOpened(chromeWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onWindowOpened(chromeWindow) {
|
||||||
|
function removeListener() {
|
||||||
|
chromeWindow.removeEventListener("load", onLoad, false);
|
||||||
|
pendingHandlers.splice(pendingHandlers.indexOf(removeListener), 1);
|
||||||
|
}
|
||||||
|
function onLoad() {
|
||||||
|
removeListener();
|
||||||
|
var type = chromeWindow.document.documentElement
|
||||||
|
.getAttribute("windowtype");
|
||||||
|
if (type == XULApp.appWindowType)
|
||||||
|
loadAndBind(chromeWindow);
|
||||||
|
}
|
||||||
|
chromeWindow.addEventListener("load", onLoad, false);
|
||||||
|
pendingHandlers.push(removeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ww = new WindowWatcher();
|
||||||
|
ww.onWindowOpened = onWindowOpened;
|
||||||
|
|
||||||
|
Extension.addUnloadMethod(
|
||||||
|
this,
|
||||||
|
function() {
|
||||||
|
ww.unload();
|
||||||
|
var handlers = pendingHandlers.slice();
|
||||||
|
handlers.forEach(function(handler) { handler(); });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var Extension = {
|
||||||
|
// === {{{Extension.addUnloadMethod()}}} ===
|
||||||
|
//
|
||||||
|
// This attaches a given method called 'unload' to the given object.
|
||||||
|
// The method is also tied to the Extension page's lifetime, so if
|
||||||
|
// the unload method isn't called before the page is unloaded, it is
|
||||||
|
// called at that time. This helps ensure both that memory leaks
|
||||||
|
// don't propagate past Extension page reloads, and it can also help
|
||||||
|
// developers find objects that aren't being properly cleaned up
|
||||||
|
// before the page is unloaded.
|
||||||
|
|
||||||
|
addUnloadMethod: function addUnloadMethod(obj, unloader) {
|
||||||
|
function unloadWrapper() {
|
||||||
|
window.removeEventListener("unload", unloadWrapper, true);
|
||||||
|
unloader.apply(obj, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener("unload", unloadWrapper, true);
|
||||||
|
|
||||||
|
obj.unload = unloadWrapper;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function EventListenerMixIns(mixInto) {
|
||||||
|
var mixIns = {};
|
||||||
|
|
||||||
|
this.add = function add(options) {
|
||||||
|
if (mixIns) {
|
||||||
|
if (options.name in mixIns)
|
||||||
|
Utils.logging.log("mixIn for", options.name, "already exists.");
|
||||||
|
options.mixInto = mixInto;
|
||||||
|
mixIns[options.name] = new EventListenerMixIn(options);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.bubble = function bubble(name, target, event) {
|
||||||
|
if (mixIns)
|
||||||
|
mixIns[name].trigger(target, event);
|
||||||
|
};
|
||||||
|
|
||||||
|
Extension.addUnloadMethod(
|
||||||
|
this,
|
||||||
|
function() {
|
||||||
|
for (name in mixIns) {
|
||||||
|
mixIns[name].unload();
|
||||||
|
delete mixIns[name];
|
||||||
|
}
|
||||||
|
mixIns = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function EventListenerMixIn(options) {
|
||||||
|
var listeners = [];
|
||||||
|
|
||||||
|
function onEvent(event, target) {
|
||||||
|
if (listeners) {
|
||||||
|
if (options.filter)
|
||||||
|
event = options.filter.call(this, event);
|
||||||
|
if (event) {
|
||||||
|
if (!target)
|
||||||
|
target = options.mixInto;
|
||||||
|
var listenersCopy = listeners.slice();
|
||||||
|
for (var i = 0; i < listenersCopy.length; i++)
|
||||||
|
try {
|
||||||
|
listenersCopy[i].call(target, event);
|
||||||
|
} catch (e) {
|
||||||
|
Utils.logger.log(e);
|
||||||
|
}
|
||||||
|
if (options.bubbleTo)
|
||||||
|
options.bubbleTo.bubble(options.name, target, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
options.mixInto[options.name] = function bind(cb) {
|
||||||
|
if (typeof(cb) != "function")
|
||||||
|
Utils.logging.log("Callback must be a function.");
|
||||||
|
if (listeners)
|
||||||
|
listeners.push(cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
options.mixInto[options.name].unbind = function unbind(cb) {
|
||||||
|
if (listeners) {
|
||||||
|
var index = listeners.indexOf(cb);
|
||||||
|
if (index != -1)
|
||||||
|
listeners.splice(index, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.trigger = function trigger(target, event) {
|
||||||
|
onEvent(event, target);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (options.observe)
|
||||||
|
options.observe.addEventListener(options.eventName,
|
||||||
|
onEvent,
|
||||||
|
options.useCapture);
|
||||||
|
|
||||||
|
Extension.addUnloadMethod(
|
||||||
|
this,
|
||||||
|
function() {
|
||||||
|
listeners = null;
|
||||||
|
if (options.observe)
|
||||||
|
options.observe.removeEventListener(options.eventName,
|
||||||
|
onEvent,
|
||||||
|
options.useCapture);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function Tabs() {
|
||||||
|
var trackedWindows = new Dictionary();
|
||||||
|
var trackedTabs = new Dictionary();
|
||||||
|
|
||||||
|
var windows = {
|
||||||
|
get focused() {
|
||||||
|
var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
|
||||||
|
.getService(Ci.nsIWindowMediator);
|
||||||
|
var chromeWindow = wm.getMostRecentWindow("navigator:browser");
|
||||||
|
if (chromeWindow)
|
||||||
|
return trackedWindows.get(chromeWindow);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
windows.__proto__ = trackedWindows.values;
|
||||||
|
|
||||||
|
var tabs = {
|
||||||
|
get focused() {
|
||||||
|
var browserWindow = windows.focused;
|
||||||
|
if (browserWindow)
|
||||||
|
return browserWindow.getFocusedTab();
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
open: function open(url) {
|
||||||
|
var browserWindow = windows.focused;
|
||||||
|
// TODO: What to do if we have no focused window?
|
||||||
|
// make a new one?
|
||||||
|
return browserWindow.addTab(url);
|
||||||
|
},
|
||||||
|
toString: function toString() {
|
||||||
|
return "[Tabs]";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var tabsMixIns = new EventListenerMixIns(tabs);
|
||||||
|
tabsMixIns.add({name: "onReady"});
|
||||||
|
tabsMixIns.add({name: "onFocus"});
|
||||||
|
tabsMixIns.add({name: "onClose"});
|
||||||
|
tabsMixIns.add({name: "onOpen"});
|
||||||
|
|
||||||
|
tabs.__proto__ = trackedTabs.values;
|
||||||
|
|
||||||
|
function newBrowserTab(tabbrowser, chromeTab) {
|
||||||
|
var browserTab = new BrowserTab(tabbrowser, chromeTab);
|
||||||
|
trackedTabs.set(chromeTab, browserTab);
|
||||||
|
return browserTab;
|
||||||
|
}
|
||||||
|
|
||||||
|
function unloadBrowserTab(chromeTab) {
|
||||||
|
var browserTab = trackedTabs.get(chromeTab);
|
||||||
|
trackedTabs.remove(chromeTab);
|
||||||
|
browserTab._unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function BrowserWindow(chromeWindow) {
|
||||||
|
var tabbrowser = chromeWindow.getBrowser();
|
||||||
|
|
||||||
|
for (var i = 0; i < tabbrowser.tabContainer.itemCount; i++)
|
||||||
|
newBrowserTab(tabbrowser,
|
||||||
|
tabbrowser.tabContainer.getItemAtIndex(i));
|
||||||
|
|
||||||
|
const EVENTS_TO_WATCH = ["TabOpen", "TabMove", "TabClose", "TabSelect"];
|
||||||
|
|
||||||
|
function onEvent(event) {
|
||||||
|
// TODO: For some reason, exceptions that are raised outside of this
|
||||||
|
// function get eaten, rather than logged, so we're adding our own
|
||||||
|
// error logging here.
|
||||||
|
try {
|
||||||
|
// This is a XUL <tab> element of class tabbrowser-tab.
|
||||||
|
var chromeTab = event.originalTarget;
|
||||||
|
|
||||||
|
switch (event.type) {
|
||||||
|
case "TabSelect":
|
||||||
|
break;
|
||||||
|
case "TabOpen":
|
||||||
|
newBrowserTab(tabbrowser, chromeTab);
|
||||||
|
tabsMixIns.bubble("onOpen",
|
||||||
|
trackedTabs.get(chromeTab),
|
||||||
|
true);
|
||||||
|
break;
|
||||||
|
case "TabMove":
|
||||||
|
break;
|
||||||
|
case "TabClose":
|
||||||
|
tabsMixIns.bubble("onClose",
|
||||||
|
trackedTabs.get(chromeTab),
|
||||||
|
true);
|
||||||
|
unloadBrowserTab(chromeTab);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
Utils.logger.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EVENTS_TO_WATCH.forEach(
|
||||||
|
function(eventType) {
|
||||||
|
tabbrowser.addEventListener(eventType, onEvent, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.addTab = function addTab(url) {
|
||||||
|
var chromeTab = tabbrowser.addTab(url);
|
||||||
|
// The TabOpen event has just been triggered, so we
|
||||||
|
// just need to fetch it from our dictionary now.
|
||||||
|
return trackedTabs.get(chromeTab);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.getFocusedTab = function getFocusedTab() {
|
||||||
|
return trackedTabs.get(tabbrowser.selectedTab);
|
||||||
|
};
|
||||||
|
|
||||||
|
Extension.addUnloadMethod(
|
||||||
|
this,
|
||||||
|
function() {
|
||||||
|
EVENTS_TO_WATCH.forEach(
|
||||||
|
function(eventType) {
|
||||||
|
tabbrowser.removeEventListener(eventType, onEvent, true);
|
||||||
|
});
|
||||||
|
for (var i = 0; i < tabbrowser.tabContainer.itemCount; i++)
|
||||||
|
unloadBrowserTab(tabbrowser.tabContainer.getItemAtIndex(i));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function BrowserTab(tabbrowser, chromeTab) {
|
||||||
|
var browser = chromeTab.linkedBrowser;
|
||||||
|
|
||||||
|
var mixIns = new EventListenerMixIns(this);
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
mixIns.add(
|
||||||
|
{name: "onReady",
|
||||||
|
observe: browser,
|
||||||
|
eventName: "DOMContentLoaded",
|
||||||
|
useCapture: true,
|
||||||
|
bubbleTo: tabsMixIns,
|
||||||
|
filter: function(event) {
|
||||||
|
// Return the document that just loaded.
|
||||||
|
event.tab = self;
|
||||||
|
return event;
|
||||||
|
}});
|
||||||
|
|
||||||
|
mixIns.add(
|
||||||
|
{name: "onFocus",
|
||||||
|
observe: chromeTab,
|
||||||
|
eventName: "TabSelect",
|
||||||
|
useCapture: true,
|
||||||
|
bubbleTo: tabsMixIns,
|
||||||
|
filter: function(event) {
|
||||||
|
// There's not really much to report here other
|
||||||
|
// than the Tab itself, but that's already the
|
||||||
|
// 'this' variable, so just return true for now.
|
||||||
|
return true;
|
||||||
|
}});
|
||||||
|
|
||||||
|
this.__proto__ = {
|
||||||
|
get isClosed() { return (browser == null); },
|
||||||
|
|
||||||
|
get url() {
|
||||||
|
if (browser && browser.currentURI)
|
||||||
|
return browser.currentURI.spec;
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
get favicon() {
|
||||||
|
if (chromeTab && chromeTab.image) {
|
||||||
|
return chromeTab.image;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
get contentWindow() {
|
||||||
|
if (browser && browser.contentWindow)
|
||||||
|
return browser.contentWindow;
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
get contentDocument() {
|
||||||
|
if (browser && browser.contentDocument)
|
||||||
|
return browser.contentDocument;
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
get raw() { return chromeTab; },
|
||||||
|
|
||||||
|
focus: function focus() {
|
||||||
|
if (browser)
|
||||||
|
tabbrowser.selectedTab = chromeTab;
|
||||||
|
},
|
||||||
|
|
||||||
|
close: function close() {
|
||||||
|
if (browser)
|
||||||
|
browser.contentWindow.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
toString: function toString() {
|
||||||
|
if (!browser)
|
||||||
|
return "[Closed Browser Tab]";
|
||||||
|
else
|
||||||
|
return "[Browser Tab]";
|
||||||
|
},
|
||||||
|
|
||||||
|
_unload: function _unload() {
|
||||||
|
mixIns.unload();
|
||||||
|
mixIns = null;
|
||||||
|
tabbrowser = null;
|
||||||
|
chromeTab = null;
|
||||||
|
browser = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var browserWatcher = new BrowserWatcher(
|
||||||
|
{onLoad: function(chromeWindow) {
|
||||||
|
var trackedWindow = trackedWindows.get(chromeWindow);
|
||||||
|
if (!trackedWindow)
|
||||||
|
trackedWindows.set(chromeWindow,
|
||||||
|
new BrowserWindow(chromeWindow));
|
||||||
|
},
|
||||||
|
onUnload: function(chromeWindow) {
|
||||||
|
var browserWindow = trackedWindows.get(chromeWindow);
|
||||||
|
trackedWindows.remove(chromeWindow);
|
||||||
|
browserWindow.unload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.__defineGetter__("tabs", function() { return tabs; });
|
||||||
|
|
||||||
|
Extension.addUnloadMethod(
|
||||||
|
this,
|
||||||
|
function() {
|
||||||
|
tabsMixIns.unload();
|
||||||
|
browserWatcher.unload();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Tabs = new Tabs().tabs;
|
||||||
|
})();
|
48
browser/base/content/tabcandy/core/utils.js
Normal file
48
browser/base/content/tabcandy/core/utils.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
(function(){
|
||||||
|
|
||||||
|
const Cc = Components.classes;
|
||||||
|
const Ci = Components.interfaces;
|
||||||
|
const Cu = Components.utils;
|
||||||
|
const Cr = Components.results;
|
||||||
|
|
||||||
|
// Get this in a way where we can load the page automatically
|
||||||
|
// where it doesn't need to be focused...
|
||||||
|
var homeWindow = Cc["@mozilla.org/embedcomp/window-watcher;1"]
|
||||||
|
.getService(Ci.nsIWindowWatcher)
|
||||||
|
.activeWindow;
|
||||||
|
|
||||||
|
var Utils = {
|
||||||
|
get activeWindow(){
|
||||||
|
var win = Cc["@mozilla.org/embedcomp/window-watcher;1"]
|
||||||
|
.getService(Ci.nsIWindowWatcher)
|
||||||
|
.activeWindow;
|
||||||
|
|
||||||
|
if( win != null ) return win;
|
||||||
|
else return homeWindow;
|
||||||
|
},
|
||||||
|
|
||||||
|
get activeTab(){
|
||||||
|
var tabBrowser = this.activeWindow.gBrowser;
|
||||||
|
return tabBrowser.selectedTab;
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
get homeTab(){
|
||||||
|
for( var i=0; i<Tabs.length; i++){
|
||||||
|
if(Tabs[i].contentWindow.location.host == "tabcandy"){
|
||||||
|
return Tabs[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
get logger(){
|
||||||
|
return homeWindow.Firebug.Console
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Utils = Utils;
|
||||||
|
|
||||||
|
})();
|
298
browser/base/content/tabcandy/jquery-ui.js
vendored
Executable file
298
browser/base/content/tabcandy/jquery-ui.js
vendored
Executable file
File diff suppressed because one or more lines are too long
19
browser/base/content/tabcandy/jquery.js
vendored
Executable file
19
browser/base/content/tabcandy/jquery.js
vendored
Executable file
File diff suppressed because one or more lines are too long
15
browser/base/content/tabcandy/overlay.js
Normal file
15
browser/base/content/tabcandy/overlay.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
var tabcandy = {
|
||||||
|
onLoad: function() {
|
||||||
|
// initialization code
|
||||||
|
this.initialized = true;
|
||||||
|
this.strings = document.getElementById("tabcandy-strings");
|
||||||
|
},
|
||||||
|
onMenuItemCommand: function(e) {
|
||||||
|
var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
|
||||||
|
.getService(Components.interfaces.nsIPromptService);
|
||||||
|
promptService.alert(window, this.strings.getString("helloMessageTitle"),
|
||||||
|
this.strings.getString("helloMessage"));
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
window.addEventListener("load", function(e) { tabcandy.onLoad(e); }, false);
|
50
browser/base/content/tabcandy/pixastic.js
Normal file
50
browser/base/content/tabcandy/pixastic.js
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* Pixastic - JavaScript Image Processing Library
|
||||||
|
* Copyright (c) 2008 Jacob Seidelin, jseidelin@nihilogic.dk, http://blog.nihilogic.dk/
|
||||||
|
* MIT License [http://www.nihilogic.dk/licenses/mit-license.txt]
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
var Pixastic=(function(){function addEvent(el,event,handler){if(el.addEventListener)
|
||||||
|
el.addEventListener(event,handler,false);else if(el.attachEvent)
|
||||||
|
el.attachEvent("on"+event,handler);}
|
||||||
|
function onready(handler){var handlerDone=false;var execHandler=function(){if(!handlerDone){handlerDone=true;handler();}}
|
||||||
|
document.write("<"+"script defer src=\"//:\" id=\"__onload_ie_sumbox__\"></"+"script>");var script=document.getElementById("__onload_ie_sumbox__");script.onreadystatechange=function(){if(script.readyState=="complete"){script.parentNode.removeChild(script);execHandler();}}
|
||||||
|
if(document.addEventListener)
|
||||||
|
document.addEventListener("DOMContentLoaded",execHandler,false);addEvent(window,"load",execHandler);}
|
||||||
|
function init(){if(!Pixastic.parseOnLoad)return;var imgEls=getElementsByClass("pixastic",null,"img");var canvasEls=getElementsByClass("pixastic",null,"canvas");var elements=imgEls.concat(canvasEls);for(var i=0;i<elements.length;i++){(function(){var el=elements[i];var actions=[];var classes=el.className.split(" ");for(var c=0;c<classes.length;c++){var cls=classes[c];if(cls.substring(0,9)=="pixastic-"){var actionName=cls.substring(9);if(actionName!="")
|
||||||
|
actions.push(actionName);}}
|
||||||
|
if(actions.length){if(el.tagName=="IMG"){var dataImg=new Image();dataImg.src=el.src;if(dataImg.complete){for(var a=0;a<actions.length;a++){var res=Pixastic.applyAction(el,el,actions[a],null);if(res)
|
||||||
|
el=res;}}else{dataImg.onload=function(){for(var a=0;a<actions.length;a++){var res=Pixastic.applyAction(el,el,actions[a],null)
|
||||||
|
if(res)
|
||||||
|
el=res;}}}}else{setTimeout(function(){for(var a=0;a<actions.length;a++){var res=Pixastic.applyAction(el,el,actions[a],null);if(res)
|
||||||
|
el=res;}},1);}}})();}}
|
||||||
|
onready(init);function getElementsByClass(searchClass,node,tag){var classElements=new Array();if(node==null)
|
||||||
|
node=document;if(tag==null)
|
||||||
|
tag='*';var els=node.getElementsByTagName(tag);var elsLen=els.length;var pattern=new RegExp("(^|\\s)"+searchClass+"(\\s|$)");for(i=0,j=0;i<elsLen;i++){if(pattern.test(els[i].className)){classElements[j]=els[i];j++;}}
|
||||||
|
return classElements;}
|
||||||
|
var debugElement;function writeDebug(text,level){if(!Pixastic.debug)return;try{switch(level){case"warn":console.warn("Pixastic:",text);break;case"error":console.error("Pixastic:",text);break;default:console.log("Pixastic:",text);}}catch(e){}
|
||||||
|
if(!debugElement){}}
|
||||||
|
return{parseOnLoad:false,debug:false,applyAction:function(img,dataImg,actionName,options){options=options||{};var imageIsCanvas=(img.tagName=="CANVAS");if(imageIsCanvas&&Pixastic.Client.isIE()){if(Pixastic.debug)writeDebug("Tried to process a canvas element but browser is IE.");return false;}
|
||||||
|
var canvas,ctx;if(Pixastic.Client.hasCanvas()){canvas=document.createElement("canvas");ctx=canvas.getContext("2d");}
|
||||||
|
var w=parseInt(img.offsetWidth);var h=parseInt(img.offsetHeight);if(actionName.indexOf("(")>-1){var tmp=actionName;actionName=tmp.substr(0,tmp.indexOf("("));var arg=tmp.match(/\((.*?)\)/);if(arg[1]){arg=arg[1].split(";");for(var a=0;a<arg.length;a++){thisArg=arg[a].split("=");if(thisArg.length==2){if(thisArg[0]=="rect"){var rectVal=thisArg[1].split(",");options[thisArg[0]]={left:parseInt(rectVal[0],10)||0,top:parseInt(rectVal[1],10)||0,width:parseInt(rectVal[2],10)||0,height:parseInt(rectVal[3],10)||0}}else{options[thisArg[0]]=thisArg[1];}}}}}
|
||||||
|
if(!options.rect){options.rect={left:0,top:0,width:w,height:h};}
|
||||||
|
var validAction=false;if(Pixastic.Actions[actionName]&&typeof Pixastic.Actions[actionName].process=="function"){validAction=true;}
|
||||||
|
if(!validAction){if(Pixastic.debug)writeDebug("Invalid action \""+actionName+"\". Maybe file not included?");return false;}
|
||||||
|
if(!Pixastic.Actions[actionName].checkSupport()){if(Pixastic.debug)writeDebug("Action \""+actionName+"\" not supported by this browser.");return false;}
|
||||||
|
if(Pixastic.Client.hasCanvas()){canvas.width=w;canvas.height=h;canvas.style.width=w+"px";canvas.style.height=h+"px";ctx.drawImage(dataImg,0,0,w,h);}
|
||||||
|
var params={image:img,canvas:canvas,width:w,height:h,useData:true,options:options}
|
||||||
|
var res=Pixastic.Actions[actionName].process(params);if(!res){return false;}
|
||||||
|
if(Pixastic.Client.hasCanvas()){if(params.useData){if(Pixastic.Client.hasCanvasImageData()){canvas.getContext("2d").putImageData(params.canvasData,options.rect.left,options.rect.top);canvas.getContext("2d").fillRect(0,0,0,0);}}
|
||||||
|
canvas.title=img.title;canvas.imgsrc=img.imgsrc;if(!imageIsCanvas)canvas.alt=img.alt;if(!imageIsCanvas)canvas.imgsrc=img.src;canvas.className=img.className;if(img.getAttribute("style"))
|
||||||
|
canvas.setAttribute("style",img.getAttribute("style"));canvas.cssText=img.cssText;canvas.name=img.name;canvas.tabIndex=img.tabIndex;canvas.id=img.id;if(img.parentNode&&img.parentNode.replaceChild){img.parentNode.replaceChild(canvas,img);}
|
||||||
|
return canvas;}
|
||||||
|
return img;},prepareData:function(params,getCopy){var ctx=params.canvas.getContext("2d");var rect=params.options.rect;var dataDesc=ctx.getImageData(rect.left,rect.top,rect.width,rect.height);var data=dataDesc.data;if(!getCopy)params.canvasData=dataDesc;return data;},process:function(img,actionName,options,callback)
|
||||||
|
{if(img.tagName=="IMG"){var dataImg=new Image();dataImg.src=img.src;if(dataImg.complete){var res=Pixastic.applyAction(img,dataImg,actionName,options);if(callback)callback(res);return res;}else{dataImg.onload=function(){var res=Pixastic.applyAction(img,dataImg,actionName,options)
|
||||||
|
if(callback)callback(res);}}}
|
||||||
|
if(img.tagName=="CANVAS"){var res=Pixastic.applyAction(img,img,actionName,options);if(callback)callback(res);return res;}},Client:{hasCanvas:(function(){var c=document.createElement("canvas");var val=false;try{val=!!((typeof c.getContext=="function")&&c.getContext("2d"));}catch(e){}
|
||||||
|
return function(){return val;}})(),hasCanvasImageData:(function(){var c=document.createElement("canvas");var val=false;var ctx;try{if(typeof c.getContext=="function"&&(ctx=c.getContext("2d"))){val=(typeof ctx.getImageData=="function");}}catch(e){}
|
||||||
|
return function(){return val;}})(),isIE:function(){return!!document.all&&!!window.attachEvent&&!window.opera;}},Actions:{}}})();if(typeof jQuery!="undefined"&&jQuery&&jQuery.fn){jQuery.fn.pixastic=function(action,options){var newElements=[];this.each(function(){if(this.tagName=="IMG"&&!this.complete){return;}
|
||||||
|
var res=Pixastic.process(this,action,options);if(res){newElements.push(res);}});if(newElements.length>0)
|
||||||
|
return jQuery(newElements);else
|
||||||
|
return this;};};Pixastic.Actions.desaturate={process:function(params){var useAverage=!!params.options.average;if(Pixastic.Client.hasCanvasImageData()){var data=Pixastic.prepareData(params);var rect=params.options.rect;var w=rect.width;var h=rect.height;var w4=w*4;var y=h;do{var offsetY=(y-1)*w4;var x=w;do{var offset=offsetY+(x-1)*4;var brightness=useAverage?(data[offset]+data[offset+1]+data[offset+2])/3:(data[offset]*0.3+data[offset+1]*0.59+data[offset+2]*0.11);data[offset]=data[offset+1]=data[offset+2]=brightness;}while(--x);}while(--y);return true;}else if(Pixastic.Client.isIE()){params.image.style.filter+=" gray";return true;}},checkSupport:function(){return(Pixastic.Client.hasCanvasImageData()||Pixastic.Client.isIE());}}
|
BIN
browser/themes/pinstripe/browser/tabcandy/tabcandy.png
Normal file
BIN
browser/themes/pinstripe/browser/tabcandy/tabcandy.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
BIN
content/.DS_Store
vendored
Normal file
BIN
content/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
content/icon.png
Normal file
BIN
content/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
117
content/tab.html
Normal file
117
content/tab.html
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||||
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
|
||||||
|
<head>
|
||||||
|
<title>Switch</title>
|
||||||
|
<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
|
||||||
|
<link rel="icon" href="chrome://abouttab/content/tabcandy.png"/>
|
||||||
|
<style media="screen" type="text/css">
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: Geneva;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab{
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
float:left;
|
||||||
|
margin: 10px;
|
||||||
|
padding: 0;
|
||||||
|
background-color: rgba(255,255,255,.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.fav{
|
||||||
|
position: absolute;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background-color: rgba(255,255,255,.8);
|
||||||
|
-moz-border-radius: 0 0 5px 0;
|
||||||
|
padding: 3px;
|
||||||
|
-moz-box-shadow: 1px 1px 3px rgba(0,0,0,.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb{
|
||||||
|
width: 160px;
|
||||||
|
height: 120px;
|
||||||
|
background-color: #ccc;
|
||||||
|
-moz-box-shadow: 1px 1px 10px rgba(0,0,0,.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb:hover{
|
||||||
|
-moz-box-shadow: 1px 1px 10px rgba(0,0,0,.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.name{
|
||||||
|
font-size: 9px;
|
||||||
|
display:block;
|
||||||
|
width:160px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.name:before{
|
||||||
|
display:inline-block;
|
||||||
|
height:12px;
|
||||||
|
width:20px;
|
||||||
|
content:" ";
|
||||||
|
position: absolute;
|
||||||
|
right:0px;
|
||||||
|
background: -moz-linear-gradient(0deg, rgba(255,255,255,0), white);
|
||||||
|
}
|
||||||
|
|
||||||
|
.close{
|
||||||
|
position: absolute;
|
||||||
|
top:12px; right:0;
|
||||||
|
margin: 1px;
|
||||||
|
width:12px; height:12px;
|
||||||
|
background-color: rgba(0,0,0,.6);
|
||||||
|
font-size: 10px;
|
||||||
|
text-align: center;
|
||||||
|
line-height:13px;
|
||||||
|
color: #DDD;
|
||||||
|
cursor: pointer;
|
||||||
|
-moz-border-radius: 10px;
|
||||||
|
-moz-box-shadow: inset 1px 1px 0px rgba(0,0,0,.5), inset -1px -1px 0px rgba(255,255,255,.5);
|
||||||
|
text-shadow: 1px 1px 1px rgba(0,0,0,.5);
|
||||||
|
font-family: Helvetica;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.search{width:100%; margin-top: 30px; text-align: center; margin-bottom: 30px;}
|
||||||
|
.search input{ width: 300px; font-size: 16pt;}
|
||||||
|
|
||||||
|
#actions{
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
right: 5px;
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unhighlight{
|
||||||
|
opacity: .1;
|
||||||
|
z-index: -100;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="search">
|
||||||
|
<input type="text"/>
|
||||||
|
</div>
|
||||||
|
<div id="actions">
|
||||||
|
<a id="tabbar" href="#">Toggle Tab Bar</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript;version=1.8" src="chrome://tabcandy/content/js/jquery.js"></script>
|
||||||
|
<script type="text/javascript;version=1.8" src="chrome://tabcandy/content/js/jquery-ui.js"></script>
|
||||||
|
<script type="text/javascript;version=1.8" src="chrome://tabcandy/content/js/utils.js"></script>
|
||||||
|
<script type="text/javascript;version=1.8" src="chrome://tabcandy/content/js/tabs.js"></script>
|
||||||
|
<script type="text/javascript;version=1.8" src="chrome://tabcandy/content/js/mirror.js"></script>
|
||||||
|
<script type="text/javascript;version=1.8" src="chrome://tabcandy/content/js/ui.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user