Skip to content

Instantly share code, notes, and snippets.

@teramako
Created March 27, 2009 15:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save teramako/86748 to your computer and use it in GitHub Desktop.
Save teramako/86748 to your computer and use it in GitHub Desktop.
let PLUGIN_INFO =
<VimperatorPlugin>
<name>{NAME}</name>
<description>like Growl (xul version)</description>
<require type="plugin">notifier.js</require>
<version>0.1</version>
<minVersion>2.0pre</minVersion>
<maxVersion>2.0</maxVersion>
<detail><![CDATA[
popup alert like Growl
]]></detail>
</VimperatorPlugin>;
liberator.plugins.xulGrowl = (function(){
let notifier = liberator.plugins.notifier;
if (!notifier){
return;
}
let count = 0;
let xulNS = new Namespace("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
let xhtmlNS = new Namespace("http://www.w3.org/1999/xhtml");
function xmlToDom(xml, xmlns){
if (!xmlns) xmlns = xulNS;
XML.ignoreWhitespace = true;
XML.prettyPrinting = false;
var doc = (new DOMParser).parseFromString('<box xmlns="' + xmlns + '">' + xml.toXMLString() + "</box>", "application/xml")
var imported = document.importNode(doc.documentElement, true);
var range = document.createRange();
range.selectNodeContents(imported);
var fragment = range.extractContents();
range.detach();
return fragment.childNodes.length > 1 ? fragment : fragment.firstChild;
}
/**
* Growl Message Class
* @param {String} title
* @param {String} message(HTML string)
* @param {String} link
*/
function GrowlMessage(){
this.init.apply(this, arguments);
}
GrowlMessage.prototype = {
init: function(){
this.time = null;
this.dom = null;
this.isPin = false;
this.count = count++;
let xml = this._createXML.apply(this, arguments);
this.dom = xmlToDom(xml);
},
setTimer: function(sec){
if (!sec) sec = 20;
this.time = setTimeout(function(self, manager){
manager.remove(self.count);
}, sec * 1000, this, growlManager);
},
clearTimer: function(){
if (this.time){
clearTimeout(this.time);
this.time = null;
return true;
}
return false;
},
pin: function(){
if (this.isPin){
this.setTimer();
this.isPin = false;
} else {
this.clearTimer();
this.isPin = true;
}
},
_createXML: function(title, message, link){
let xml =
<vbox count={this.count}
style="margin-top:10px;-moz-border-radius:5px;background-color:rgba(0,0,0,0.75);color:white;max-width:300px;padding:5px;"
xmlns={xulNS}>
<hbox style="border-bottom: thin solid rgba(192,192,192,0.5);">
<titlebar flex="1"><label value={this.count + ": " + title} flex="1"/></titlebar>
<checkbox label="" oncommand={"liberator.plugins.xulGrowl.pin(" + this.count + ");"} tooltipText="pin" style="-moz-apperance:none;"/>
<toolbarbutton oncommand={"liberator.plugins.xulGrowl.remove(" + this.count + ");"} class="tab-close-button"/>
</hbox>
<hbox><vbox><image src="chrome://vimperator/skin/icon.png" width="32" height="32"/><spacer flex="1"/></vbox></hbox>
</vbox>
;
xml.xulNS::hbox[1].appendChild(new XML('<div xmlns="http://www.w3.org/1999/xhtml">' + message + '</div>'));
if (link)
xml.appendChild(<div xmlns={xhtmlNS}><a href="#" onclick="liberator.open(this.textContent,liberator.NEW_TAB);">{link}</a></div>);
return xml;
},
};
let growlManager = {
initialize: function(){
this.root.appendChild(this.panel);
},
update: function(message){
if (this.panel.state == "closed")
this.open();
let gm = new GrowlMessage(message.title, message.message, message.link);
this.panel.appendChild(gm.dom);
gm.setTimer();
this.gmList.push(gm);
},
gmList: [],
panel: xmlToDom(<panel noautofocus="true" noautohide="true" width="300" style="background-color:transparent;border:none;" xmlns={xulNS}/>),
getIndexAndMessageByCount: function(count){
for (let [i, gm] in Iterator(this.gmList)){
if (count == gm.count)
return [i, gm];
}
return null;
},
pin: function(count){
let indexAndGm = this.getIndexAndMessageByCount(count);
if (indexAndGm){
indexAndGm[1].pin();
}
},
remove: function(count){
count = parseInt(count, 10);
let indexAndGm = this.getIndexAndMessageByCount(count);
if (indexAndGm){
let [index, gm] = indexAndGm;
if (this.panel.childNodes.length <= 1)
this.panel.hidePopup();
this.panel.removeChild(gm.dom);
this.gmList.splice(index, 1);
return true;
}
return false;
},
root: document.documentElement,
open: function(){
let cb = getBrowser().mCurrentBrowser;
this.panel.openPopup(cb,"overlay",cb.boxObject.width - this.panel.boxObject.width - 10, 0, false, true);
},
close: function(){
this.panel.hidePopup();
this.root.removeChild(this.panel);
},
};
notifier.observer.register(notifier.Observer, growlManager);
return growlManager;
})();
function onUnload(){
try{
plugins.xulGrowl.close();
} catch(e) {};
}
// vim:sw=2 ts=2:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment