view release on metacpan or search on metacpan
lib/Alice/HTTP/Server.pm view on Meta::CPAN
sub BUILD {
my $self = shift;
$self->httpd;
$self->ping;
}
sub _build_httpd {
my $self = shift;
my $httpd;
# eval in case server can't bind port
eval {
$httpd = Fliggy::Server->new(
host => $self->address,
port => $self->port,
);
$httpd->register_service(
builder {
enable "Session",
store => $self->session,
state => Plack::Session::State::Cookie->new(expires => 60 * 60 * 24 * 7);
share/static/alice.js view on Meta::CPAN
for (var i = 0, length = properties.length; i < length; i++) {
var property = properties[i], value = source[property];
if (ancestor && Object.isFunction(value) &&
value.argumentNames()[0] == "$super") {
var method = value;
value = (function(m) {
return function() { return ancestor[m].apply(this, arguments); };
})(property).wrap(method);
value.valueOf = method.valueOf.bind(method);
value.toString = method.toString.bind(method);
}
this.prototype[property] = value;
}
return this;
}
return {
create: create,
Methods: {
share/static/alice.js view on Meta::CPAN
return update(array, args);
}
function argumentNames() {
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
.replace(/\s+/g, '').split(',');
return names.length == 1 && !names[0] ? [] : names;
}
function bind(context) {
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
var __method = this, args = slice.call(arguments, 1);
return function() {
var a = merge(args, arguments);
return __method.apply(context, a);
}
}
function bindAsEventListener(context) {
var __method = this, args = slice.call(arguments, 1);
return function(event) {
var a = update([event || window.event], args);
return __method.apply(context, a);
}
}
function curry() {
if (!arguments.length) return this;
var __method = this, args = slice.call(arguments, 0);
share/static/alice.js view on Meta::CPAN
}
function defer() {
var args = update([0.01], arguments);
return this.delay.apply(this, args);
}
function wrap(wrapper) {
var __method = this;
return function() {
var a = update([__method.bind(this)], arguments);
return wrapper.apply(this, a);
}
}
function methodize() {
if (this._methodized) return this._methodized;
var __method = this;
return this._methodized = function() {
var a = update([this], arguments);
return __method.apply(null, a);
};
}
return {
argumentNames: argumentNames,
bind: bind,
bindAsEventListener: bindAsEventListener,
curry: curry,
delay: delay,
defer: defer,
wrap: wrap,
methodize: methodize
}
})());
share/static/alice.js view on Meta::CPAN
var PeriodicalExecuter = Class.create({
initialize: function(callback, frequency) {
this.callback = callback;
this.frequency = frequency;
this.currentlyExecuting = false;
this.registerCallback();
},
registerCallback: function() {
this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
execute: function() {
this.callback(this);
},
stop: function() {
if (!this.timer) return;
clearInterval(this.timer);
this.timer = null;
share/static/alice.js view on Meta::CPAN
this.parameters = params.toQueryParams();
try {
var response = new Ajax.Response(this);
if (this.options.onCreate) this.options.onCreate(response);
Ajax.Responders.dispatch('onCreate', this, response);
this.transport.open(this.method.toUpperCase(), this.url,
this.options.asynchronous);
if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
this.transport.onreadystatechange = this.onStateChange.bind(this);
this.setRequestHeaders();
this.body = this.method == 'post' ? (this.options.postBody || params) : null;
this.transport.send(this.body);
/* Force Firefox to handle ready state 4 for synchronous requests */
if (!this.options.asynchronous && this.transport.overrideMimeType)
this.onStateChange();
}
share/static/alice.js view on Meta::CPAN
this.container = {
success: (container.success || container),
failure: (container.failure || (container.success ? null : container))
};
options = Object.clone(options);
var onComplete = options.onComplete;
options.onComplete = (function(response, json) {
this.updateContent(response.responseText);
if (Object.isFunction(onComplete)) onComplete(response, json);
}).bind(this);
$super(url, options);
},
updateContent: function(responseText) {
var receiver = this.container[this.success() ? 'success' : 'failure'],
options = this.options;
if (!options.evalScripts) responseText = responseText.stripScripts();
share/static/alice.js view on Meta::CPAN
this.decay = (this.options.decay || 1);
this.updater = { };
this.container = container;
this.url = url;
this.start();
},
start: function() {
this.options.onComplete = this.updateComplete.bind(this);
this.onTimerEvent();
},
stop: function() {
this.updater.options.onComplete = undefined;
clearTimeout(this.timer);
(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
},
updateComplete: function(response) {
if (this.options.decay) {
this.decay = (response.responseText == this.lastText ?
this.decay * this.options.decay : 1);
this.lastText = response.responseText;
}
this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
},
onTimerEvent: function() {
this.updater = new Ajax.Updater(this.container, this.url, this.options);
}
});
function $(element) {
if (arguments.length > 1) {
share/static/alice.js view on Meta::CPAN
nodes.each(function(node) { element.appendChild(node) });
}
else {
element.innerHTML = content.stripScripts();
}
}
else {
element.innerHTML = content.stripScripts();
}
content.evalScripts.bind(content).defer();
return element;
}
return update;
})(),
replace: function(element, content) {
element = $(element);
if (content && content.toElement) content = content.toElement();
else if (!Object.isElement(content)) {
content = Object.toHTML(content);
var range = element.ownerDocument.createRange();
range.selectNode(element);
content.evalScripts.bind(content).defer();
content = range.createContextualFragment(content.stripScripts());
}
element.parentNode.replaceChild(content, element);
return element;
},
insert: function(element, insertions) {
element = $(element);
if (Object.isString(insertions) || Object.isNumber(insertions) ||
share/static/alice.js view on Meta::CPAN
content = Object.toHTML(content);
tagName = ((position == 'before' || position == 'after')
? element.parentNode : element).tagName.toUpperCase();
childNodes = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
if (position == 'top' || position == 'after') childNodes.reverse();
childNodes.each(insert.curry(element));
content.evalScripts.bind(content).defer();
}
return element;
},
wrap: function(element, wrapper, attributes) {
element = $(element);
if (Object.isElement(wrapper))
$(wrapper).writeAttribute(attributes || { });
else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
share/static/alice.js view on Meta::CPAN
var nextSibling = element.next(),
fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
parent.removeChild(element);
if (nextSibling)
fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
else
fragments.each(function(node) { parent.appendChild(node) });
}
else element.outerHTML = content.stripScripts();
content.evalScripts.bind(content).defer();
return element;
};
}
Element._returnOffset = function(l, t) {
var result = [l, t];
result.left = l;
result.top = t;
return result;
};
share/static/alice.js view on Meta::CPAN
registerFormCallbacks: function() {
Form.getElements(this.element).each(this.registerCallback, this);
},
registerCallback: function(element) {
if (element.type) {
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
Event.observe(element, 'click', this.onElementEvent.bind(this));
break;
default:
Event.observe(element, 'change', this.onElementEvent.bind(this));
break;
}
}
}
});
Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
getValue: function() {
return Form.Element.getValue(this.element);
}
share/static/alice.js view on Meta::CPAN
return Event.extend(event);
}
Event.Handler = Class.create({
initialize: function(element, eventName, selector, callback) {
this.element = $(element);
this.eventName = eventName;
this.selector = selector;
this.callback = callback;
this.handler = this.handleEvent.bind(this);
},
start: function() {
Event.observe(this.element, this.eventName, this.handler);
return this;
},
stop: function() {
Event.stopObserving(this.element, this.eventName, this.handler);
return this;
share/static/alice.js view on Meta::CPAN
break;
}
effect.startOn += timestamp;
effect.finishOn += timestamp;
if (!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
this.effects.push(effect);
if (!this.interval)
this.interval = setInterval(this.loop.bind(this), 15);
},
remove: function(effect) {
this.effects = this.effects.reject(function(e) { return e==effect });
if (this.effects.length == 0) {
clearInterval(this.interval);
this.interval = null;
}
},
loop: function() {
var timePos = new Date().getTime();
share/static/alice.js view on Meta::CPAN
effect.event('afterFinish');
});
}
});
Effect.Tween = Class.create(Effect.Base, {
initialize: function(object, from, to) {
object = Object.isString(object) ? $(object) : object;
var args = $A(arguments), method = args.last(),
options = args.length == 5 ? args[3] : null;
this.method = Object.isFunction(method) ? method.bind(object) :
Object.isFunction(object[method]) ? object[method].bind(object) :
function(value) { object[method] = value };
this.start(Object.extend({ from: from, to: to }, options || { }));
},
update: function(position) {
this.method(position);
}
});
Effect.Event = Class.create(Effect.Base, {
initialize: function() {
share/static/alice.js view on Meta::CPAN
}, arguments[2] || { });
this.start(options);
},
setup: function() {
this.restoreAfterFinish = this.options.restoreAfterFinish || false;
this.elementPositioning = this.element.getStyle('position');
this.originalStyle = { };
['top','left','width','height','fontSize'].each( function(k) {
this.originalStyle[k] = this.element.style[k];
}.bind(this));
this.originalTop = this.element.offsetTop;
this.originalLeft = this.element.offsetLeft;
var fontSize = this.element.getStyle('font-size') || '100%';
['em','px','%','pt'].each( function(fontSizeType) {
if (fontSize.indexOf(fontSizeType)>0) {
this.fontSize = parseFloat(fontSize);
this.fontSizeType = fontSizeType;
}
}.bind(this));
this.factor = (this.options.scaleTo - this.options.scaleFrom)/100;
this.dims = null;
if (this.options.scaleMode=='box')
this.dims = [this.element.offsetHeight, this.element.offsetWidth];
if (/^content/.test(this.options.scaleMode))
this.dims = [this.element.scrollHeight, this.element.scrollWidth];
if (!this.dims)
this.dims = [this.options.scaleMode.originalHeight,
share/static/alice.js view on Meta::CPAN
if (this.element.getStyle('display')=='none') { this.cancel(); return; }
this.oldStyle = { };
if (!this.options.keepBackgroundImage) {
this.oldStyle.backgroundImage = this.element.getStyle('background-image');
this.element.setStyle({backgroundImage: 'none'});
}
if (!this.options.endcolor)
this.options.endcolor = this.element.getStyle('background-color').parseColor('#ffffff');
if (!this.options.restorecolor)
this.options.restorecolor = this.element.getStyle('background-color');
this._base = $R(0,2).map(function(i){ return parseInt(this.options.startcolor.slice(i*2+1,i*2+3),16) }.bind(this));
this._delta = $R(0,2).map(function(i){ return parseInt(this.options.endcolor.slice(i*2+1,i*2+3),16)-this._base[i] }.bind(this));
},
update: function(position) {
this.element.setStyle({backgroundColor: $R(0,2).inject('#',function(m,v,i){
return m+((this._base[i]+(this._delta[i]*position)).round().toColorPart()); }.bind(this)) });
},
finish: function() {
this.element.setStyle(Object.extend(this.oldStyle, {
backgroundColor: this.options.restorecolor
}));
}
});
Effect.ScrollTo = function(element) {
var options = arguments[1] || { },
share/static/alice.js view on Meta::CPAN
unit = (components.length == 3) ? components[2] : null;
}
var originalValue = this.element.getStyle(property);
return {
style: property.camelize(),
originalValue: unit=='color' ? parseColor(originalValue) : parseFloat(originalValue || 0),
targetValue: unit=='color' ? parseColor(value) : value,
unit: unit
};
}.bind(this)).reject(function(transform){
return (
(transform.originalValue == transform.targetValue) ||
(
transform.unit != 'color' &&
(isNaN(transform.originalValue) || isNaN(transform.targetValue))
)
);
});
},
update: function(position) {
share/static/alice.js view on Meta::CPAN
},
addTracks: function(tracks){
tracks.each(function(track){
track = $H(track);
var data = track.values().first();
this.tracks.push($H({
ids: track.keys().first(),
effect: Effect.Morph,
options: { style: data }
}));
}.bind(this));
return this;
},
play: function(){
return new Effect.Parallel(
this.tracks.map(function(track){
var ids = track.get('ids'), effect = track.get('effect'), options = track.get('options');
var elements = [$(ids) || $$(ids)].flatten();
return elements.map(function(e){ return new effect(e, Object.extend({ sync:true }, options)) });
}).flatten(),
this.options
share/static/alice.js view on Meta::CPAN
this.deactivate(this.last_active);
}
};
var Draggables = {
drags: [],
observers: [],
register: function(draggable) {
if(this.drags.length == 0) {
this.eventMouseUp = this.endDrag.bindAsEventListener(this);
this.eventMouseMove = this.updateDrag.bindAsEventListener(this);
this.eventKeypress = this.keyPress.bindAsEventListener(this);
Event.observe(document, "mouseup", this.eventMouseUp);
Event.observe(document, "mousemove", this.eventMouseMove);
Event.observe(document, "keypress", this.eventKeypress);
}
this.drags.push(draggable);
},
unregister: function(draggable) {
this.drags = this.drags.reject(function(d) { return d==draggable });
share/static/alice.js view on Meta::CPAN
Event.stopObserving(document, "keypress", this.eventKeypress);
}
},
activate: function(draggable) {
if(draggable.options.delay) {
this._timeout = setTimeout(function() {
Draggables._timeout = null;
window.focus();
Draggables.activeDraggable = draggable;
}.bind(this), draggable.options.delay);
} else {
window.focus(); // allows keypress events if window isn't currently focused, fails for Safari
this.activeDraggable = draggable;
}
},
deactivate: function() {
this.activeDraggable = null;
},
share/static/alice.js view on Meta::CPAN
if(options.scroll && !options.scroll.scrollTo && !options.scroll.outerHTML) {
options.scroll = $(options.scroll);
this._isScrollChild = Element.childOf(this.element, options.scroll);
}
Element.makePositioned(this.element); // fix IE
this.options = options;
this.dragging = false;
this.eventMouseDown = this.initDrag.bindAsEventListener(this);
Event.observe(this.handle, "mousedown", this.eventMouseDown);
Draggables.register(this);
},
destroy: function() {
Event.stopObserving(this.handle, "mousedown", this.eventMouseDown);
Draggables.unregister(this);
},
share/static/alice.js view on Meta::CPAN
var d = this.currentDelta();
pos[0] -= d[0]; pos[1] -= d[1];
if(this.options.scroll && (this.options.scroll != window && this._isScrollChild)) {
pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
}
var p = [0,1].map(function(i){
return (point[i]-pos[i]-this.offset[i])
}.bind(this));
if(this.options.snap) {
if(Object.isFunction(this.options.snap)) {
p = this.options.snap(p[0],p[1],this);
} else {
if(Object.isArray(this.options.snap)) {
p = p.map( function(v, i) {
return (v/this.options.snap[i]).round()*this.options.snap[i] }.bind(this));
} else {
p = p.map( function(v) {
return (v/this.options.snap).round()*this.options.snap }.bind(this));
}
}}
var style = this.element.style;
if((!this.options.constraint) || (this.options.constraint=='horizontal'))
style.left = p[0] + "px";
if((!this.options.constraint) || (this.options.constraint=='vertical'))
style.top = p[1] + "px";
if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
share/static/alice.js view on Meta::CPAN
clearInterval(this.scrollInterval);
this.scrollInterval = null;
Draggables._lastScrollPointer = null;
}
},
startScrolling: function(speed) {
if(!(speed[0] || speed[1])) return;
this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
this.lastScrolled = new Date();
this.scrollInterval = setInterval(this.scroll.bind(this), 10);
},
scroll: function() {
var current = new Date();
var delta = current - this.lastScrolled;
this.lastScrolled = current;
if(this.options.scroll == window) {
with (this._getWindowScroll(this.options.scroll)) {
if (this.scrollSpeed[0] || this.scrollSpeed[1]) {
var d = delta / 1000;
share/static/alice.js view on Meta::CPAN
'target':ele,
'event': opt['type']
};
if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);
else ele['on'+opt['type']] = func;
},
'remove':function(shortcut_combination) {
shortcut_combination = shortcut_combination.toLowerCase();
var binding = this.all_shortcuts[shortcut_combination];
delete(this.all_shortcuts[shortcut_combination])
if(!binding) return;
var type = binding['event'];
var ele = binding['target'];
var callback = binding['callback'];
if(ele.detachEvent) ele.detachEvent('on'+type, callback);
else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
else ele['on'+type] = false;
}
};
function str_repeat(i, m) {
for (var o = []; m > 0; o[--m] = i);
return o.join('');
share/static/alice.js view on Meta::CPAN
function getNode() {
var parent = this.commonAncestorContainer;
while (parent.nodeType == Node.TEXT_NODE)
parent = parent.parentNode;
var child = parent.childElements().detect(function(child) {
var range = document.createRange();
range.selectNodeContents(child);
return this.betweenRange(range);
}.bind(this));
return $(child || parent);
}
return {
beforeRange: beforeRange,
afterRange: afterRange,
betweenRange: betweenRange,
equalRange: equalRange,
getNode: getNode
share/static/alice.js view on Meta::CPAN
range.collapse(false);
range.select();
} else {
this.execCommand('insertHTML', false, html);
}
}
function execCommand(command, ui, value) {
var handler = this.commands.get(command);
if (handler) {
handler.bind(this)(value);
} else {
try {
window.document.execCommand(command, ui, value);
} catch(e) { return null; }
}
document.activeElement.fire("field:change");
}
function queryCommandState(state) {
var handler = this.queryCommands.get(state);
if (handler) {
return handler.bind(this)();
} else {
try {
return window.document.queryCommandState(state);
} catch(e) { return null; }
}
}
function getSelectedStyles() {
var styles = $H({});
var editor = this;
share/static/alice.js view on Meta::CPAN
function createToolbarElement() {
var toolbar = new Element('div', { 'class': 'editor_toolbar' });
this.editor.insert({before: toolbar});
return toolbar;
}
function addButtonSet(set) {
$A(set).each(function(button){
this.addButton(button);
}.bind(this));
}
function addButton(options, handler) {
options = $H(options);
if (!options.get('name'))
options.set('name', options.get('label').toLowerCase());
var name = options.get('name');
var button = this.createButtonElement(this.element, options);
share/static/alice.js view on Meta::CPAN
else if (options.get('handler'))
return options.get('handler');
else
return function(editor) { editor.execCommand(name); };
}
function observeButtonClick(element, handler) {
element.on('click', function(event) {
handler(this.editor);
event.stop();
}.bind(this));
}
function buttonStateHandler(name, options) {
if (options.query)
return options.query;
else if (options.get('query'))
return options.get('query');
else
return function(editor) { return editor.queryCommandState(name); };
}
function observeStateChanges(element, name, handler) {
var previousState;
this.editor.on("selection:change", function(event) {
var state = handler(this.editor);
if (state != previousState) {
previousState = state;
this.updateButtonState(element, name, state);
}
}.bind(this));
}
function updateButtonState(element, name, state) {
if (state)
element.addClassName('selected');
else
element.removeClassName('selected');
}
return {
share/static/alice.js view on Meta::CPAN
this.isMobile = this.isPhone || Prototype.Browser.MobileSafari;
this.loadDelay = this.isMobile ? 3000 : 1000;
if (window.navigator.standalone || window.navigator.userAgent.match(/Fluid/)) this.loadDelay = 0;
this.keyboard = new Alice.Keyboard(this);
this.input = new Alice.Input(this, "msg");
this.submit = $("submit");
this.submit.observe("click", function (e) {
this.input.send(); e.stop()}.bind(this));
this.tabs.observe("webkitTransitionEnd", this.shiftEnd.bind(this));
this.tabs.observe("transitionend", this.shiftEnd.bind(this));
this.makeSortable();
this.setupTopic();
this.setupNicklist();
this.setupMenus();
},
getBacklog: function (win, max, limit) {
this.connection.requestChunk(win.id, limit, max);
},
share/static/alice.js view on Meta::CPAN
var req = new XMLHttpRequest();
req.open("GET", "https://noembed.com/providers");
req.onreadystatechange = function(){
if (req.readyState == 4) {
try {
var providers = req.responseText.evalJSON();
this.oembeds = providers.inject([], function(acc, site){
return acc.concat(site.patterns.map(function(pat){return new RegExp(pat)}));
});
} catch (e) {}
setTimeout(this.fetchOembeds.bind(this), 1000 * 60 * 5);
if (cb) cb();
}
}.bind(this);
req.send();
},
embed: function(a, win) {
var params = {
url: a.href,
maxheight: 300,
};
var req = new XMLHttpRequest();
req.open("GET", "https://www.noembed.com/embed?" + Object.toQueryString(params));
req.onreadystatechange = function(){
if (req.readyState == 4) {
var data = req.responseText.evalJSON();
this.embedContent(a, win, data);
}
}.bind(this);
req.send();
},
embedContent: function(a, win, data) {
if (!data || !data.html) return;
var html = data.html;
var elem = new Element("DIV", {"class": "oembed"});
if (data.provider_name == "Twitter") {
share/static/alice.js view on Meta::CPAN
if ($('servers')) {
Alice.connections.connectServer(action.network);
}
},
disconnect: function (action) {
action.windows.each(function (win_info) {
var win = this.getWindow(win_info.id);
if (win) {
win.disable();
}
}.bind(this));
if ($('servers')) {
Alice.connections.disconnectServer(action.network);
}
},
focus: function (action) {
if (!action.window_number) return;
if (action.window_number == "next") {
this.nextWindow();
}
else if (action.window_number.match(/^prev/)) {
share/static/alice.js view on Meta::CPAN
toggleHelp: function() {
var help = $('help');
help.visible() ? help.hide() : help.show();
},
toggleJoin: function() {
this.connection.get("/join", function (transport) {
this.input.disabled = true;
$('windows').insert(transport.responseText);
}.bind(this));
},
toggleConfig: function(e) {
this.connection.get("/config", function (transport) {
this.input.disabled = true;
$('windows').insert(transport.responseText);
}.bind(this));
if (e) e.stop();
},
togglePrefs: function(e) {
this.connection.get("/prefs", function (transport) {
this.input.disabled = true;
$('windows').insert(transport.responseText);
}.bind(this));
if (e) e.stop();
},
toggleTabsets: function(e) {
this.connection.get("/tabsets", function (transport) {
this.input.disabled = true;
$('windows').insert(transport.responseText);
Alice.tabsets.focusIndex(0);
}.bind(this));
},
windows: function () {
return this.window_map.values();
},
nth_window: function(n) {
var tab = this.tabs.down('.visible:not(.info_tab)', n - 1);
if (tab) {
var m = tab.id.match(/([^_]+)_tab/);
share/static/alice.js view on Meta::CPAN
openWindow: function(serialized, msgid) {
if (!msgid) msgid = this.msgid();
var win = new Alice.Window(this, serialized, msgid);
this.addWindow(win);
return win;
},
addWindow: function(win) {
this.window_map.set(win.id, win);
if (window.fluid)
window.fluid.addDockMenuItem(win.title, win.focus.bind(win));
},
removeWindow: function(win) {
this.tabs_layout = this.tabs.getLayout();
this.windows().invoke("updateTabLayout");
if (win.active) this.focusLast();
if (window.fluid)
window.fluid.removeDockMenuItem(win.title);
share/static/alice.js view on Meta::CPAN
var classes = win.statuses;
classes.each(function(c){left.addClassName(c)});
left_menu.innerHTML += sprintf('<li rel="%s" class="%s"><span>%s</span></a>', win.id, classes.join(" "), win.title)
}
else if (pos.right) {
var classes = win.statuses;
classes.each(function(c){right.addClassName(c)});
right_menu.innerHTML += sprintf('<li rel="%s" class="%s"><span>%s</span></a>', win.id, classes.join(" "), win.title)
}
}.bind(this));
this.toggleMenu(left, !!left_menu.innerHTML);
this.toggleMenu(right, !!right_menu.innerHTML);
},
toggleMenu: function(menu, active) {
if (active) {
menu.addClassName("active");
}
else {
share/static/alice.js view on Meta::CPAN
var tabs = res.childElements();
var order = tabs.collect(function(t){
var m = t.id.match(/([^_]+)_tab/);
if (m) return m[1]
});
if (order.length) this.connection.sendTabOrder(order);
setTimeout(function(){
this.windows().invoke("updateTabLayout");
this.activeWindow().shiftTab();
}.bind(this), 100);
}.bind(this)
});
},
addMissed: function() {
if (!window.fluid) return;
window.fluid.dockBadge ? window.fluid.dockBadge++ :
window.fluid.dockBadge = 1;
},
clearMissed: function() {
if (!window.fluid) return;
window.fluid.dockBadge = "";
},
ready: function() {
this.freeze();
setTimeout(this.updateOverflowMenus.bind(this), 1000);
this.fetchOembeds(function() {
this.connection.connect(function() {
this.focusHash() || this.activeWindow().focus();
}.bind(this));
}.bind(this));
},
log: function () {
var win = this.activeWindow();
for (var i=0; i < arguments.length; i++) {
if (window.console && window.console.log) {
console.log(arguments[i]);
}
if (this.options.debug == "true") {
if (win) {
share/static/alice.js view on Meta::CPAN
this.selectSet(name);
var active = this.activeWindow();
if (!active.visible) {
active = this.nextWindow();
}
if (active) active.shiftTab();
setTimeout(this.updateOverflowMenus.bind(this), 2000);
}
},
selectSet: function(name) {
var hash = window.location.hash;
hash = hash.replace(/^[^\/]*/, name);
window.location.hash = hash;
window.location = window.location.toString();
this.selectedSet = name;
},
share/static/alice.js view on Meta::CPAN
win.scrollToPosition(position);
},
setupNicklist: function() {
this.nicklist.observe("click", function(e) {
var li = e.findElement('a');
if (li) {
var nick = a.innerHTML;
this.connection.requestWindow(nick, this.activeWindow().id);
}
}.bind(this));
},
setupTopic: function() {
this.topic.observe(this.supportsTouch ? "touchstart" : "click", function(e) {
if (this.supportsTouch) e.stop();
if (this.topic.getStyle("height") == this.topic_height) {
this.topic.setStyle({height: "auto"});
} else {
this.topic.setStyle({height: this.topic_height});
}
}.bind(this));
},
setupMenus: function() {
var click = this.supportsTouch ? "touchend" : "mouseup";
$('join_button').observe(click, function (e) {
e.stop();
this.toggleJoin();
}.bind(this));
$('config_menu').on(click, ".dropdown li", function(e,li) {
e.stop();
var text = li.textContent;
if (text.match(/Help/)) {
this.toggleHelp();
} else if (text.match(/Preferences/)) {
this.togglePrefs();
} else if (text.match(/Connections/)) {
this.toggleConfig();
}
$$('.dropdown.open').invoke("removeClassName", "open");
}.bind(this));
$('tabset_dropdown').on(click, ".dropdown li span", function(e,li) {
e.stop();
var name = li.innerHTML.unescapeHTML();
if (name == "Edit Sets")
this.toggleTabsets();
else if (name == "All tabs")
this.clearSet(li);
else if (this.tabsets[name])
this.showSet(name);
$$('.dropdown.open').invoke("removeClassName", "open");
}.bind(this));
['tab_menu_left', 'tab_menu_right'].each(function(side) {
$(side).on(click, ".dropdown li", function(e, li) {
e.stop();
if (li.getAttribute("rel")) {
$(side).removeClassName("open");
var win = this.getWindow(li.getAttribute("rel"));
if (win) win.focus();
}
}.bind(this));
}.bind(this));
},
baseFilters: function() {
return [
function(li, win) {
Alice.makeLinksClickable(li.down("div.msg"));
},
function(li, win) {
if (li.hasClassName("avatar")) {
share/static/alice.js view on Meta::CPAN
this.reconnecting = true;
this.reconnect_count = 0;
this.connect();
},
handleException: function(request, exception) {
this.application.log("encountered an error with stream.");
this.application.log(exception);
this.connected = false;
if (!this.aborting)
setTimeout(this.connect.bind(this), 2000);
else
this.changeStatus("ok");
},
handleComplete: function(transport) {
this.application.log("connection was closed cleanly.");
this.connected = false;
if (!this.aborting)
setTimeout(this.connect.bind(this), 2000);
else
this.changeStatus("ok");
},
processQueue: function(data) {
try {
var queue = data.queue;
var length = queue.length;
for (var i=0; i<length; i++) {
if (queue[i].type == "identify") {
share/static/alice.js view on Meta::CPAN
var parameters = Object.toQueryString({
t: now.getTime() / 1000,
tab: this.application.activeWindow().id
});
var protocol = (window.location.protocol.match(/^https/) ? "wss://" : "ws://");
var url = protocol + window.location.host + "/wsstream?" + parameters;
this.request = new WebSocket(url);
this.request.onopen = function(){
this.connected = true;
setTimeout(cb, 100);
}.bind(this);
this.request.onmessage = this.handleUpdate.bind(this);
this.request.onerror = this.handleException.bind(this);
this.request.onclose = this.handleComplete.bind(this);
},
handleUpdate: function(e) {
var data = e.data.evalJSON();
this.processQueue(data);
},
sendMessage: function(form) {
if (!this.connected) return false;
share/static/alice.js view on Meta::CPAN
closeWindow: function(win) {
this.sendMessage({source: win.id, msg: "/close"});
},
handleException: function(exception) {
this.application.log("encountered an error with stream.");
this.application.log(exception);
this.connected = false;
if (!this.aborting)
setTimeout(this.connect.bind(this), 2000);
else
this.changeStatus("ok");
},
requestWindow: function(title, windowId, message) {
this.sendMessage({source: windowId, msg: "/create " + title});
if (message) {
setTimeout(function() {
this.application.displayMessage(message)
}.bind(this), 1000);
}
}
});
Alice.Connection.XHR = Class.create(Alice.Connection, {
initialize: function(application) {
this.type = "xhr";
this.pings = [];
this.pingLimit = 10;
this.seperator = "--xalicex\n";
share/static/alice.js view on Meta::CPAN
this.request = new Ajax.Request('/stream', {
method: 'get',
parameters: {
t: now.getTime() / 1000,
tab: this.application.activeWindow().id
},
on401: this.gotoLogin,
on500: this.gotoLogin,
on502: this.gotoLogin,
on503: this.gotoLogin,
onException: this.handleException.bind(this),
onInteractive: function(transport) {
if (!this.connected) {
this.connected = true;
setTimeout(cb, 0);
}
this.handleUpdate(transport);
}.bind(this),
onComplete: this.handleComplete.bind(this)
});
}.bind(this), this.application.loadDelay);
},
handleUpdate: function(transport) {
if (this.reconnecting) {
this.application.activeWindow().showHappyAlert("Reconnected to the Alice server");
this.reconnecting = false;
}
this.reconnect_count = 0;
share/static/alice.js view on Meta::CPAN
source: windowId,
msg: "/create " + title,
stream: this.id
},
on401: this.gotoLogin,
onSuccess: function (transport) {
this.handleUpdate(transport);
if (message) {
setTimeout(function() {
this.application.displayMessage(message)
}.bind(this), 1000);
}
}.bind(this)
});
}
});
Alice.Window = Class.create({
initialize: function(application, serialized, msgid) {
this.application = application;
this.element = $(serialized['id']);
this.title = serialized['title'];
share/static/alice.js view on Meta::CPAN
this.updateTabLayout();
},
setupEvents: function() {
this.application.supportsTouch ? this.setupTouchEvents() : this.setupMouseEvents();
},
setupTouchEvents: function() {
this.messages.observe("touchstart", function (e) {
this.showNick(e);
}.bind(this));
this.tab.observe("touchstart", function (e) {
e.stop();
if (!this.active) this.focus();
}.bind(this));
this.tabButton.observe("touchstart", function(e) {
if (this.active) {
e.stop();
confirm("Are you sure you want to close this tab?") && this.close()
}
}.bind(this));
},
setupMouseEvents: function() {
this.tab.observe("mousedown", function(e) {
if (!this.active) {this.focus(); this.focusing = true}
}.bind(this));
this.tab.observe("click", function(e) {this.focusing = false}.bind(this));
this.tabButton.observe("click", function(e) {
if (this.active && !this.focusing)
if (this.type != "channel" || confirm("Are you sure you want to leave "+this.title+"?"))
this.close()
}.bind(this));
this.messages.observe("mouseover", this.showNick.bind(this));
},
checkScrollBack: function() {
if (this.active && this.element.scrollTop == 0) {
clearInterval(this.scrollListener);
var first = this.messages.down("li[id]");
if (first) {
first = first.id.replace("msg-", "") - 1;
this.messageLimit += this.chunkSize;
}
else {
first = this.msgid;
}
this.application.log("requesting chunk" + first);
this.tab.addClassName("loading");
this.application.getBacklog(this, first, this.chunkSize);
}
else {
clearTimeout(this.scrollListener);
this.scrollListener = setTimeout(this.checkScrollBack.bind(this), 1000);
}
},
clearMessages: function() {
clearTimeout(this.scrollListener);
this.messages.update("");
this.lastNick = "";
},
updateTabLayout: function() {
share/static/alice.js view on Meta::CPAN
nick = li.down("span.nick");
}
if (nick) {
this.visibleNickTimeout = setTimeout(function(nick) {
if (nick) nick.style.opacity = 1;
setTimeout(function(){
if (this.application.overlayVisible) return;
if (nick) nick.style.opacity = 0;
}.bind(this, nick) , 1000);
}.bind(this, nick), 500);
}
}
else {
this.visibleNick = "";
clearTimeout(this.visibleNickTimeout);
}
},
focus: function(event) {
if (!this.application.currentSetContains(this)) return;
share/static/alice.js view on Meta::CPAN
this.element.addClassName('active');
this.tab.addClassName('active');
if (!this.active) {
this.active = true;
setTimeout(function(){
this.scrollToPosition(this.lastScrollPosition);
if (!this.scrollBackEmpty) this.checkScrollBack();
}.bind(this), 0);
}
this.application.setSource(this.id);
this.application.displayNicks(this.nicks);
this.markRead();
this.setWindowHash();
this.shiftTab();
var last = this.messages.childElements().last();
share/static/alice.js view on Meta::CPAN
this.tab.removeClassName("unread");
this.tab.removeClassName("highlight");
this.statuses = [];
this.application.unHighlightChannelSelect(this.id);
},
markUnread: function(classname) {
var classes = ["unread"];
if (classname) classes.push(classname);
classes.each(function(c){this.tab.addClassName(c)}.bind(this));
this.application.highlightChannelSelect(this.id, classes);
this.statuses = classes;
},
disable: function () {
this.markRead();
this.tab.addClassName('disabled');
},
enable: function () {
share/static/alice.js view on Meta::CPAN
this.trimMessages();
this.msgid = chunk['range'][1];
}
else {
this.bulk_insert = true;
this.messages.insert({"top": chunk['html']});
}
this.messages.select("li:not(.filtered)").each(function (li) {
this.application.applyFilters(li, this);
}.bind(this));
this.bulk_insert = false;
this.scrollToPosition(position);
setTimeout(function(){this.removeClassName("loading")}.bind(this.tab), 1000);
this.scrollListener = setTimeout(this.checkScrollBack.bind(this), 1000);
},
addMessage: function(message) {
if (!message.html || message.msgid <= this.msgid) return;
if (message.msgid) this.msgid = message.msgid;
if (message.nicks) this.updateNicks(message.nicks);
var position = this.captureScrollPosition();
share/static/alice.js view on Meta::CPAN
var pos_a = this.nicks_order.indexOf(a),
pos_b = this.nicks_order.indexOf(b);
if (pos_a == pos_b)
return a.toLowerCase().localeCompare(b.toLowerCase());
else if (pos_a > pos_b)
return -1;
else if (pos_a < pos_b)
return 1;
}.bind(this));
},
updateNicks: function(nicks) {
this.nicks = nicks;
if (this.active) this.application.displayNicks(this.nicks);
},
removeImage: function(e) {
e.stop();
var div = e.findElement('div.image');
if (div) {
var a = div.down("a");
var id = a.identify();
a.update(a.href);
a.style.display = "inline";
div.replace(a);
var contain = a.up();
contain.innerHTML = contain.innerHTML.replace("\n", "");
var a = $(id);
a.observe("click", function(e){e.stop();this.inlineImage(a)}.bind(this));
}
},
inlineImage: function(a) {
a.stopObserving("click");
var src = a.readAttribute("img") || a.innerHTML;
var prefix = alice.options.image_prefix;
var img = new Element("IMG", {src: prefix + src});
img.hide();
share/static/alice.js view on Meta::CPAN
var wrap = new Element("DIV", {"class": "image"});
var hide = new Element("A", {"class": "hideimg"});
var position = this.captureScrollPosition();
img.show();
a.replace(wrap);
wrap.insert(a);
a.update(img);
a.insert(hide);
a.style.display = "inline-block";
hide.observe("click", this.removeImage.bind(this));
hide.update("hide");
this.scrollToPosition(position);
}.bind(this));
a.insert({after: img});
}
});
Alice.Toolbar = Class.create(WysiHat.Toolbar, {
createButtonElement: function(toolbar, options) {
var button = Element('button');
button.update(options.get('label'));
button.addClassName(options.get('name'));
share/static/alice.js view on Meta::CPAN
observeButtonClick: function(element, handler) {
element.on('click', function(e) {e.stop()});
element.on('mouseup', function(event) {
alice.input.focus();
handler(this.editor, element, this);
this.editor.fire("selection:change");
event.stop();
}.bind(this));
},
});
Object.extend(Alice.Toolbar, {
updateColors: function (editor) {
var range = alice.input.range || editor;
if (range) {
var node = range.getNode();
var fg = node.getStyle("color");
var bg = node.getStyle("background-color");
share/static/alice.js view on Meta::CPAN
var colorcontainer = new Element("div").addClassName("colors");
this.colors().each(function(color) {
var box = new Element("span").addClassName("color");
box.setStyle({"background-color": color});
colorcontainer.insert(box);
});
elem.insert(colorcontainer);
document.body.insert(elem);
elem.observe("mousedown", this.clicked.bind(this));
elem.observe("mouseup", function(e) {e.stop()});
this.button = button;
this.elem = elem;
this.cb = callback;
this.fg = true;
},
clicked: function(e) {
e.stop();
share/static/alice.js view on Meta::CPAN
if (this.canContentEditable()) {
this.editor = WysiHat.Editor.attach(this.textarea);
this.element = this.editor;
this.toolbar = new Alice.Toolbar(this.element)
this.toolbar.addButtonSet(Alice.Toolbar.ButtonSet);
var input = new Element("input", {type: "hidden", name: "html", value: 1});
this.textarea.form.appendChild(input);
document.observe("mousedown", function(e) {
if (!e.findElement(".editor")) this.uncancelNextFocus();
}.bind(this));
this.editor.observe("keydown", function(){this.cancelNextFocus()}.bind(this));
this.editor.observe("keyup", this.updateRange.bind(this));
this.editor.observe("mouseup", this.updateRange.bind(this));
this.editor.observe("paste", this.pasteHandler.bind(this));
this.toolbar.element.on("mouseup","button",function(){
this.cancelNextFocus();
}.bind(this));
} else {
this.element = this.textarea;
this.element.observe("keydown", this.resize.bind(this));
this.element.observe("cut", this.resize.bind(this));
this.element.observe("paste", this.resize.bind(this));
this.element.observe("change", this.resize.bind(this));
}
this.history = [];
this.index = -1;
this.buffer = "";
this.completion = false;
this.focused = false;
if (!this.application.isMobile) this.focus();
this.element.observe("blur", this.onBlur.bind(this));
},
setValue: function(value) {
this.textarea.setValue(value);
if (this.editor) {
this.editor.update(value);
var text = document.createElement("BR");
this.editor.appendChild(text);
}
},
share/static/alice.js view on Meta::CPAN
}
else {
alert("Could not send message, not connected!");
}
},
completeNickname: function(prev) {
if (this.disabled) return;
if (!this.completion) {
this.completion = new Alice.Completion(this.application.activeWindow().getNicknames(), this.editor);
this.element.observe("keypress", this.onKeyPress.bind(this));
}
if (prev)
this.completion.prev();
else
this.completion.next();
},
stopCompletion: function() {
if (this.completion) {
share/static/alice.js view on Meta::CPAN
},
resize: function() {
(function() {
var height = this.getContentHeight();
if (height == 0) {
this.element.setStyle({ height: null, top: 0 });
} else if (height <= 150) {
this.element.setStyle({ height: height + "px", top: "0px" });
}
}).bind(this).defer();
},
getContentHeight: function() {
var element = new Element("div").setStyle({
position: "absolute",
visibility: "hidden",
left: "-" + this.element.getWidth() + "px",
width: this.element.getWidth() - 7 + "px",
fontFamily: this.element.getStyle("fontFamily"),
fontSize: this.element.getStyle("fontSize"),
share/static/alice.js view on Meta::CPAN
e.stop();
var fd = new FormData();
fd.append("image", blob);
fd.append("key", "f1f60f1650a07bfe5f402f35205dffd4");
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://api.imgur.com/2/upload.json");
xhr.onload = function() {
var url = xhr.responseText.evalJSON();
this.editor.insertHTML(url.upload.links.original);
this.updateRange();
}.bind(this);
xhr.send(fd);
return;
}
}
}
var text = e.clipboardData.getData("Text");
if (text) {
e.preventDefault();
text = text.escapeHTML().replace(/\n+/g, "<br>\n");
share/static/alice.js view on Meta::CPAN
if (this.enabled) {
this.activeWindow = this.application.activeWindow();
if (method.match(/\d$/)) {
this.onNumeric.call(this, event, method.substr(-1));
}
else {
this[method].call(this, event);
}
delete this.activeWindow;
}
}.bind(this), options);
},
onCmd: function(e) {
if (e.keyCode == 186) {
e.stop();
this.application.nextUnreadWindow();
}
},
onNumeric: function(event, number) {