view release on metacpan or search on metacpan
lib/App/Alice.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; }
tr.input div {
padding: 0 3px;
background: black;
margin: 3px 0;
position: relative; }
tr.input div.editor,
tr.input textarea {
line-height: 1.2em;
min-height: 1.2em;
width: 100%;
padding: 3px 0;
border: none;
margin: 0;
outline: 0 none;
font-size: 12px;
overflow: hidden;
resize: none;
font-family: "Lucida Grande", Helvetica, sans-serif; }
div.editor {
white-space: pre-wrap;
-khtml-nbsp-mode: space; }
tr.input div.editor_toolbar {
overflow: hidden;
position: absolute;
right: -170px;
padding-right: 8px;
top: -3px;
width: 180px;
height: 20px;
-webkit-border-radius: 3px 0 0 3px;
-moz-border-radius: 3px 0 0 3px;
border-radius: 3px 0 0 3px;
background: url(image/sprites.png) 0px -240px no-repeat black;
z-index: 902;
opacity: 0.2;
-webkit-transition-property: right;
-webkit-transition-duration: 0.3s; }
tr.input div.editor_toolbar button {
visibility: hidden;
display: block;
float: left;
color: #222222;
line-height: 10px;
font-size: 11px;
margin: 0;
padding: 4px 3px 5px 3px;
text-align: center;
background: none;
cursor: pointer;
border: none; }
tr.input div.editor_toolbar button:hover {
color: black; }
tr.input div.editor_toolbar button.selected {
color: yellow; }
.bold {
font-weight: bold; }
.italic {
font-style: italic; }
.underline {
text-decoration: underline; }
tr.input div.editor_toolbar:hover {
opacity: 0.4;
cursor: pointer; }
tr.input div.editor_toolbar.visible:hover {
opacity: 1;
cursor: inherit; }
tr.input div.editor_toolbar.visible {
background-color: rgba(255, 255, 255, 0.6);
background-image: none;
right: -4px;
-webkit-transition-property: right;
-webkit-transition-duration: 0.3s;
opacity: 1; }
tr.input div.editor_toolbar.visible button {
visibility: visible; }
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; }
tr.input input.send {
display: none; }
div#tab_container {
position: fixed;
bottom: 0px;
left: 0px;
right: 0px;
share/static/alice-default.css view on Meta::CPAN
padding: 0;
height: auto;
line-height: 0px; }
tr.input div {
padding: 0 3px;
background: white;
margin: 3px 0;
position: relative; }
tr.input div.editor,
tr.input textarea {
line-height: 1.2em;
min-height: 1.2em;
width: 100%;
padding: 3px 0;
border: none;
margin: 0;
outline: 0 none;
font-size: 12px;
overflow: hidden;
resize: none;
font-family: "Lucida Grande", Helvetica, sans-serif; }
div.editor {
white-space: pre-wrap;
-khtml-nbsp-mode: space; }
tr.input div.editor_toolbar {
overflow: hidden;
position: absolute;
right: -170px;
padding-right: 8px;
top: -3px;
width: 180px;
height: 20px;
-webkit-border-radius: 3px 0 0 3px;
-moz-border-radius: 3px 0 0 3px;
border-radius: 3px 0 0 3px;
background: url(image/sprites.png) 0px -240px no-repeat black;
z-index: 902;
opacity: 0.2;
-webkit-transition-property: right;
-webkit-transition-duration: 0.3s; }
tr.input div.editor_toolbar button {
visibility: hidden;
display: block;
float: left;
color: #eeeeee;
line-height: 10px;
font-size: 11px;
margin: 0;
padding: 4px 3px 5px 3px;
text-align: center;
background: none;
cursor: pointer;
border: none; }
tr.input div.editor_toolbar button:hover {
color: white; }
tr.input div.editor_toolbar button.selected {
color: yellow; }
.bold {
font-weight: bold; }
.italic {
font-style: italic; }
.underline {
text-decoration: underline; }
tr.input div.editor_toolbar:hover {
opacity: 0.4;
cursor: pointer; }
tr.input div.editor_toolbar.visible:hover {
opacity: 1;
cursor: inherit; }
tr.input div.editor_toolbar.visible {
background-color: rgba(0, 0, 0, 0.6);
background-image: none;
right: -4px;
-webkit-transition-property: right;
-webkit-transition-duration: 0.3s;
opacity: 1; }
tr.input div.editor_toolbar.visible button {
visibility: visible; }
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; }
tr.input input.send {
display: none; }
div#tab_container {
position: fixed;
bottom: 0px;
left: 0px;
right: 0px;
share/static/alice.js view on Meta::CPAN
* (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
var button = Element('button');
button.update(options.get('label'));
button.addClassName(options.get('name'));
toolbar.appendChild(button);
return button;
},
observeButtonClick: function(element, handler) {
element.on('click', function(event) {
handler(this.editor, element, this);
this.editor.fire("selection:change");
event.stop();
}.bind(this));
}
});
Alice.Toolbar.ButtonSet = WysiHat.Toolbar.ButtonSets.Basic.concat(
[
{
label: "Colors",
handler: function (editor, button, toolbar) {
var cb = function (color, fg) {
fg ? editor.colorSelection(color) : editor.backgroundColorSelection(color)
};
if (toolbar.picker) {
toolbar.picker.remove();
toolbar.picker = undefined;
} else {
toolbar.picker = new Alice.Colorpicker(button, cb);
}
}
},
{
label: "»",
handler: function (editor, button, toolbar) {
button.up("div.editor_toolbar").removeClassName("visible");
if (toolbar.picker) {
toolbar.picker.remove();
toolbar.picker = undefined;
}
}
}
]
);
Alice.Colorpicker = Class.create({
share/static/alice.js view on Meta::CPAN
});
Alice.Input = Class.create({
initialize: function(win, element) {
this.window = win;
this.application = this.window.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);
this.toolbar.element.observe("click", function(e) {
if (this.toolbar.element.hasClassName("visible")) return;
this.toolbar.element.addClassName("visible");
this.focus();
}.bind(this));
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.history = [];
this.index = -1;
share/static/alice.js view on Meta::CPAN
this.element.observe("keypress", this.onKeyPress.bind(this));
this.element.observe("blur", this.onBlur.bind(this));
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));
},
setValue: function(value) {
this.editor ? this.editor.update(value) : this.textarea.setValue(value);
},
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;
}
},
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
},
newLine: function() {
console.log("newLine");
},
send: function() {
this.application.connection.sendMessage(this.textarea.form);
this.history.push(this.getValue());
this.setValue("");
if (this.editor) this.editor.update();
this.index = -1;
this.stash();
this.update();
this.focus(1);
},
completeNickname: function() {
if (this.disabled) return;
if (!this.completion) {
this.completion = new Alice.Completion(this.window.getNicknames());
share/static/alice.js view on Meta::CPAN
getCommand: function(index) {
if (index == -1) {
return this.buffer;
} else {
return this.history[index];
}
},
resize: function() {
if (this.editor) {
this.textarea.setValue(this.editor.innerHTML);
}
(function() {
if (!this.window.active) return;
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: "-1px" });
}
}).bind(this).defer();
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
if (selection.rangeCount > 0) {
var range = selection.getRangeAt(0);
this.range = range;
}
},
pasteHandler: function(e) {
var url = e.clipboardData.getData("URL");
if (url) {
e.preventDefault();
this.editor.insertHTML(url);
this.updateRange();
return;
}
var text = e.clipboardData.getData("Text");
if (text) {
e.preventDefault();
text = text.escapeHTML().replace(/\n+/g, "<br>");
this.editor.insertHTML(text);
this.updateRange();
return;
}
}
});
Alice.Keyboard = Class.create({
initialize: function(application) {
this.application = application;
this.isMac = navigator.platform.match(/mac/i);
this.enable();