Alice

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

          (tweets, video, etc.)

0.19  Tue 31 Aug 2010
        - Added a dark theme
        - Made preferences and connections windows
          into popup divs instead of real windows
        - Redis message store improvements
        - Improved debug output
        - Workarounds for weird android browser
          quirks
        - Much better mobile style
        - Improved reconnect behavior
        - Nick tab completion in private messages
        - Use browser's timezone for timestamps
        - Faster page loads

0.18  Tue 10 Aug 2010
        - Shortcuts work on Linux and Windows
        - Alt-[0-9] shortcuts added to jump to tab
        - javascript bug fixes
        - Added link to grant Chrome permission

Changes  view on Meta::CPAN

        - Use cookie based auth
        - Don't break on perl 5.8
        - Added Redis message store
        - Moved most display logic to CSS

0.12  Thu 25 Mar 2010
        - Switched to Twiggy from AE:HTTPD
        - Many HTML/CSS tweaks
        - Sends buffered messages with initial page
          load (loads much faster)
        - Improved iPhone stylesheet

0.11  Sat 13 Mar 2010
        - Improved unicode support
        - Faster shutdown process
        - Make / an alias for /view
        - Show context for log search result on click

0.10  Mon 22 Feb 2010
        - Added NullLogger to fix test failures

Makefile.PL  view on Meta::CPAN

ALICE_SCSS := $(CSS_SOURCE)/alice.scss
ALICE_JS := $(JS_SOURCE)/alice/src/alice.js
SITE_JS := $(BUILD)/alice.js

COLORFILES := $(foreach dir,$(CSS_SOURCE)/colors,$(wildcard $(dir)/*.scss))
CSSFILES := $(addprefix $(BUILD)/alice-,$(notdir $(COLORFILES:.scss=.css)))

$(BUILD)/alice-%.css: $(CSS_SOURCE)/colors/%.scss $(ALICE_SCSS)
	cat $< $(ALICE_SCSS) | sass --scss -s $@

assets: stylesheets javascript

stylesheets: $(CSSFILES)

javascript: $(JAVASCRIPT_SOURCES)
	sprocketize $(INCLUDE) $(ALICE_JS) > $(SITE_JS)
};

WriteAll;

lib/Alice/Config.pm  view on Meta::CPAN

  isa     => 'Str',
  default => "show",
);

has first_run => (
  is      => 'rw',
  isa     => 'Bool',
  default => 1,
);

has style => (
  is      => 'rw',
  isa     => 'Str',
  default => 'default',
);

has timeformat => (
  is      => 'rw',
  isa     => 'Str',
  default => '24',
);

lib/Alice/Readme.pod  view on Meta::CPAN

running on OS X) or libnotify (on Linux.)

You can add additional patterns to highlight in the Preferences
window.

If you are using Fluid.app (a SSB for OS X) or Chrome you can also
get notifications when the window is unfocused.

=head1 MOBILE INTERFACE

Alice has an iPhone style sheet, but it may work in other mobile
browsers as well. Any help or bug reports would be much appreciated.

=head1 COPYRIGHT

Copyright 2010 by Lee Aylward E<lt>leedo@cpan.orgE<gt>

This program is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut

share/static/alice-dark.css  view on Meta::CPAN

div#windows.nicklist div#nicklist_toggle {
  right: 135px; }

div#windows.nicklist div.window.active {
  right: 121px; }

ul#nicklist {
  background-color: #111111;
  border-left: 1px solid black;
  position: absolute;
  list-style: none;
  margin: 0;
  padding: 0;
  top: 0px;
  bottom: 0px;
  left: -120px;
  right: auto;
  width: 120px;
  overflow-y: auto;
  overflow-x: hidden;
  visibility: hidden; }

share/static/alice-dark.css  view on Meta::CPAN

  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,

share/static/alice-dark.css  view on Meta::CPAN

  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;
  font-size: 11px;
  position: absolute;
  left: 0px;
  height: 25px;
  overflow: hidden;
  width: 5000px;
  -webkit-transition: left 0.25s ease-in-out;

share/static/alice-dark.css  view on Meta::CPAN

  font-size: 11px;
  height: 15px;
  min-height: 15px;
  overflow: hidden;
  z-index: 901;
  text-decoration: none;
  color: white;
  -webkit-box-shadow: 2px 0 2px rgba(0, 0, 0, 0.2); }

ul.messages {
  list-style: none;
  margin: 0;
  padding: 3px 0;
  margin: 0; }

ul.messages > li {
  font-size: 13px;
  display: block;
  position: relative;
  background-color: #111111; }

share/static/alice-dark.css  view on Meta::CPAN


ul.messages li.monospaced + li.monospaced.consecutive {
  padding-top: 0px; }

ul.messages li.monospaced div.msg {
  font-family: Monaco, monospace;
  font-size: 10px;
  line-height: 12px;
  word-wrap: normal; }

li.monospaced div.msg span[style*="bold"] {
  letter-spacing: -1px; }

ul.messages li.event {
  font-size: 11px;
  background: #333333;
  border-bottom: 1px solid #111111; }

ul.messages li.event.notice {
  background: #eb2222;
  color: #fff; }

share/static/alice-dark.css  view on Meta::CPAN


div.config div.sidebar {
  position: absolute;
  top: 0px;
  bottom: 29px;
  left: 0px;
  width: 150px;
  background: #444444; }

div.config div.sidebar ul {
  list-style: none;
  margin: 0;
  padding: 0px;
  position: absolute;
  top: 22px;
  bottom: 24px;
  overflow: auto;
  right: 0px;
  left: 0px; }

div.config div#tabset_data {

share/static/alice-dark.css  view on Meta::CPAN

  bottom: 29px;
  left: 155px;
  right: 0px;
  overflow: auto;
  font-size: 0.8em; }

div.config div#tabset_data ul {
  display: none;
  margin: 0;
  padding: 0;
  list-style: none; }

div.config div#tabset_data ul.active {
  display: block; }

div.config div#tabset_data ul li {
  margin-bottom: 0.25em; }

div.config div.sidebar h2 {
  text-transform: uppercase;
  color: #cccccc;

share/static/alice-dark.css  view on Meta::CPAN

  color: white; }

/* auto-generated css classes for irc->html */
.bold {
  font-weight: bold; }

.ul {
  text-decoration: underline; }

.italic {
  font-style: italic; }

.fg-fff {
  color: #fff; }

.bg-fff {
  background-color: #fff; }

.fg-000 {
  color: #000; }

share/static/alice-dark.css  view on Meta::CPAN

  top: 100%;
  margin-top: 1px; }

.dropdown.bottom ul {
  bottom: 100%;
  top: auto; }

.dropdown ul {
  position: absolute;
  left: 0px;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 12px;
  background: #444444;
  border: 1px solid #222222;
  -webkit-box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
  -moz-box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
  box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
  display: none;
  white-space: nowrap; }

share/static/alice-default.css  view on Meta::CPAN

div#windows.nicklist div#nicklist_toggle {
  right: 135px; }

div#windows.nicklist div.window.active {
  right: 121px; }

ul#nicklist {
  background-color: #eaeaea;
  border-left: 1px solid #c1c1c1;
  position: absolute;
  list-style: none;
  margin: 0;
  padding: 0;
  top: 0px;
  bottom: 0px;
  left: -120px;
  right: auto;
  width: 120px;
  overflow-y: auto;
  overflow-x: hidden;
  visibility: hidden; }

share/static/alice-default.css  view on Meta::CPAN

  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,

share/static/alice-default.css  view on Meta::CPAN

  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;
  font-size: 11px;
  position: absolute;
  left: 0px;
  height: 25px;
  overflow: hidden;
  width: 5000px;
  -webkit-transition: left 0.25s ease-in-out;

share/static/alice-default.css  view on Meta::CPAN

  font-size: 11px;
  height: 15px;
  min-height: 15px;
  overflow: hidden;
  z-index: 901;
  text-decoration: none;
  color: #222222;
  -webkit-box-shadow: 2px 0 2px rgba(0, 0, 0, 0.2); }

ul.messages {
  list-style: none;
  margin: 0;
  padding: 3px 0;
  margin: 0; }

ul.messages > li {
  font-size: 13px;
  display: block;
  position: relative;
  background-color: #eaeaea; }

share/static/alice-default.css  view on Meta::CPAN


ul.messages li.monospaced + li.monospaced.consecutive {
  padding-top: 0px; }

ul.messages li.monospaced div.msg {
  font-family: Monaco, monospace;
  font-size: 10px;
  line-height: 12px;
  word-wrap: normal; }

li.monospaced div.msg span[style*="bold"] {
  letter-spacing: -1px; }

ul.messages li.event {
  font-size: 11px;
  background: #d9e7fb;
  border-bottom: 1px solid white; }

ul.messages li.event.notice {
  background: #eb2222;
  color: #fff; }

share/static/alice-default.css  view on Meta::CPAN


div.config div.sidebar {
  position: absolute;
  top: 0px;
  bottom: 29px;
  left: 0px;
  width: 150px;
  background: #dddddd; }

div.config div.sidebar ul {
  list-style: none;
  margin: 0;
  padding: 0px;
  position: absolute;
  top: 22px;
  bottom: 24px;
  overflow: auto;
  right: 0px;
  left: 0px; }

div.config div#tabset_data {

share/static/alice-default.css  view on Meta::CPAN

  bottom: 29px;
  left: 155px;
  right: 0px;
  overflow: auto;
  font-size: 0.8em; }

div.config div#tabset_data ul {
  display: none;
  margin: 0;
  padding: 0;
  list-style: none; }

div.config div#tabset_data ul.active {
  display: block; }

div.config div#tabset_data ul li {
  margin-bottom: 0.25em; }

div.config div.sidebar h2 {
  text-transform: uppercase;
  color: #777777;

share/static/alice-default.css  view on Meta::CPAN

  color: #222222; }

/* auto-generated css classes for irc->html */
.bold {
  font-weight: bold; }

.ul {
  text-decoration: underline; }

.italic {
  font-style: italic; }

.fg-fff {
  color: #fff; }

.bg-fff {
  background-color: #fff; }

.fg-000 {
  color: #000; }

share/static/alice-default.css  view on Meta::CPAN

  top: 100%;
  margin-top: 1px; }

.dropdown.bottom ul {
  bottom: 100%;
  top: auto; }

.dropdown ul {
  position: absolute;
  left: 0px;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 12px;
  background: #dddddd;
  border: 1px solid #999999;
  -webkit-box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
  -moz-box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
  box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
  display: none;
  white-space: nowrap; }

share/static/alice-solarized.css  view on Meta::CPAN

div#windows.nicklist div#nicklist_toggle {
  right: 135px; }

div#windows.nicklist div.window.active {
  right: 121px; }

ul#nicklist {
  background-color: #eee8d5;
  border-left: 1px solid #ddd7c5;
  position: absolute;
  list-style: none;
  margin: 0;
  padding: 0;
  top: 0px;
  bottom: 0px;
  left: -120px;
  right: auto;
  width: 120px;
  overflow-y: auto;
  overflow-x: hidden;
  visibility: hidden; }

share/static/alice-solarized.css  view on Meta::CPAN

  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,

share/static/alice-solarized.css  view on Meta::CPAN

  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;
  font-size: 11px;
  position: absolute;
  left: 0px;
  height: 25px;
  overflow: hidden;
  width: 5000px;
  -webkit-transition: left 0.25s ease-in-out;

share/static/alice-solarized.css  view on Meta::CPAN

  font-size: 11px;
  height: 15px;
  min-height: 15px;
  overflow: hidden;
  z-index: 901;
  text-decoration: none;
  color: #fdf6e3;
  -webkit-box-shadow: 2px 0 2px rgba(0, 0, 0, 0.2); }

ul.messages {
  list-style: none;
  margin: 0;
  padding: 3px 0;
  margin: 0; }

ul.messages > li {
  font-size: 13px;
  display: block;
  position: relative;
  background-color: #eee8d5; }

share/static/alice-solarized.css  view on Meta::CPAN


ul.messages li.monospaced + li.monospaced.consecutive {
  padding-top: 0px; }

ul.messages li.monospaced div.msg {
  font-family: Monaco, monospace;
  font-size: 10px;
  line-height: 12px;
  word-wrap: normal; }

li.monospaced div.msg span[style*="bold"] {
  letter-spacing: -1px; }

ul.messages li.event {
  font-size: 11px;
  background: #bbd6ea;
  border-bottom: 1px solid #fdf6e3; }

ul.messages li.event.notice {
  background: #eb2222;
  color: #fff; }

share/static/alice-solarized.css  view on Meta::CPAN


div.config div.sidebar {
  position: absolute;
  top: 0px;
  bottom: 29px;
  left: 0px;
  width: 150px;
  background: #586e75; }

div.config div.sidebar ul {
  list-style: none;
  margin: 0;
  padding: 0px;
  position: absolute;
  top: 22px;
  bottom: 24px;
  overflow: auto;
  right: 0px;
  left: 0px; }

div.config div#tabset_data {

share/static/alice-solarized.css  view on Meta::CPAN

  bottom: 29px;
  left: 155px;
  right: 0px;
  overflow: auto;
  font-size: 0.8em; }

div.config div#tabset_data ul {
  display: none;
  margin: 0;
  padding: 0;
  list-style: none; }

div.config div#tabset_data ul.active {
  display: block; }

div.config div#tabset_data ul li {
  margin-bottom: 0.25em; }

div.config div.sidebar h2 {
  text-transform: uppercase;
  color: #eee8d5;

share/static/alice-solarized.css  view on Meta::CPAN

  color: white; }

/* auto-generated css classes for irc->html */
.bold {
  font-weight: bold; }

.ul {
  text-decoration: underline; }

.italic {
  font-style: italic; }

.fg-fff {
  color: #fff; }

.bg-fff {
  background-color: #fff; }

.fg-000 {
  color: #000; }

share/static/alice-solarized.css  view on Meta::CPAN

  top: 100%;
  margin-top: 1px; }

.dropdown.bottom ul {
  bottom: 100%;
  top: auto; }

.dropdown ul {
  position: absolute;
  left: 0px;
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 12px;
  background: #586e75;
  border: 1px solid #44555a;
  -webkit-box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
  -moz-box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
  box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);
  display: none;
  white-space: nowrap; }

share/static/alice.js  view on Meta::CPAN

/*  Prototype JavaScript framework, version 1.7
 *  (c) 2005-2010 Sam Stephenson
 *
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site: http://www.prototypejs.org/
 *
 *--------------------------------------------------------------------------*/

var Prototype = {

  Version: '1.7',

  Browser: (function(){
    var ua = navigator.userAgent;

share/static/alice.js  view on Meta::CPAN

  var uid = element._prototypeUID;
  if (uid) {
    Element.stopObserving(element);
    element._prototypeUID = void 0;
    delete Element.Storage[uid];
  }
}

Element.Methods = {
  visible: function(element) {
    return $(element).style.display != 'none';
  },

  toggle: function(element) {
    element = $(element);
    Element[Element.visible(element) ? 'hide' : 'show'](element);
    return element;
  },

  hide: function(element) {
    element = $(element);
    element.style.display = 'none';
    return element;
  },

  show: function(element) {
    element = $(element);
    element.style.display = '';
    return element;
  },

  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
    return element;
  },

  update: (function(){

share/static/alice.js  view on Meta::CPAN

    return false;
  },

  scrollTo: function(element) {
    element = $(element);
    var pos = Element.cumulativeOffset(element);
    window.scrollTo(pos[0], pos[1]);
    return element;
  },

  getStyle: function(element, style) {
    element = $(element);
    style = style == 'float' ? 'cssFloat' : style.camelize();
    var value = element.style[style];
    if (!value || value == 'auto') {
      var css = document.defaultView.getComputedStyle(element, null);
      value = css ? css[style] : null;
    }
    if (style == 'opacity') return value ? parseFloat(value) : 1.0;
    return value == 'auto' ? null : value;
  },

  getOpacity: function(element) {
    return $(element).getStyle('opacity');
  },

  setStyle: function(element, styles) {
    element = $(element);
    var elementStyle = element.style, match;
    if (Object.isString(styles)) {
      element.style.cssText += ';' + styles;
      return styles.include('opacity') ?
        element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
    }
    for (var property in styles)
      if (property == 'opacity') element.setOpacity(styles[property]);
      else
        elementStyle[(property == 'float' || property == 'cssFloat') ?
          (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
            property] = styles[property];

    return element;
  },

  setOpacity: function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;
    return element;
  },

  makePositioned: function(element) {
    element = $(element);
    var pos = Element.getStyle(element, 'position');
    if (pos == 'static' || !pos) {
      element._madePositioned = true;
      element.style.position = 'relative';
      if (Prototype.Browser.Opera) {
        element.style.top = 0;
        element.style.left = 0;
      }
    }
    return element;
  },

  undoPositioned: function(element) {
    element = $(element);
    if (element._madePositioned) {
      element._madePositioned = undefined;
      element.style.position =
        element.style.top =
        element.style.left =
        element.style.bottom =
        element.style.right = '';
    }
    return element;
  },

  makeClipping: function(element) {
    element = $(element);
    if (element._overflow) return element;
    element._overflow = Element.getStyle(element, 'overflow') || 'auto';
    if (element._overflow !== 'hidden')
      element.style.overflow = 'hidden';
    return element;
  },

  undoClipping: function(element) {
    element = $(element);
    if (!element._overflow) return element;
    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
    element._overflow = null;
    return element;
  },

  clonePosition: function(element, source) {
    var options = Object.extend({
      setLeft:    true,
      setTop:     true,
      setWidth:   true,
      setHeight:  true,

share/static/alice.js  view on Meta::CPAN

    if (Element.getStyle(element, 'position') == 'absolute') {
      parent = Element.getOffsetParent(element);
      delta = Element.viewportOffset(parent);
    }

    if (parent == document.body) {
      delta[0] -= document.body.offsetLeft;
      delta[1] -= document.body.offsetTop;
    }

    if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
    if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
    if (options.setHeight) element.style.height = source.offsetHeight + 'px';
    return element;
  }
};

Object.extend(Element.Methods, {
  getElementsBySelector: Element.Methods.select,

  childElements: Element.Methods.immediateDescendants
});

share/static/alice.js  view on Meta::CPAN

    names: {
      className: 'class',
      htmlFor:   'for'
    },
    values: { }
  }
};

if (Prototype.Browser.Opera) {
  Element.Methods.getStyle = Element.Methods.getStyle.wrap(
    function(proceed, element, style) {
      switch (style) {
        case 'height': case 'width':
          if (!Element.visible(element)) return null;

          var dim = parseInt(proceed(element, style), 10);

          if (dim !== element['offset' + style.capitalize()])
            return dim + 'px';

          var properties;
          if (style === 'height') {
            properties = ['border-top-width', 'padding-top',
             'padding-bottom', 'border-bottom-width'];
          }
          else {
            properties = ['border-left-width', 'padding-left',
             'padding-right', 'border-right-width'];
          }
          return properties.inject(dim, function(memo, property) {
            var val = proceed(element, property);
            return val === null ? memo : memo - parseInt(val, 10);
          }) + 'px';
        default: return proceed(element, style);
      }
    }
  );

  Element.Methods.readAttribute = Element.Methods.readAttribute.wrap(
    function(proceed, element, attribute) {
      if (attribute === 'title') return element.title;
      return proceed(element, attribute);
    }
  );
}

else if (Prototype.Browser.IE) {
  Element.Methods.getStyle = function(element, style) {
    element = $(element);
    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
    var value = element.style[style];
    if (!value && element.currentStyle) value = element.currentStyle[style];

    if (style == 'opacity') {
      if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
        if (value[1]) return parseFloat(value[1]) / 100;
      return 1.0;
    }

    if (value == 'auto') {
      if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
        return element['offset' + style.capitalize()] + 'px';
      return null;
    }
    return value;
  };

  Element.Methods.setOpacity = function(element, value) {
    function stripAlpha(filter){
      return filter.replace(/alpha\([^\)]*\)/gi,'');
    }
    element = $(element);
    var currentStyle = element.currentStyle;
    if ((currentStyle && !currentStyle.hasLayout) ||
      (!currentStyle && element.style.zoom == 'normal'))
        element.style.zoom = 1;

    var filter = element.getStyle('filter'), style = element.style;
    if (value == 1 || value === '') {
      (filter = stripAlpha(filter)) ?
        style.filter = filter : style.removeAttribute('filter');
      return element;
    } else if (value < 0.00001) value = 0;
    style.filter = stripAlpha(filter) +
      'alpha(opacity=' + (value * 100) + ')';
    return element;
  };

  Element._attributeTranslations = (function(){

    var classProp = 'className',
        forProp = 'for',
        el = document.createElement('div');

share/static/alice.js  view on Meta::CPAN

                if (!attribute) return null;
                return attribute.strip();
              };
            }
            el = null;
            return f;
          })(),
          _flag: function(element, attribute) {
            return $(element).hasAttribute(attribute) ? attribute : null;
          },
          style: function(element) {
            return element.style.cssText.toLowerCase();
          },
          title: function(element) {
            return element.title;
          }
        }
      }
    }
  })();

  Element._attributeTranslations.write = {
    names: Object.extend({
      cellpadding: 'cellPadding',
      cellspacing: 'cellSpacing'
    }, Element._attributeTranslations.read.names),
    values: {
      checked: function(element, value) {
        element.checked = !!value;
      },

      style: function(element, value) {
        element.style.cssText = value ? value : '';
      }
    }
  };

  Element._attributeTranslations.has = {};

  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
      'encType maxLength readOnly longDesc frameBorder').each(function(attr) {
    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
    Element._attributeTranslations.has[attr.toLowerCase()] = attr;

share/static/alice.js  view on Meta::CPAN

          Element.select(element, expression)[index || 0];
      }
    })();
  }

}

else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1) ? 0.999999 :
      (value === '') ? '' : (value < 0.00001) ? 0 : value;
    return element;
  };
}

else if (Prototype.Browser.WebKit) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;

    if (value == 1)
      if (element.tagName.toUpperCase() == 'IMG' && element.width) {
        element.width++; element.width--;
      } else try {
        var n = document.createTextNode(' ');
        element.appendChild(n);
        element.removeChild(n);
      } catch (e) { }

share/static/alice.js  view on Meta::CPAN

      return null;
    }

    if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
      return window.parseFloat(value);
    }

    var isPercentage = value.include('%'), isViewport = (context === document.viewport);

    if (/\d/.test(value) && element && element.runtimeStyle && !(isPercentage && isViewport)) {
      var style = element.style.left, rStyle = element.runtimeStyle.left;
      element.runtimeStyle.left = element.currentStyle.left;
      element.style.left = value || 0;
      value = element.style.pixelLeft;
      element.style.left = style;
      element.runtimeStyle.left = rStyle;

      return value;
    }

    if (element && isPercentage) {
      context = context || element.parentNode;
      var decimal = toDecimal(value);
      var whole = null;
      var position = element.getStyle('position');

share/static/alice.js  view on Meta::CPAN

      }
      element = $(element.parentNode);
    }
    return true;
  }

  var hasLayout = Prototype.K;
  if ('currentStyle' in document.documentElement) {
    hasLayout = function(element) {
      if (!element.currentStyle.hasLayout) {
        element.style.zoom = 1;
      }
      return element;
    };
  }

  function cssNameFor(key) {
    if (key.include('border')) key = key + '-width';
    return key.camelize();
  }

share/static/alice.js  view on Meta::CPAN

    _begin: function() {
      if (this._prepared) return;

      var element = this.element;
      if (isDisplayed(element)) {
        this._prepared = true;
        return;
      }

      var originalStyles = {
        position:   element.style.position   || '',
        width:      element.style.width      || '',
        visibility: element.style.visibility || '',
        display:    element.style.display    || ''
      };

      element.store('prototype_original_styles', originalStyles);

      var position = element.getStyle('position'),
       width = element.getStyle('width');

      if (width === "0px" || width === null) {
        element.style.display = 'block';
        width = element.getStyle('width');
      }

      var context = (position === 'fixed') ? document.viewport :
       element.parentNode;

      element.setStyle({
        position:   'absolute',
        visibility: 'hidden',
        display:    'block'

share/static/alice.js  view on Meta::CPAN

         this.get('margin-right');
      }

      element.setStyle({ width: newWidth + 'px' });

      this._prepared = true;
    },

    _end: function() {
      var element = this.element;
      var originalStyles = element.retrieve('prototype_original_styles');
      element.store('prototype_original_styles', null);
      element.setStyle(originalStyles);
      this._prepared = false;
    },

    _compute: function(property) {
      var COMPUTATIONS = Element.Layout.COMPUTATIONS;
      if (!(property in COMPUTATIONS)) {
        throw "Property not found.";
      }

share/static/alice.js  view on Meta::CPAN

  }

  function getDimensions(element) {
    element = $(element);
    var display = Element.getStyle(element, 'display');

    if (display && display !== 'none') {
      return { width: element.offsetWidth, height: element.offsetHeight };
    }

    var style = element.style;
    var originalStyles = {
      visibility: style.visibility,
      position:   style.position,
      display:    style.display
    };

    var newStyles = {
      visibility: 'hidden',
      display:    'block'
    };

    if (originalStyles.position !== 'fixed')
      newStyles.position = 'absolute';

share/static/alice.js  view on Meta::CPAN

      return element;
    }

    var offsetParent = getOffsetParent(element);
    var eOffset = element.viewportOffset(),
     pOffset = offsetParent.viewportOffset();

    var offset = eOffset.relativeTo(pOffset);
    var layout = element.getLayout();

    element.store('prototype_absolutize_original_styles', {
      left:   element.getStyle('left'),
      top:    element.getStyle('top'),
      width:  element.getStyle('width'),
      height: element.getStyle('height')
    });

    element.setStyle({
      position: 'absolute',
      top:    offset.top + 'px',
      left:   offset.left + 'px',

share/static/alice.js  view on Meta::CPAN

    return element;
  }

  function relativize(element) {
    element = $(element);
    if (Element.getStyle(element, 'position') === 'relative') {
      return element;
    }

    var originalStyles =
     element.retrieve('prototype_absolutize_original_styles');

    if (originalStyles) element.setStyle(originalStyles);
    return element;
  }

  if (Prototype.Browser.IE) {
    getOffsetParent = getOffsetParent.wrap(
      function(proceed, element) {
        element = $(element);

share/static/alice.js  view on Meta::CPAN

};

Element.setContentZoom = function(element, percent) {
  element = $(element);
  element.setStyle({fontSize: (percent/100) + 'em'});
  if (Prototype.Browser.WebKit) window.scrollBy(0,0);
  return element;
};

Element.getInlineOpacity = function(element){
  return $(element).style.opacity || '';
};

Element.forceRerendering = function(element) {
  try {
    element = $(element);
    var n = document.createTextNode(' ');
    element.appendChild(n);
    element.removeChild(n);
  } catch(e) { }
};

share/static/alice.js  view on Meta::CPAN

  },
  tagifyText: function(element) {
    var tagifyStyle = 'position:relative';
    if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';

    element = $(element);
    $A(element.childNodes).each( function(child) {
      if (child.nodeType==3) {
        child.nodeValue.toArray().each( function(character) {
          element.insertBefore(
            new Element('span', {style: tagifyStyle}).update(
              character == ' ' ? String.fromCharCode(160) : character),
              child);
        });
        Element.remove(child);
      }
    });
  },
  multiple: function(element, effect) {
    var elements;
    if (((typeof element == 'object') ||

share/static/alice.js  view on Meta::CPAN

      scaleTo:   percent
    }, 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;

share/static/alice.js  view on Meta::CPAN

    effect.element.setOpacity(effect.options.from).show();
  }}, arguments[1] || { });
  return new Effect.Opacity(element,options);
};

Effect.Puff = function(element) {
  element = $(element);
  var oldStyle = {
    opacity: element.getInlineOpacity(),
    position: element.getStyle('position'),
    top:  element.style.top,
    left: element.style.left,
    width: element.style.width,
    height: element.style.height
  };
  return new Effect.Parallel(
   [ new Effect.Scale(element, 200,
      { sync: true, scaleFromCenter: true, scaleContent: true, restoreAfterFinish: true }),
     new Effect.Opacity(element, { sync: true, to: 0.0 } ) ],
     Object.extend({ duration: 1.0,
      beforeSetupInternal: function(effect) {
        Position.absolutize(effect.effects[0].element);
      },
      afterFinishInternal: function(effect) {

share/static/alice.js  view on Meta::CPAN


Effect.Grow = function(element) {
  element = $(element);
  var options = Object.extend({
    direction: 'center',
    moveTransition: Effect.Transitions.sinoidal,
    scaleTransition: Effect.Transitions.sinoidal,
    opacityTransition: Effect.Transitions.full
  }, arguments[1] || { });
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    height: element.style.height,
    width: element.style.width,
    opacity: element.getInlineOpacity() };

  var dims = element.getDimensions();
  var initialMoveX, initialMoveY;
  var moveX, moveY;

  switch (options.direction) {
    case 'top-left':
      initialMoveX = initialMoveY = moveX = moveY = 0;
      break;

share/static/alice.js  view on Meta::CPAN


Effect.Shrink = function(element) {
  element = $(element);
  var options = Object.extend({
    direction: 'center',
    moveTransition: Effect.Transitions.sinoidal,
    scaleTransition: Effect.Transitions.sinoidal,
    opacityTransition: Effect.Transitions.none
  }, arguments[1] || { });
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    height: element.style.height,
    width: element.style.width,
    opacity: element.getInlineOpacity() };

  var dims = element.getDimensions();
  var moveX, moveY;

  switch (options.direction) {
    case 'top-left':
      moveX = moveY = 0;
      break;
    case 'top-right':

share/static/alice.js  view on Meta::CPAN


  return new Effect.Opacity(element,
    Object.extend(Object.extend({  duration: 2.0, from: 0,
      afterFinishInternal: function(effect) { effect.element.setStyle({opacity: oldOpacity}); }
    }, options), {transition: reverser}));
};

Effect.Fold = function(element) {
  element = $(element);
  var oldStyle = {
    top: element.style.top,
    left: element.style.left,
    width: element.style.width,
    height: element.style.height };
  element.makeClipping();
  return new Effect.Scale(element, 5, Object.extend({
    scaleContent: false,
    scaleX: false,
    afterFinishInternal: function(effect) {
    new Effect.Scale(element, 1, {
      scaleContent: false,
      scaleY: false,
      afterFinishInternal: function(effect) {
        effect.element.hide().undoClipping().setStyle(oldStyle);
      } });
  }}, arguments[1] || { }));
};

Effect.Morph = Class.create(Effect.Base, {
  initialize: function(element) {
    this.element = $(element);
    if (!this.element) throw(Effect._elementDoesNotExistError);
    var options = Object.extend({
      style: { }
    }, arguments[1] || { });

    if (!Object.isString(options.style)) this.style = $H(options.style);
    else {
      if (options.style.include(':'))
        this.style = options.style.parseStyle();
      else {
        this.element.addClassName(options.style);
        this.style = $H(this.element.getStyles());
        this.element.removeClassName(options.style);
        var css = this.element.getStyles();
        this.style = this.style.reject(function(style) {
          return style.value == css[style.key];
        });
        options.afterFinishInternal = function(effect) {
          effect.element.addClassName(effect.options.style);
          effect.transforms.each(function(transform) {
            effect.element.style[transform.style] = '';
          });
        };
      }
    }
    this.start(options);
  },

  setup: function(){
    function parseColor(color){
      if (!color || ['rgba(0, 0, 0, 0)','transparent'].include(color)) color = '#ffffff';
      color = color.parseColor();
      return $R(0,2).map(function(i){
        return parseInt( color.slice(i*2+1,i*2+3), 16 );
      });
    }
    this.transforms = this.style.map(function(pair){
      var property = pair[0], value = pair[1], unit = null;

      if (value.parseColor('#zzzzzz') != '#zzzzzz') {
        value = value.parseColor();
        unit  = 'color';
      } else if (property == 'opacity') {
        value = parseFloat(value);
        if (Prototype.Browser.IE && (!this.element.currentStyle.hasLayout))
          this.element.setStyle({zoom: 1});
      } else if (Element.CSS_LENGTH.test(value)) {
          var components = value.match(/^([\+\-]?[0-9\.]+)(.*)$/);
          value = parseFloat(components[1]);
          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) {
    var style = { }, transform, i = this.transforms.length;
    while(i--)
      style[(transform = this.transforms[i]).style] =
        transform.unit=='color' ? '#'+
          (Math.round(transform.originalValue[0]+
            (transform.targetValue[0]-transform.originalValue[0])*position)).toColorPart() +
          (Math.round(transform.originalValue[1]+
            (transform.targetValue[1]-transform.originalValue[1])*position)).toColorPart() +
          (Math.round(transform.originalValue[2]+
            (transform.targetValue[2]-transform.originalValue[2])*position)).toColorPart() :
        (transform.originalValue +
          (transform.targetValue - transform.originalValue) * position).toFixed(3) +
            (transform.unit === null ? '' : transform.unit);
    this.element.setStyle(style, true);
  }
});

Effect.Transform = Class.create({
  initialize: function(tracks){
    this.tracks  = [];
    this.options = arguments[1] || { };
    this.addTracks(tracks);
  },
  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)) });

share/static/alice.js  view on Meta::CPAN

  'fontSize fontWeight height left letterSpacing lineHeight ' +
  'marginBottom marginLeft marginRight marginTop markerOffset maxHeight '+
  'maxWidth minHeight minWidth opacity outlineColor outlineOffset ' +
  'outlineWidth paddingBottom paddingLeft paddingRight paddingTop ' +
  'right textIndent top width wordSpacing zIndex');

Element.CSS_LENGTH = /^(([\+\-]?[0-9\.]+)(em|ex|px|in|cm|mm|pt|pc|\%))|0$/;

String.__parseStyleElement = document.createElement('div');
String.prototype.parseStyle = function(){
  var style, styleRules = $H();
  if (Prototype.Browser.WebKit)
    style = new Element('div',{style:this}).style;
  else {
    String.__parseStyleElement.innerHTML = '<div style="' + this + '"></div>';
    style = String.__parseStyleElement.childNodes[0].style;
  }

  Element.CSS_PROPERTIES.each(function(property){
    if (style[property]) styleRules.set(property, style[property]);
  });

  if (Prototype.Browser.IE && this.include('opacity'))
    styleRules.set('opacity', this.match(/opacity:\s*((?:0|1)?(?:\.\d*)?)/)[1]);

  return styleRules;
};

if (document.defaultView && document.defaultView.getComputedStyle) {
  Element.getStyles = function(element) {
    var css = document.defaultView.getComputedStyle($(element), null);
    return Element.CSS_PROPERTIES.inject({ }, function(styles, property) {
      styles[property] = css[property];
      return styles;
    });
  };
} else {
  Element.getStyles = function(element) {
    element = $(element);
    var css = element.currentStyle, styles;
    styles = Element.CSS_PROPERTIES.inject({ }, function(results, property) {
      results[property] = css[property];
      return results;
    });
    if (!styles.opacity) styles.opacity = element.getOpacity();
    return styles;
  };
}

Effect.Methods = {
  morph: function(element, style) {
    element = $(element);
    new Effect.Morph(element, Object.extend({ style: style }, arguments[2] || { }));
    return element;
  },
  visualEffect: function(element, effect, options) {
    element = $(element);
    var s = effect.dasherize().camelize(), klass = s.charAt(0).toUpperCase() + s.substring(1);
    new Effect[klass](element, options);
    return element;
  },
  highlight: function(element, options) {
    element = $(element);

share/static/alice.js  view on Meta::CPAN

    }
  },

  startDrag: function(event) {
    this.dragging = true;
    if(!this.delta)
      this.delta = this.currentDelta();

    if(this.options.zindex) {
      this.originalZ = parseInt(Element.getStyle(this.element,'z-index') || 0);
      this.element.style.zIndex = this.options.zindex;
    }

    if(this.options.ghosting) {
      this._clone = this.element.cloneNode(true);
      this._originallyAbsolute = (this.element.getStyle('position') == 'absolute');
      if (!this._originallyAbsolute)
        Position.absolutize(this.element);
      this.element.parentNode.insertBefore(this._clone, this.element);
    }

share/static/alice.js  view on Meta::CPAN

    var d = this.currentDelta();
    if(revert && this.options.reverteffect) {
      if (dropped == 0 || revert != 'failure')
        this.options.reverteffect(this.element,
          d[1]-this.delta[1], d[0]-this.delta[0]);
    } else {
      this.delta = d;
    }

    if(this.options.zindex)
      this.element.style.zIndex = this.originalZ;

    if(this.options.endeffect)
      this.options.endeffect(this.element);

    Draggables.deactivate(this);
    Droppables.reset();
  },

  keyPress: function(event) {
    if(event.keyCode!=Event.KEY_ESC) return;

share/static/alice.js  view on Meta::CPAN

      } 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
  },

  stopScrolling: function() {
    if(this.scrollInterval) {
      clearInterval(this.scrollInterval);
      this.scrollInterval = null;
      Draggables._lastScrollPointer = null;
    }
  },

share/static/alice.js  view on Meta::CPAN

      constraint:  options.constraint,
      handle:      options.handle };

    if(options.starteffect)
      options_for_draggable.starteffect = options.starteffect;

    if(options.reverteffect)
      options_for_draggable.reverteffect = options.reverteffect;
    else
      if(options.ghosting) options_for_draggable.reverteffect = function(element) {
        element.style.top  = 0;
        element.style.left = 0;
      };

    if(options.endeffect)
      options_for_draggable.endeffect = options.endeffect;

    if(options.zindex)
      options_for_draggable.zindex = options.zindex;

    var options_for_droppable = {
      overlap:     options.overlap,

share/static/alice.js  view on Meta::CPAN


  onHover: function(element, dropon, overlap) {
    if(Element.isParent(dropon, element)) return;

    if(overlap > .33 && overlap < .66 && Sortable.options(dropon).tree) {
      return;
    } else if(overlap>0.5) {
      Sortable.mark(dropon, 'before');
      if(dropon.previousSibling != element) {
        var oldParentNode = element.parentNode;
        element.style.visibility = "hidden"; // fix gecko rendering
        dropon.parentNode.insertBefore(element, dropon);
        if(dropon.parentNode!=oldParentNode)
          Sortable.options(oldParentNode).onChange(element);
        Sortable.options(dropon.parentNode).onChange(element);
      }
    } else {
      Sortable.mark(dropon, 'after');
      var nextElement = dropon.nextSibling || null;
      if(nextElement != element) {
        var oldParentNode = element.parentNode;
        element.style.visibility = "hidden"; // fix gecko rendering
        dropon.parentNode.insertBefore(element, nextElement);
        if(dropon.parentNode!=oldParentNode)
          Sortable.options(oldParentNode).onChange(element);
        Sortable.options(dropon.parentNode).onChange(element);
      }
    }
  },

  onEmptyHover: function(element, dropon, overlap) {
    var oldParentNode = element.parentNode;

share/static/alice.js  view on Meta::CPAN

		else {
			throw('Huh ?!');
		}
		f = f.substring(m[0].length);
	}
	return o.join('');
}
/*  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);

share/static/alice.js  view on Meta::CPAN

    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;
    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,
     italicSelection:          italicSelection,
     italicSelected:           italicSelected,
     strikethroughSelection:   strikethroughSelection,

share/static/alice.js  view on Meta::CPAN

     getSelectedStyles:        getSelectedStyles,

    commands: $H({}),

    queryCommands: $H({
      link:          linkSelected,
      orderedlist:   orderedListSelected,
      unorderedlist: unorderedListSelected
    }),

    styleSelectors: $H({
      fontname:    'fontFamily',
      fontsize:    'fontSize',
      forecolor:   'color',
      hilitecolor: 'backgroundColor',
      backcolor:   'backgroundColor'
    })
  };
})(window);

if (Prototype.Browser.IE) {

share/static/alice.js  view on Meta::CPAN

});
WysiHat.Formatting = (function() {
  var ACCUMULATING_LINE      = {};
  var EXPECTING_LIST_ITEM    = {};
  var ACCUMULATING_LIST_ITEM = {};

  return {
    getBrowserMarkupFrom: function(applicationMarkup) {
      var container = new Element("div").update(applicationMarkup);

      function spanify(element, style) {
        element.replace(
          '<span style="' + style +
          '" class="Apple-style-span">' +
          element.innerHTML + '</span>'
        );
      }

      function convertStrongsToSpans() {
        container.select("strong").each(function(element) {
          spanify(element, "font-weight: bold");
        });
      }

      function convertEmsToSpans() {
        container.select("em").each(function(element) {
          spanify(element, "font-style: italic");
        });
      }

      function convertDivsToParagraphs() {
        container.select("div").each(function(element) {
          element.replace("<p>" + element.innerHTML + "</p>");
        });
      }

      if (Prototype.Browser.WebKit || Prototype.Browser.Gecko) {

share/static/alice.js  view on Meta::CPAN

WysiHat.Toolbar.ButtonSets = {};

WysiHat.Toolbar.ButtonSets.Basic = $A([
  { label: "Bold" },
  { label: "Underline" },
  { label: "Italic" }
]);
/*	SWFObject v2.2 <http://code.google.com/p/swfobject/>
	is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>
*/
var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,...

(function() {

  if (window.WebSocket && !window.WEB_SOCKET_FORCE_FLASH) return;

  var logger;
  if (window.WEB_SOCKET_LOGGER) {
    logger = WEB_SOCKET_LOGGER;
  } else if (window.console && window.console.log && window.console.error) {
    logger = window.console;

share/static/alice.js  view on Meta::CPAN

        logger.error(
            "[WebSocket] You must host HTML and WebSocketMain.swf in the same host " +
            "('" + location.host + "' != '" + swfHost + "'). " +
            "See also 'How to host HTML file and SWF file in different domains' section " +
            "in README.md. If you use WebSocketMainInsecure.swf, you can suppress this message " +
            "by WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR = true;");
      }
    }
    var container = document.createElement("div");
    container.id = "webSocketContainer";
    container.style.position = "absolute";
    if (WebSocket.__isFlashLite()) {
      container.style.left = "0px";
      container.style.top = "0px";
    } else {
      container.style.left = "-100px";
      container.style.top = "-100px";
    }
    var holder = document.createElement("div");
    holder.id = "webSocketFlash";
    container.appendChild(holder);
    document.body.appendChild(container);
    swfobject.embedSWF(
      WEB_SOCKET_SWF_LOCATION,
      "webSocketFlash",
      "1" /* width */,
      "1" /* height */,

share/static/alice.js  view on Meta::CPAN

        options[pref] = $(pref).checked ? "show" : "hide";
      });
      $A($("highlights").options).each(function(option) {
        options.highlights.push(option.value);
      });

      $A($("monospace_nicks").options).each(function(option) {
        options.monospace_nicks.push(option.value);
      });

      ["style", "timeformat", "quitmsg"].each(function(pref) {
        options[pref] = $(pref).value;
      });

      Alice.prefs.remove();

			new Ajax.Request('/save', {
        method: 'get',
        parameters: options,
        onSuccess: function(){
          var reload = (alice.options.avatars != options.avatars ||
                        alice.options.images != options.images ||
                        alice.options.style != options.style);

          if (reload) {
            window.location.reload();
          }
          else {
            alice.options = options;
            if (window.location.toString().match(/safe/i)) {
              alice.options.avatars = "hide";
              alice.options.images = "hide";
            }

share/static/alice.js  view on Meta::CPAN

             +data.provider_name+'</a></sup>'
    });
    a.up("div.msg").insert(elem);
    win.scrollToPosition(position);

    a.observe('click', function(e) {
      e.stop();
      var position = win.captureScrollPosition();
      if (elem.innerHTML) {
        elem.innerHTML = "";
        elem.style.display = "none";
        return;
      }
      elem.style.display = "block";
      elem.innerHTML = html;
      Alice.makeLinksClickable(elem);
      var images = elem.select("img");
      if (images.length) {
        images.each(function(img) {
          img.observe("load", function(e) {
            win.scrollToPosition(position);
            img.stopObserving(img, "load");
          });
        });

share/static/alice.js  view on Meta::CPAN

      right: "0px",
    });
  },

  shiftTabs: function(shift) {
    var current = this.tabShift();

    var left = current + shift;
    var time = Math.min(Math.max(0.1, Math.abs(shift) / 100), 0.5);

    this.tabs.style.webkitTransitionDuration = time+"s";
    this.tabs.setStyle({left: left+"px"});
    this.tabs_layout = this.tabs.getLayout();
  },

  shiftEnd: function(e) {
    this.tabs_layout = this.tabs.getLayout();
    this.updateOverflowMenus();
  },

  makeSortable: function() {

share/static/alice.js  view on Meta::CPAN

          var diff = (time - win.lasttimestamp) / 1000;
          remove = !(diff >= 300 || (diff > 60 && time.getMinutes() % 5 == 0));
          if (!remove) win.lasttimestamp = time;
        }

        if (remove) {
          stamp.remove();
        }
        else {
          stamp.update(Alice.epochToLocal(seconds, this.options.timeformat));
          stamp.style.opacity = 1;
        }
      },

      function(li, win) {
        if (!this.overlayVisible || !li.hasClassName("avatar")) return;

        var nick = li.down('span.nick');
        if (nick) nick.style.opacity = 1;
      },

      function(li, win) {
        if (win.bulk_insert) return;

        if (li.hasClassName("message") && !win.active && win.title != "info") {
          if (li.hasClassName("highlight") || win.type == "privmsg")
            win.markUnread("highlight");
          else if (!li.hasClassName("self"))
            win.markUnread();

share/static/alice.js  view on Meta::CPAN

        }
      }
    ];
  },

  toggleOverlay: function () {
    this.overlayVisible = !this.overlayVisible;
    var opacity = this.overlayVisible ? 1 : 0;

    $$("li.avatar span.nick").each(function(span){
      span.style.opacity = opacity;
    });
  }

});
Alice.Connection = {
  gotoLogin: function() {
    window.location = "/login";
  },

  connect: function(cb) {

share/static/alice.js  view on Meta::CPAN

      if (li.hasClassName("consecutive")) {
        var stem = li.previous("li:not(.consecutive)");
        if (!stem) return;
        nick = stem.down("span.nick");
      } else {
        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);
    }
  },

share/static/alice.js  view on Meta::CPAN

    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");

share/static/alice.js  view on Meta::CPAN

    img.observe("load", function(){
      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});
  }
});

share/templates/config.html  view on Meta::CPAN

      </tr>

      <tr>
        <td>
          <label>Server address</label>
          <input type="text" name="<?= $network ?>_host" value="<?= $config->{host} || "" ?>" size="15"/>
        </td>

        <td>
          <label>Port</label>
          <input type="text" name="<?= $network ?>_port" value="<?= $config->{port} || "" ?>" size="6" style="float:left"/>

            <input type="checkbox" name="<?= $network ?>_ssl"<? if ($config->{ssl}) { ?> checked="checked"<? } ?> />
            <span style="font-size:0.7em">SSL</span>
        </td>
      </tr>

      <tr>
        <td>
          <label>Nick</label>
          <input type="text" name="<?= $network ?>_nick" value="<?= $config->{nick} || ""?>" size="15" />
        </td>

        <td>

share/templates/config.html  view on Meta::CPAN


        <td>
          <label>Password</label>
          <input type="text" name="<?= $network ?>_password" value="<?= $config->{password} || ""?>" size="15" />
        </td>
      </tr>

      <tr>
        <td>
          <label>Channels
            <span style="font-size:0.8em">(e.g. <span style="font-family:monospace;font-size:1em">#alice</span>)</span>
          </label>
          <select name="<?= $network ?>_channels" multiple="multiple" id="channels_<?= $network ?>" class="channelselect">
            <? for my $channel (@{$config->{channels}}) { ?>
            <option value="<?= $channel ?>"><?= $channel ?></option>
            <? } ?>
          </select>
          <div class="controls">
            <a href="#" onclick="return Alice.connections.addChannel('<?= $network ?>')">Add</a>
            <a href="#" onclick="return Alice.connections.removeChannels('<?= $network ?>')">Remove</a>
          </div>

share/templates/config.html  view on Meta::CPAN

          </div>
        </td>
      </tr>
    </table>

? }

  </div>

  <div class="buttons">
    <a style="text-decoration:none;color:#fff;font-size:11px" href="/export" target="_blank">export config</a>
    <button type="submit">Save</button>
    <button onclick="Alice.connections.remove(); return false;">Cancel</button>
  </div>

  </form>

</div>

share/templates/help.html  view on Meta::CPAN

? my $app = shift;

<div id="help" style="display:none">
  <h1>Alice Help</h1>
  <div id="helpclose">close</div>
  <div id="topics">
    <dl>
      <h2>Commands</h2>
      <? for my $command ($app->commands) { ?>
        <? next unless $command->{eg} and $command->{desc}; ?>
        <dt><?= $command->{eg} ?></dt>
        <dd><?= $command->{desc} ?></dd>
      <? } ?>

share/templates/index_head.html  view on Meta::CPAN

? my ($app, @windows) = @_;
? my $titlewin = @windows > 1 ? $windows[1] : $windows[0];
<!DOCTYPE html>
<html>
  <head>
    <title><?= $titlewin->title ?></title>
    <script type="text/javascript" src="<?= $app->static_url("alice.js") ?>?v=4"></script>
    <link rel="shortcut icon" href="<?= $app->static_url("favicon.ico") ?>">
    <link type="text/css" rel="stylesheet" href="<?= $app->static_url("alice-".$app->config->style.".css") ?>?v=5" />
    <link type="text/css" rel="stylesheet" href="https://noembed.com/noembed.css" />
    <link rel="apple-touch-icon" href="<?= $app->static_url("image/alice.png") ?>" />
    <link rel="apple-touch-startup-image" href="<?= $app->static_url("image/alice.png") ?>" />
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
  </head>
  <body>
    <img style="position:absolute;top:-100px;left:-100px" src="<?= $app->static_url("image/sprites.png") ?>" />

    <div class="dropdown top" id="config_menu">
      <?= $_mt->render_file("alice_menu.html", $app) ?>
    </div>

    <div id="topic">No topic set.</div>
    <div id="windows" class="compact-scroll">
      <div id="nicklist_toggle"></div>

share/templates/join.html  view on Meta::CPAN

        <label for="join_network">Network</label>
        <select id="join_network">
          <? my @ircs = sort {$a->name cmp $b->name} $app->connected_ircs ?>
          <? for my $irc (@ircs) { ?>
            <option name="<?= $irc->name ?>"><?= $irc->name ?></option>
          <? } ?>
        </select>
      </td>
    </tr>
    <tr>
      <td style="padding-top:0">
        <label for="join_channel">Channel</label>
        <input type="text" id="join_channel" style="width:150px" value=""/>
      </td>
    </tr>
  </table>

  <div class="buttons">
    <button type="submit" onclick="Alice.joinChannel()">Save</button>
    <button onclick="alice.input.disabled = false; $('join').remove(); return false;">Cancel</button>
  </div>
</div>

share/templates/login.html  view on Meta::CPAN

? my ($app, $dest, $error) = @_;
<html>
  <head>
    <title>Use Alice Login</title>
    <link rel="shortcut icon" href="<?= $app->static_url("favicon.ico") ?>">
    <style type="text/css">
      body {
        text-align: center;
        font-family: Helvetica, Arial, sans-serif;
        font-size: 12px;
        background: #eee;
      }
      form {
        display: block;
        width: 150px;
        margin: 0 auto;

share/templates/login.html  view on Meta::CPAN

      input[type="submit"] {
        font-size: 16px;
        margin-bottom: 0;
        margin-top: 30px;
      }
      .error {
        color: #d00b0b;
        display: block;
        margin-top: 15px;
      }
    </style>
    <link rel="apple-touch-icon" href="<?= $app->static_url("image/alice.png") ?>" />
    <link rel="apple-touch-startup-image" href="<?= $app->static_url("image/alice.png") ?>" />
    <meta name="viewport" content="width=device-width; initial-scale=1; maximum-scale=1" />
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="format-detection" content="telephone=no">
  </head>
  <body>
    <form action="/login" method="post">
      <input type="hidden" name="dest" value="<?= $dest || "/" ?>" />

share/templates/new_server.html  view on Meta::CPAN

      </tr>

      <tr>
        <td>
          <label>Server address</label>
          <input type="text" name="<?= $alias ?>_host" value="" size="15"/>
        </td>

        <td>
          <label>Port</label>
          <input type="text" name="<?= $alias ?>_port" value="6667" size="6" style="float:left"/>

            <input type="checkbox" name="<?= $alias ?>_ssl" />
            <span style="font-size:0.7em">SSL</span>
        </td>
      </tr>

      <tr>
        <td>
          <label>Nick</label>
          <input type="text" name="<?= $alias ?>_nick" value="" size="15" />
        </td>

        <td>

share/templates/new_server.html  view on Meta::CPAN


        <td>
          <label>Password</label>
          <input type="text" name="<?= $alias ?>_password" value="" size="15" />
        </td>
      </tr>

      <tr>
        <td>
          <label>Channels
            <span style="font-size:0.8em">(e.g. <span style="font-family:monospace;font-size:1em">#alice</span>)</span>
          </label>
          <select name="<?= $alias ?>_channels" multiple="multiple" id="channels_<?= $alias ?>" class="channelselect">
          </select>
          <div class="controls">
            <a href="#" onclick="return Alice.connections.addChannel('<?= $alias ?>')">Add</a>
            <a href="#" onclick="return Alice.connections.removeChannels('<?= $alias ?>')">Remove</a>
          </div>
        </td>

        <td>

share/templates/prefs.html  view on Meta::CPAN

            </td></tr>

            <tr><td>
              <input type="checkbox"<? if ($app->config->avatars eq "show") { ?> checked="checked"<? } ?> name="avatars" id="avatars" />
              <label for="avatars">Show avatars?</label>
            </td></tr>

            <tr><td>
              <input type="checkbox"<? if ($app->config->alerts eq "show") { ?> checked="checked"<? } ?> name="alerts" id="alerts" />
              <label for="alerts">Enable alerts?</label>
              <a style="font-size:10px" href="javascript:void(0)" onclick="window.webkitNotifications.requestPermission()">Grant permission</a>
            </td></tr>

            <tr><td>
              <input type="checkbox"<? if ($app->config->audio eq "show") { ?> checked="checked"<? } ?> name="audio" id="audio" />
              <label for="audio">Enable audio?</label>
            </td></tr>

            <tr><td>
              <label for="style">Style</label>
              <select name="style" id="style">
                <option value="default"<? if ($app->config->style eq "default") {?> selected<? } ?>>Default</option>
                <option value="dark"<? if ($app->config->style eq "dark") {?> selected<? } ?>>Dark</option>
                <option value="solarized"<? if ($app->config->style eq "solarized") {?> selected<? } ?>>Solarized</option>
              </select>
            </td></tr>

            <tr><td>
              <label for="timeformat">Time Format</label>
              <select name="timeformat" id="timeformat">
                <option value="12"<? if ($app->config->timeformat eq "12") {?> selected<? } ?>>12 Hour</option>
                <option value="24"<? if ($app->config->timeformat eq "24") {?> selected<? } ?>>24 Hour</option>
              </select>
            </td></tr>

share/templates/prefs.html  view on Meta::CPAN

              </select>
              <div class="controls">
                <a href="#" onclick="return Alice.prefs.addNick()">Add</a>
                <a href="#" onclick="return Alice.prefs.removeNicks()">Remove</a>
              </div>
            </td></tr>
          </table>
        </td>
      </tr>
      <tr>
        <td style="padding-top:0" colspan="2">
          <label for="quitmsg">Quit Message</label>
          <input type="text" name="quitmsg" id="quitmsg" style="width:295px" value="<?= $app->config->quitmsg ?>"/>
        </td>
      </tr>
    </table>

    <div class="buttons">
      <button type="submit">Save</button>
      <button onclick="Alice.prefs.remove(); return false;">Cancel</button>
    </div>

  </form>

share/templates/range.html  view on Meta::CPAN

? my ($app, $results, $position) = @_;

<div style="display:none" id="wrap_<?= $position ?>" class="context_wrapper">
  <ul class="<?= $position ?>">
? for my $result (@$results) {
  <li><strong><?= $result->[3] ?> </strong><?= $result->[5] ?></li>
? }
  </ul>
</div>

<script type="text/javascript">
? if ($position eq "before") {
  Effect.SlideDown("wrap_<?= $position ?>", { duration: 0.3 });  

share/templates/tab.html  view on Meta::CPAN

? my ($app, $window) = @_;
<li title="<?= $window->network ?>:<?= $window->title ?>" id="<?= $window->id ?>_tab" class="<?= $window->type ?>_tab<?= $window->disabled ? " disabled" : "" ?> visible">
  <div class="hit_area">
    <div class="tab_button" id="<?= $window->id ?>_tab_button"></div>
    <div style="float:left"><?= $window->pretty_name ?></div>
  </div>
</li>

share/templates/tabsets.html  view on Meta::CPAN

          <li>
            <input type="checkbox"<?= $set->includes($window->id) ? " checked" : "" ?> name="<?= $window->id ?>">
            <?= $window->title ?>
          </li>
        <? } ?>
        </ul>
      <? } ?>

    </div>

    <ul id="empty_tabset" style="display:none">
      <? for my $window (@windows) { ?>
        <li>
          <input type="checkbox" name="<?= $window->id ?>" />
          <?= $window->title ?>
        </li>
      <? } ?>
    </ul>

    <div class="buttons">
      <button type="submit">Save</button>

t/alice/test_config  view on Meta::CPAN

  'message_store' => 'Memory',
  'image_prefix' => 'https://noembed.com/i/',
  'order' => [],
  'animate' => 'show',
  'monospace_nicks' => [],
  'address' => '127.0.0.1',
  'avatars' => 'show',
  'images' => 'show',
  'alerts' => 'show',
  'tabsets' => {},
  'style' => 'default',
  'timeformat' => '24',
  'port' => 50029,
  'first_run' => 1,
  'servers' => {
    'test' => {
      'nick' => 'tester',
      'autoconnect' => 0,
      'port' => 6667,
      'host' => 'not.real.server'
    }



( run in 0.907 second using v1.01-cache-2.11-cpan-49f99fa48dc )