view release on metacpan or search on metacpan
lib/Alice/Readme.pod view on Meta::CPAN
The only difference of note is the "Avatar" field. In reality, this field
just sets the B<realname>. Alice abuses this field to get avatars for users.
If a user has an image URL or an email address as their realname, alice
will display the image next too their messages. This feature can be disabled
in the Preferences window.
=head2 PREFERENCES WINDOW
The Preferences window can be used to set configuration options that
are not connection specific. You can toggle the use of avatars, timestamps,
and notifications. You can also edit a list of highlightable terms.
=head2 HTTP AUTHENTICATION
Some configuration options do not have a UI yet. The most notable
of these options is HTTP authentication. If you would like to use
HTTP authentication, you will have to edit your configuration file
by hand. You can find this file at ~/.alice/config.
The config is simply a perl hash. So, if you are familiar with perl it
should not be too intimidating. If you do not know perl, sorry! :)
You will need to add "user" and "pass" values to the "auth" hash.
The resulting section of configuration might look like this:
'auth' => {
'user' => 'lee',
share/static/alice-dark.css view on Meta::CPAN
padding: 0;
height: auto;
line-height: 0px; }
div#input div {
padding: 0 3px;
background: black;
margin: 3px 0;
position: relative; }
div#input div.editor,
div#input textarea {
color: white;
line-height: 1.2em;
min-height: 1.2em;
max-height: 150px;
display: block;
padding: 3px 0;
border: none;
margin: 0;
outline: 0 none;
font-size: 12px;
overflow: hidden;
resize: none;
font-family: "Lucida Grande", Helvetica, sans-serif;
background: black; }
div#input textarea {
width: 100%; }
div#input div.editor {
margin-right: 75px;
-khtml-nbsp-mode: space; }
div#input div.editor_toolbar {
overflow: hidden;
position: absolute;
top: -3px;
right: 0px;
width: 70px;
bottom: -3px;
z-index: 902;
background: #333333; }
div#input div.editor_toolbar button {
display: block;
float: left;
color: white;
line-height: 12px;
font-size: 12px;
margin: 0;
padding: 4px 4px;
text-align: center;
background: none;
cursor: pointer;
border: none;
color: #666666; }
div#input div.editor_toolbar button.colors:hover {
background: none; }
div#input div.editor_toolbar button.colors {
width: 14px;
height: 14px;
border: 2px solid white;
margin: 4px;
padding: 0; }
div#input div.editor_toolbar button.selected {
color: white; }
.bold {
font-weight: bold; }
.italic {
font-style: italic; }
.underline {
text-decoration: underline; }
div.editor div,
div.editor p,
div.editor h1,
div.editor h2,
div.editor h3,
div.editor h4,
div.editor h5,
div.editor span {
font-size: 1em !important;
margin: 0 !important;
padding: 0 !important; }
div.editor img {
display: none !important; }
div#input input.send {
display: none; }
ul#tabs {
list-style: none;
margin: 0;
padding: 0;
padding-left: 1px;
share/static/alice-dark.css view on Meta::CPAN
padding-right: 0px !important;
text-overflow: clip; }
div.msg {
margin-left: 54px !important; }
div#input div {
margin-right: 58px;
background: none; }
div#input div.editor_toolbar {
display: none; }
div#input div.editor {
margin-right: 0; }
div#input input.send {
display: block;
position: absolute;
bottom: 0px;
right: 2px;
z-index: 904; }
div.msg.monospace, div.msg.announce {
share/static/alice-default.css view on Meta::CPAN
padding: 0;
height: auto;
line-height: 0px; }
div#input div {
padding: 0 3px;
background: white;
margin: 3px 0;
position: relative; }
div#input div.editor,
div#input textarea {
color: black;
line-height: 1.2em;
min-height: 1.2em;
max-height: 150px;
display: block;
padding: 3px 0;
border: none;
margin: 0;
outline: 0 none;
font-size: 12px;
overflow: hidden;
resize: none;
font-family: "Lucida Grande", Helvetica, sans-serif;
background: white; }
div#input textarea {
width: 100%; }
div#input div.editor {
margin-right: 75px;
-khtml-nbsp-mode: space; }
div#input div.editor_toolbar {
overflow: hidden;
position: absolute;
top: -3px;
right: 0px;
width: 70px;
bottom: -3px;
z-index: 902;
background: #efefef; }
div#input div.editor_toolbar button {
display: block;
float: left;
color: #222222;
line-height: 12px;
font-size: 12px;
margin: 0;
padding: 4px 4px;
text-align: center;
background: none;
cursor: pointer;
border: none;
color: #999999; }
div#input div.editor_toolbar button.colors:hover {
background: none; }
div#input div.editor_toolbar button.colors {
width: 14px;
height: 14px;
border: 2px solid black;
margin: 4px;
padding: 0; }
div#input div.editor_toolbar button.selected {
color: black; }
.bold {
font-weight: bold; }
.italic {
font-style: italic; }
.underline {
text-decoration: underline; }
div.editor div,
div.editor p,
div.editor h1,
div.editor h2,
div.editor h3,
div.editor h4,
div.editor h5,
div.editor span {
font-size: 1em !important;
margin: 0 !important;
padding: 0 !important; }
div.editor img {
display: none !important; }
div#input input.send {
display: none; }
ul#tabs {
list-style: none;
margin: 0;
padding: 0;
padding-left: 1px;
share/static/alice-default.css view on Meta::CPAN
padding-right: 0px !important;
text-overflow: clip; }
div.msg {
margin-left: 54px !important; }
div#input div {
margin-right: 58px;
background: none; }
div#input div.editor_toolbar {
display: none; }
div#input div.editor {
margin-right: 0; }
div#input input.send {
display: block;
position: absolute;
bottom: 0px;
right: 2px;
z-index: 904; }
div.msg.monospace, div.msg.announce {
share/static/alice-solarized.css view on Meta::CPAN
padding: 0;
height: auto;
line-height: 0px; }
div#input div {
padding: 0 3px;
background: #fdf6e3;
margin: 3px 0;
position: relative; }
div#input div.editor,
div#input textarea {
color: #073642;
line-height: 1.2em;
min-height: 1.2em;
max-height: 150px;
display: block;
padding: 3px 0;
border: none;
margin: 0;
outline: 0 none;
font-size: 12px;
overflow: hidden;
resize: none;
font-family: "Lucida Grande", Helvetica, sans-serif;
background: #fdf6e3; }
div#input textarea {
width: 100%; }
div#input div.editor {
margin-right: 75px;
-khtml-nbsp-mode: space; }
div#input div.editor_toolbar {
overflow: hidden;
position: absolute;
top: -3px;
right: 0px;
width: 70px;
bottom: -3px;
z-index: 902;
background: #eee8d5; }
div#input div.editor_toolbar button {
display: block;
float: left;
color: white;
line-height: 12px;
font-size: 12px;
margin: 0;
padding: 4px 4px;
text-align: center;
background: none;
cursor: pointer;
border: none;
color: #93a1a1; }
div#input div.editor_toolbar button.colors:hover {
background: none; }
div#input div.editor_toolbar button.colors {
width: 14px;
height: 14px;
border: 2px solid #073642;
margin: 4px;
padding: 0; }
div#input div.editor_toolbar button.selected {
color: #586e75; }
.bold {
font-weight: bold; }
.italic {
font-style: italic; }
.underline {
text-decoration: underline; }
div.editor div,
div.editor p,
div.editor h1,
div.editor h2,
div.editor h3,
div.editor h4,
div.editor h5,
div.editor span {
font-size: 1em !important;
margin: 0 !important;
padding: 0 !important; }
div.editor img {
display: none !important; }
div#input input.send {
display: none; }
ul#tabs {
list-style: none;
margin: 0;
padding: 0;
padding-left: 1px;
share/static/alice-solarized.css view on Meta::CPAN
padding-right: 0px !important;
text-overflow: clip; }
div.msg {
margin-left: 54px !important; }
div#input div {
margin-right: 58px;
background: none; }
div#input div.editor_toolbar {
display: none; }
div#input div.editor {
margin-right: 0; }
div#input input.send {
display: block;
position: absolute;
bottom: 0px;
right: 2px;
z-index: 904; }
div.msg.monospace, div.msg.announce {
share/static/alice.js view on Meta::CPAN
/* WysiHat - WYSIWYG JavaScript framework, version 0.2.1
* (c) 2008-2010 Joshua Peek
*
* WysiHat is freely distributable under the terms of an MIT-style license.
*--------------------------------------------------------------------------*/
var WysiHat = {};
WysiHat.Editor = {
attach: function(textarea) {
var editArea;
textarea = $(textarea);
var id = textarea.id + '_editor';
if (editArea = $(id)) return editArea;
editArea = new Element('div', {
'id': id,
'class': 'editor',
'contentEditable': 'true'
});
editArea.update(WysiHat.Formatting.getBrowserMarkupFrom(textarea.value));
Object.extend(editArea, WysiHat.Commands);
textarea.insert({before: editArea});
textarea.hide();
return editArea;
}
};
WysiHat.BrowserFeatures = (function() {
function createTmpIframe(callback) {
var frame, frameDocument;
frame = new Element('iframe');
frame.setStyle({
position: 'absolute',
left: '-1000px'
share/static/alice.js view on Meta::CPAN
value = element.innerHTML;
else if (element.getValue)
value = element.getValue();
if (value && element.previousValue != value) {
element.fire("field:change");
element.previousValue = value;
}
}
$(document.body).on("keyup", 'input,textarea,*[contenteditable=""],*[contenteditable=true]', fieldChangeHandler);
});
WysiHat.Commands = (function(window) {
function boldSelection() {
this.execCommand('bold', false, null);
}
function boldSelected() {
return this.queryCommandState('bold');
}
share/static/alice.js view on Meta::CPAN
this.execCommand('insertorderedlist', false, null);
}
function insertOrderedList() {
this.toggleOrderedList();
}
function orderedListSelected() {
var element = window.getSelection().getNode();
if (element) return element.match('*[contenteditable=""] ol, *[contenteditable=true] ol, *[contenteditable=""] ol *, *[contenteditable=true] ol *');
return false;
}
function toggleUnorderedList() {
var selection, node;
selection = window.getSelection();
node = selection.getNode();
if (this.unorderedListSelected() && !node.match("ul li:last-child, ul li:last-child *")) {
share/static/alice.js view on Meta::CPAN
this.execCommand('insertunorderedlist', false, null);
}
function insertUnorderedList() {
this.toggleUnorderedList();
}
function unorderedListSelected() {
var element = window.getSelection().getNode();
if (element) return element.match('*[contenteditable=""] ul, *[contenteditable=true] ul, *[contenteditable=""] ul *, *[contenteditable=true] ul *');
return false;
}
function insertImage(url) {
this.execCommand('insertImage', false, url);
}
function insertHTML(html) {
if (Prototype.Browser.IE) {
var range = window.document.selection.createRange();
share/static/alice.js view on Meta::CPAN
return handler.bind(this)();
} else {
try {
return window.document.queryCommandState(state);
} catch(e) { return null; }
}
}
function getSelectedStyles() {
var styles = $H({});
var editor = this;
editor.styleSelectors.each(function(style){
var node = editor.selection.getNode();
styles.set(style.first(), Element.getStyle(node, style.last()));
});
return styles;
}
return {
boldSelection: boldSelection,
boldSelected: boldSelected,
underlineSelection: underlineSelection,
underlineSelected: underlineSelected,
share/static/alice.js view on Meta::CPAN
result = container = new Element("div");
walk(element.childNodes);
flush();
return result.innerHTML;
}
};
})();
WysiHat.Toolbar = Class.create((function() {
function initialize(editor) {
this.editor = editor;
this.element = this.createToolbarElement();
}
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) {
share/static/alice.js view on Meta::CPAN
return button;
}
function buttonHandler(name, options) {
if (options.handler)
return options.handler;
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');
share/static/alice.js view on Meta::CPAN
button.addClassName(options.get('name'));
toolbar.appendChild(button);
return button;
},
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");
var button = alice.input.toolbar.element.down("button.colors");
button.setStyle({"border-color": fg, "background-color": bg});
}
return 1;
}
});
Alice.Toolbar.ButtonSet = [
{
label: "",
name: "colors",
query: Alice.Toolbar.updateColors,
handler: function (editor, button, toolbar) {
var cb = function (color, fg) {
if (fg) {
button.setStyle({"border-color": color})
editor.colorSelection(color);
} else {
button.setStyle({"background-color": color});
editor.backgroundColorSelection(color);
}
};
if (toolbar.picker) {
toolbar.picker.remove();
toolbar.picker = undefined;
} else {
toolbar.picker = new Alice.Colorpicker(button, cb);
}
}
},
{
label: "b",
name: "bold",
handler: function (editor, button, toolbar) {
editor.boldSelection();
}
},
{
label: "i",
name: "italic",
handler: function (editor, button, toolbar) {
editor.italicSelection();
}
},
{
label: "u",
name: "underline",
handler: function (editor, button, toolbar) {
var elem = toolbar.element.down(".underline");
if (elem.hasClassName("selected"))
elem.removeClassName("selected");
else
elem.addClassName("selected");
editor.underlineSelection();
}
}
];
Alice.Colorpicker = Class.create({
initialize: function(button, callback) {
var elem = new Element("div").addClassName("color_picker");
var toggle = new Element("div").addClassName("toggle");
var blank = new Element("span").addClassName("blank").addClassName("color");
share/static/alice.js view on Meta::CPAN
}
});
Alice.Input = Class.create({
initialize: function(application, element) {
this.application = application;
this.textarea = $(element);
this.disabled = false;
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));
share/static/alice.js view on Meta::CPAN
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);
}
},
getValue: function() {
if (this.editor) {
return this.editor.innerHTML;
}
return this.textarea.getValue();
},
onKeyPress: function(event) {
if (event.keyCode != Event.KEY_TAB) {
this.completion = false;
this.element.stopObserving("keypress");
}
},
share/static/alice.js view on Meta::CPAN
if (this.focused) return;
if (this.skipThisFocus) {
this.skipThisFocus = false;
return;
}
}
this.focused = true;
if (this.editor) {
var selection = window.getSelection();
selection.removeAllRanges();
if (this.range) {
selection.addRange(this.range);
} else {
var text = document.createTextNode("");
this.editor.appendChild(text);
selection.selectNode(text);
this.range = selection.getRangeAt(0);
}
this.editor.focus();
} else {
this.textarea.focus();
}
},
onBlur: function(e) {
this.focused = false;
},
previousCommand: function() {
share/static/alice.js view on Meta::CPAN
},
send: function() {
var msg = this.getValue();
if (msg.length > 1024*2) {
alert("That message is way too long, dude.");
return;
}
if (this.editor) this.textarea.value = msg;
var success = this.application.connection.sendMessage(this.textarea.form);
if (success) {
this.history.push(msg);
this.setValue("");
if (this.editor) this.editor.update();
this.index = -1;
this.stash();
this.update();
this.focus(1);
}
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() {
share/static/alice.js view on Meta::CPAN
visibility: "hidden",
left: "-" + this.element.getWidth() + "px",
width: this.element.getWidth() - 7 + "px",
fontFamily: this.element.getStyle("fontFamily"),
fontSize: this.element.getStyle("fontSize"),
lineHeight: this.element.getStyle("lineHeight"),
whiteSpace: "pre-wrap",
wordWrap: "break-word"
});
if (this.editor) element.addClassName("editor");
var value = this.getValue();
element.update(value.replace(/\n$/, "\n\n").replace("\n", "<br>"));
$(document.body).insert(element);
var height = element.getHeight();
element.remove();
return height;
},
share/static/alice.js view on Meta::CPAN
var blob = items[i].getAsFile();
if (blob && blob.type.match(/image/)) {
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");
this.editor.insertHTML(text);
this.updateRange();
return;
}
var url = e.clipboardData.getData("URL");
if (url) {
e.preventDefault();
this.editor.insertHTML(url);
this.updateRange();
return;
}
}
});
Alice.Keyboard = Class.create({
initialize: function(application) {
this.application = application;
this.isMac = navigator.platform.match(/mac/i);
share/static/alice.js view on Meta::CPAN
onCmdK: function() {
this.activeWindow.clearMessages();
this.application.connection.sendMessage({
msg: "/clear",
source: this.activeWindow.id,
});
},
onCmdB: function() {
if (this.application.input.editor) {
this.application.input.focus();
this.application.input.editor.boldSelection();
}
},
onCmdShiftU: function() {
if (this.application.input.editor) {
this.application.input.focus();
this.application.input.editor.underlineSelection();
}
},
onCmdI: function() {
if (this.application.input.editor) {
this.application.input.focus();
this.application.input.editor.italicSelection();
}
},
onCmdU: function() {
this.application.nextUnreadWindow();
},
onCmdShiftM: function() {
this.application.windows().invoke('markRead');
},
share/static/alice.js view on Meta::CPAN
enable: function() {
this.enabled = true;
},
disable: function() {
this.enabled = false;
}
});
Alice.Completion = Class.create({
initialize: function(candidates, editor) {
var range = this.getRange();
if (!range) return;
this.element = range.startContainer;
this.editor = editor;
if (this.element == this.editor) {
this.addTextNode();
}
this.value = this.element.data || "";
this.index = range.startOffset;
this.findStem();
this.matches = this.matchAgainst(candidates);
this.matchIndex = -1;
},
addTextNode: function() {
this.editor.innerHTML = "";
var node = document.createTextNode("");
this.editor.appendChild(node);
var selection = window.getSelection();
selection.removeAllRanges();
selection.selectNode(node);
range = selection.getRangeAt(0);
this.element = node;
},
getRange: function() {
var selection = window.getSelection();
if (selection.rangeCount > 0) {