Alice

 view release on metacpan or  search on metacpan

inc/Module/Install/Metadata.pm  view on Meta::CPAN

	$self->provides( %{ $build->find_dist_packages || {} } );
}

sub feature {
	my $self     = shift;
	my $name     = shift;
	my $features = ( $self->{values}->{features} ||= [] );
	my $mods;

	if ( @_ == 1 and ref( $_[0] ) ) {
		# The user used ->feature like ->features by passing in the second
		# argument as a reference.  Accomodate for that.
		$mods = $_[0];
	} else {
		$mods = \@_;
	}

	my $count = 0;
	push @$features, (
		$name => [
			map {

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

    event  => "say",
    nick   => $from,
    window => $self->serialized,
    ($options{source} ? (source => $options{source}) : ()),
    html   => encoded_string($html),
    self   => $options{self} ? 1 : 0,
    hightlight  => $options{highlight} ? 1 : 0,
    msgid       => $self->buffer->next_msgid,
    timestamp   => time,
    monospaced  => $options{mono} ? 1 : 0,
    consecutive => $from eq $self->buffer->previous_nick ? 1 : 0,
  };

  $message->{html} = $self->render->("message", $message);

  $self->buffer->add($message);
  return $message;
}

__PACKAGE__->meta->make_immutable;
1;

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


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',
      'pass' => 'mypassword',
    },

=head1 COMMANDS

=over 4

lib/Alice/Role/IRCEvents.pm  view on Meta::CPAN


sub reconnect_irc {
  my ($self, $name, $time) = @_;
  my $irc = $self->get_irc($name);
  throw InvalidNetwork "$name isn't one of your networks" unless $irc;

  my $interval = time - $irc->connect_time;

  if ($interval < 15) {
    $time = 15 - $interval;
    $self->send_info($irc->name, "last attempt was within 15 seconds, delaying $time seconds")
  }

  if (!defined $time) {
    # increase timer by 15 seconds each time, until it hits 5 minutes
    $time = min 60 * 5, 15 * $irc->reconnect_count;
  }

  $self->send_info($irc->name, "reconnecting in $time seconds");
  $irc->reconnect_timer(AE::timer $time, 0, sub {$self->connect_irc($name)});
}

sub disconnect_irc {
  my ($self, $name, $msg) = @_;
  my $irc = $self->get_irc($name);
  throw InvalidNetwork "$name isn't one of your networks" unless $irc;

  if ($irc->reconnect_timer) {
    $self->cancel_reconnect($name);

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

  my $html = irc_to_html($body, classes => 1, ($options{monospaced} ? () : (invert => "italic")));

  my $message = {
    type      => "message",
    event     => "say",
    nick      => $nick,
    window    => $self->serialized,
    html      => encoded_string($html),
    msgid     => $self->buffer->next_msgid,
    timestamp => time,
    consecutive => $nick eq $self->buffer->previous_nick,
    %options,
  };

  $message->{html} = $self->render->("message", $message);

  $self->buffer->add($message);
  return $message;
}

sub close_action {

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

  margin: 0;
  padding: 3px 0;
  margin: 0; }

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

ul.messages > li:not(.consecutive) {
  clear: both; }

ul.messages li.highlight div.msg {
  border-right: 3px solid #ff4300; }

.info ul.messages li.highlight,
ul.messages li.self {
  background: #111111;
  border-right: none; }

.info ul.messages li.highlight div.msg,
ul.messages li.self div.msg {
  background: #333333; }

ul.messages li div.msg {
  background: #222222; }

ul.messages li.consecutive div.left {
  opacity: 0;
  height: 0px;
  position: absolute;
  left: -1000px; }

div.left {
  float: left;
  width: 95px;
  overflow: hidden;
  font-weight: bold;

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

  border-top: none; }

ul.messages li.avatar div.left {
  padding-bottom: 3px;
  padding-top: 3px; }

li.event div.left {
  padding: 5px 0;
  width: 95px; }

ul.messages li.avatar:not(.consecutive) {
  z-index: 800; }

div.left img {
  max-width: 32px;
  max-height: 32px;
  float: right;
  display: block; }

ul.messages li.avatar span.nick {
  position: absolute;

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

  color: #fff;
  opacity: 0; }

div.timehint {
  font-size: 10px;
  float: right;
  padding: 6px 5px 0 5px;
  color: #666666;
  opacity: 0; }

li.consecutive div.timehint {
  padding: 3px 5px 0 5px; }

div.msg {
  margin-left: 100px;
  min-height: 1.2em;
  padding: 3px 5px;
  word-wrap: break-word;
  -khtml-line-break: after-white-space;
  -khtml-nbsp-mode: space;
  border-top: 1px solid #111111;

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

li.monospaced div.msg {
  padding: 7px 5px; }

li.event + li.message div.msg {
  border-top: 1px solid transparent; }

ul.messages li:first-child div.msg {
  border-top: 1px solid transparent; }

/* so the last avatar doesn't hang off the edge */
ul.messages li.avatar:not(.consecutive) div.msg {
  min-height: 35px; }

ul.messages li.monospaced.avatar:not(.consecutive) div.msg {
  min-height: 24px; }

.noavatars ul.messages li.avatar:not(.consecutive) div.msg {
  min-height: 0px; }

.noavatars ul.messages li.monospaced.avatar:not(.consecutive) div.msg {
  min-height: 0px; }

ul.messages li.message:last-child {
  border-bottom: 1px solid #111111; }

ul.messages li.consecutive div.msg {
  border-top: none; }

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

div.msg a {
  word-break: break-all; }

div.oembed a {
  word-break: normal; }

div.image a {
  position: relative; }

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

div.image a a.hideimg:hover {
  background: rgba(0, 0, 0, 0.5);
  opacity: 1; }

div.msg div.oembed img,
div.msg div.image img {
  border: none;
  max-height: 300px;
  max-width: 100%; }

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

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

  margin: 0;
  padding: 3px 0;
  margin: 0; }

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

ul.messages > li:not(.consecutive) {
  clear: both; }

ul.messages li.highlight div.msg {
  border-right: 3px solid #ff4300; }

.info ul.messages li.highlight,
ul.messages li.self {
  background: #fffbd0;
  border-right: none; }

.info ul.messages li.highlight div.msg,
ul.messages li.self div.msg {
  background: #fffbd0; }

ul.messages li div.msg {
  background: white; }

ul.messages li.consecutive div.left {
  opacity: 0;
  height: 0px;
  position: absolute;
  left: -1000px; }

div.left {
  float: left;
  width: 95px;
  overflow: hidden;
  font-weight: bold;

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

  border-top: none; }

ul.messages li.avatar div.left {
  padding-bottom: 3px;
  padding-top: 3px; }

li.event div.left {
  padding: 5px 0;
  width: 95px; }

ul.messages li.avatar:not(.consecutive) {
  z-index: 800; }

div.left img {
  max-width: 32px;
  max-height: 32px;
  float: right;
  display: block; }

ul.messages li.avatar span.nick {
  position: absolute;

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

  color: #fff;
  opacity: 0; }

div.timehint {
  font-size: 10px;
  float: right;
  padding: 6px 5px 0 5px;
  color: #cccccc;
  opacity: 0; }

li.consecutive div.timehint {
  padding: 3px 5px 0 5px; }

div.msg {
  margin-left: 100px;
  min-height: 1.2em;
  padding: 3px 5px;
  word-wrap: break-word;
  -khtml-line-break: after-white-space;
  -khtml-nbsp-mode: space;
  border-top: 1px solid #eeeeee;

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

li.monospaced div.msg {
  padding: 7px 5px; }

li.event + li.message div.msg {
  border-top: 1px solid transparent; }

ul.messages li:first-child div.msg {
  border-top: 1px solid transparent; }

/* so the last avatar doesn't hang off the edge */
ul.messages li.avatar:not(.consecutive) div.msg {
  min-height: 35px; }

ul.messages li.monospaced.avatar:not(.consecutive) div.msg {
  min-height: 24px; }

.noavatars ul.messages li.avatar:not(.consecutive) div.msg {
  min-height: 0px; }

.noavatars ul.messages li.monospaced.avatar:not(.consecutive) div.msg {
  min-height: 0px; }

ul.messages li.message:last-child {
  border-bottom: 1px solid #eeeeee; }

ul.messages li.consecutive div.msg {
  border-top: none; }

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

div.msg a {
  word-break: break-all; }

div.oembed a {
  word-break: normal; }

div.image a {
  position: relative; }

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

div.image a a.hideimg:hover {
  background: rgba(0, 0, 0, 0.5);
  opacity: 1; }

div.msg div.oembed img,
div.msg div.image img {
  border: none;
  max-height: 300px;
  max-width: 100%; }

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

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

  margin: 0;
  padding: 3px 0;
  margin: 0; }

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

ul.messages > li:not(.consecutive) {
  clear: both; }

ul.messages li.highlight div.msg {
  border-right: 3px solid #cb4b16; }

.info ul.messages li.highlight,
ul.messages li.self {
  background: #fffaed;
  border-right: none; }

.info ul.messages li.highlight div.msg,
ul.messages li.self div.msg {
  background: #fffaed; }

ul.messages li div.msg {
  background: #fdf6e3; }

ul.messages li.consecutive div.left {
  opacity: 0;
  height: 0px;
  position: absolute;
  left: -1000px; }

div.left {
  float: left;
  width: 95px;
  overflow: hidden;
  font-weight: bold;

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

  border-top: none; }

ul.messages li.avatar div.left {
  padding-bottom: 3px;
  padding-top: 3px; }

li.event div.left {
  padding: 5px 0;
  width: 95px; }

ul.messages li.avatar:not(.consecutive) {
  z-index: 800; }

div.left img {
  max-width: 32px;
  max-height: 32px;
  float: right;
  display: block; }

ul.messages li.avatar span.nick {
  position: absolute;

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

  color: #fff;
  opacity: 0; }

div.timehint {
  font-size: 10px;
  float: right;
  padding: 6px 5px 0 5px;
  color: #93a1a1;
  opacity: 0; }

li.consecutive div.timehint {
  padding: 3px 5px 0 5px; }

div.msg {
  margin-left: 100px;
  min-height: 1.2em;
  padding: 3px 5px;
  word-wrap: break-word;
  -khtml-line-break: after-white-space;
  -khtml-nbsp-mode: space;
  border-top: 1px solid #eee8d5;

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

li.monospaced div.msg {
  padding: 7px 5px; }

li.event + li.message div.msg {
  border-top: 1px solid transparent; }

ul.messages li:first-child div.msg {
  border-top: 1px solid transparent; }

/* so the last avatar doesn't hang off the edge */
ul.messages li.avatar:not(.consecutive) div.msg {
  min-height: 35px; }

ul.messages li.monospaced.avatar:not(.consecutive) div.msg {
  min-height: 24px; }

.noavatars ul.messages li.avatar:not(.consecutive) div.msg {
  min-height: 0px; }

.noavatars ul.messages li.monospaced.avatar:not(.consecutive) div.msg {
  min-height: 0px; }

ul.messages li.message:last-child {
  border-bottom: 1px solid #eee8d5; }

ul.messages li.consecutive div.msg {
  border-top: none; }

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

div.msg a {
  word-break: break-all; }

div.oembed a {
  word-break: normal; }

div.image a {
  position: relative; }

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

div.image a a.hideimg:hover {
  background: rgba(0, 0, 0, 0.5);
  opacity: 1; }

div.msg div.oembed img,
div.msg div.image img {
  border: none;
  max-height: 300px;
  max-width: 100%; }

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

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

        isSupported = true;
      }

      div = form = null;

      return isSupported;
    })()
  },

  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,

  emptyFunction: function() { },

  K: function(x) { return x }
};

if (Prototype.Browser.MobileSafari)
  Prototype.BrowserFeatures.SpecificElementExtensions = false;
/* Based on Alex Arnell's inheritance implementation. */

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

  }

  function uniq(sorted) {
    return this.inject([], function(array, value, index) {
      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
        array.push(value);
      return array;
    });
  }

  function intersect(array) {
    return this.uniq().findAll(function(item) {
      return array.detect(function(value) { return item === value });
    });
  }


  function clone() {
    return slice.call(this, 0);
  }

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

  Object.extend(arrayProto, {
    _each:     _each,
    clear:     clear,
    first:     first,
    last:      last,
    compact:   compact,
    flatten:   flatten,
    without:   without,
    reverse:   reverse,
    uniq:      uniq,
    intersect: intersect,
    clone:     clone,
    toArray:   clone,
    size:      size,
    inspect:   inspect
  });

  var CONCAT_ARGUMENTS_BUGGY = (function() {
    return [].concat(arguments)[0][0] !== 1;
  })(1,2)

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


    var responder = _createResponder(element, eventName, handler);

    if (!responder) return element;

    if (eventName.include(':')) {
      if (element.addEventListener)
        element.addEventListener("dataavailable", responder, false);
      else {
        element.attachEvent("ondataavailable", responder);
        element.attachEvent("onlosecapture", responder);
      }
    } else {
      var actualEventName = _getDOMEventName(eventName);

      if (element.addEventListener)
        element.addEventListener(actualEventName, responder, false);
      else
        element.attachEvent("on" + actualEventName, responder);
    }

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

        break;
      }
    }
    if (!responder) return element;

    if (eventName.include(':')) {
      if (element.removeEventListener)
        element.removeEventListener("dataavailable", responder, false);
      else {
        element.detachEvent("ondataavailable", responder);
        element.detachEvent("onlosecapture", responder);
      }
    } else {
      var actualEventName = _getDOMEventName(eventName);
      if (element.removeEventListener)
        element.removeEventListener(actualEventName, responder, false);
      else
        element.detachEvent('on' + actualEventName, responder);
    }

    registry.set(eventName, responders.without(responder));

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


    if (element == document && document.createEvent && !element.dispatchEvent)
      element = document.documentElement;

    var event;
    if (document.createEvent) {
      event = document.createEvent('HTMLEvents');
      event.initEvent('dataavailable', bubble, true);
    } else {
      event = document.createEventObject();
      event.eventType = bubble ? 'ondataavailable' : 'onlosecapture';
    }

    event.eventName = eventName;
    event.memo = memo || { };

    if (document.createEvent)
      element.dispatchEvent(event);
    else
      element.fireEvent(event.eventType, event);

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

      return 1 - (Math.cos(pos * 4.5 * Math.PI) * Math.exp(-pos * 6));
    },
    none: function(pos) {
      return 0;
    },
    full: function(pos) {
      return 1;
    }
  },
  DefaultOptions: {
    duration:   1.0,   // seconds
    fps:        100,   // 100= assume 66fps max.
    sync:       false, // true for combining
    from:       0.0,
    to:         1.0,
    delay:      0.0,
    queue:      'parallel'
  },
  tagifyText: function(element) {
    var tagifyStyle = 'position:relative';
    if (Prototype.Browser.IE) tagifyStyle += ';zoom:1';

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

  WebSocket.OPEN = 1;
  WebSocket.CLOSING = 2;
  WebSocket.CLOSED = 3;

  WebSocket.__flash = null;
  WebSocket.__instances = {};
  WebSocket.__tasks = [];
  WebSocket.__nextId = 0;

  /**
   * Load a new flash security policy file.
   * @param {string} url
   */
  WebSocket.loadFlashPolicyFile = function(url){
    WebSocket.__addTask(function() {
      WebSocket.__flash.loadManualPolicyFile(url);
    });
  };

  /**
   * Loads WebSocketMain.swf and creates WebSocketMain object in Flash.

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

    if (WebSocket.__flash) return;

    if (WebSocket.__swfLocation) {
      window.WEB_SOCKET_SWF_LOCATION = WebSocket.__swfLocation;
    }
    if (!window.WEB_SOCKET_SWF_LOCATION) {
      logger.error("[WebSocket] set WEB_SOCKET_SWF_LOCATION to location of WebSocketMain.swf");
      return;
    }
    if (!window.WEB_SOCKET_SUPPRESS_CROSS_DOMAIN_SWF_ERROR &&
        !WEB_SOCKET_SWF_LOCATION.match(/(^|\/)WebSocketMainInsecure\.swf(\?.*)?$/) &&
        WEB_SOCKET_SWF_LOCATION.match(/^\w+:\/\/([^\/]+)/)) {
      var swfHost = RegExp.$1;
      if (location.host != swfHost) {
        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 {

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

            if (avatar)
              li.down("a.nick").insert('<img src="'+alice.options.image_prefix+avatar+'" />');
          }
          else {
            li.removeClassName("avatar");
          }
        }
      },

      function(li, win) {
        if (li.hasClassName("consecutive")) {
          var prev = li.previous();
          if (!prev) return;

          if (prev && prev.hasClassName("avatar") && !prev.hasClassName("consecutive"))
            prev.down('div.msg').setStyle({minHeight: '0px'});
          if (prev && prev.hasClassName("monospaced"))
            prev.down('div.msg').setStyle({paddingBottom: '0px'});
        }
      },

      function(li, win) {
        var stamp = li.down('.timestamp');
        if (!stamp) return;

        var remove = false;
        var seconds = stamp.innerHTML.strip();

        if (li.hasClassName("message")) {
          var time = new Date(seconds * 1000);
          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;
      },

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

  },

  showNick: function (e) {
    var li = e.findElement("li.message");
    if (li && li.hasClassName("avatar")) {
      if (this.application.overlayVisible || li == this.visibleNick) return;
      clearTimeout(this.visibleNickTimeout);

      this.visibleNick = li;
      var nick;
      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;

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

? my ($app, $msg) = @_;
? my $classes = join " ", (
?   grep {$msg->{$_}} qw/highlight self consecutive monospaced avatar/,
? );

<li class="message <?= $classes ?>" id="msg-<?= $msg->{msgid} ?>"<?= $msg->{avatar} ? " avatar=$msg->{avatar}" : "" ?>>
    <div class="timehint timestamp"><?= $msg->{timestamp} ?></div>
    <div class="left">
      <a href="javascript:alice.connection.requestWindow('<?= $msg->{nick} ?>','<?= $msg->{window}{id} ?>')" class="nick"<?= $msg->{source} ? " title=$msg->{source}" : "" ?>>
        <span class="nick"><?= $msg->{nick} ?></span>

      </a>
    </div>



( run in 1.129 second using v1.01-cache-2.11-cpan-39bf76dae61 )