App-Alice

 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: "&raquo;",
      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();



( run in 0.381 second using v1.01-cache-2.11-cpan-de7293f3b23 )