Merge branch 'master' of github.com:annando/friendica-addons

This commit is contained in:
Michael 2012-05-16 08:15:49 +02:00
commit 07806ead6f
248 changed files with 97636 additions and 375 deletions

BIN
convpath.tgz Normal file

Binary file not shown.

Binary file not shown.

View file

@ -1,43 +1,7 @@
Installing the Friendica/Facebook connector Installing the Friendica/Facebook connector
1. Visit https://developers.facebook.com/apps to register an app. Detailed instructions how to use this plugin can be found at
a) Click "Create a new app" https://github.com/friendica/friendica/wiki/How-to:-Friendica%E2%80%99s-Facebook-connector
b) We'd be very happy if you include "Friendica" in the application name
to increase name recognition.
c) Edit your app settings on the setup page. The Friendica icons are present
in the images directory and may be uploaded as a Facebook app icon. Use
images/friendica-16.jpg for the Icon and images/Friendica-128.jpg for the logo.
d) In the App Display name enter the name of your app (this should default to the
name you chose in part a).
e) Enter YourDomain.com in the App Domain field and hit return.
f) In "Select how your app connects with Facebook select "Website" and enter the
full URL to your Friendica install including HTTPS and a trailing slash.
2. Enable the Facebook plugin by clicking on the icon next to it's name on the plugin
page of your admin panel.
b) return to the Facebook plugin page in your admin panel, and fill in the App-ID
and Application Secret settings you got from Facebook.
c) Click save.
d) Finally, return to the Facebook settings page, and activate real-time updates.
i. If you for any reason prefer to use a configuration file instead of the admin panels,
Activate the plugin by including it in .htconfig.php, e.g.
$a->config['system']['addon'] = 'plugin1,plugin2,facebook';
and set the following values:
$a->config['facebook']['appid'] = 'xxxxxxxxxxx';
$a->config['facebook']['appsecret'] = 'xxxxxxxxxxxxxxx';
Replace with the settings Facebook gives you.
3. To use the Facebook plugin, visit the "connector settings" area of your settings
page. Click "Install Facebook Connector".
4. This will ask you to login to Facebook and allow the plugin to do it's stuff.
Allow it to do so.
5. You're done. To turn it off visit the Plugin Settings page again and
'Remove Facebook posting'.
Vidoes and embeds will not be posted if there is no other content. Links Vidoes and embeds will not be posted if there is no other content. Links
and images will be converted to a format suitable for the Facebook API and and images will be converted to a format suitable for the Facebook API and

510
facebook/facebook.php Executable file → Normal file
View file

@ -1,7 +1,7 @@
<?php <?php
/** /**
* Name: Facebook Connector * Name: Facebook Connector
* Version: 1.1 * Version: 1.2
* Author: Mike Macgirvin <http://macgirvin.com/profile/mike> * Author: Mike Macgirvin <http://macgirvin.com/profile/mike>
* Tobias Hößl <https://github.com/CatoTH/> * Tobias Hößl <https://github.com/CatoTH/>
*/ */
@ -9,33 +9,8 @@
/** /**
* Installing the Friendica/Facebook connector * Installing the Friendica/Facebook connector
* *
* 1. register an API key for your site from developer.facebook.com * Detailed instructions how to use this plugin can be found at
* a. We'd be very happy if you include "Friendica" in the application name * https://github.com/friendica/friendica/wiki/How-to:-Friendica%E2%80%99s-Facebook-connector
* to increase name recognition. The Friendica icons are also present
* in the images directory and may be uploaded as a Facebook app icon.
* Use images/friendica-16.jpg for the Icon and images/friendica-128.jpg for the Logo.
* b. The url should be your site URL with a trailing slash.
* Friendica is a software application and does not require a Privacy Policy
* or Terms of Service, though your installation of it might. Facebook may require
* that you provide a Privacy Policy, which we find ironic.
* c. Set the following values in your .htconfig.php file
* $a->config['facebook']['appid'] = 'xxxxxxxxxxx';
* $a->config['facebook']['appsecret'] = 'xxxxxxxxxxxxxxx';
* Replace with the settings Facebook gives you.
* d. Navigate to Set Web->Site URL & Domain -> Website Settings. Set
* Site URL to yoursubdomain.yourdomain.com. Set Site Domain to your
* yourdomain.com.
* 2. Visit the Facebook Settings section of the "Settings->Plugin Settings" page.
* and click 'Install Facebook Connector'.
* 3. Visit the Facebook Settings section of the "Settings->Plugin Settings" page.
* and click 'Install Facebook Connector'.
* 4. This will ask you to login to Facebook and grant permission to the
* plugin to do its stuff. Allow it to do so.
* 5. Optional step: If you want to use Facebook Real Time Updates (so new messages
* and new contacts are added ~1min after they are postet / added on FB), go to
* Settings -> plugins -> facebook and press the "Activate Real-Time Updates"-button.
* 6. You're done. To turn it off visit the Plugin Settings page again and
* 'Remove Facebook posting'.
* *
* Vidoes and embeds will not be posted if there is no other content. Links * Vidoes and embeds will not be posted if there is no other content. Links
* and images will be converted to a format suitable for the Facebook API and * and images will be converted to a format suitable for the Facebook API and
@ -96,8 +71,11 @@ function facebook_module() {}
// If a->argv[1] is a nickname, this is a callback from Facebook oauth requests. // If a->argv[1] is a nickname, this is a callback from Facebook oauth requests.
// If $_REQUEST["realtime_cb"] is set, this is a callback from the Real-Time Updates API // If $_REQUEST["realtime_cb"] is set, this is a callback from the Real-Time Updates API
/**
* @param App $a
*/
function facebook_init(&$a) { function facebook_init(&$a) {
if (x($_REQUEST, "realtime_cb") && x($_REQUEST, "realtime_cb")) { if (x($_REQUEST, "realtime_cb") && x($_REQUEST, "realtime_cb")) {
logger("facebook_init: Facebook Real-Time callback called", LOGGER_DEBUG); logger("facebook_init: Facebook Real-Time callback called", LOGGER_DEBUG);
@ -191,7 +169,7 @@ function facebook_init(&$a) {
$r = q("SELECT `uid` FROM `user` WHERE `nickname` = '%s' LIMIT 1", $r = q("SELECT `uid` FROM `user` WHERE `nickname` = '%s' LIMIT 1",
dbesc($nick) dbesc($nick)
); );
if(! count($r)) if(!(isset($r) && count($r)))
return; return;
$uid = $r[0]['uid']; $uid = $r[0]['uid'];
@ -233,6 +211,9 @@ function facebook_init(&$a) {
} }
/**
* @param int $uid
*/
function fb_get_self($uid) { function fb_get_self($uid) {
$access_token = get_pconfig($uid,'facebook','access_token'); $access_token = get_pconfig($uid,'facebook','access_token');
if(! $access_token) if(! $access_token)
@ -244,133 +225,165 @@ function fb_get_self($uid) {
} }
} }
function fb_get_friends_sync_new($uid, $access_token, $person) { /**
$link = 'http://facebook.com/profile.php?id=' . $person->id; * @param int $uid
* @param string $access_token
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' LIMIT 1", * @param array $persons
intval($uid), */
dbesc($link) function fb_get_friends_sync_new($uid, $access_token, $persons) {
); $persons_todo = array();
foreach ($persons as $person) {
if (count($r) == 0) { $link = 'http://facebook.com/profile.php?id=' . $person->id;
logger('fb_get_friends: new contact found: ' . $link, LOGGER_DEBUG);
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' LIMIT 1",
fb_get_friends_sync_full($uid, $access_token, $person); intval($uid),
} dbesc($link)
);
if (count($r) == 0) {
logger('fb_get_friends: new contact found: ' . $link, LOGGER_DEBUG);
$persons_todo[] = $person;
}
if (count($persons_todo) > 0) fb_get_friends_sync_full($uid, $access_token, $persons_todo);
}
} }
function fb_get_friends_sync_full($uid, $access_token, $person) { /**
$s = fetch_url('https://graph.facebook.com/' . $person->id . '?access_token=' . $access_token); * @param int $uid
if($s) { * @param object $contact
$jp = json_decode($s); */
logger('fb_get_friends: info: ' . print_r($jp,true), LOGGER_DATA); function fb_get_friends_sync_parsecontact($uid, $contact) {
$contact->link = 'http://facebook.com/profile.php?id=' . $contact->id;
// always use numeric link for consistency // If its a page then set the first name from the username
if (!$contact->first_name and $contact->username)
$contact->first_name = $contact->username;
$jp->link = 'http://facebook.com/profile.php?id=' . $person->id; // check if we already have a contact
// If its a page then set the first name from the username $r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' LIMIT 1",
if (!$jp->first_name and $jp->username) intval($uid),
$jp->first_name = $jp->username; dbesc($contact->link)
);
// check if we already have a contact if(count($r)) {
$r = q("SELECT * FROM `contact` WHERE `uid` = %d AND `url` = '%s' LIMIT 1", // check that we have all the photos, this has been known to fail on occasion
intval($uid),
dbesc($jp->link)
);
if(count($r)) { if((! $r[0]['photo']) || (! $r[0]['thumb']) || (! $r[0]['micro'])) {
require_once("Photo.php");
// check that we have all the photos, this has been known to fail on occasion $photos = import_profile_photo('https://graph.facebook.com/' . $contact->id . '/picture', $uid, $r[0]['id']);
if((! $r[0]['photo']) || (! $r[0]['thumb']) || (! $r[0]['micro'])) { q("UPDATE `contact` SET `photo` = '%s',
require_once("Photo.php"); `thumb` = '%s',
`micro` = '%s',
`name-date` = '%s',
`uri-date` = '%s',
`avatar-date` = '%s'
WHERE `id` = %d LIMIT 1
",
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($r[0]['id'])
);
}
return;
}
else {
$photos = import_profile_photo('https://graph.facebook.com/' . $jp->id . '/picture', $uid, $r[0]['id']); // create contact record
q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `alias`, `notify`, `poll`,
`name`, `nick`, `photo`, `network`, `rel`, `priority`,
`writable`, `blocked`, `readonly`, `pending` )
VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, 0, 0, 0 ) ",
intval($uid),
dbesc(datetime_convert()),
dbesc($contact->link),
dbesc(normalise_link($contact->link)),
dbesc(''),
dbesc(''),
dbesc($contact->id),
dbesc('facebook ' . $contact->id),
dbesc($contact->name),
dbesc(($contact->nickname) ? $contact->nickname : strtolower($contact->first_name)),
dbesc('https://graph.facebook.com/' . $contact->id . '/picture'),
dbesc(NETWORK_FACEBOOK),
intval(CONTACT_IS_FRIEND),
intval(1),
intval(1)
);
}
$r = q("UPDATE `contact` SET `photo` = '%s', $r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1",
`thumb` = '%s', dbesc($contact->link),
`micro` = '%s', intval($uid)
`name-date` = '%s', );
`uri-date` = '%s',
`avatar-date` = '%s'
WHERE `id` = %d LIMIT 1
",
dbesc($photos[0]),
dbesc($photos[1]),
dbesc($photos[2]),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($r[0]['id'])
);
}
return;
}
else {
// create contact record if(! count($r)) {
$r = q("INSERT INTO `contact` ( `uid`, `created`, `url`, `nurl`, `addr`, `alias`, `notify`, `poll`, return;
`name`, `nick`, `photo`, `network`, `rel`, `priority`, }
`writable`, `blocked`, `readonly`, `pending` )
VALUES ( %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, 0, 0, 0 ) ",
intval($uid),
dbesc(datetime_convert()),
dbesc($jp->link),
dbesc(normalise_link($jp->link)),
dbesc(''),
dbesc(''),
dbesc($jp->id),
dbesc('facebook ' . $jp->id),
dbesc($jp->name),
dbesc(($jp->nickname) ? $jp->nickname : strtolower($jp->first_name)),
dbesc('https://graph.facebook.com/' . $jp->id . '/picture'),
dbesc(NETWORK_FACEBOOK),
intval(CONTACT_IS_FRIEND),
intval(1),
intval(1)
);
}
$r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1", $contact_id = $r[0]['id'];
dbesc($jp->link),
intval($uid)
);
if(! count($r)) { require_once("Photo.php");
return;
}
$contact = $r[0]; $photos = import_profile_photo($r[0]['photo'],$uid,$contact_id);
$contact_id = $r[0]['id'];
require_once("Photo.php"); q("UPDATE `contact` SET `photo` = '%s',
`thumb` = '%s',
$photos = import_profile_photo($r[0]['photo'],$uid,$contact_id); `micro` = '%s',
`name-date` = '%s',
$r = q("UPDATE `contact` SET `photo` = '%s', `uri-date` = '%s',
`thumb` = '%s', `avatar-date` = '%s'
`micro` = '%s', WHERE `id` = %d LIMIT 1
`name-date` = '%s', ",
`uri-date` = '%s', dbesc($photos[0]),
`avatar-date` = '%s' dbesc($photos[1]),
WHERE `id` = %d LIMIT 1 dbesc($photos[2]),
", dbesc(datetime_convert()),
dbesc($photos[0]), dbesc(datetime_convert()),
dbesc($photos[1]), dbesc(datetime_convert()),
dbesc($photos[2]), intval($contact_id)
dbesc(datetime_convert()), );
dbesc(datetime_convert()),
dbesc(datetime_convert()),
intval($contact_id)
);
}
} }
/**
* @param int $uid
* @param string $access_token
* @param array $persons
*/
function fb_get_friends_sync_full($uid, $access_token, $persons) {
if (count($persons) == 0) return;
$nums = Ceil(count($persons) / 50);
for ($i = 0; $i < $nums; $i++) {
$batch_request = array();
for ($j = $i * 50; $j < ($i+1) * 50 && $j < count($persons); $j++) $batch_request[] = array('method'=>'GET', 'relative_url'=>$persons[$j]->id);
$s = post_url('https://graph.facebook.com/', array('access_token' => $access_token, 'batch' => json_encode($batch_request)));
if($s) {
$results = json_decode($s);
logger('fb_get_friends: info: ' . print_r($results,true), LOGGER_DATA);
foreach ($results as $contact) {
if ($contact->code != 200) logger('fb_get_friends: not found: ' . print_r($contact,true), LOGGER_DEBUG);
else fb_get_friends_sync_parsecontact($uid, json_decode($contact->body));
}
}
}
}
// if $fullsync is true, only new contacts are searched for // if $fullsync is true, only new contacts are searched for
/**
* @param int $uid
* @param bool $fullsync
*/
function fb_get_friends($uid, $fullsync = true) { function fb_get_friends($uid, $fullsync = true) {
$r = q("SELECT `uid` FROM `user` WHERE `uid` = %d AND `account_expired` = 0 LIMIT 1", $r = q("SELECT `uid` FROM `user` WHERE `uid` = %d AND `account_expired` = 0 LIMIT 1",
@ -394,17 +407,23 @@ function fb_get_friends($uid, $fullsync = true) {
logger('facebook: fb_get_friends: json: ' . print_r($j,true), LOGGER_DATA); logger('facebook: fb_get_friends: json: ' . print_r($j,true), LOGGER_DATA);
if(! $j->data) if(! $j->data)
return; return;
foreach($j->data as $person)
if ($fullsync) $persons_todo = array();
fb_get_friends_sync_full($uid, $access_token, $person); foreach($j->data as $person) $persons_todo[] = $person;
else
fb_get_friends_sync_new($uid, $access_token, $person); if ($fullsync)
fb_get_friends_sync_full($uid, $access_token, $persons_todo);
else
fb_get_friends_sync_new($uid, $access_token, $persons_todo);
} }
} }
// This is the POST method to the facebook settings page // This is the POST method to the facebook settings page
// Content is posted to Facebook in the function facebook_post_hook() // Content is posted to Facebook in the function facebook_post_hook()
/**
* @param App $a
*/
function facebook_post(&$a) { function facebook_post(&$a) {
$uid = local_user(); $uid = local_user();
@ -455,6 +474,10 @@ function facebook_post(&$a) {
// Facebook settings form // Facebook settings form
/**
* @param App $a
* @return string
*/
function facebook_content(&$a) { function facebook_content(&$a) {
if(! local_user()) { if(! local_user()) {
@ -478,7 +501,6 @@ function facebook_content(&$a) {
if (get_pconfig(local_user(),'facebook','post')) { if (get_pconfig(local_user(),'facebook','post')) {
$access_token = get_pconfig(local_user(),'facebook','access_token'); $access_token = get_pconfig(local_user(),'facebook','access_token');
if ($access_token) { if ($access_token) {
$private_wall = intval(get_pconfig($uid,'facebook','private_wall'));
$s = fetch_url('https://graph.facebook.com/me/feed?access_token=' . $access_token); $s = fetch_url('https://graph.facebook.com/me/feed?access_token=' . $access_token);
if($s) { if($s) {
$j = json_decode($s); $j = json_decode($s);
@ -556,7 +578,11 @@ function facebook_content(&$a) {
} }
/**
* @param App $a
* @param null|object $b
* @return mixed
*/
function facebook_cron($a,$b) { function facebook_cron($a,$b) {
$last = get_config('facebook','last_poll'); $last = get_config('facebook','last_poll');
@ -597,6 +623,8 @@ function facebook_cron($a,$b) {
$last_friend_check = get_pconfig($rr['uid'],'facebook','friend_check'); $last_friend_check = get_pconfig($rr['uid'],'facebook','friend_check');
if($last_friend_check) if($last_friend_check)
$next_friend_check = $last_friend_check + 86400; $next_friend_check = $last_friend_check + 86400;
else
$next_friend_check = 0;
if($next_friend_check <= time()) { if($next_friend_check <= time()) {
fb_get_friends($rr['uid'], true); fb_get_friends($rr['uid'], true);
set_pconfig($rr['uid'],'facebook','friend_check',time()); set_pconfig($rr['uid'],'facebook','friend_check',time());
@ -617,7 +645,7 @@ function facebook_cron($a,$b) {
logger('facebook_cron: Failed', LOGGER_NORMAL); logger('facebook_cron: Failed', LOGGER_NORMAL);
if(strlen($a->config['admin_email']) && !get_config('facebook', 'realtime_err_mailsent')) { if(strlen($a->config['admin_email']) && !get_config('facebook', 'realtime_err_mailsent')) {
$res = mail($a->config['admin_email'], t('Problems with Facebook Real-Time Updates'), mail($a->config['admin_email'], t('Problems with Facebook Real-Time Updates'),
"Hi!\n\nThere's a problem with the Facebook Real-Time Updates that cannot be solved automatically. Maybe a permission issue?\n\nPlease try to re-activate it on " . $a->config["system"]["url"] . "/admin/plugins/facebook\n\nThis e-mail will only be sent once.", "Hi!\n\nThere's a problem with the Facebook Real-Time Updates that cannot be solved automatically. Maybe a permission issue?\n\nPlease try to re-activate it on " . $a->config["system"]["url"] . "/admin/plugins/facebook\n\nThis e-mail will only be sent once.",
'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n" 'From: ' . t('Administrator') . '@' . $_SERVER['SERVER_NAME'] . "\n"
. 'Content-type: text/plain; charset=UTF-8' . "\n" . 'Content-type: text/plain; charset=UTF-8' . "\n"
@ -637,7 +665,10 @@ function facebook_cron($a,$b) {
} }
/**
* @param App $a
* @param null|object $b
*/
function facebook_plugin_settings(&$a,&$b) { function facebook_plugin_settings(&$a,&$b) {
$b .= '<div class="settings-block">'; $b .= '<div class="settings-block">';
@ -648,6 +679,10 @@ function facebook_plugin_settings(&$a,&$b) {
} }
/**
* @param App $a
* @param null|object $o
*/
function facebook_plugin_admin(&$a, &$o){ function facebook_plugin_admin(&$a, &$o){
@ -692,6 +727,10 @@ function facebook_plugin_admin(&$a, &$o){
} }
} }
/**
* @param App $a
* @param null|object $o
*/
function facebook_plugin_admin_post(&$a, &$o){ function facebook_plugin_admin_post(&$a, &$o){
check_form_security_token_redirectOnErr('/admin/plugins/facebook', 'fbsave'); check_form_security_token_redirectOnErr('/admin/plugins/facebook', 'fbsave');
@ -711,6 +750,11 @@ function facebook_plugin_admin_post(&$a, &$o){
} }
} }
/**
* @param App $a
* @param object $b
* @return mixed
*/
function facebook_jot_nets(&$a,&$b) { function facebook_jot_nets(&$a,&$b) {
if(! local_user()) if(! local_user())
return; return;
@ -725,6 +769,11 @@ function facebook_jot_nets(&$a,&$b) {
} }
/**
* @param App $a
* @param object $b
* @return mixed
*/
function facebook_post_hook(&$a,&$b) { function facebook_post_hook(&$a,&$b) {
@ -743,6 +792,9 @@ function facebook_post_hook(&$a,&$b) {
$reply = false; $reply = false;
$likes = false; $likes = false;
$deny_arr = array();
$allow_arr = array();
$toplevel = (($b['id'] == $b['parent']) ? true : false); $toplevel = (($b['id'] == $b['parent']) ? true : false);
@ -789,8 +841,7 @@ function facebook_post_hook(&$a,&$b) {
$allow_str = dbesc(implode(', ',$recipients)); $allow_str = dbesc(implode(', ',$recipients));
if($allow_str) { if($allow_str) {
$r = q("SELECT `notify` FROM `contact` WHERE `id` IN ( $allow_str ) AND `network` = 'face'"); $r = q("SELECT `notify` FROM `contact` WHERE `id` IN ( $allow_str ) AND `network` = 'face'");
$allow_arr = array(); if(count($r))
if(count($r))
foreach($r as $rr) foreach($r as $rr)
$allow_arr[] = $rr['notify']; $allow_arr[] = $rr['notify'];
} }
@ -798,8 +849,7 @@ function facebook_post_hook(&$a,&$b) {
$deny_str = dbesc(implode(', ',$deny)); $deny_str = dbesc(implode(', ',$deny));
if($deny_str) { if($deny_str) {
$r = q("SELECT `notify` FROM `contact` WHERE `id` IN ( $deny_str ) AND `network` = 'face'"); $r = q("SELECT `notify` FROM `contact` WHERE `id` IN ( $deny_str ) AND `network` = 'face'");
$deny_arr = array(); if(count($r))
if(count($r))
foreach($r as $rr) foreach($r as $rr)
$deny_arr[] = $rr['notify']; $deny_arr[] = $rr['notify'];
} }
@ -854,8 +904,8 @@ function facebook_post_hook(&$a,&$b) {
// unless it's a dislike - just send the text as a comment // unless it's a dislike - just send the text as a comment
if($b['verb'] == ACTIVITY_DISLIKE) // if($b['verb'] == ACTIVITY_DISLIKE)
$msg = trim(strip_tags(bbcode($msg))); // $msg = trim(strip_tags(bbcode($msg)));
// Old code // Old code
/*$search_str = $a->get_baseurl() . '/search'; /*$search_str = $a->get_baseurl() . '/search';
@ -896,7 +946,7 @@ function facebook_post_hook(&$a,&$b) {
if(preg_match("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/is",$b['body'],$matches)) if(preg_match("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/is",$b['body'],$matches))
$image = $matches[3]; $image = $matches[3];
if ($image != '') if ($image == '')
if(preg_match("/\[img\](.*?)\[\/img\]/is",$b['body'],$matches)) if(preg_match("/\[img\](.*?)\[\/img\]/is",$b['body'],$matches))
$image = $matches[1]; $image = $matches[1];
@ -965,7 +1015,6 @@ function facebook_post_hook(&$a,&$b) {
// Since facebook increased the maxpostlen massively this never should happen again :) // Since facebook increased the maxpostlen massively this never should happen again :)
if (strlen($msg) > FACEBOOK_MAXPOSTLEN) { if (strlen($msg) > FACEBOOK_MAXPOSTLEN) {
$shortlink = "";
require_once('library/slinky.php'); require_once('library/slinky.php');
$display_url = $b['plink']; $display_url = $b['plink'];
@ -1006,10 +1055,14 @@ function facebook_post_hook(&$a,&$b) {
'access_token' => $fb_token, 'access_token' => $fb_token,
'message' => $msg 'message' => $msg
); );
if(isset($image)) if(isset($image)) {
$postvars['picture'] = $image; $postvars['picture'] = $image;
if(isset($link)) //$postvars['type'] = "photo";
}
if(isset($link)) {
$postvars['link'] = $link; $postvars['link'] = $link;
//$postvars['type'] = "link";
}
if(isset($linkname)) if(isset($linkname))
$postvars['name'] = $linkname; $postvars['name'] = $linkname;
} }
@ -1026,11 +1079,18 @@ function facebook_post_hook(&$a,&$b) {
if($reply) { if($reply) {
$url = 'https://graph.facebook.com/' . $reply . '/' . (($likes) ? 'likes' : 'comments'); $url = 'https://graph.facebook.com/' . $reply . '/' . (($likes) ? 'likes' : 'comments');
} } else if (($link != "") or ($image != "") or ($b['title'] == '') or (strlen($msg) < 500)) {
else {
$url = 'https://graph.facebook.com/me/feed'; $url = 'https://graph.facebook.com/me/feed';
if($b['plink']) if($b['plink'])
$postvars['actions'] = '{"name": "' . t('View on Friendica') . '", "link": "' . $b['plink'] . '"}'; $postvars['actions'] = '{"name": "' . t('View on Friendica') . '", "link": "' . $b['plink'] . '"}';
} else {
// if its only a message and a subject and the message is larger than 500 characters then post it as note
$postvars = array(
'access_token' => $fb_token,
'message' => bbcode($b['body']),
'subject' => $b['title'],
);
$url = 'https://graph.facebook.com/me/notes';
} }
logger('facebook: post to ' . $url); logger('facebook: post to ' . $url);
@ -1088,6 +1148,10 @@ function facebook_post_hook(&$a,&$b) {
} }
} }
/**
* @param App $app
* @param object $data
*/
function facebook_enotify(&$app, &$data) { function facebook_enotify(&$app, &$data) {
if (x($data, 'params') && $data['params']['type'] == NOTIFY_SYSTEM && x($data['params'], 'system_type') && $data['params']['system_type'] == 'facebook_connection_invalid') { if (x($data, 'params') && $data['params']['type'] == NOTIFY_SYSTEM && x($data['params'], 'system_type') && $data['params']['system_type'] == 'facebook_connection_invalid') {
$data['itemlink'] = '/facebook'; $data['itemlink'] = '/facebook';
@ -1097,6 +1161,10 @@ function facebook_enotify(&$app, &$data) {
} }
} }
/**
* @param App $a
* @param object $b
*/
function facebook_post_local(&$a,&$b) { function facebook_post_local(&$a,&$b) {
// Figure out if Facebook posting is enabled for this post and file it in 'postopts' // Figure out if Facebook posting is enabled for this post and file it in 'postopts'
@ -1123,6 +1191,10 @@ function facebook_post_local(&$a,&$b) {
} }
/**
* @param App $a
* @param object $b
*/
function fb_queue_hook(&$a,&$b) { function fb_queue_hook(&$a,&$b) {
$qi = q("SELECT * FROM `queue` WHERE `network` = '%s'", $qi = q("SELECT * FROM `queue` WHERE `network` = '%s'",
@ -1181,8 +1253,14 @@ function fb_queue_hook(&$a,&$b) {
} }
} }
/**
* @param string $access_token
* @param int $since
* @return object
*/
function fb_get_timeline($access_token, &$since) { function fb_get_timeline($access_token, &$since) {
$entries = new stdClass();
$entries->data = array(); $entries->data = array();
$newest = 0; $newest = 0;
@ -1211,7 +1289,7 @@ function fb_get_timeline($access_token, &$since) {
else else
break; break;
$url = $j->paging->next; $url = (isset($j->paging) && isset($j->paging->next) ? $j->paging->next : '');
} while (($oldestdate > $since) and ($since != 0) and ($url != '')); } while (($oldestdate > $since) and ($since != 0) and ($url != ''));
@ -1221,6 +1299,9 @@ function fb_get_timeline($access_token, &$since) {
return($entries); return($entries);
} }
/**
* @param int $uid
*/
function fb_consume_all($uid) { function fb_consume_all($uid) {
require_once('include/items.php'); require_once('include/items.php');
@ -1245,7 +1326,7 @@ function fb_consume_all($uid) {
// Get the last date // Get the last date
$lastdate = get_pconfig($uid,'facebook','lastdate'); $lastdate = get_pconfig($uid,'facebook','lastdate');
// fetch all items since the last date // fetch all items since the last date
$j = fb_get_timeline($access_token, &$lastdate); $j = fb_get_timeline($access_token, $lastdate);
if (isset($j->data)) { if (isset($j->data)) {
logger('fb_consume_stream: feed: ' . print_r($j,true), LOGGER_DATA); logger('fb_consume_stream: feed: ' . print_r($j,true), LOGGER_DATA);
fb_consume_stream($uid,$j,false); fb_consume_stream($uid,$j,false);
@ -1256,6 +1337,11 @@ function fb_consume_all($uid) {
logger('fb_consume_stream: feed: got no data from Facebook: ' . print_r($j,true), LOGGER_NORMAL); logger('fb_consume_stream: feed: got no data from Facebook: ' . print_r($j,true), LOGGER_NORMAL);
} }
/**
* @param int $uid
* @param string $link
* @return string
*/
function fb_get_photo($uid,$link) { function fb_get_photo($uid,$link) {
$access_token = get_pconfig($uid,'facebook','access_token'); $access_token = get_pconfig($uid,'facebook','access_token');
if(! $access_token || (! stristr($link,'facebook.com/photo.php'))) if(! $access_token || (! stristr($link,'facebook.com/photo.php')))
@ -1264,14 +1350,22 @@ function fb_get_photo($uid,$link) {
$ret = preg_match('/fbid=([0-9]*)/',$link,$match); $ret = preg_match('/fbid=([0-9]*)/',$link,$match);
if($ret) if($ret)
$photo_id = $match[1]; $photo_id = $match[1];
else
return "";
$x = fetch_url('https://graph.facebook.com/' . $photo_id . '?access_token=' . $access_token); $x = fetch_url('https://graph.facebook.com/' . $photo_id . '?access_token=' . $access_token);
$j = json_decode($x); $j = json_decode($x);
if($j->picture) if($j->picture)
return "\n\n" . '[url=' . $link . '][img]' . $j->picture . '[/img][/url]'; return "\n\n" . '[url=' . $link . '][img]' . $j->picture . '[/img][/url]';
//else //else
// return "\n" . '[url=' . $link . ']' . t('link') . '[/url]'; // return "\n" . '[url=' . $link . ']' . t('link') . '[/url]';
return "";
} }
/**
* @param int $uid
* @param object $j
* @param bool $wall
*/
function fb_consume_stream($uid,$j,$wall = false) { function fb_consume_stream($uid,$j,$wall = false) {
$a = get_app(); $a = get_app();
@ -1283,7 +1377,7 @@ function fb_consume_stream($uid,$j,$wall = false) {
if(! count($user)) if(! count($user))
return; return;
$my_local_url = $a->get_baseurl() . '/profile/' . $user[0]['nickname']; // $my_local_url = $a->get_baseurl() . '/profile/' . $user[0]['nickname'];
$no_linking = get_pconfig($uid,'facebook','no_linking'); $no_linking = get_pconfig($uid,'facebook','no_linking');
if($no_linking) if($no_linking)
@ -1300,7 +1394,9 @@ function fb_consume_stream($uid,$j,$wall = false) {
if(! count($j->data) || (! strlen($self_id))) if(! count($j->data) || (! strlen($self_id)))
return; return;
foreach($j->data as $entry) { $top_item = 0;
foreach($j->data as $entry) {
logger('fb_consume: entry: ' . print_r($entry,true), LOGGER_DATA); logger('fb_consume: entry: ' . print_r($entry,true), LOGGER_DATA);
$datarray = array(); $datarray = array();
@ -1310,12 +1406,10 @@ function fb_consume_stream($uid,$j,$wall = false) {
intval($uid) intval($uid)
); );
if(count($r)) { if(count($r)) {
$post_exists = true;
$orig_post = $r[0]; $orig_post = $r[0];
$top_item = $r[0]['id']; $top_item = $r[0]['id'];
} }
else { else {
$post_exists = false;
$orig_post = null; $orig_post = null;
} }
@ -1330,7 +1424,7 @@ function fb_consume_stream($uid,$j,$wall = false) {
else { else {
// Looking if user is known - if not he is added // Looking if user is known - if not he is added
$access_token = get_pconfig($uid, 'facebook', 'access_token'); $access_token = get_pconfig($uid, 'facebook', 'access_token');
fb_get_friends_sync_new($uid, $access_token, $from); fb_get_friends_sync_new($uid, $access_token, array($from));
$r = q("SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1", $r = q("SELECT * FROM `contact` WHERE `notify` = '%s' AND `uid` = %d AND `blocked` = 0 AND `readonly` = 0 LIMIT 1",
dbesc($from->id), dbesc($from->id),
@ -1379,32 +1473,32 @@ function fb_consume_stream($uid,$j,$wall = false) {
logger('facebook: post '.$entry->id.' from '.$from->name); logger('facebook: post '.$entry->id.' from '.$from->name);
$datarray['body'] = escape_tags($entry->message); $datarray['body'] = (isset($entry->message) ? escape_tags($entry->message) : '');
if($entry->name and $entry->link) if(isset($entry->name) and isset($entry->link))
$datarray['body'] .= "\n\n[bookmark=".$entry->link."]".$entry->name."[/bookmark]"; $datarray['body'] .= "\n\n[bookmark=".$entry->link."]".$entry->name."[/bookmark]";
elseif ($entry->name) elseif (isset($entry->name))
$datarray['body'] .= "\n\n[b]" . $entry->name."[/b]"; $datarray['body'] .= "\n\n[b]" . $entry->name."[/b]";
if($entry->caption) { if(isset($entry->caption)) {
if(!$entry->name and $entry->link) if(!isset($entry->name) and isset($entry->link))
$datarray['body'] .= "\n\n[bookmark=".$entry->link."]".$entry->caption."[/bookmark]"; $datarray['body'] .= "\n\n[bookmark=".$entry->link."]".$entry->caption."[/bookmark]";
else else
$datarray['body'] .= "[i]" . $entry->caption."[/i]\n"; $datarray['body'] .= "[i]" . $entry->caption."[/i]\n";
} }
if(!$entry->caption and !$entry->name) { if(!isset($entry->caption) and !isset($entry->name)) {
if ($entry->link) if (isset($entry->link))
$datarray['body'] .= "\n[url]".$entry->link."[/url]\n"; $datarray['body'] .= "\n[url]".$entry->link."[/url]\n";
else else
$datarray['body'] .= "\n"; $datarray['body'] .= "\n";
} }
$quote = ""; $quote = "";
if($entry->description) if(isset($entry->description))
$quote = $entry->description; $quote = $entry->description;
if ($entry->properties) if (isset($entry->properties))
foreach ($entry->properties as $property) foreach ($entry->properties as $property)
$quote .= "\n".$property->name.": [url=".$property->href."]".$property->text."[/url]"; $quote .= "\n".$property->name.": [url=".$property->href."]".$property->text."[/url]";
@ -1414,19 +1508,19 @@ function fb_consume_stream($uid,$j,$wall = false) {
// Only import the picture when the message is no video // Only import the picture when the message is no video
// oembed display a picture of the video as well // oembed display a picture of the video as well
if ($entry->type != "video") { if ($entry->type != "video") {
if($entry->picture && $entry->link) { if(isset($entry->picture) && isset($entry->link)) {
$datarray['body'] .= "\n" . '[url=' . $entry->link . '][img]'.$entry->picture.'[/img][/url]'; $datarray['body'] .= "\n" . '[url=' . $entry->link . '][img]'.$entry->picture.'[/img][/url]';
} }
else { else {
if($entry->picture) if(isset($entry->picture))
$datarray['body'] .= "\n" . '[img]' . $entry->picture . '[/img]'; $datarray['body'] .= "\n" . '[img]' . $entry->picture . '[/img]';
// if just a link, it may be a wall photo - check // if just a link, it may be a wall photo - check
if($entry->link) if(isset($entry->link))
$datarray['body'] .= fb_get_photo($uid,$entry->link); $datarray['body'] .= fb_get_photo($uid,$entry->link);
} }
} }
if (($datarray['app'] == "Events") and $entry->actions) if (($datarray['app'] == "Events") and isset($entry->actions))
foreach ($entry->actions as $action) foreach ($entry->actions as $action)
if ($action->name == "View") if ($action->name == "View")
$datarray['body'] .= " [url=".$action->link."]".$entry->story."[/url]"; $datarray['body'] .= " [url=".$action->link."]".$entry->story."[/url]";
@ -1446,10 +1540,10 @@ function fb_consume_stream($uid,$j,$wall = false) {
$datarray['body'] .= "\n"; $datarray['body'] .= "\n";
if ($entry->icon) if (isset($entry->icon))
$datarray['body'] .= "[img]".$entry->icon."[/img] &nbsp; "; $datarray['body'] .= "[img]".$entry->icon."[/img] &nbsp; ";
if ($entry->actions) if (isset($entry->actions))
foreach ($entry->actions as $action) foreach ($entry->actions as $action)
if (($action->name != "Comment") and ($action->name != "Like")) if (($action->name != "Comment") and ($action->name != "Like"))
$datarray['body'] .= "[url=".$action->link."]".$action->name."[/url] &nbsp; "; $datarray['body'] .= "[url=".$action->link."]".$action->name."[/url] &nbsp; ";
@ -1459,28 +1553,29 @@ function fb_consume_stream($uid,$j,$wall = false) {
//if(($datarray['body'] != '') and ($uid == 1)) //if(($datarray['body'] != '') and ($uid == 1))
// $datarray['body'] .= "[noparse]".print_r($entry, true)."[/noparse]"; // $datarray['body'] .= "[noparse]".print_r($entry, true)."[/noparse]";
if ($entry->place->name or $entry->place->location->street or if (isset($entry->place)) {
$entry->place->location->city or $entry->place->location->Denmark) { if ($entry->place->name or $entry->place->location->street or
$datarray['coord'] = ''; $entry->place->location->city or $entry->place->location->Denmark) {
if ($entry->place->name) $datarray['coord'] = '';
$datarray['coord'] .= $entry->place->name; if ($entry->place->name)
if ($entry->place->location->street) $datarray['coord'] .= $entry->place->name;
$datarray['coord'] .= $entry->place->location->street; if ($entry->place->location->street)
if ($entry->place->location->city) $datarray['coord'] .= $entry->place->location->street;
$datarray['coord'] .= " ".$entry->place->location->city; if ($entry->place->location->city)
if ($entry->place->location->country) $datarray['coord'] .= " ".$entry->place->location->city;
$datarray['coord'] .= " ".$entry->place->location->country; if ($entry->place->location->country)
} else if ($entry->place->location->latitude and $entry->place->location->longitude) $datarray['coord'] .= " ".$entry->place->location->country;
$datarray['coord'] = substr($entry->place->location->latitude, 0, 8) } else if ($entry->place->location->latitude and $entry->place->location->longitude)
$datarray['coord'] = substr($entry->place->location->latitude, 0, 8)
.' '.substr($entry->place->location->longitude, 0, 8); .' '.substr($entry->place->location->longitude, 0, 8);
}
$datarray['created'] = datetime_convert('UTC','UTC',$entry->created_time); $datarray['created'] = datetime_convert('UTC','UTC',$entry->created_time);
$datarray['edited'] = datetime_convert('UTC','UTC',$entry->updated_time); $datarray['edited'] = datetime_convert('UTC','UTC',$entry->updated_time);
// If the entry has a privacy policy, we cannot assume who can or cannot see it, // If the entry has a privacy policy, we cannot assume who can or cannot see it,
// as the identities are from a foreign system. Mark it as private to the owner. // as the identities are from a foreign system. Mark it as private to the owner.
if($entry->privacy && $entry->privacy->value !== 'EVERYONE') { if(isset($entry->privacy) && $entry->privacy->value !== 'EVERYONE') {
$datarray['private'] = 1; $datarray['private'] = 1;
$datarray['allow_cid'] = '<' . $self[0]['id'] . '>'; $datarray['allow_cid'] = '<' . $self[0]['id'] . '>';
} }
@ -1565,7 +1660,7 @@ function fb_consume_stream($uid,$j,$wall = false) {
$likedata['object'] = '<object><type>' . ACTIVITY_OBJ_NOTE . '</type><local>1</local>' . $likedata['object'] = '<object><type>' . ACTIVITY_OBJ_NOTE . '</type><local>1</local>' .
'<id>' . $orig_post['uri'] . '</id><link>' . xmlify('<link rel="alternate" type="text/html" href="' . xmlify($orig_post['plink']) . '" />') . '</link><title>' . $orig_post['title'] . '</title><content>' . $orig_post['body'] . '</content></object>'; '<id>' . $orig_post['uri'] . '</id><link>' . xmlify('<link rel="alternate" type="text/html" href="' . xmlify($orig_post['plink']) . '" />') . '</link><title>' . $orig_post['title'] . '</title><content>' . $orig_post['body'] . '</content></object>';
$item = item_store($likedata); item_store($likedata);
} }
} }
if(is_array($comments)) { if(is_array($comments)) {
@ -1644,7 +1739,7 @@ function fb_consume_stream($uid,$j,$wall = false) {
'to_email' => $user[0]['email'], 'to_email' => $user[0]['email'],
'uid' => $user[0]['uid'], 'uid' => $user[0]['uid'],
'item' => $cmntdata, 'item' => $cmntdata,
'link' => $a->get_baseurl() . '/display/' . $importer['nickname'] . '/' . $item, 'link' => $a->get_baseurl() . '/display/' . $user[0]['nickname'] . '/' . $item,
'source_name' => $cmntdata['author-name'], 'source_name' => $cmntdata['author-name'],
'source_link' => $cmntdata['author-link'], 'source_link' => $cmntdata['author-link'],
'source_photo' => $cmntdata['author-avatar'], 'source_photo' => $cmntdata['author-avatar'],
@ -1663,6 +1758,9 @@ function fb_consume_stream($uid,$j,$wall = false) {
} }
/**
* @return bool|string
*/
function fb_get_app_access_token() { function fb_get_app_access_token() {
$acc_token = get_config('facebook','app_access_token'); $acc_token = get_config('facebook','app_access_token');
@ -1708,6 +1806,9 @@ function facebook_subscription_del_users() {
if (!facebook_check_realtime_active()) del_config('facebook', 'realtime_active'); if (!facebook_check_realtime_active()) del_config('facebook', 'realtime_active');
} }
/**
* @param bool $second_try
*/
function facebook_subscription_add_users($second_try = false) { function facebook_subscription_add_users($second_try = false) {
$a = get_app(); $a = get_app();
$access_token = fb_get_app_access_token(); $access_token = fb_get_app_access_token();
@ -1744,6 +1845,9 @@ function facebook_subscription_add_users($second_try = false) {
}; };
} }
/**
* @return null|array
*/
function facebook_subscriptions_get() { function facebook_subscriptions_get() {
$access_token = fb_get_app_access_token(); $access_token = fb_get_app_access_token();
@ -1760,6 +1864,9 @@ function facebook_subscriptions_get() {
} }
/**
* @return bool
*/
function facebook_check_realtime_active() { function facebook_check_realtime_active() {
$ret = facebook_subscriptions_get(); $ret = facebook_subscriptions_get();
if (is_null($ret)) return false; if (is_null($ret)) return false;
@ -1773,7 +1880,14 @@ function facebook_check_realtime_active() {
// DELETE-request to $url // DELETE-request to $url
if(! function_exists('facebook_delete_url')) { if(! function_exists('facebook_delete_url')) {
function facebook_delete_url($url,$headers = null, &$redirects = 0, $timeout = 0) { /**
* @param string $url
* @param null|array $headers
* @param int $redirects
* @param int $timeout
* @return bool|string
*/
function facebook_delete_url($url,$headers = null, &$redirects = 0, $timeout = 0) {
$a = get_app(); $a = get_app();
$ch = curl_init($url); $ch = curl_init($url);
if(($redirects > 8) || (! $ch)) if(($redirects > 8) || (! $ch))
@ -1844,7 +1958,7 @@ function facebook_delete_url($url,$headers = null, &$redirects = 0, $timeout = 0
$url_parsed = @parse_url($url); $url_parsed = @parse_url($url);
if (isset($url_parsed)) { if (isset($url_parsed)) {
$redirects++; $redirects++;
return delete_url($url,$headers,$redirects,$timeout); return facebook_delete_url($url,$headers,$redirects,$timeout);
} }
} }
$a->set_curl_code($http_code); $a->set_curl_code($http_code);

1
fromgplus/README Normal file
View file

@ -0,0 +1 @@
This extension is a preparation of the upcoming import of items via Google+

10
fromgplus/fromgplus.php Executable file → Normal file
View file

@ -1,8 +1,8 @@
<?php <?php
/** /**
* Name: From GPlus * Name: From GPlus
* Description: Imports posts from a Google+ account and repeats them * Description: Imports posts from a Google+ account and repeats them - not working by now
* Version: 1.0 * Version: 0.1
* Author: Michael Vogel <ike@piratenpartei.de> * Author: Michael Vogel <ike@piratenpartei.de>
* *
*/ */
@ -36,7 +36,8 @@ function fromgplus_addon_settings(&$a,&$s) {
$s .= '<input id="fromgplus-account" type="text" name="fromgplus-account" value="'.$account.'" />'; $s .= '<input id="fromgplus-account" type="text" name="fromgplus-account" value="'.$account.'" />';
$s .= '</div><div class="clear"></div>'; $s .= '</div><div class="clear"></div>';
$s .= '<div class="settings-submit-wrapper" ><input type="submit" id="fromgplus-submit" name="fromgplus-submit" class="settings-submit" value="' . t('Submit') . '" /></div>'; $s .= '<div class="settings-submit-wrapper" ><input type="submit" id="fromgplus-submit" name="fromgplus-submit"
class="settings-submit" value="' . t('Submit') . '" /></div>';
$s .= '</div>'; $s .= '</div>';
return; return;
@ -124,7 +125,8 @@ function handleattachments($item) {
return($post); return($post);
} }
$result = file_get_contents("https://www.googleapis.com/plus/v1/people/".$google["id"]."/activities/public?alt=json&pp=1&key=".$google["key"]."&maxResults=".$google["maxfetch"]); $result =
file_get_contents("https://www.googleapis.com/plus/v1/people/".$google["id"]."/activities/public?alt=json&pp=1&key=".$google["key"]."&maxResults=".$google["maxfetch"]);
$activities = json_decode($result); $activities = json_decode($result);
$state = array("lastid"=>''); $state = array("lastid"=>'');

View file

@ -1,128 +0,0 @@
<?php
require_once("statusnet.lib.php");
include("config.php");
function html2bbcode($html) {
$bbcode = html_entity_decode($html, ENT_QUOTES, 'UTF-8');
$bbcode = str_replace(array("\n"), array(""), $bbcode);
$bbcode = str_replace(array("<b>", "</b>"), array("[b]", "[/b]"), $bbcode);
$bbcode = str_replace(array("<i>", "</i>"), array("[i]", "[/i]"), $bbcode);
$bbcode = str_replace(array("<s>", "</s>"), array("[s]", "[/s]"), $bbcode);
$bbcode = str_replace(array("<br />"), array("\n"), $bbcode);
$bbcode = trim(strip_tags($bbcode));
return($bbcode);
}
function friendicapost($post) {
global $friendica;
$api = new Statusnet($friendica["user"], $friendica["pw"], "GooglePlus", $friendica["server"]);
$ret = $api->updateStatus($post);
$api->endSession();
}
function handleattachments($item) {
$post = "";
foreach ($item->object->attachments as $attachment) {
switch($attachment->objectType) {
case "video":
//$post .= "\n\n[url=".$attachment->url."]".
// "[size=large][b]".html2bbcode($attachment->displayName)."[/b][/size][/url]\n";
$post .= "\n\n[bookmark=".$attachment->url."]".html2bbcode($attachment->displayName)."[/bookmark]\n";
//if (strpos($attachment->embed->url, "youtube.com"))
// $post .= "[youtube]".$attachment->url."[/youtube]\n";
//else
/// $post .= "[url=".$attachment->url."][img]".$attachment->image->url."[/img][/url]\n";
///$post .= "[quote]".trim(html2bbcode($attachment->content))."[/quote]";
break;
case "article":
//$post .= "\n\n[url=".$attachment->url."]".
// "[size=large][b]".html2bbcode($attachment->displayName)."[/b][/size][/url]\n";
$post .= "\n\n[bookmark=".$attachment->url."]".html2bbcode($attachment->displayName)."[/bookmark]\n";
$post .= "[quote]".trim(html2bbcode($attachment->content))."[/quote]";
break;
case "photo":
//$post .= "\n\n[url=".$attachment->fullImage->url."]".
// "[img]".$attachment->fullImage->url."[/img][/url]\n";
$post .= "\n\n[img]".$attachment->fullImage->url."[/img]\n";
if ($attachment->displayName != "")
$post .= html2bbcode($attachment->displayName)."\n";
break;
case "photo-album":
$post .= "\n\n[url=".$attachment->url."]".
"[size=large][b]".html2bbcode($attachment->displayName)."[/b][/size][/url]\n";
break;
default:
print_r($attachment);
die();
break;
}
}
return($post);
}
$result = file_get_contents("https://www.googleapis.com/plus/v1/people/".$google["id"]."/activities/public?alt=json&pp=1&key=".$google["key"]."&maxResults=".$google["maxfetch"]);
$activities = json_decode($result);
$state = array("lastid"=>'');
if (file_exists($statefile))
$state = unserialize(file_get_contents($statefile));
$lastid = "";
foreach($activities->items as $item) {
if ($item->id == $state["lastid"])
break;
if ($lastid == "")
$lastid = $item->id;
switch($item->object->objectType) {
case "note":
$post = html2bbcode($item->object->content);
if (is_array($item->object->attachments))
$post .= handleattachments($item);
friendicapost($post);
break;
case "activity":
$post = html2bbcode($item->annotation)."\n";
//$post .= html2bbcode("&#x2672; ");
$post .= html2bbcode("&#x267B; ");
$post .= "[url=".$item->object->actor->url."]".$item->object->actor->displayName."[/url]";
$post .= " \n";
//$post .= "[quote]";
$post .= html2bbcode($item->object->content);
if (is_array($item->object->attachments))
$post .= "\n".trim(handleattachments($item));
//$post .= "[/quote]";
friendicapost($post);
break;
default:
print_r($item);
die();
break;
}
}
if ($lastid != "") {
$state['lastid'] = $lastid;
file_put_contents($statefile, serialize($state));
}
?>

BIN
jappixmini.tgz Normal file

Binary file not shown.

7
jappixmini/MIT.txt Normal file
View file

@ -0,0 +1,7 @@
You may distribute all files which are not within the jappix/ folder under the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

31
jappixmini/README Normal file
View file

@ -0,0 +1,31 @@
Jappix Mini Plugin
==================
This quick-and-dirty addon allows you to add a Jabber-based, Facebook-like chat
to Friendica. It uses Jappix Mini.
It is necessary to use a BOSH host - so to use this plugin, each users need to
know the address of a BOSH host that works with his account. The BOSH server of
the Jappix project (https://bind.jappix.com/) is not locked to a specific XMPP
provider, but keep in mind that only personal usage is approved according to
http://codingteam.net/project/jappix/doc/BoshServer.
If you have a larger server, it is recommended that you install your own BOSH
server and recommend it using the configuration help field. If it is on the
same server, you can also deactivate the BOSH proxy. This should improve the
performance.
The addon has an experimental autosubscribe and autosuggest functionality which
tries to add your Friendica contacts to your roster automatically.
Limitations:
- Jabber passwords can only be encrypted if they are at most 39 characters
long.
Notes on the license
--------------------
The license of this addon is AGPL, as required by Jappix Mini. If you make
modifications to the addon, you are responsible for providing a proper facility
for downloading the changed source code.
Moreover, it may be necessary that you publish the source code of the Friendica
application and all other used addons if you do not use standard versions.

54
jappixmini/jappix/AUTHORS Normal file
View file

@ -0,0 +1,54 @@
Jappix - An open social platform
These are the authors of Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 15/01/12
-------------------------------------------------
Here are the Jappix contributors, who coded or translated the application (Codingteam.net nicknames):
# DEVELOPERS
- am0ur3ux
- LinkMauve
- Maranda
- Mathieui
- Olivier
- sim6
- Vanaryon
# TRANSLATORS
- allan
- Arsimael
- Belzeneph
- Catdarko
- Cerritus
- chunzu
- ebraminio
- Finkregh
- hamano
- JanCBorchardt
- jarda
- joeka
- kr2ysiek
- krohn
- Lenwe
- LinkMauve
- Liverbool
- lwj
- m1st
- Maime
- Maranda
- mbajur
- mentalo
- mkwm
- Otourly
- pocamon
- quimi
- sahwar
- Vanaryon
- vitalyster
- Zash

662
jappixmini/jappix/COPYING Normal file
View file

@ -0,0 +1,662 @@
GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU Affero General Public License is a free, copyleft license
for software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.
The licenses for most software and other practical works are
designed to take away your freedom to share and change the works. By
contrast, our General Public Licenses are intended to guarantee your
freedom to share and change all versions of a program--to make sure it
remains free software for all its users.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.
A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate. Many developers of free software are heartened and
encouraged by the resulting cooperation. However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.
The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community. It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server. Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.
An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals. This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU Affero General Public
License.
"Copyright" also means copyright-like laws that apply to other kinds
of works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further restriction,
you may remove that term. If a license document contains a further
restriction but permits relicensing or conveying under this License, you
may add to a covered work material governed by the terms of that license
document, provided that the further restriction does not survive such
relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Remote Network Interaction; Use with the GNU General Public License.
Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software. This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.
Notwithstanding any other provision of this License, you have permission
to link or combine any covered work with a work licensed under version 3
of the GNU General Public License into a single combined work, and to
convey the resulting work. The terms of this License will continue to
apply to the part which is the covered work, but the work with which it is
combined will remain governed by version 3 of the GNU General Public
License.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may differ
in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU Affero
General Public License "or any later version" applies to it, you have
the option of following the terms and conditions either of that
numbered version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number
of the GNU Affero General Public License, you may choose any version
ever published by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that
proxy's public statement of acceptance of a version permanently
authorizes you to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source. For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code. There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.

23
jappixmini/jappix/INSTALL Normal file
View file

@ -0,0 +1,23 @@
Jappix - An open social platform
These are the installation instructions for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 15/09/10
-------------------------------------------------
It's very simple to install Jappix on your webserver, you just have to follow these things:
# INSTALLATION
- The HTTP server : http://codingteam.net/project/jappix/doc/HttpServer
- The XMPP server : http://codingteam.net/project/jappix/doc/XmppServer
- The BOSH server : http://codingteam.net/project/jappix/doc/BoshServer
- The Jappix app. : http://codingteam.net/project/jappix/doc/JappixApp
# MORE
- The whole documentation is available at : http://codingteam.net/project/jappix/doc
Now, you can use Jappix. Happy socializing!

20
jappixmini/jappix/README Normal file
View file

@ -0,0 +1,20 @@
Jappix - An open social platform
This is the readme file for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 18/02/11
-------------------------------------------------
Please refer to the installation instructions that are located in the INSTALL file to process the Jappix installation.
The Jappix Project official service: https://www.jappix.com/
The Jappix Project website: https://project.jappix.com/
The Jappix Project panel: http://codingteam.net/project/jappix
Jappix is released under the terms of the AGPL license. See COPYING for details.
Have fun with Jappix!

27
jappixmini/jappix/THANKS Normal file
View file

@ -0,0 +1,27 @@
Jappix - An open social platform
These are the special thanks for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 16/02/11
-------------------------------------------------
We would like to thanks the authors of these tools, coming from other projects:
# PROJECTS
- Base64 http://rumkin.com
- DrawSVGChart http://codingteam.net/project/codingteam
- idzXHR http://www.iadvize.com/plugin_strophe_xmpp.html
- JSJaC http://blog.jwchat.org/jsjac/
- jQuery http://jquery.com/
- jQuery Form http://jquery.malsup.com/form/
- jQuery Timers http://plugins.jquery.com/project/timers
- jXHR http://mulletxhr.com/
- Mobile Detect http://code.google.com/p/php-mobile-detect/
- JSMin http://github.com/rgrove/jsmin-php/
- PHP-gettext https://launchpad.net/php-gettext
- Silk icons http://www.famfamfam.com/lab/icons/silk/
- Smileys http://www.gajim.org/

View file

@ -0,0 +1 @@
Spaco [0.9]

View file

@ -0,0 +1,26 @@
/*
Jappix - An open social platform
This is the Ad-Hoc CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 20/12/10
*/
#adhoc .content {
padding: 10px 0 10px 0;
}
#adhoc .adhoc-head {
background-color: #f1f6fd;
border: 1px #9dc4fc solid;
width: 598px;
height: 18px;
font-size: 0.9em;
margin: 0 10px 12px 10px;
padding: 6px 10px;
}

View file

@ -0,0 +1,29 @@
/*
Jappix - An open social platform
This is the anonymous mode CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 06/11/10
*/
#top-content {
min-width: 500px !important;
}
#main-content {
min-width: 490px !important;
min-height: 450px !important;
}
#left-content {
display: none;
}
#right-content {
left: 0;
}

View file

@ -0,0 +1,93 @@
/*
Jappix - An open social platform
This is the archives CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 19/12/10
*/
#archives .content {
padding: 10px 0 10px 0;
}
#archives .filter {
background-color: #e9f1fd;
border-right: 1px solid #9dc4fc;
width: 180px;
padding: 12px;
position: absolute;
top: 0;
left: 0;
bottom: 0;
float: left;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
-moz-border-radius-topleft: 4px;
-moz-border-radius-bottomleft: 4px;
-webkit-border-top-left-radius: 4px;
-webkit-border-bottom-left-radius: 4px;
}
#archives .filter .friend {
margin-bottom: 12px;
}
#archives .filter .friend {
height: 210px;
width: 180px;
float: none;
}
#archives .current,
#archives .logs {
position: absolute;
bottom: 0;
right: 0;
left: 204px;
}
#archives .current {
background-color: #e4eef9;
border-bottom: 1px solid #9dc4fc;
font-size: 0.9em;
height: 16px;
padding: 6px;
top: 0;
}
#archives .current span {
height: 16px;
overflow: hidden;
}
#archives .current .name {
max-width: 160px;
font-weight: bold;
float: left;
}
#archives .current .time {
color: #47646a;
font-size: 0.95em;
float: right;
}
#archives .logs {
color: black;
font-size: 0.9em;
overflow: auto;
padding: 8px 10px 0;
float: left;
position: absolute;
top: 29px;
}
#archives .logs a {
color: black;
text-decoration: underline;
}

View file

@ -0,0 +1,47 @@
/*
Jappix - An open social platform
This is the board CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 26/08/11
*/
#board .one-board {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
height: 18px;
z-index: 10000;
font-size: 0.92em;
padding: 6px 8px;
box-shadow: 0 0 8px #5c5c5c;
-moz-box-shadow: 0 0 8px #5c5c5c;
-webkit-box-shadow: 0 0 8px #5c5c5c;
}
#board .one-board:hover {
cursor: pointer;
}
#board .one-board.visible {
display: block;
}
#board .one-board.error {
background-color: rgb(241,160,160);
background-color: rgba(241,160,160,0.9);
color: #420c0c;
}
#board .one-board.info {
background-color: rgb(248,246,186);
background-color: rgba(248,246,186,0.9);
color: #2f2a02;
}

View file

@ -0,0 +1,530 @@
/*
Jappix - An open social platform
This is the buddy-list CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 31/08/11
*/
#buddy-list {
background-color: rgb(20,20,20);
background-color: rgba(20,20,20,0.85);
color: #919191;
padding: 15px 6px 4px 6px;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
box-shadow: 0 0 6px #5c5c5c;
-moz-box-shadow: 0 0 6px #5c5c5c;
-webkit-box-shadow: 0 0 6px #5c5c5c;
}
#buddy-list .content {
background: #e8f1f3;
background: -moz-linear-gradient(top, #e8f1f3, #e4edef);
background: -webkit-gradient(linear, left top, left bottom, from(#e8f1f3), to(#e4edef));
color: #666666;
height: 207px;
padding: 4px 4px 0 4px;
overflow-x: hidden;
overflow-y: auto;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
-moz-border-radius-topleft: 3px;
-moz-border-radius-topright: 3px;
-webkit-border-top-left-radius: 3px;
-webkit-border-top-right-radius: 3px;
}
#buddy-list .one-group {
margin-bottom: 10px;
}
#buddy-list .one-group a.group {
color: #202c2f;
font-size: 0.8em;
margin: 3px 6px;
padding-left: 12px;
max-height: 15px;
text-decoration: none;
overflow: hidden;
display: block;
}
#buddy-list .one-group a.group.plus {
background-position: -4px -1143px;
}
#buddy-list .one-group a.group.minus {
background-position: -4px -1162px;
}
#buddy-list .one-group a.group:hover {
cursor: pointer;
}
#buddy-list .hidden-buddy,
#buddy-list .foot-edit-finish,
.buddy-conf-more-display-available {
display: none;
}
#buddy-list .buddy {
width: 100%;
height: 50px;
margin-bottom: 4px;
}
#buddy-list .buddy-click {
background: #d9e7ea;
width: 100%;
height: 100%;
overflow: hidden;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
#buddy-list .buddy-click:hover,
#buddy-list .buddy-click:focus {
background: #cedee1;
cursor: pointer;
}
#buddy-list .buddy-click:active {
background: #c3d3d7;
}
#buddy-list .gateway {
height: 27px;
}
#buddy-list .gateway .name {
margin-left: 0;
}
#buddy-list .gateway .buddy-presence {
float: left;
overflow: hidden;
width: 0;
margin: 0 4px;
}
#buddy-list .avatar-container {
float: left;
text-align: center;
margin: 3px;
width: 46px;
height: 46px;
}
#buddy-list .avatar {
max-width: 44px;
max-height: 44px;
}
#buddy-list .name {
margin: 4px 3px 5px 56px;
}
#buddy-list .buddy-name {
height: 17px;
font-weight: bold;
font-size: 0.8em;
color: #264249;
margin: 5px 0 5px 2px;
overflow: hidden;
}
#buddy-list .buddy.blocked p.buddy-name {
text-decoration: line-through;
}
#buddy-list .buddy-presence {
height: 14px;
font-size: 0.7em;
color: #3a585e;
padding: 2px 0 0 16px;
margin-top: -3px;
}
#buddy-list .unavailable,
#page-switch .unavailable,
#page-engine p.bc-infos span.show.unavailable {
background-position: 0 -153px;
}
#buddy-list .available,
#page-engine p.bc-infos span.show.available,
#page-engine .list .available,
#page-engine .list .chat,
#page-switch .available,
#my-infos .f-presence a[data-value=available] span {
background-position: 0 -169px;
}
#buddy-list .away,
#page-engine p.bc-infos span.show.away,
#page-engine .list .away,
#page-switch .away,
#my-infos .f-presence a[data-value=away] span {
background-position: 0 -185px;
}
#buddy-list .busy,
#page-engine p.bc-infos span.show.busy,
#page-engine .list .xa,
#page-engine .list .dnd,
#page-switch .busy,
#my-infos .f-presence a[data-value=xa] span {
background-position: 0 -201px;
}
#buddy-list .error,
#page-switch .error,
#page-engine p.bc-infos span.show.error {
background-position: 0 -217px;
}
#buddy-list .buddy-infos {
position: absolute;
z-index: 100;
width: 337px;
color: white;
font-size: 0.8em;
}
.buddy-infos-subarrow {
background-position: 0 -241px;
opacity: 0.8;
width: 9px;
height: 20px;
margin-top: 12px;
float: left;
}
.buddy-infos-subitem {
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.8);
padding: 8px 10px;
width: 308px;
text-shadow: 0 1px 1px black;
float: left;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
.manage-infos p.bm-authorize,
#rosterx .oneresult span.action.add {
background-position: 0 -1181px;
}
.manage-infos p.bm-remove,
#rosterx .oneresult span.action.delete,
#attach div.one-file a.remove {
background-position: 0 -1200px;
}
.manage-infos p.bm-remove {
margin-bottom: 18px;
}
.manage-infos p.bm-rename {
background-position: 0 -1216px;
}
.manage-infos p.bm-group {
background-position: 0 -1241px;
}
.manage-infos div.bm-choose {
max-height: 95px;
margin: 0 0 8px 102px;
overflow: auto;
}
.manage-infos div.bm-choose label {
float: left;
clear: both;
margin-bottom: 1px;
}
.manage-infos div.bm-choose input {
float: left;
}
.manage-infos div.bm-choose input[type=checkbox] {
margin: 0 6px 0 0;
}
.manage-infos div.bm-choose div {
clear: both;
}
.manage-infos p.bm-rename,
.manage-infos p.bm-group {
height: 26px;
}
.manage-infos p.bm-rename label,
.manage-infos p.bm-group label {
width: 80px;
padding-top: 3px;
float: left;
}
.manage-infos p.bm-rename input,
.manage-infos p.bm-group input {
float: left;
width: 155px;
}
.manage-infos a.save {
float: right;
margin: 4px;
}
.buddy-infos-subitem p {
margin: 6px 0;
padding-left: 22px;
height: 16px;
overflow: hidden;
}
.buddy-infos-subitem a {
color: white;
text-decoration: underline;
}
.tune-note {
background-position: 0 -676px;
}
.location-world {
background-position: 0 -658px;
}
.view-individual {
background-position: 0 -34px;
}
.edit-buddy {
background-position: 0 -1008px;
}
#buddy-list .filter {
background-color: white;
border-top: 1px solid #b8c2c4;
height: 15px;
padding: 2px 4px;
font-size: 0.8em;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
-moz-border-radius-bottomleft: 3px;
-moz-border-radius-bottomright: 3px;
-webkit-border-bottom-left-radius: 3px;
-webkit-border-bottom-right-radius: 3px;
}
#buddy-list .filter input {
border: none;
color: #273a3f;
width: 211px;
padding: 0;
box-shadow: none;
-moz-box-shadow: none;
-webkit-box-shadow: none;
}
#buddy-list .filter a {
display: none;
background-color: #9a2d2d;
color: white;
height: 13px;
width: 13px;
margin-top: 1px;
font-size: 0.8em;
text-align: center;
text-decoration: none;
float: right;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
#buddy-list .filter a:hover,
#buddy-list .filter a:focus {
background-color: #8c2121;
}
#buddy-list .filter a:active {
background-color: #7e1919;
}
#buddy-list .foot {
padding: 9px 1px 3px;
}
#buddy-list .buddy-list-icon {
height: 16px;
width: 16px;
margin: -3px 5px 0 0;
float: left;
}
#buddy-list .buddy-list-icon a.talk-images {
height: 16px;
width: 16px;
display: block;
}
#buddy-list .add,
#page-engine .text .tools-add {
background-position: 0 -1047px;
}
#buddy-list .join {
background-position: 0 -1065px;
}
#buddy-list .groupchat,
#page-switch .groupchat-default {
background-position: 0 -1082px;
}
#buddy-list .more {
background-position: 0 -1100px;
}
#buddy-list .foot-edit-finish a {
color: white;
font-size: 0.8em;
margin: -3px 4px 0 0;
float: right;
display: block;
}
#buddy-list .foot-edit-finish a:hover,
#buddy-list .foot-edit-finish a:focus {
text-decoration: underline;
cursor: pointer;
}
.buddy-conf-item {
position: absolute;
width: 263px;
color: white;
z-index: 9998;
text-align: left;
font-size: 0.8em;
margin-left: -10px;
}
.buddy-conf-item:hover {
cursor: default;
}
.buddy-conf-subarrow {
background-position: 0 -241px;
opacity: 0.8;
height: 10px;
width: 18px;
margin-left: 9px;
}
.buddy-conf-subitem {
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.8);
padding: 10px;
text-shadow: 0 1px 1px black;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
.buddy-conf-p {
margin-bottom: 4px;
width: 220px;
font-weight: bold;
float: left;
}
.buddy-conf-input {
padding-top: 2px;
}
.buddy-conf-text {
font-size: 11px;
clear: both;
margin-bottom: 3px;
}
.buddy-conf-text a {
color: white;
}
.buddy-conf-text a:hover,
.buddy-conf-text a:focus {
cursor: pointer;
text-decoration: underline;
}
.buddy-conf-text a.buddy-conf-add-search {
text-decoration: underline;
margin-top: 6px;
display: block;
}
.buddy-conf-select {
font-size: 1.1em;
clear: both;
margin-bottom: 8px;
width: 180px;
height: 23px;
}
.join-jid {
width: 220px;
margin-top: 5px;
}
.add-contact-jid,
.add-contact-name,
.add-contact-gateway {
width: 156px;
margin-bottom: 4px;
}
.add-contact-name-get {
font-size: 0.8em;
display: none;
}
.buddy-conf-subitem label {
clear: both;
}
.buddy-conf-subitem label span {
width: 76px;
height: 14px;
margin-top: 3px;
overflow: hidden;
float: left;
}
#buddy-conf-join ul {
width: 224px;
max-height: 160px;
left: 10px;
top: 51px;
}
.buddy-conf-join-select {
margin: 8px 0 0 0;
}

View file

@ -0,0 +1,545 @@
/*
Jappix - An open social platform
This is the channel CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 26/08/11
*/
#channel .top div.update {
position: absolute;
top: 12px;
left: 115px;
right: 15px;
bottom: 15px;
border-radius: 20px;
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
}
#channel .top p {
font-size: 0.9em;
margin-bottom: 10px;
}
#channel .top h2 {
font-size: 1.6em;
margin-bottom: 10px;
color: #232323;
}
#channel .top a {
font-size: 0.9em;
color: #232323;
}
#channel .top.individual div.update {
right: 36px;
}
#channel .top.individual div.shortcuts,
#userinfos .main-infos div.shortcuts {
width: 16px;
float: right;
}
#channel .top.individual div.shortcuts {
margin: 2px 5px 0 0;
}
#channel .top.individual div.shortcuts a,
#userinfos .main-infos div.shortcuts a {
height: 16px;
width: 16px;
margin-bottom: 4px;
display: block;
}
#channel .top.individual div.shortcuts a.message,
#userinfos .main-infos a.message {
background-position: 0 -1717px;
}
#channel .top.individual div.shortcuts a.chat,
#userinfos .main-infos a.chat {
background-position: 0 -1737px;
}
#channel .top.individual div.shortcuts a.command,
#userinfos .main-infos a.command {
background-position: 0 -1758px;
}
#channel .microblog-body {
height: 20px;
margin-right: 50px;
}
#channel .microblog-body input {
width: 100%;
height: 100%;
padding: 8px;
}
#channel .one-microblog-icon {
position: absolute;
top: 38px;
right: 0;
}
#channel div.update .one-microblog-icon,
#channel div.update .postit {
width: 16px;
height: 16px;
display: block;
}
#channel div.update .attach {
background-position: 0 -79px;
display: none;
}
#attach {
position: absolute;
width: 263px;
margin-left: -227px;
color: white;
font-size: 0.85em;
z-index: 9998;
text-align: left;
display: none;
}
#attach p {
margin-bottom: 6px !important;
}
#attach input[type=submit] {
margin: 8px 0 6px 0;
}
#attach .wait {
float: right;
margin: 7px 5px;
}
#attach div.one-file {
height: 16px;
margin-top: 2px;
}
#attach div.one-file a.link {
color: white;
width: 215px;
height: 14px;
margin-left: 2px;
overflow: hidden;
float: left;
}
#attach div.one-file a.remove {
width: 16px;
height: 16px;
float: left;
}
.attach-subarrow {
background-position: 0 -241px;
opacity: 0.8;
height: 10px;
width: 18px;
margin-left: 226px;
}
.attach-subitem {
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.8);
padding: 10px;
text-shadow: 0 1px 1px black;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
.attach-p {
font-weight: bold;
float: left;
}
#channel .one-update {
margin-bottom: 12px;
padding: 6px 6px 8px 6px;
border-bottom: 1px dotted #d0d0d0;
min-height: 50px;
color: black;
position: relative;
display: none;
}
#channel .one-update .avatar-container {
text-align: center;
margin-right: 16px;
float: left;
height: 50px;
width: 50px;
}
#channel .one-update .avatar-container:hover {
cursor: pointer;
}
#channel .one-update img.avatar {
max-height: 50px;
max-width: 50px;
}
#channel .one-update div.body {
margin-left: 65px;
opacity: 0.8;
}
#channel .one-update:hover div.body {
opacity: 1;
}
#channel .one-update a.repeat {
background-position: 0 -1681px;
height: 16px;
width: 16px;
margin-right: 4px;
float: left;
}
#channel .one-update span a {
text-decoration: underline;
}
#channel .one-update p {
display: block;
margin: 0 12px 5px 0;
}
#channel .one-update p b.name:hover {
cursor: pointer;
text-decoration: underline;
}
#channel .one-update p.infos {
font-size: 0.9em;
}
#channel .one-update p.infos a.geoloc {
background-position: 0 -1778px;
color: #363636;
margin-left: 18px;
padding-left: 14px;
}
#channel .one-update p.infos a.geoloc:hover,
#channel .one-update p.infos a.geoloc:focus,
#channel .one-update p.infos a.geoloc:active {
color: #141414;
}
#channel .one-update p.file {
font-size: 0.9em;
margin: 6px 0 5px 10px;
}
#channel .one-update p.file a.link,
#inbox .inbox-new-file a.file {
min-height: 16px;
padding-left: 22px;
text-decoration: underline;
display: block;
}
#channel .one-update p.file a.link {
margin-top: 4px;
}
#channel p.file a,
#inbox .inbox-new-file a.file {
background-position: 0 -988px;
}
#channel p.file a.audio,
#inbox .inbox-new-file a.file.audio {
background-position: 0 -899px;
}
#channel p.file a.image,
#inbox .inbox-new-file a.file.image {
background-position: 0 -917px;
}
#channel p.file a.video,
#inbox .inbox-new-file a.file.video {
background-position: 0 -935px;
}
#channel p.file a.document,
#inbox .inbox-new-file a.file.document {
background-position: 0 -953px;
}
#channel p.file a.package,
#inbox .inbox-new-file a.file.package {
background-position: 0 -971px;
}
#channel .one-update p.file a.thumb img {
border: 1px solid #a2a2a2;
max-width: 140px;
max-height: 105px;
margin: 4px 10px 2px 0;
padding: 1px;
}
#channel .one-update p.file a.thumb img:hover {
border-color: #464646;
}
#channel .one-update div.comments,
.popup.large div.comments {
width: 410px;
margin: 2px 0 2px 76px;
}
#channel .one-update div.comments div.arrow,
.popup.large div.comments div.arrow {
background-position: 0 -1702px;
width: 20px;
height: 8px;
margin-left: 20px;
display: block;
}
#channel .one-update div.comments div.comments-content,
.popup.large div.comments div.comments-content {
background-color: #e5ebec;
color: black;
font-size: 0.9em;
text-shadow: 0 1px 0 white;
}
#channel .one-update div.comments input,
.popup.large div.comments input {
width: 356px;
margin: 6px 0;
padding: 4px 5px;
}
#channel .one-update div.comments span.icon,
.popup.large div.comments span.icon {
background-position: 0 -1082px;
height: 16px;
width: 16px;
margin: 10px;
float: left;
}
#channel .one-update div.comments .one-comment.loading span.icon,
.popup.large div.comments .one-comment.loading span.icon {
margin: 0 10px 0 0;
}
#channel .one-update div.comments .one-comment,
.popup.large div.comments .one-comment {
border-bottom: 1px solid #f4f4f4;
padding: 4px 8px 0px 8px;
position: relative;
display: block;
}
#channel .one-update div.comments .one-comment.compose,
.popup.large div.comments .one-comment.compose {
border-bottom: 2px solid #f4f4f4;
height: 36px;
padding: 0;
}
#channel .one-update div.comments .one-comment.new,
.popup.large div.comments .one-comment.new {
display: none;
}
#channel .one-update div.comments a.one-comment,
.popup.large div.comments a.one-comment {
text-decoration: none;
}
#channel .one-update div.comments a.one-comment:hover,
#channel .one-update div.comments a.one-comment:focus,
.popup.large div.comments a.one-comment:hover,
.popup.large div.comments a.one-comment:focus {
text-decoration: underline;
}
#channel .one-update div.comments .one-comment.loading,
.popup.large div.comments .one-comment.loading {
padding-bottom: 5px;
}
#channel .one-update div.comments .one-comment div.marker,
.popup.large div.comments .one-comment div.marker {
background-color: #6d8387;
width: 2px;
position: absolute;
top: 0;
left: 0;
bottom: 0;
}
#channel .one-update div.comments .one-comment .avatar-container,
.popup.large div.comments .one-comment .avatar-container {
text-align: center;
width: 30px;
height: 30px;
margin: 2px 8px 0 0;
float: left;
}
#channel .one-update div.comments .one-comment .avatar-container:hover,
.popup.large div.comments .one-comment .avatar-container:hover {
cursor: pointer;
}
#channel .one-update div.comments .one-comment img.avatar,
.popup.large div.comments .one-comment img.avatar {
max-height: 30px;
max-width: 30px;
}
#channel .one-update div.comments .one-comment .comment-container,
.popup.large div.comments .one-comment .comment-container {
float: left;
}
#channel .one-update div.comments .one-comment a.name,
.popup.large div.comments .one-comment a.name {
font-weight: bold;
text-decoration: none;
font-size: 0.95em;
padding-bottom: 2px;
float: left;
}
#channel .one-update div.comments .one-comment a.name:hover,
#channel .one-update div.comments .one-comment a.name:focus,
.popup.large div.comments .one-comment a.name:hover,
.popup.large div.comments .one-comment a.name:focus {
text-decoration: underline;
}
#channel .one-update div.comments .one-comment span.date,
#channel .one-update div.comments .one-comment a.remove,
.popup.large div.comments .one-comment span.date,
.popup.large div.comments .one-comment a.remove {
font-size: 0.85em;
float: right;
}
#channel .one-update div.comments .one-comment.me:hover span.date,
.popup.large div.comments .one-comment.me:hover span.date {
display: none;
}
#channel .one-update div.comments .one-comment.me a.remove,
.popup.large div.comments .one-comment.me a.remove {
display: none;
}
#channel .one-update div.comments .one-comment.me:hover a.remove,
.popup.large div.comments .one-comment.me:hover a.remove {
display: block;
}
#channel .one-update div.comments .one-comment p.body,
.popup.large div.comments .one-comment p.body {
clear: both;
}
#channel a.more {
background-position: 0 -334px;
color: black;
height: 16px;
text-decoration: none;
margin: -2px 0 0 4px;
padding: 0 0 14px 20px;
display: block;
visibility: hidden;
}
#channel a.more:hover,
#channel a.more:focus {
text-decoration: underline;
}
#channel a.mbtool {
width: 11px;
height: 11px;
display: none;
position: absolute;
right: 0;
}
#channel .one-update:hover a.mbtool {
display: block;
}
#channel a.mbtool:hover,
#channel a.mbtool:focus {
text-decoration: none;
}
#channel a.mbtool.profile {
background-position: -1px -1333px;
top: 24px;
}
#channel a.mbtool.repost {
background-position: -1px -1354px;
}
#channel a.mbtool.remove {
background-position: -1px -1312px;
}
#channel a.mbtool.repost,
#channel a.mbtool.remove {
top: 6px;
}
#channel .footer {
bottom: 0;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
-moz-border-radius-bottomleft: 4px;
-moz-border-radius-bottomright: 4px;
-webkit-border-bottom-left-radius: 4px;
-webkit-border-bottom-right-radius: 4px;
}
#channel .footer div {
margin-left: 5px;
padding-left: 24px;
min-height: 16px;
font-size: 0.85em;
width: auto !important;
}
#channel .footer .sync {
background-position: 0 -804px;
display: none;
}
#channel .footer .unsync {
background-position: 0 -830px;
display: none;
}

View file

@ -0,0 +1,16 @@
/*
Jappix - An open social platform
This is the directory tool CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 13/02/11
*/
#directory .content {
padding: 10px 0 10px 0;
}

View file

@ -0,0 +1,61 @@
/*
Jappix - An open social platform
This is the discovery CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 13/02/11
*/
#discovery .content {
padding: 10px 0 10px 0;
}
#discovery .content p {
margin: 5px 10px 5px 10px;
text-align: justify;
font-size: 0.85em;
}
#discovery .discovery-head,
#directory .directory-head,
#rosterx .rosterx-head,
#privacy .privacy-head {
width: 606px;
height: 24px;
margin: 0 10px 10px 10px;
padding: 6px;
background: #f1f6fd;
border: 1px #9dc4fc solid;
}
#discovery .disco-server-text,
#directory .directory-server-text {
float: left;
font-size: 0.9em;
margin: 3px;
}
#discovery .disco-server-input,
#directory .directory-server-input {
float: right;
width: 200px;
padding: 2px;
height: 18px;
float: right;
margin-right: 10px;
padding: 2px;
}
#discovery .disco-category {
display: none;
margin-bottom: 22px;
}
#discovery .disco-category-title {
font-weight: bold;
}

View file

@ -0,0 +1,179 @@
/*
Jappix - An open social platform
This is the favorites CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 28/12/10
*/
#favorites .content {
padding: 10px 0 10px 0;
}
#favorites .fedit-head-select {
min-width: 190px;
max-width: 210px;
}
#favorites .switch-fav {
margin: 0 10px 0 10px;
width: 200px;
height: 355px;
border-right: 1px #c0c0c0 dotted;
float: left;
}
#favorites .room-switcher {
width: 188px;
height: 18px;
border-bottom: 1px #9dc4fc solid;
float: left;
padding: 10px 6px;
font-size: 0.9em;
}
#favorites .room-switcher:hover {
background-color: #e9f1fd;
cursor: pointer;
}
#favorites .room-switcher:active {
background-color: #f1f6fd;
}
#favorites .switch-fav .icon {
float: left;
height: 16px;
width: 16px;
margin: 0 8px 0 0;
}
#favorites .switch-fav .room-list .list-icon {
background-position: 0 -855px;
}
#favorites .switch-fav .room-search .search-icon {
background-position: 0 -876px;
}
#favorites .static-fav {
width: 385px;
height: 335px;
margin: 0 10px 0 0;
padding: 10px;
float: right;
}
#favorites .favorites-search {
display: none;
}
#favorites .static-fav-head {
width: 393px;
margin: -10px;
}
#favorites .static-fav-results {
width: 406px;
height: 314px;
margin: 10px -10px -10px -10px;
padding: 6px 0 0 0;
}
#favorites .fedit-line {
height: 30px;
font-size: 0.9em;
padding: 10px 0 4px 4px;
border-bottom: 1px #9dc4fc solid;
}
#favorites .fedit-line:hover {
background: #e9f1fd;
}
#favorites label {
width: 140px;
margin-top: 3px;
}
#favorites input {
height: 18px;
width: 186px;
margin-top: 0;
padding: 2px;
}
#favorites .fedit-select {
min-width: 160px;
}
#favorites .fedit-actions {
margin: 10px 0 0;
font-size: 0.9em;
float: right;
}
#favorites input[type=checkbox] {
margin-top: 5px;
}
#favorites .fedit-terminate {
float: right;
}
#favorites .fedit-add {
display: block;
}
#favorites .fedit-edit {
background-position: 2px -1240px;
}
#favorites .fedit-remove {
margin: 0 8px 0 0;
}
#favorites .add,
.popup .results .one-button.one-add {
background-position: 3px -1177px;
}
#favorites .remove,
#inbox .remove {
background-position: 3px -1196px;
}
#favorites .join,
#inbox .reply,
#inbox .send,
.popup .results .one-button.one-chat {
background-position: 3px -124px;
}
#favorites .one-button,
#inbox .one-button,
.popup .results .one-button {
padding-left: 20px !important;
font-size: 0.98em;
}
#favorites .fsearch-results {
overflow: auto;
}
#favorites .room-name {
margin: 4px 2px 5px;
max-width: 210px;
float: left;
}
#favorites .fsearch-noresults {
display: none;
font-size: 0.9em;
font-weight: bold;
}

View file

@ -0,0 +1,579 @@
/*
Jappix - An open social platform
This is the home CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 15/01/12
*/
#home {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
min-height: 550px;
min-width: 875px;
}
#home .corporation,
#home .corporation .corp_network,
#home .locale,
#home .obsolete {
background-color: rgb(20,20,20);
background-color: rgba(20,20,20,0.70);
color: white;
position: absolute;
top: 0;
text-shadow: 0 0 1px black;
z-index: 100;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
-moz-border-radius-bottomleft: 3px;
-moz-border-radius-bottomright: 3px;
-webkit-border-bottom-left-radius: 3px;
-webkit-border-bottom-right-radius: 3px;
}
#home .corporation {
background-position: 9px -357px;
left: 12px;
height: 26px;
width: 34px;
}
#home .corporation.hovered {
height: 28px;
border-radius: 0;
-moz-border-radius: 0;
-webkit-border-radius: 0;
}
#home .corporation .corp_network {
width: 180px;
padding: 10px 12px;
top: 28px;
display: none;
border-top-right-radius: 3px;
-moz-border-radius-topright: 3px;
-webkit-border-top-right-radius: 3px;
}
#home .corporation.hovered .corp_network {
display: block;
}
#home .corporation .corp_network h2 {
font-size: 1.1em;
margin: 14px 0 4px 0;
}
#home .corporation .corp_network h2.nomargin {
margin-top: 0;
}
#home .corporation .corp_network a {
font-size: 0.8em;
margin: 2px 0;
padding: 2px 6px;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
#home .corporation .corp_network a span {
margin: 2px 0;
display: block;
}
#home .corporation .corp_network a span.name {
font-weight: bold;
}
#home .corporation .corp_network a span.desc {
font-size: 0.9em;
margin-left: 2px;
}
#home .locale {
left: 52px;
font-size: 0.8em;
}
#home .locale .current {
height: 19px;
padding: 3px 12px 4px 12px;
font-weight: bold;
}
#home .locale .current:hover {
cursor: default;
}
#home .locale .current .current_align {
height: 19px;
vertical-align: middle;
display: table-cell;
}
#home .locale .list {
margin: 2px 0 2px;
}
#home .locale .list a,
#home .corporation .corp_network a {
color: white;
text-decoration: none;
display: block;
}
#home .locale .list a {
padding: 3px 10px;
}
#home .locale .list a:hover,
#home .locale .list a:focus,
#home .corporation .corp_network a:hover,
#home .corporation .corp_network a:focus {
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.1);
cursor: pointer;
}
#home .locale .list a:active,
#home .corporation .corp_network a:active {
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.14);
}
#home .obsolete {
height: 60px;
padding: 4px 10px;
right: 12px;
font-size: 0.9em;
font-weight: bold;
display: none;
}
#home .obsolete a {
height: 33px;
width: 33px;
margin: 5px 2px 0 0;
float: left;
}
#home .obsolete a:hover,
#home .obsolete a:focus {
opacity: 0.8;
}
#home .obsolete a:active {
opacity: 0.6;
}
#home .obsolete a.firefox {
background-position: 1px 0;
}
#home .obsolete a.chrome {
background-position: -34px 0;
}
#home .obsolete a.safari {
background-position: -68px 0;
}
#home .obsolete a.opera {
background-position: -101px 0;
}
#home .obsolete a.ie {
background-position: -135px 0;
}
#home .plane {
background-position: 0 -384px;
width: 507px;
height: 328px;
position: absolute;
left: 0;
top: 60px;
}
#home .main {
background-color: rgb(20,20,20);
background-color: rgba(20,20,20,0.85);
position: absolute;
top: 50%;
margin-top: -200px;
width: 800px;
height: 400px;
left: 50%;
margin-left: -400px;
z-index: 50;
border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
box-shadow: 0 0 35px #5c5c5c;
-moz-box-shadow: 0 0 35px #5c5c5c;
-webkit-box-shadow: 0 0 35px #5c5c5c;
}
#home .left {
float: left;
width: 350px;
height: 370px;
margin: 15px 0 15px 15px;
color: white;
text-align: center;
text-shadow: 0 1px 1px black;
}
#home .left .logo {
background-position: 0 0;
float: left;
margin: 30px 20px;
width: 311px;
height: 113px;
}
#home .left p.upper {
margin: 12px 0 20px 0;
}
#home .left p.secondary {
margin: 8px 0 0 16px;
font-size: 0.9em;
width: 320px;
}
#home .right {
background: #e4eef9;
background: -moz-linear-gradient(top, #e4eef9, #C5E1FF);
background: -webkit-gradient(linear, left top, left bottom, from(#e4eef9), to(#C5E1FF));
float: right;
width: 385px;
height: 350px;
margin: 15px 15px 15px 0;
padding: 10px;
font-size: 13px;
text-align: justify;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
box-shadow: 0 0 20px black;
-moz-box-shadow: 0 0 20px black;
-webkit-box-shadow: 0 0 20px black;
}
#home .right h1 {
font-size: 16px;
padding-bottom: 4px;
border-bottom: 1px black dotted;
}
#home .right p {
margin-bottom: 4px;
}
#home .right p a {
border-width: 0 0 1px 0;
border-style: dotted;
border-color: black;
}
#home .right p a:hover,
#home .right p a:focus {
border-style: solid;
text-decoration: none;
}
#home .right button {
display: block;
margin-left: 22px;
width: 342px;
height: 64px;
text-decoration: none;
font-weight: bold;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
#home .right button:hover {
cursor: pointer;
}
#home .right button span {
float: left;
}
#home .right button span.home-images {
height: 16px;
width: 16px;
margin: 5px 7px 7px 24px;
}
#home .right button span.text {
padding-left: 20px;
font-size: 1.5em;
}
#home .right .login {
background-color: #72d071;
background-position: 0 0;
border: 1px solid #5cb55c;
margin-top: 22px;
box-shadow: 0 0 10px #89e389;
-moz-box-shadow: 0 0 10px #89e389;
-webkit-box-shadow: 0 0 10px #89e389;
}
#home .right .login:hover,
#home .right .login:focus {
border: 1px solid #419141;
box-shadow: 0 0 15px #72d071;
-moz-box-shadow: 0 0 15px #72d071;
-webkit-box-shadow: 0 0 15px #72d071;
}
#home .right .login:active {
background-color: #97e896;
background-position: 0 -80px;
}
#home .right .login span.text {
color: #2d612d;
text-shadow: 1px 1px 1px #5cb55c;
}
#home .right .login span.home-images {
background-position: 0 -230px;
}
#home .right .register {
background-color: #f6ef82;
background-position: 0 -160px;
border: 1px solid #e3db56;
margin-top: 15px;
box-shadow: 0 0 15px #f1e968;
-moz-box-shadow: 0 0 15px #f1e968;
-webkit-box-shadow: 0 0 15px #f1e968;
}
#home .right .register:hover,
#home .right .register:focus {
border: 1px solid #d2c93f;
box-shadow: 0 0 15px #e0d743;
-moz-box-shadow: 0 0 15px #e0d743;
-webkit-box-shadow: 0 0 15px #e0d743;
}
#home .right .register:active {
background-color: #fdf7af;
background-position: 0 -240px;
}
#home .right .register span.text {
color: #6d6813;
text-shadow: 1px 1px 1px #dbd56e;
}
#home .right .register span.home-images {
background-position: 0 -204px;
}
#home .right p.notice {
margin-top: 24px;
font-size: 0.9em;
}
#home .right .navigation {
clear: both;
width: 385px;
border-top: 1px black dotted;
position: absolute;
text-align: right;
bottom: 25px;
right: 25px;
padding-top: 6px;
}
#home .right .navigation a {
margin-left: 9px;
color: black;
text-decoration: none;
font-size: 0.9em;
height: 12px;
padding: 0 0 4px 20px;
float: right;
}
#home .right .navigation a:hover,
#home .right .navigation a:focus {
text-decoration: underline;
}
#home .right .navigation a.unencrypted {
background-position: 0 -256px;
}
#home .right .navigation a.encrypted {
background-position: 0 -282px;
}
#home .right .navigation a.project {
background-position: 0 -126px;
}
#home .right .navigation a.manager {
background-position: 0 -152px;
}
#home .right .navigation a.mobile {
background-position: 0 -178px;
}
#home a.advanced {
background-position: 0 -334px;
font-size: 0.9em;
height: 16px;
margin-bottom: 10px;
padding-left: 16px;
display: block;
}
#home fieldset.advanced {
display: none;
}
#home .anonymouser input[type=text] {
width: 160px;
}
#home .homediv.registerer .success a {
font-weight: bold;
text-decoration: underline;
}
#home fieldset {
border: 1px solid black;
margin: 12px 0 12px 0;
padding: 5px 0 4px 0;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
#home legend {
font-size: 0.9em;
margin: 0 0 0 15px;
padding: 0 2px;
text-transform: uppercase;
}
#home label {
width: 110px;
display: block;
float: left;
clear: both;
margin: 0 0 5px 12px;
}
#home input,
#home select {
float: left;
margin-bottom: 5px;
}
#home input[type=text],
#home input[type=password],
#home select {
width: 140px;
margin-top: -2px;
}
#home input[type=submit] {
min-width: 120px;
float: right;
}
#home span.jid {
display: block;
float: left;
margin: 0 4px;
}
#home input.nick, #home input.server {
width: 110px;
}
#home .info {
padding: 6px;
position: absolute;
bottom: 62px;
right: 35px;
border-width: 1px;
border-style: dotted;
clear: both;
width: 350px;
}
#home .info.success {
background-color: #aee578;
border-color: #85b05c;
display: none;
}
#home .info.fail {
background-color: #f19d9d;
border-color: #b34f4f;
}
#home .info.report {
background-color: #f3f48b;
border-color: #c9c66b;
display: none;
}
#home .info.report span {
text-decoration: underline;
}
#home .notice.simple {
background-color: rgb(20,20,20);
background-color: rgba(20,20,20,0.7);
color: white;
font-size: 0.9em;
text-decoration: none;
text-shadow: 0 1px 0 black;
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 8px 20px;
z-index: 100;
box-shadow: 0 0 25px #ababab;
-moz-box-shadow: 0 0 25px #ababab;
-webkit-box-shadow: 0 0 25px #ababab;
}
#home .notice.simple .title {
background-color: rgb(20,20,20);
background-color: rgba(20,20,20,0.4);
background-position: 8px -299px;
border-width: 0 1px 1px 1px;
border-style: solid;
border-color: #141414;
font-weight: bold;
padding: 8px 8px 8px 30px;
}
#home .notice.simple .text {
margin-left: 20px;
}

View file

@ -0,0 +1,146 @@
/*
Jappix - An open social platform
These are all the IE compliant CSS classes
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 22/04/11
*/
/* rgba(255,255,255,0.9) */
.search ul {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#edffffff,endColorstr=#edffffff);
}
/* rgba(255,255,255,0.3) */
a.finish:active,
#manager-buttons input:active,
#install-buttons input:active {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#49ffffff,endColorstr=#49ffffff);
}
/* rgba(255,255,255,0.2) */
a.finish:hover,
a.finish:focus,
#manager-buttons input:hover,
#manager-buttons input:focus,
#install-buttons input:hover,
#install-buttons input:focus,
.notifications-content .one-notification:active {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#33ffffff,endColorstr=#33ffffff);
}
/* rgba(255,255,255,0.14) */
#home .locale .list a:active {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#2fffffff,endColorstr=#2fffffff);
}
/* rgba(255,255,255,0.1) */
#home .locale .list a:hover,
#home .locale .list a:focus,
a.finish,
a.finish.disabled:hover,
a.finish.disabled:focus,
a.finish.disabled:active,
#manager-buttons input,
#install-buttons input,
.notifications-content .one-notification:hover,
.notifications-content .one-notification:focus {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#20ffffff,endColorstr=#20ffffff);
}
/* rgba(255,239,104,0.8) */
.popup .infos {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#deffef68,endColorstr=#deffef68);
}
/* rgba(225,160,20,0.3) */
.search ul li.hovered {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#46e1a014,endColorstr=#46e1a014);
}
/* rgba(248,246,186,0.9) */
#board .one-board.info {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#edf8f6ba,endColorstr=#edf8f6ba);
}
/* rgba(241,160,160,0.9) */
#board .one-board.error {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#edf1a0a0,endColorstr=#edf1a0a0);
}
/* rgba(234,234,234,0.8) */
#page-engine .chatstate {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#deeaeaea,endColorstr=#deeaeaea);
}
/* rgba(20,20,20,0.6) */
#home .locale,
#home .obsolete,
#home .notice.simple {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#a0141414,endColorstr=#a0141414);
}
/* rgba(20,20,20,0.8) */
#home .main,
#reconnect .pane,
#my-infos,
#right-content,
#buddy-list,
#manager,
#install {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#de141414,endColorstr=#de141414);
}
/* rgba(20,20,20,0.9) */
.popup {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#ed141414,endColorstr=#ed141414);
}
/* rgba(0,0,0,0.2) */
#install-top .step {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#33000000,endColorstr=#33000000);
}
/* rgba(0,0,0,0.6) */
.lock {
background: url(../img/others/lock.png) repeat !important;
}
/* rgba(0,0,0,0.8) */
#page-engine .tooltip-subitem,
.attach-subitem,
.buddy-infos-subitem,
.buddy-conf-subitem,
.tools-content-subitem {
background: transparent;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#de000000,endColorstr=#de000000);
}
/* Fix a fieldset padding bug */
legend {
margin-bottom: 5px !important;
}
/* Fix an opacity bug */
a.finish.disabled {
filter: alpha(opacity = 20) !important;
}

View file

@ -0,0 +1,89 @@
/*
Jappix - An open social platform
This is the images CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 16/01/12
*/
.body-images {
background-image: url(../img/sprites/background.png);
background-repeat: repeat;
background-color: #93c5fa;
}
.install-images {
background-image: url(../img/sprites/install.png);
background-repeat: no-repeat;
}
.home-images {
background-image: url(../img/sprites/home.png);
background-repeat: no-repeat;
}
.browsers-images {
background-image: url(../img/sprites/browsers.png);
background-repeat: no-repeat;
}
.buttons-images {
background-image: url(../img/sprites/buttons.png);
background-repeat: repeat-x;
}
.talk-images {
background-image: url(../img/sprites/talk.png);
background-repeat: no-repeat;
}
.smileys-images {
background-image: url(../img/sprites/smileys.png);
background-repeat: no-repeat;
}
.welcome-images {
background-image: url(../img/sprites/welcome.png);
background-repeat: no-repeat;
}
.me-images {
background-image: url(../img/sprites/me.png);
background-repeat: no-repeat;
}
.manager-images {
background-image: url(../img/sprites/manager.png);
background-repeat: no-repeat;
}
.mobile-images {
background-image: url(../img/sprites/mobile.png);
background-repeat: no-repeat;
}
.wait-small {
background-image: url(../img/wait/wait-small.gif);
background-repeat: no-repeat;
height: 16px;
width: 16px;
}
.wait-medium {
background-image: url(../img/wait/wait-medium.png);
background-repeat: no-repeat;
height: 24px;
width: 24px;
}
.wait-big {
background-image: url(../img/wait/wait-big.gif);
background-repeat: no-repeat;
height: 30px;
width: 30px;
}

View file

@ -0,0 +1,202 @@
/*
Jappix - An open social platform
This is the inbox CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 28/12/10
*/
#inbox .content {
padding: 10px 0 10px 0;
}
#inbox .content p {
margin: 3px 10px;
text-align: justify;
font-size: 0.9em;
}
#inbox .inbox-results {
height: 310px;
width: 620px;
margin: -5px 0 0 10px;
padding: 6px 0 0 0;
overflow: auto;
}
#inbox .message-unread {
background-color: #E9F1FD;
}
#inbox .one-message {
font-size: 0.9em;
border-bottom: 1px #b2c7cb solid;
}
#inbox .message-head {
padding: 6px 0 7px 4px;
overflow: hidden;
}
#inbox .message-head:hover {
background-color: #e9f1fd;
cursor: pointer;
}
#inbox .message-head:active {
background-color: #f1f6fd;
}
#inbox .one-message.message-reading,
#inbox .one-message.message-reading .message-head {
background-color: #f1f6fd;
}
#inbox .avatar-container {
float: left;
width: 40px;
height: 40px;
margin-right: 7px;
text-align: center;
background-repeat: no-repeat;
}
#inbox .avatar {
max-width: 40px;
max-height: 40px;
}
#inbox .message-jid,
#inbox .message-subject {
float: left;
margin: 0 2px;
overflow: hidden;
}
#inbox .message-jid {
width: 165px;
font-weight: bold;
}
#inbox .message-subject {
width: 355px;
}
#inbox .message-truncated {
color: #42646b;
font-size: 0.8em;
margin: 23px 0 0 49px;
}
#inbox .message-body {
padding: 8px 5px 5px 5px;
}
#inbox .message-body a {
text-decoration: underline;
}
#inbox .message-meta {
margin-top: 6px;
padding: 3px 4px;
border-top: 1px #b2c7cb dotted;
}
#inbox .message-meta span.date {
color: #28474e;
font-size: 0.8em;
margin: 10px 0 0 4px;
float: left;
}
#inbox .message-meta a {
font-size: 0.98em;
margin: 5px;
float: right;
display: block;
}
#inbox .inbox-noresults {
font-weight: bold;
display: none;
}
#inbox .a-show-messages {
display: none;
}
#inbox .inbox-new {
display: none;
height: 300px;
width: 620px;
margin: -5px 0 0 10px;
padding: 16px 0 0 0;
}
#inbox .inbox-new-block {
border-top: 1px #686868 dotted;
padding-top: 9px;
min-height: 32px;
clear: both;
}
#inbox .inbox-new-text {
float: left;
width: 100px;
}
#inbox .inbox-new-textarea {
width: 460px;
height: 109px;
margin-bottom: 10px;
float: left;
}
#inbox .inbox-new input {
float: left;
}
#inbox .inbox-new-to ul {
width: 264px;
max-height: 168px;
font-size: 0.9em;
left: 120px;
top: 31px;
}
#inbox .inbox-new-to-input {
width: 260px;
}
#inbox .inbox-new-subject-input {
width: 380px;
}
#inbox .inbox-new-file a {
display: block;
float: left;
}
#inbox .inbox-new-file a.file {
font-size: 0.85em;
height: 16px;
max-width: 320px;
margin: 3px 0 15px 013px;
overflow: hidden;
}
#inbox .inbox-new-file a.one-button {
font-size: 0.85em;
margin: -2px 0 0 25px;
}
#inbox .inbox-new-send a {
font-size: 0.85em;
float: right;
display: block;
}

View file

@ -0,0 +1,285 @@
/*
Jappix - An open social platform
This is the install CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 08/06/11
*/
body {
color: white;
}
#install {
background-color: rgb(20,20,20);
background-color: rgba(20,20,20,0.85);
width: 800px;
margin: 35px auto;
padding-bottom: 17px;
border-radius: 6px;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
box-shadow: 0 0 35px #5c5c5c;
-moz-box-shadow: 0 0 35px #5c5c5c;
-webkit-box-shadow: 0 0 35px #5c5c5c;
}
#install a {
color: black;
text-decoration: underline;
}
#install .clear {
clear: both;
}
#install fieldset {
border: 1px solid black;
margin: 22px 0 15px 0;
padding: 7px 2px 5px 2px;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
#install legend {
font-size: 0.9em;
margin: 0 0 0 15px;
padding: 0 2px;
text-transform: uppercase;
}
#install label {
width: 200px;
display: block;
float: left;
clear: both;
margin: 0 0 9px 12px;
}
#install input {
float: left;
margin-bottom: 5px;
}
#install input[type=text],
#install input[type=url],
#install input[type=password] {
margin-top: -2px;
padding: 3px;
font-size: 0.95em;
min-width: 220px;
}
#install input.icon {
padding-left: 24px;
min-width: 199px;
max-height: 18px;
}
#install input.icon#user_name {
background-position: 4px -204px;
}
#install input.icon#user_password {
background-position: 4px -226px;
}
#install input.icon#user_repassword {
background-position: 4px -248px;
}
#install-top {
padding: 30px 45px;
}
#install-top .logo {
background-position: 0 0;
min-width: 88px;
height: 36px;
padding: 32px 0 0 66px;
font-size: 32px;
color: white;
text-transform: lowercase;
float: left;
text-shadow: 0 1px 1px black;
}
#install-top .step {
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.2);
border: 2px solid white;
padding: 6px 21px;
font-size: 2.7em;
text-shadow: 0 1px 1px black;
float: right;
border-radius: 40px;
-moz-border-radius: 40px;
-webkit-border-radius: 40px;
box-shadow: 0 0 10px #202020;
-moz-box-shadow: 0 0 10px #202020;
-webkit-box-shadow: 0 0 10px #202020;
}
#install-top .step span {
font-size: 0.6em;
}
#install-content {
background: #e4eef9;
background: -moz-linear-gradient(top, #e4eef9, #d0e5fa);
background: -webkit-gradient(linear, left top, left bottom, from(#e4eef9), to(#d0e5fa));
color: black;
font-size: 0.9em;
margin: 0 10px;
padding: 20px 24px;
min-height: 260px;
clear: both;
right: 10px;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
box-shadow: 0 0 20px #202020;
-moz-box-shadow: 0 0 20px #202020;
-webkit-box-shadow: 0 0 20px #202020;
}
#install-content h3 {
padding-left: 24px;
margin-bottom: 15px;
}
#install-content h3.start {
background-position: 0 -73px;
}
#install-content h3.storage {
background-position: 0 -95px;
}
#install-content h3.account {
background-position: 0 -117px;
}
#install-content h3.main {
background-position: 0 -139px;
}
#install-content h3.hosts {
background-position: 0 -161px;
}
#install-content h3.services {
background-position: 0 -183px;
}
#install-content p {
margin-bottom: 10px;
}
#install-content .info {
color: black;
border-width: 1px;
border-style: dashed;
padding: 6px 8px;
display: block;
text-decoration: none;
}
#install-content .info.smallspace {
margin: 14px 0 10px 0;
}
#install-content .info.bigspace {
margin: 35px 0 20px 0;
}
#install-content .info.first {
margin-top: 28px;
}
#install-content .info.last {
margin-bottom: 28px;
}
#install-content .info.neutral {
background-color: #f0f19d;
border-color: #b3ad4f;
}
#install-content a.info.neutral:hover,
#install-content a.info.neutral:focus {
background-color: #eced96;
}
#install-content a.info.neutral:active {
background-color: #e9ea93;
}
#install-content .info.success {
background-color: #a8dca9;
border-color: #5e9f5f;
}
#install-content a.info.success:hover,
#install-content a.info.success:focus {
background-color: #a0d5a1;
}
#install-content a.info.success:active {
background-color: #9ad09b;
}
#install-content .info.fail {
background-color: #f19d9d;
border-color: #b34f4f;
}
#install-content ol {
margin: 20px 30px;
}
#install-content ol li {
margin-bottom: 1px;
}
#install-buttons {
margin-top: 22px;
}
#install-buttons input {
border: 1px solid white;
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.1);
color: white;
padding: 4px 8px;
margin-right: 20px;
text-shadow: 0 1px 1px black;
float: right;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
box-shadow: 0 0 5px #202020;
-moz-box-shadow: 0 0 5px #202020;
-webkit-box-shadow: 0 0 5px #202020;
}
#install-buttons input:hover,
#install-buttons input:focus {
cursor: pointer;
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.2);
box-shadow: 0 0 15px #202020;
-moz-box-shadow: 0 0 15px #202020;
-webkit-box-shadow: 0 0 15px #202020;
}
#install-buttons input:active {
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.3);
}

View file

@ -0,0 +1,34 @@
/*
Jappix - An open social platform
This is the integratebox CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 06/11/10
*/
#integratebox .top {
height: 40px;
}
#integratebox .content {
text-align: center;
height: 385px;
}
#integratebox .one-media img {
max-height: 385px;
max-width: 640px;
}
#integratebox .one-media a img {
border: none;
}
#integratebox .one-media audio {
margin-top: 170px;
}

View file

@ -0,0 +1,148 @@
/*
Jappix - An open social platform
This is the datepicker CSS stylesheet
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 28/12/10
*/
div.datepicker {
position: relative;
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
width: 196px;
height: 147px;
position: absolute;
cursor: default;
top: 0;
left: 0;
display: none;
}
.datepickerHidden {
display: none;
}
div.datepicker table {
border-collapse:collapse;
}
div.datepicker a {
text-decoration: none;
cursor: default;
outline: none;
}
div.datepicker table td {
text-align: right;
padding: 0;
margin: 0;
}
div.datepicker th {
text-align: center;
color: #47646a;
font-weight: normal;
}
div.datepicker tbody th {
text-align: left;
}
div.datepicker tbody a {
display: block;
}
.datepickerDays a {
width: 20px;
line-height: 16px;
height: 16px;
padding-right: 2px;
}
.datepickerYears a,
.datepickerMonths a {
width: 44px;
line-height: 36px;
height: 36px;
text-align: center;
}
td.datepickerNotInMonth {
background: #c7d1d4;
}
tbody.datepickerDays td.datepickerSelected {
background: #b0bdc1;
}
tbody.datepickerYears td.datepickerSelected,
tbody.datepickerMonths td.datepickerSelected {
background: #9daaae;
}
div.datepicker a:hover,
div.datepicker a:focus {
color: #3d7682;
}
div.datepicker tbody th {
text-align: left;
}
.datepickerSpace div {
width: 20px;
}
.datepickerGoNext a,
.datepickerGoPrev a,
.datepickerMonth a {
text-align: center;
height: 20px;
line-height: 20px;
}
.datepickerGoNext a {
float: right;
width: 20px;
}
.datepickerGoPrev a {
float: left;
width: 20px;
}
table.datepickerViewDays tbody.datepickerMonths,
table.datepickerViewDays tbody.datepickerYears {
display: none;
}
table.datepickerViewMonths tbody.datepickerDays,
table.datepickerViewMonths tbody.datepickerYears,
table.datepickerViewMonths tr.datepickerDoW {
display: none;
}
table.datepickerViewYears tbody.datepickerDays,
table.datepickerViewYears tbody.datepickerMonths,
table.datepickerViewYears tr.datepickerDoW {
display: none;
}
td.datepickerDisabled a,
td.datepickerDisabled.datepickerNotInMonth a {
color: #333;
}
td.datepickerSpecial a {
background: #700;
}
td.datepickerSpecial.datepickerSelected a {
background: #a00;
}

View file

@ -0,0 +1,131 @@
/*
Jappix - An open social platform
This is the main CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 05/10/11
*/
* {
margin: 0;
padding: 0;
}
body {
font: normal 14.4px Helvetica, Verdana, sans-serif;
text-shadow: 0 0 5px white;
}
h1 {
margin-bottom: 15px;
}
a {
text-decoration: none;
color: black;
outline-style: none;
}
a:hover,
a:focus {
cursor: pointer;
text-decoration: underline;
}
legend {
color: black;
}
input,
textarea {
background-color: white;
border: 1px solid #636363;
font-size: 0.95em;
padding: 2px;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
box-shadow: inset 0 3px 10px #dcdcdc;
-moz-box-shadow: inset 0 3px 10px #dcdcdc;
-webkit-box-shadow: inset 0 3px 10px #dcdcdc;
}
textarea {
font-size: 1.1em;
}
input:focus,
input[type=submit]:hover,
input[type=reset]:hover,
textarea:focus {
border: 1px solid #e1a014;
box-shadow: inset 0 3px 10px #edd9bc;
-moz-box-shadow: inset 0 3px 10px #edd9bc;
-webkit-box-shadow: inset 0 3px 10px #edd9bc;
}
input[type=submit],
input[type=reset] {
cursor: pointer;
}
input[type=submit]:active,
input[type=reset]:active {
box-shadow: inset 0 3px 15px #e1a753;
-moz-box-shadow: inset 0 3px 15px #e1a753;
-webkit-box-shadow: inset 0 3px 15px #e1a753;
}
input[disabled],
textarea[disabled] {
background-color: #f3f3f3;
border: 1px solid #989898;
}
input:placeholder {
color: #67787c !important;
}
input:-moz-placeholder {
color: #67787c !important;
}
input::-webkit-input-placeholder {
color: #67787c !important;
}
input.placeholder {
color: #67787c !important;
}
input[type=checkbox] {
margin-top: 2px;
}
input[type=checkbox],
input[type=radio] {
background: transparent none !important;
border: 0 none !important;
}
.please-complete,
.please-complete:hover,
.please-complete:focus {
border: 1px #ac2525 solid !important;
box-shadow: inset 0 3px 10px #f39c9c !important;
-moz-box-shadow: inset 0 3px 10px #f39c9c !important;
-webkit-box-shadow: inset 0 3px 10px #f39c9c !important;
}
.hidden {
display: none !important;
}
.clear {
clear: both !important;
}

View file

@ -0,0 +1,543 @@
/*
Jappix - An open social platform
This is the manager CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 31/08/11
*/
#manager {
background-color: rgb(20,20,20);
background-color: rgba(20,20,20,0.85);
width: 945px;
margin: 0 auto 25px;
padding-bottom: 17px;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
-moz-border-radius-bottomleft: 4px;
-moz-border-radius-bottomright: 4px;
-webkit-border-bottom-left-radius: 4px;
-webkit-border-bottom-right-radius: 4px;
box-shadow: 0 0 35px #5c5c5c;
-moz-box-shadow: 0 0 35px #5c5c5c;
-webkit-box-shadow: 0 0 35px #5c5c5c;
}
#manager a {
color: black;
text-decoration: underline;
}
#manager .clear {
clear: both;
}
#manager fieldset {
border: 1px solid black;
margin: 22px 0 15px 0;
padding: 7px 2px 5px 2px;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
#manager legend {
font-size: 0.9em;
margin: 0 0 0 15px;
padding: 0 2px;
text-transform: uppercase;
}
#manager label {
width: 200px;
display: block;
float: left;
clear: both;
margin: 0 0 9px 12px;
}
#manager label.master {
text-decoration: underline;
}
#manager input,
#manager select {
float: left;
margin-bottom: 5px;
}
#manager input[type=radio] {
margin: 2px 8px 5px 0;
}
#manager input[type=text],
#manager input[type=url],
#manager input[type=password],
#manager select {
margin-top: -2px;
font-size: 0.95em;
}
#manager input[type=text],
#manager input[type=url],
#manager input[type=password] {
padding: 3px;
min-width: 220px;
}
#manager input.icon {
padding-left: 24px;
min-width: 199px;
max-height: 18px;
}
#manager input.icon#admin_name {
background-position: 4px -510px;
}
#manager input.icon#admin_password,
#manager input.icon#user_repassword {
background-position: 4px -532px;
}
#manager input.icon#user_name,
#manager input.icon#music_artist {
background-position: 4px -554px;
}
#manager input.icon#user_password {
background-position: 4px -576px;
}
#manager input.icon#music_title {
background-position: 4px -598px;
}
#manager input.icon#music_album {
background-position: 4px -620px;
}
#manager input.icon#background_image_color,
#manager input.icon#background_color_color {
background-position: 4px -641px;
}
#manager select {
min-width: 160px;
max-width: 230px;
}
#manager-top {
padding: 25px 45px 30px;
}
#manager-top .logo {
background-position: 0 0;
min-width: 89px;
height: 40px;
padding: 28px 0 0 65px;
font-size: 32px;
color: white;
text-transform: lowercase;
float: left;
text-shadow: 0 1px 1px black;
}
#manager-top .meta {
background-color: #e0eaec;
font-size: 0.9em;
padding: 12px 7px 12px 14px;
float: right;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
box-shadow: 0 0 10px #202020;
-moz-box-shadow: 0 0 10px #202020;
-webkit-box-shadow: 0 0 10px #202020;
}
#manager-top .meta span {
margin-right: 10px;
color: black;
}
#manager-top .meta a {
background-color: #f1f6fd;
border: 1px solid #b9cbcf;
color: #224249;
padding: 4px 8px 4px 21px;
margin-left: 2px;
text-decoration: none;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
#manager-top .meta a:hover,
#manager-top .meta a:focus {
border: 1px solid #95b1b7;
}
#manager-top .meta a:active {
border: 1px solid #77989f;
}
#manager-top .meta a.logout {
background-position: 3px -69px;
}
#manager-top .meta a.close {
background-position: 3px -90px;
}
#manager-tabs {
margin-left: 12px;
}
#manager-tabs a {
background-color: #d9e7ea;
color: #204249;
width: 107px;
height: 17px;
padding: 4px 4px 4px 16px;
margin-left: 4px;
font-size: 0.94em;
text-decoration: none;
overflow: hidden;
float: left;
border-top-right-radius: 3px;
border-top-left-radius: 3px;
-moz-border-radius-topright: 3px;
-moz-border-radius-topleft: 3px;
-webkit-border-top-right-radius: 3px;
-webkit-border-top-left-radius: 3px;
}
#manager-tabs a:hover,
#manager-tabs a:focus {
background-color: #cedee1;
text-decoration: none;
}
#manager-tabs a:active {
background-color: #c3d3d7;
text-decoration: none;
}
#manager-tabs a.tab-active {
background-color: #e4eef9 !important;
}
#manager-content {
background: #e4eef9;
background: -moz-linear-gradient(top, #e4eef9, #d0e5fa);
background: -webkit-gradient(linear, left top, left bottom, from(#e4eef9), to(#d0e5fa));
color: black;
font-size: 0.9em;
margin: 0 10px;
padding: 20px 24px;
min-height: 260px;
clear: both;
right: 10px;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
box-shadow: 0 0 20px #202020;
-moz-box-shadow: 0 0 20px #202020;
-webkit-box-shadow: 0 0 20px #202020;
}
#manager-content h3 {
padding-left: 24px;
margin-bottom: 15px;
}
#manager-content h3.login {
background-position: 0 -466px;
}
#manager-content h3.statistics {
background-position: 0 -203px;
}
#manager-content h3.configuration {
background-position: 0 -224px;
}
#manager-content h3.hosts {
background-position: 0 -246px;
}
#manager-content h3.storage {
background-position: 0 -268px;
}
#manager-content h3.design {
background-position: 0 -290px;
}
#manager-content h3.users {
background-position: 0 -312px;
}
#manager-content h3.updates {
background-position: 0 -334px;
}
#manager-content h4 {
border-top: 1px dotted black;
padding-top: 5px;
margin: 20px 0 14px;
clear: both;
}
#manager-content ul,
#manager-content ol {
width: 380px;
margin: 8px 0 20px 18px;
}
#manager-content li {
margin-bottom: 3px;
}
#manager-content li.total {
margin-bottom: 14px;
}
#manager-content li b {
width: 190px;
float: left;
}
#manager-content li span {
margin-left: 10px;
float: left;
}
#manager-content ul.stats,
#manager-content ol.stats {
float: left;
}
#manager-content object.stats {
border: 1px dotted #bed4d9;
width: 450px;
height: 270px;
margin-bottom: 20px;
float: right;
}
#manager-content p,
#manager-content div {
margin-bottom: 10px;
}
#manager-content .info {
color: black;
border-width: 1px;
border-style: dashed;
padding: 6px 8px;
display: block;
text-decoration: none;
}
#manager-content .info.bottomspace {
margin-bottom: 16px;
}
#manager-content .info.smallspace {
margin: 14px 0 10px 0;
}
#manager-content .info.bigspace {
margin: 35px 0 20px 0;
}
#manager-content .info.neutral {
background-color: #f0f19d;
border-color: #b3ad4f;
}
#manager-content a.info.neutral:hover,
#manager-content a.info.neutral:focus {
background-color: #eced96;
}
#manager-content a.info.neutral:active {
background-color: #e9ea93;
}
#manager-content .info.success {
background-color: #a8dca9;
border-color: #5e9f5f;
}
#manager-content a.info.success:hover,
#manager-content a.info.success:focus {
background-color: #a0d5a1;
}
#manager-content a.info.success:active {
background-color: #9ad09b;
}
#manager-content .info.fail {
background-color: #f19d9d;
border-color: #b34f4f;
}
#manager-content a.info.fail:hover,
#manager-content a.info.fail:focus {
background-color: #ea9595;
}
#manager-content a.info.fail:active {
background-color: #e59090;
}
#manager-content .browse {
margin: 2px 0 6px;
max-height: 243px;
overflow: auto;
}
#manager-content .browse .one-browse {
padding: 5px 10px 5px 34px;
height: 17px;
}
#manager-content .browse .user {
background-position: 9px -111px;
}
#manager-content .browse .other {
background-position: 9px -133px;
}
#manager-content .browse .folder {
background-position: 9px -178px;
}
#manager-content .browse .audio {
background-position: 9px -154px;
}
#manager-content .browse .alert {
background-position: 9px -353px;
}
#manager-content .browse .image {
background-position: 9px -374px;
}
#manager-content .browse .video {
background-position: 9px -397px;
}
#manager-content .browse .document {
background-position: 9px -418px;
}
#manager-content .browse .package {
background-position: 9px -441px;
}
#manager-content .browse .previous {
background-position: 9px -485px;
margin-bottom: 4px;
}
#manager-content .browse div {
margin: 0;
}
#manager-content .browse input {
float: right;
margin: 1px 0;
}
#manager-content .browse .odd {
background-color: #e9f1fd;
}
#manager-content .browse .even {
background-color: #f1f6fd;
}
#manager-content .sub {
border-left: 1px solid black;
margin: 5px 0 20px 22px;
padding-left: 12px;
clear: both;
}
#manager span.logo_links a {
width: 16px;
height: 16px;
margin-right: 6px;
float: left;
}
#manager span.logo_links a.remove {
background-position: 0 -688px;
}
#manager span.logo_links a.view {
background-position: 0 -666px;
}
#manager-content .clear {
margin: 0;
}
#manager-content textarea.notice-text {
height: 70px;
width: 600px;
margin-left: 4px;
padding: 5px;
font-size: 1.2em;
}
#manager-buttons {
margin-top: 22px;
}
#manager-buttons input {
border: 1px solid white;
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.1);
color: white;
padding: 4px 8px;
margin-left: -12px;
margin-right: 20px;
font-size: 1em;
text-shadow: 0 1px 1px black;
float: right;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
box-shadow: 0 0 5px #202020;
-moz-box-shadow: 0 0 5px #202020;
-webkit-box-shadow: 0 0 5px #202020;
}
#manager-buttons input:hover,
#manager-buttons input:focus {
cursor: pointer;
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.2);
box-shadow: 0 0 15px #202020;
-moz-box-shadow: 0 0 15px #202020;
-webkit-box-shadow: 0 0 15px #202020;
}
#manager-buttons input:active {
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.3);
}

View file

@ -0,0 +1,49 @@
/*
Jappix - An open social platform
This is the Jappix Me tool CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 16/01/12
*/
#me .content {
padding: 10px 0;
}
#me .logo {
background-position: 0 0;
width: 300px;
height: 61px;
margin: 20px auto 0 auto;
display: block;
}
#me .infos {
margin-top: 30px;
}
#me .infos p {
margin-top: 8px;
}
#me .infos p.infos-title {
margin-top: 0;
}
#me .infos a {
text-decoration: underline;
}
#me a.go {
text-align: center;
font-weight: bold;
width: 300px;
margin: 30px auto 0 auto;
padding: 8px 12px;
display: block;
}

View file

@ -0,0 +1,73 @@
/*
Jappix - An open social platform
This is the Jappix Mini legacy IE CSS stylesheet
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 20/03/11
*/
#jappix_mini {
width: expression(document.documentElement.clientWidth - 150 + 'px') !important;
position: absolute !important;
bottom: auto !important;
right: auto !important;
top: expression(((document.documentElement.clientHeight - this.offsetHeight) + (ignoreMiniTop = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop)) + 'px') !important;
left: expression((150 + this.offsetWidth - (document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth) + (ignoreMiniLeft = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft)) + 'px') !important;
}
#jappix_mini .jm_images {
background-image: url(../img/sprites/mini.gif) !important;
}
#jappix_mini .jm_images_animate {
background-image: url(../img/sprites/animate.gif) !important;
}
#jappix_mini a.jm_button {
width: 1px !important;
}
#jappix_mini div.jm_roster {
right: -1px !important;
bottom: 23px !important;
}
#jappix_mini div.jm_roster div.jm_buddies {
height: expression(this.scrollHeight > (document.documentElement.clientHeight - 70) ? (document.documentElement.clientHeight - 70) + 'px' : 'auto') !important;
}
#jappix_mini a.jm_pane {
height: 12px !important;
overflow-y: hidden !important;
}
#jappix_mini a.jm_button.jm_clicked {
background-image: none !important;
}
#jappix_mini div.jm_conversations a.jm_clicked {
border-right: none !important;
padding: 7px 6px 6px 6px !important;
}
#jappix_mini div.jm_chat-content {
bottom: 23px !important;
right: -2px !important;
}
#jappix_popup {
height: expression(document.documentElement.clientHeight + 'px') !important;
width: expression(document.documentElement.clientWidth + 'px') !important;
position: absolute !important;
top: expression(((ignorePopupTop = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop)) + 'px') !important;
left: expression(((ignorePopupLeft = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft)) + 'px') !important;
}
#jappix_popup div.jm_prompt {
position: absolute !important;
}

View file

@ -0,0 +1,540 @@
/*
Jappix - An open social platform
This is the Jappix Mini CSS stylesheet
-------------------------------------------------
License: AGPL
Authors: Vanaryon, Julien
Last revision: 16/01/12
*/
#jappix_mini,
#jappix_popup {
font: normal 11px helvetica, "Lucida Grande", "Lucida Sans", "Lucida Sans Unicode", Arial, sans-serif;
}
#jappix_mini {
margin-left: 130px;
position: fixed;
bottom: 0;
right: 20px;
z-index: 999;
}
#jappix_mini *,
#jappix_popup * {
border: none;
color: black;
width: auto;
height: auto;
margin: 0;
padding: 0;
overflow: visible;
font-size: 11px;
text-align: left;
text-transform: none;
text-shadow: none;
opacity: 1.0;
border-radius: 0;
-moz-border-radius: 0;
-webkit-border-radius: 0;
box-shadow: none;
-moz-box-shadow: none;
-webkit-box-shadow: none;
}
#jappix_mini .jm_images {
background-image: url(../img/sprites/mini.png);
background-repeat: no-repeat;
}
#jappix_mini .jm_images_animate {
background-image: url(../img/sprites/animate.png);
background-repeat: no-repeat;
}
#jappix_mini a {
text-decoration: none;
cursor: pointer;
}
#jappix_mini a:hover {
cursor: pointer;
}
#jappix_mini div.jm_position {
float: right;
}
#jappix_mini a.jm_pane {
background-color: #f4f4f4;
background-position: 0 -100px;
background-repeat: repeat-x;
border-color: #999999;
border-style: solid;
border-width: 1px 1px 0 1px;
font-weight: bold;
outline-style: none;
display: block;
padding: 6px;
height: 13px;
}
#jappix_mini a.jm_pane:hover {
background: white;
}
#jappix_mini a.jm_pane:hover,
#jappix_mini a.jm_pane:focus {
border-color: #666666;
}
#jappix_mini div.jm_starter,
#jappix_mini div.jm_conversations,
#jappix_mini div.jm_conversation {
float: left;
position: relative;
}
#jappix_mini div.jm_conversation {
width: 153px;
}
#jappix_mini a.jm_chat-tab {
border-width: 1px 0 0 1px;
width: 140px;
float: right;
overflow: hidden;
}
#jappix_mini a.jm_chat-tab.jm_clicked {
background: white;
position: relative;
border-top: none;
border-left: 1px solid #999999;
padding-top: 7px;
}
#jappix_mini a.jm_chat-tab span.jm_notify {
position: absolute;
top: 6px;
right: 9px;
}
#jappix_mini a.jm_chat-tab span.jm_notify span {
float: left;
}
#jappix_mini a.jm_chat-tab span.jm_notify span.jm_notify_left {
background-position: 0 -360px;
}
#jappix_mini a.jm_chat-tab span.jm_notify span.jm_notify_right {
background-position: -7px -360px;
}
#jappix_mini a.jm_chat-tab span.jm_notify span.jm_notify_left,
#jappix_mini a.jm_chat-tab span.jm_notify span.jm_notify_right {
height: 16px;
width: 7px;
}
#jappix_mini a.jm_chat-tab span.jm_notify span.jm_notify_middle {
background-color: #c60505;
color: white;
font-size: 0.85em;
height: 14px;
padding-top: 2px;
}
#jappix_mini div.jm_conversation.jm_type_groupchat span.jm_name {
margin-left: 4px;
}
#jappix_mini div.jm_chat-content {
background-color: white;
border: 1px solid #999999;
height: 300px;
width: 260px;
position: absolute;
right: -1px;
bottom: 25px;
display: none;
}
#jappix_mini div.jm_actions {
background-color: #565d5e;
border-bottom: 1px solid #3a3a3a;
height: 14px;
padding: 4px 6px;
font-weight: bold;
overflow: hidden;
}
#jappix_mini div.jm_actions span.jm_nick {
color: white;
height: 16px;
width: 225px;
overflow: hidden;
float: left;
}
#jappix_mini div.jm_actions a.jm_one-action {
background-color: #727879;
margin: 0 -2px 0 5px;
height: 15px;
width: 15px;
outline-style: none;
float: right;
}
#jappix_mini div.jm_actions a.jm_one-action:hover,
#jappix_mini div.jm_actions a.jm_one-action:focus {
background-color: #7f8788;
}
#jappix_mini div.jm_actions a.jm_one-action:active {
background-color: #8c9293;
}
#jappix_mini div.jm_actions a.jm_logo {
background-position: 7px 2px;
width: 81px;
height: 22px;
margin: -4px 0 0 -2px;
outline-style: none;
float: left;
}
#jappix_mini div.jm_actions a.jm_logo:hover,
#jappix_mini div.jm_actions a.jm_logo:focus {
background-color: #636a6b;
}
#jappix_mini div.jm_actions a.jm_logo:active {
background-color: #707677;
}
#jappix_mini div.jm_actions a.jm_close {
background-position: 1px -341px;
}
#jappix_mini div.jm_actions a.jm_join {
background-position: 0 -327px;
}
#jappix_mini div.jm_received-messages {
background-color: white;
padding: 5px 0 4px;
height: 242px;
overflow: auto;
}
#jappix_mini div.jm_received-messages p {
margin: 3px 0;
word-wrap: break-word;
}
#jappix_mini div.jm_received-messages p,
#jappix_mini div.jm_received-messages a {
color: black !important;
}
#jappix_mini div.jm_received-messages div.jm_group {
margin: 2px 6px 9px 6px;
padding-bottom: 8px;
border-bottom: 1px solid #eaeaea;
}
#jappix_mini div.jm_received-messages div.jm_system-message p,
#jappix_mini div.jm_received-messages div.jm_system-message a {
color: #053805 !important;
font-style: italic !important;
}
#jappix_mini div.jm_received-messages p a {
text-decoration: underline;
}
#jappix_mini div.jm_received-messages b {
margin-bottom: 3px;
display: block;
}
#jappix_mini div.jm_received-messages b.jm_me {
color: #123a5c;
}
#jappix_mini div.jm_received-messages b.jm_him {
color: #801e1e;
}
#jappix_mini div.jm_received-messages span.jm_date {
font-size: 0.8em;
float: right;
display: none;
}
#jappix_mini div.jm_received-messages div.jm_group:hover span.jm_date {
display: block;
}
#jappix_mini input.jm_send-messages {
background-color: white;
border-color: #999999;
border-style: solid;
border-width: 1px 0 0 0;
padding: 5px;
width: 250px;
min-height: 14px;
}
#jappix_mini div.jm_disabled div.jm_chat-content,
#jappix_mini div.jm_disabled input.jm_send-messages,
#jappix_mini div.jm_disabled a.jm_pane {
background: #f3f3f3 !important;
}
#jappix_mini div.jm_disabled input.jm_send-messages {
color: #9d9d9d;
}
#jappix_mini div.jm_roster {
background-color: white;
border: 1px solid #999999;
width: 160px;
position: absolute;
right: 0;
bottom: 25px;
display: none;
}
#jappix_mini div.jm_roster div.jm_buddies {
width: 100%;
max-height: 300px;
padding: 5px 0;
overflow: auto;
}
#jappix_mini div.jm_roster div.jm_grouped {
margin: 2px 0;
}
#jappix_mini div.jm_roster div.jm_grouped div.jm_name {
margin-bottom: 2px;
padding: 4px 8px 0;
font-weight: bold;
}
#jappix_mini a.jm_friend {
border-color: white;
border-style: solid;
border-width: 1px 0;
outline-style: none;
padding: 6px;
display: block;
}
#jappix_mini a.jm_friend.jm_offline {
display: none;
}
#jappix_mini a.jm_friend:hover,
#jappix_mini a.jm_friend:focus {
background-color: #888888;
border-color: #494949;
color: white;
}
#jappix_mini a.jm_friend:hover span.jm_presence,
#jappix_mini a.jm_friend:focus span.jm_presence {
background-position: 0 -84px;
}
#jappix_mini a.jm_button {
padding: 6px 10px;
position: relative;
z-index: 1;
}
#jappix_mini a.jm_button.jm_clicked {
background: white;
border-top: none;
border-left: 1px solid #999999;
border-right: 1px solid #999999;
padding: 7px 10px 6px 10px;
}
#jappix_mini span.jm_animate {
background-position: 0 0;
width: 111px;
height: 102px;
position: absolute;
top: -100px;
left: -74px;
z-index: 1;
display: block;
}
#jappix_mini span.jm_counter {
background-position: 0 -288px;
color: #333333;
height: 16px;
padding-left: 25px;
display: block;
}
#jappix_mini span.jm_counter.jm_error {
background-position: 0 -305px;
}
#jappix_mini span.jm_presence {
display: block;
height: 16px;
width: 16px;
margin-right: 4px;
float: left;
}
#jappix_mini span.jm_name {
color: #272727;
height: 14px;
width: 105px;
overflow: hidden;
float: left;
}
#jappix_mini .jm_available,
#jappix_mini .jm_chat {
background-position: 0 -20px;
}
#jappix_mini .jm_away {
background-position: 0 -36px;
}
#jappix_mini .jm_xa,
#jappix_mini .jm_dnd {
background-position: 0 -52px;
}
#jappix_mini .jm_unavailable {
background-position: 0 -68px;
}
#jappix_mini .jm_smiley {
border: 0 none;
height: 16px;
width: 16px;
vertical-align: bottom;
}
#jappix_mini .jm_smiley-wink {
background-position: 0 -148px;
}
#jappix_mini .jm_smiley-waii {
background-position: 0 -164px;
}
#jappix_mini .jm_smiley-unhappy {
background-position: 0 -180px;
}
#jappix_mini .jm_smiley-tongue {
background-position: 0 -196px;
}
#jappix_mini .jm_smiley-surprised {
background-position: 0 -212px;
}
#jappix_mini .jm_smiley-smile {
background-position: 0 -228px;
}
#jappix_mini .jm_smiley-happy {
background-position: 0 -244px;
}
#jappix_mini .jm_smiley-grin {
background-position: 0 -260px;
}
#jappix_popup {
background: url(../img/others/blank.gif) repeat;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 999;
}
#jappix_popup div.jm_prompt {
background-color: #565d5e;
border: 1px solid #3a3a3a;
width: 346px;
position: fixed;
top: 50%;
left: 50%;
margin-left: -175px;
padding: 16px 2px 2px 2px;
border-top-right-radius: 4px;
border-top-left-radius: 4px;
-moz-border-radius-topright: 4px;
-moz-border-radius-topleft: 4px;
-webkit-border-top-right-radius: 4px;
-webkit-border-top-left-radius: 4px;
box-shadow: 0 0 35px #232323;
-moz-box-shadow: 0 0 35px #232323;
-webkit-box-shadow: 0 0 35px #232323;
}
#jappix_popup div.jm_prompt form {
background-color: white;
border: 1px solid #3a3a3a;
width: 332px;
padding: 6px;
}
#jappix_popup div.jm_prompt form input {
background-color: #f9f9f9;
border: 1px solid #666666;
font-size: 1.1em;
padding: 1px 2px;
}
#jappix_popup div.jm_prompt form input:hover,
#jappix_popup div.jm_prompt form input:focus {
border: 1px solid #202020;
}
#jappix_popup div.jm_prompt form input.jm_text {
width: 326px;
margin: 6px 0;
display: block;
}
#jappix_popup div.jm_prompt form input.jm_submit {
text-align: center;
margin-left: 3px;
float: right;
}
#jappix_popup div.jm_prompt form input.jm_submit:hover,
#jappix_popup div.jm_prompt form input.jm_submit:focus {
background-color: #f3f3f3;
cursor: pointer;
}
#jappix_popup div.jm_prompt form input.jm_submit:active {
background-color: #e8e8e8;
}
#jappix_popup div.jm_prompt div.jm_clear {
clear: both;
}

View file

@ -0,0 +1,288 @@
/*
Jappix - An open social platform
This is the Jappix Mobile CSS stylesheet
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 05/10/11
*/
/* BEGIN GENERAL STYLE */
* {
margin: 0;
padding: 0;
}
body {
font: normal 14.4px Helvetica, Verdana, sans-serif;
background-color: #dcdcdc;
margin: 0 auto;
text-align: center;
min-width: 200px;
min-height: 260px;
}
a {
color: black;
}
/* END GENERAL STYLE */
/* BEGIN HEADER STYLE */
.header {
background-color: #2d2d2d;
border-bottom: 1px solid #6d6d6d;
color: #405964;
padding: 6px 0;
height: 30px;
}
.header div {
background-position: 0 0;
width: 83px;
height: 30px;
}
/* END HEADER STYLE */
/* BEGIN HOME STYLE */
#home .header div {
margin: 0 auto;
}
#home .notification {
padding: 2px;
margin-top: -1px;
}
#noscript {
background: #86a2ff;
border-bottom: 1px solid #5890d6;
color: #1e4b82;
}
#error {
background: #ff8686;
border-bottom: 1px solid #d65858;
color: #821e1e;
display: none;
}
#info {
background: #f3eba7;
border-bottom: 1px solid #d9d085;
color: #5e5616;
display: none;
}
#home .login {
padding: 8px 0;
margin: 30px 0 30px 0;
}
#home .login input {
margin-top: 5px;
padding: 2px;
}
#home .login input.xid,
#home .login input.password {
display: block;
margin: 4px auto;
font-size: 0.85em;
padding: 4px;
background-color: white;
border: 1px solid #636363;
width: 150px;
padding-left: 24px;
}
#home .login input.xid {
background-position: 4px -30px;
}
#home .login input.password {
background-position: 4px -53px;
}
#home .login label {
margin-bottom: 12px;
display: block;
}
#home .login label input {
margin-right: 4px;
}
#home a {
font-size: 0.8em;
}
/* END HOME STYLE */
/* BEGIN TALK STYLE */
#talk .header div,
#chat .header div {
float: left;
margin-left: 7px;
}
#talk .header button,
#chat .header button {
float: right;
margin-right: 7px;
padding: 2px;
}
#talk a.one-buddy {
display: none;
background-color: #87a5ab;
border-bottom: 1px solid #5b8088;
text-shadow: 1px 1px 1px #5b8088;
text-decoration: none;
color: white;
outline-style: none;
padding: 10px 0;
}
#talk a.one-buddy:hover {
cursor: pointer;
}
#talk a.available,
#talk a.chat {
background-color: #83b187;
border-bottom: 1px solid #4d8252;
text-shadow: 1px 1px 1px #4d8252;
}
#talk a.available:hover,
#talk a.chat:hover,
#talk a.available:focus,
#talk a.chat:focus {
background-color: #89c68e;
}
#talk a.available:active,
#talk a.chat:active {
background-color: #90d496;
}
#talk a.away {
background-color: #e0be7b;
border-bottom: 1px solid #ae8941;
text-shadow: 1px 1px 1px #ae8941;
}
#talk a.away:hover,
#talk a.away:focus {
background-color: #eac784;
}
#talk a.away:active {
background-color: #f3d294;
}
#talk a.xa,
#talk a.dnd {
background-color: #db8989;
border-bottom: 1px solid #a24343;
text-shadow: 1px 1px 1px #a24343;
}
#talk a.xa:hover,
#talk a.dnd:hover,
#talk a.xa:focus,
#talk a.dnd:focus {
background-color: #e89797;
}
#talk a.xa:active,
#talk a.dnd:active {
background-color: #ef9f9f;
}
/* END TALK STYLE */
/* BEGIN CHAT STYLE */
#chat {
display: none;
}
#chat .one-chat,
#chat .one-chat p,
#chat .one-chat div,
#chat .one-chat input {
position: absolute;
bottom: 0;
right: 0;
}
#chat .one-chat {
top: 43px;
left: 0;
}
#chat .one-chat p {
background-color: #87a5ab;
border-bottom: 1px solid #5b8088;
text-shadow: 1px 1px 1px #5b8088;
color: white;
top: 0;
left: 0;
height: 18px;
padding: 2px 0;
font-size: 0.9em;
}
#chat .one-chat div {
border-bottom: 1px solid #cbcbcb;
top: 23px;
left: 0;
bottom: 25px;
overflow: auto;
text-align: left;
}
#chat .one-chat span {
display: block;
font-size: 0.85em;
margin: 4px 6px;
word-wrap: break-word;
}
#chat .one-chat b {
margin-right: 3px;
}
#chat .one-chat b.me {
color: #123a5c;
}
#chat .one-chat b.him {
color: #801e1e;
}
#chat .one-chat input {
background-color: white;
bottom: 0;
height: 25px;
width: 100%;
border: none;
}
#chat .one-chat input.submit {
right: 0;
width: 35px;
}
/* END CHAT STYLE */

View file

@ -0,0 +1,91 @@
/*
Jappix - An open social platform
This is the mucadmin CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 11/05/11
*/
#mucadmin .content {
padding: 10px 0 10px 0;
}
#mucadmin .content p {
margin: 5px 10px 5px 10px;
text-align: justify;
}
#mucadmin .mucadmin-head-jid {
text-decoration: underline;
font-size: 0.9em;
float: right;
margin: 1px 4px 1px 1px;
}
#mucadmin .mucadmin-forms {
height: 310px;
width: 620px;
margin: -5px 0 0 10px;
padding: 6px 0 0 0;
overflow: auto;
}
#mucadmin .mucadmin-forms label {
width: 260px;
}
#mucadmin .mucadmin-topic label,
#mucadmin .mucadmin-aut label,
#mucadmin .mucadmin-others label {
font-size: 0.9em;
}
#mucadmin .mucadmin-forms textarea {
height: 60px;
width: 300px;
margin: 5px 12px 10px 0;
}
#mucadmin .results {
height: auto;
width: auto;
overflow: visible;
margin: 5px;
}
#mucadmin .aut-group {
float: left;
padding-bottom: 4px;
}
#mucadmin .one-aut {
clear: both;
margin: 0 10px 5px 0;
}
#mucadmin .aut-add {
clear: both;
float: left;
margin-bottom: 5px;
font-size: 0.9em;
}
#mucadmin .aut-remove {
float: left;
}
#mucadmin .aut-remove:hover,
#mucadmin .aut-remove:focus {
font-weight: bold;
text-decoration: none;
}
#mucadmin .mucadmin-others a {
float: left;
font-size: 0.9em;
}

View file

@ -0,0 +1,330 @@
/*
Jappix - An open social platform
This is the my-infos CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 31/08/11
*/
#my-infos {
background-color: rgb(20,20,20);
background-color: rgba(20,20,20,0.85);
color: #919191;
margin-top: 8px;
padding: 15px 6px 6px 6px;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
box-shadow: 0 0 6px #5c5c5c;
-moz-box-shadow: 0 0 6px #5c5c5c;
-webkit-box-shadow: 0 0 6px #5c5c5c;
}
#my-infos .content {
background: #e8f1f3;
background: -moz-linear-gradient(top, #e4edef, #e8f1f3);
background: -webkit-gradient(linear, left top, left bottom, from(#e4edef), to(#e8f1f3));
color: #919191;
max-height: 140px;
padding: 1px 0;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
#my-infos .element {
height: 24px;
margin: 6px 0;
position: relative;
}
#my-infos .element .icon {
background-color: white;
border-color: #636363;
border-width: 1px;
border-style: solid;
margin-left: 6px;
height: 22px;
width: 25px;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
#my-infos .element div.bubble a {
width: 100%;
height: 20px;
}
#my-infos .element .icon:hover,
#my-infos .element div.bubble a:hover {
background-color: #f4f4f4;
}
#my-infos .element .icon:active,
#my-infos .element div.bubble a:active {
background-color: #ededed;
}
#my-infos .f-presence div.bubble a[data-value=available] {
background-position: 4px -167px;
}
#my-infos .f-presence div.bubble a[data-value=away] {
background-position: 4px -183px;
}
#my-infos .f-presence div.bubble a[data-value=xa] {
background-position: 4px -199px;
}
#my-infos .f-mood div.bubble a[data-value=crazy] {
background-position: 4px -296px;
}
#my-infos .f-mood div.bubble a[data-value=excited] {
background-position: 4px -314px;
}
#my-infos .f-mood div.bubble a[data-value=playful] {
background-position: 4px -332px;
}
#my-infos .f-mood div.bubble a[data-value=happy] {
background-position: 4px -350px;
}
#my-infos .f-mood div.bubble a[data-value=shocked] {
background-position: 4px -368px;
}
#my-infos .f-mood div.bubble a[data-value=hot] {
background-position: 4px -386px;
}
#my-infos .f-mood div.bubble a[data-value=sad] {
background-position: 4px -404px;
}
#my-infos .f-mood div.bubble a[data-value=amorous] {
background-position: 4px -422px;
}
#my-infos .f-mood div.bubble a[data-value=confident] {
background-position: 4px -440px;
}
#my-infos .f-mood a[data-value] span {
background-position: 0 -352px;
}
#my-infos .f-mood a[data-value=crazy] span,
.mood-one {
background-position: 0 -298px;
}
#my-infos .f-mood a[data-value=excited] span,
.mood-two {
background-position: 0 -316px;
}
#my-infos .f-mood a[data-value=playful] span,
.mood-three {
background-position: 0 -334px;
}
#my-infos .f-mood a[data-value=happy] span,
.mood-four {
background-position: 0 -352px;
}
#my-infos .f-mood a[data-value=shocked] span,
.mood-five {
background-position: 0 -370px;
}
#my-infos .f-mood a[data-value=hot] span,
.mood-six {
background-position: 0 -388px;
}
#my-infos .f-mood a[data-value=sad] span,
.mood-seven {
background-position: 0 -406px;
}
#my-infos .f-mood a[data-value=amorous] span,
.mood-eight {
background-position: 0 -424px;
}
#my-infos .f-mood a[data-value=confident] span,
.mood-nine {
background-position: 0 -442px;
}
#my-infos .f-activity div.bubble a[data-value=doing_chores] {
background-position: 4px -458px;
}
#my-infos .f-activity div.bubble a[data-value=drinking] {
background-position: 4px -476px;
}
#my-infos .f-activity div.bubble a[data-value=eating] {
background-position: 4px -494px;
}
#my-infos .f-activity div.bubble a[data-value=exercising] {
background-position: 4px -512px;
}
#my-infos .f-activity div.bubble a[data-value=grooming] {
background-position: 4px -548px;
}
#my-infos .f-activity div.bubble a[data-value=having_appointment] {
background-position: 4px -566px;
}
#my-infos .f-activity div.bubble a[data-value=inactive] {
background-position: 4px -530px;
}
#my-infos .f-activity div.bubble a[data-value=relaxing] {
background-position: 4px -620px;
}
#my-infos .f-activity div.bubble a[data-value=talking] {
background-position: 4px -602px;
}
#my-infos .f-activity div.bubble a[data-value=traveling] {
background-position: 4px -584px;
}
#my-infos .f-activity div.bubble a[data-value=working] {
background-position: 4px -638px;
}
#my-infos .f-activity a[data-value] span {
background-position: 0 -514px;
}
#my-infos .f-activity a[data-value=doing_chores] span,
.activity-doing_chores {
background-position: 0 -460px;
}
#my-infos .f-activity a[data-value=drinking] span,
.activity-drinking {
background-position: 0 -478px;
}
#my-infos .f-activity a[data-value=eating] span,
.activity-eating {
background-position: 0 -496px;
}
#my-infos .f-activity a[data-value=exercising] span,
.activity-exercising {
background-position: 0 -514px;
}
#my-infos .f-activity a[data-value=grooming] span,
.activity-grooming {
background-position: 0 -550px;
}
#my-infos .f-activity a[data-value=having_appointment] span,
.activity-having_appointment {
background-position: 0 -568px;
}
#my-infos .f-activity a[data-value=inactive] span,
.activity-inactive {
background-position: 0 -532px;
}
#my-infos .f-activity a[data-value=relaxing] span,
.activity-relaxing {
background-position: 0 -622px;
}
#my-infos .f-activity a[data-value=talking] span,
.activity-talking {
background-position: 0 -604px;
}
#my-infos .f-activity a[data-value=traveling] span,
.activity-traveling {
background-position: 0 -586px;
}
#my-infos .f-activity a[data-value=working] span,
.activity-working {
background-position: 0 -640px;
}
#my-infos .element .icon.picker {
border-width: 1px 0 1px 1px;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
-moz-border-radius-topright: 0;
-moz-border-radius-bottomright: 0;
-webkit-border-top-right-radius: 0;
-webkit-border-bottom-right-radius: 0;
}
#my-infos .element .icon.disabled {
background-color: #f3f3f3;
border-color: #989898;
cursor: default;
}
#my-infos .element div.bubble {
background-color: white;
border-color: #636363;
border-width: 1px 1px 0 1px;
border-style: solid;
width: 25px;
padding: 1px 0;
position: absolute;
bottom: 21px;
left: 6px;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
-moz-border-radius-topleft: 2px;
-moz-border-radius-topright: 2px;
-webkit-border-top-left-radius: 2px;
-webkit-border-top-right-radius: 2px;
}
#my-infos .element a {
float: left;
}
#my-infos .element .icon span {
height: 16px;
width: 16px;
margin: 3px 4px;
display: block;
}
#my-infos .element input {
height: 18px;
width: 190px;
font-size: 0.85em;
padding-left: 4px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
-moz-border-radius-topleft: 0;
-moz-border-radius-bottomleft: 0;
-webkit-border-top-left-radius: 0;
-webkit-border-top-bottom-radius: 0;
}

View file

@ -0,0 +1,97 @@
/*
Jappix - An open social platform
This is the options CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 26/04/11
*/
#options label {
width: 190px;
font-size: 0.94em;
}
#options .forms {
width: 610px;
height: 328px;
margin: 15px 15px 15px 15px;
float: left;
}
#options .forms select {
margin-top: -3px;
min-width: 120px;
float: left;
}
#options .forms a.linked {
font-size: 0.9em;
float: left;
}
#options fieldset.privacy {
display: none;
}
#options .sub-ask-delete, #options .sub-ask-pass, #options .sub-ask-pass-success {
display: none;
}
#options .sub-ask {
display: none;
width: 592px;
padding: 8px;
float: left;
border: 1px #879da2 dotted;
background: #cbdde1;
}
#options .sub-ask-top {
font-size: 0.9em;
margin-top: -3px;
}
#options .sub-ask-title {
margin-bottom: 4px;
float: left;
}
#options .sub-ask-close {
float: right;
}
#options .sub-ask-close:hover {
cursor: pointer;
}
#options .sub-ask-content {
clear: both;
height: 25px;
font-size: 0.9em;
border-top: 1px #416972 solid;
padding: 12px 0;
}
#options .sub-ask-content label {
width: 125px;
}
#options .sub-ask-content input {
width: 125px;
}
#options .sub-ask-bottom {
clear: both;
font-size: 0.9em;
float: right;
text-decoration: underline;
}
#options .sub-ask-bottom:hover {
cursor: pointer;
}

View file

@ -0,0 +1,118 @@
/*
Jappix - An open social platform
This is the others CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 31/08/11
*/
#audio {
display: none;
}
#top-content {
position: absolute;
right: 5px;
left: 5px;
top: 0;
min-width: 860px;
z-index: 50;
}
#main-content {
position: absolute;
top: 34px;
left: 5px;
right: 5px;
bottom: 5px;
min-width: 850px;
min-height: 450px;
}
#left-content {
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 248px;
}
#right-content {
background-color: rgb(20,20,20);
background-color: rgba(20,20,20,0.85);
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 260px;
z-index: 10;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
box-shadow: 0 0 6px #5c5c5c;
-moz-box-shadow: 0 0 6px #5c5c5c;
-webkit-box-shadow: 0 0 6px #5c5c5c;
}
#general-wait {
background: url(../img/others/blank.gif) repeat;
z-index: 10000;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.general-wait-content {
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.9);
background-position: 8px 8px;
padding: 8px;
position: absolute;
right: 5px;
bottom: 5px;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
box-shadow: 0 0 2px #000;
-moz-box-shadow: 0 0 2px #000;
-webkit-box-shadow: 0 0 2px #000;
}
.inbox-hidable,
.options-hidable,
.pep-hidable,
.pubsub-hidable,
.archives-hidable,
.commands-hidable,
.privacy-hidable,
.xmpplinks-hidable {
display: none;
}
#reconnect .pane {
background-color: rgb(20,20,20);
background-color: rgba(20,20,20,0.85);
color: white;
padding: 25px;
z-index: 10000;
text-shadow: 0 1px 1px black;
position: absolute;
left: 0;
right: 0;
top: 0;
box-shadow: 0 0 35px #232323;
-moz-box-shadow: 0 0 35px #232323;
-webkit-box-shadow: 0 0 35px #232323;
}
#reconnect .pane a {
margin-top: -4px;
float: right;
}

View file

@ -0,0 +1,601 @@
/*
Jappix - An open social platform
This is the page-engine CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 31/08/11
*/
#page-engine {
background-color: #f4f4f4;
position: absolute;
top: 40px;
bottom: 6px;
right: 6px;
left: 6px;
z-index: 8;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
#page-engine .top {
background: #e8f1f3;
background: -moz-linear-gradient(top, #e8f1f3, #dee8ea);
background: -webkit-gradient(linear, left top, left bottom, from(#e8f1f3), to(#dee8ea));
border-bottom: 1px solid #d0d0d0;
color: black;
position: absolute;
top: 0;
left: 0;
right: 0;
padding: 6px;
height: 80px;
border-top-right-radius: 3px;
border-top-left-radius: 3px;
-moz-border-radius-topright: 3px;
-moz-border-radius-topleft: 3px;
-webkit-border-top-right-radius: 3px;
-webkit-border-top-left-radius: 3px;
}
#page-engine .top .avatar-container {
text-align: center;
margin: 2px 0 0 10px;
height: 76px;
width: 76px;
float: left;
}
#page-engine .top .avatar {
max-height: 76px;
max-width: 76px;
}
#page-engine .top .name {
text-align: right;
padding: 7px;
}
#page-engine p.bc-name {
font-size: 2.3em;
margin-bottom: 5px;
}
#page-engine p.bc-infos {
font-size: 0.85em;
height: 16px;
overflow: hidden;
position: absolute;
left: 115px;
right: 12px;
}
#page-engine .page-engine-chan[data-type=groupchat] p.bc-infos {
left: 12px;
}
#page-engine p.bc-infos span.show {
padding-left: 18px;
}
#page-engine p.bc-infos a {
text-decoration: underline;
}
#page-engine div.bc-pep {
float: right;
}
#page-engine div.bc-pep a {
height: 16px;
width: 16px;
margin-left: 4px;
float: left;
}
#page-engine div.bc-pep a:hover {
cursor: default;
}
#page-engine div.bc-pep a[href]:hover {
cursor: pointer;
}
#page-engine .content,
#page-engine .list {
font-size: 0.9em;
position: absolute;
top: 93px;
right: 0;
bottom: 29px;
overflow: auto;
box-shadow: inset 0 3px 10px #e8e8e8;
-moz-box-shadow: inset 0 3px 10px #e8e8e8;
-webkit-box-shadow: inset 0 3px 10px #e8e8e8;
}
#page-engine .content {
left: 0;
padding: 12px 14px 0;
}
#page-engine .content a {
text-decoration: underline;
}
#page-engine .page-engine-chan {
display: none;
}
#page-engine .chat .content,
#page-engine .chat .list {
bottom: 93px;
}
#page-engine .chat .content {
padding-bottom: 24px;
}
#page-engine .groupchat-content {
padding-bottom: 16px !important;
right: 191px !important;
}
#page-engine .list {
border-left: 1px solid #c8c8c8;
padding: 8px 0 0;
width: 190px;
right: 0;
}
#page-engine .list .role {
display: none;
margin-bottom: 10px;
}
#page-engine .list .title {
font-weight: bold;
color: #383838;
margin-left: 8px;
}
#page-engine .list .user {
background: #eff2f2;
background: -moz-linear-gradient(top, #eff2f2, #ecefef);
background: -webkit-gradient(linear, left top, left bottom, from(#eff2f2), to(#ecefef));
border-color: #c8c8c8;
border-width: 1px 0;
border-style: solid;
color: #383838;
margin-bottom: 3px;
height: 32px;
overflow: hidden;
}
#page-engine .list .user:hover {
background: #e9ecec;
cursor: pointer;
}
#page-engine .list .user:active {
background: #e3e7e7;
}
#page-engine .list .user.myself {
background-color: #eff2f2;
cursor: default;
}
#page-engine .list .user .name {
float: left;
height: 18px;
overflow: hidden;
margin: 7px 0 7px 3px;
padding-left: 18px;
}
#page-engine .list .user .avatar-container {
text-align: center;
float: right;
height: 32px;
width: 32px;
}
#page-engine .list .user .avatar {
max-height: 32px;
max-width: 32px;
}
#page-engine .one-group,
#archives .one-group {
border-bottom: 1px dotted #d0d0d0;
padding-bottom: 8px;
margin-bottom: 10px;
}
#page-engine .one-line,
#archives .one-line,
#page-engine .one-group b.name,
#archives .one-group b.name {
padding-left: 50px;
word-wrap: break-word;
}
#page-engine .one-group b.name,
#archives .one-group b.name {
display: block;
margin-bottom: 4px;
}
#page-engine .one-group b.name.me,
#archives .one-group b.name.me {
color: #123a5c;
}
#page-engine .one-group b.name.him,
#archives .one-group b.name.him {
color: #801e1e;
}
#page-engine .one-group span.date,
#archives .one-group span.date {
float: right;
font-size: 0.9em;
}
#page-engine .one-group .avatar-container,
#archives .one-group .avatar-container {
text-align: center;
margin: 4px 0 0 6px;
height: 30px;
width: 30px;
float: left;
}
#page-engine .one-group .avatar,
#archives .one-group .avatar {
max-height: 30px;
max-width: 30px;
}
#page-engine b.name.talk-images {
background-position: 50px -99px;
padding-left: 68px;
}
#page-engine .user-message,
#archives .user-message {
margin-bottom: 3px;
}
#page-engine .system-message {
color: #053805 !important;
margin-bottom: 3px !important;
padding-left: 0 !important;
}
#page-engine .system-message a {
color: #053805 !important;
}
#page-engine .system-message p.help b {
margin-bottom: 5px;
text-decoration: underline;
display: block;
}
#page-engine .system-message p.help em {
width: 240px;
text-decoration: underline;
margin-left: 5px;
float: left;
}
#page-engine .my-nick {
font-weight: bold;
}
#page-engine .old-message {
font-size: 11px !important;
margin-bottom: 1px !important;
}
#page-engine .chatstate {
background-color: rgb(234,234,234);
background-color: rgba(234,234,234,0.8);
color: #2c2c2c;
padding: 3px 10px 2px 8px;
position: absolute;
bottom: 93px;
left: 0;
font-size: 0.75em;
border-top-right-radius: 3px;
-moz-border-radius-topright: 3px;
-webkit-border-top-right-radius: 3px;
}
#page-engine .text {
height: 93px;
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
#page-engine .footer {
background: #e8f1f3;
background: -moz-linear-gradient(top, #dee8ea, #e8f1f3);
background: -webkit-gradient(linear, left top, left bottom, from(#dee8ea), to(#e8f1f3));
border-color: #d0d0d0;
border-width: 1px 0 0;
border-style: solid;
color: black;
position: absolute;
left: 0;
right: 0;
padding: 6px;
height: 16px;
}
#page-engine .chat .footer {
border-width: 1px 0;
position: static;
}
#page-engine .chat-tools-content {
height: 16px;
width: 16px;
margin-right: 8px;
float: left;
}
#page-engine .tools-tooltip {
display: block;
height: 16px;
width: 16px;
overflow: hidden;
float: left;
}
#page-engine .text .chat-tools-smileys {
margin-left: 4px;
}
#page-engine .text .chat-tools-file {
display: none;
}
#page-engine .text .chat-tools-file.mini .bubble-file {
z-index: 39;
}
#page-engine .text .chat-tools-file.mini .tooltip-subitem {
width: 22px;
height: 20px;
}
#page-engine .text .chat-tools-file.mini .wait {
margin: -2px 0 0 -1px;
}
#page-engine .text .tools-smileys {
background-position: 0 -388px;
}
#page-engine .text .tools-style {
background-position: 0 -700px;
}
#page-engine .text .tools-file {
background-position: 0 -1956px;
}
#page-engine .text .tools-save {
background-position: 0 -719px;
}
#page-engine .text .tools-clear {
background-position: 0 -739px;
}
#page-engine .text .tools-infos,
#channel .top div.shortcuts a.profile {
background-position: 0 -758px;
}
#page-engine .text .tools-add,
#page-engine .text .tools-archives,
#page-engine .text .tools-mucadmin {
display: none;
}
#page-engine .text .tools-mucadmin {
background-position: 0 -777px;
}
#page-engine .bubble-style label.bold {
font-weight: bold;
}
#page-engine .bubble-style label.italic {
font-style: italic;
}
#page-engine .bubble-style label.underline {
text-decoration: underline;
}
#page-engine .bubble-style a.color {
height: 18px;
width: 18px;
border-color: white;
border-width: 1px;
border-style: solid;
margin: 6px 5px 0 0;
float: left;
opacity: 0.6;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
box-shadow: 0 0 5px black;
-moz-box-shadow: 0 0 5px black;
-webkit-box-shadow: 0 0 5px black;
}
#page-engine .bubble-style a.color:hover,
#page-engine .bubble-style a.color:focus {
opacity: 0.7;
}
#page-engine .bubble-style a.color.selected {
opacity: 1;
border-color: #ffb20d;
}
#page-engine .bubble-file .tooltip-subitem {
width: 240px;
}
#page-engine .bubble-file input[type=file] {
width: 220px;
}
#page-engine .bubble-file input[type=submit],
#page-engine .bubble-file input[type=reset] {
margin: 4px 4px 0 0;
}
#page-engine .text .compose,
#page-engine .muc-ask {
position: absolute;
left: 0;
}
#page-engine .text .compose {
top: 29px;
right: 12px;
bottom: 12px;
}
#page-engine .muc-ask {
right: 0;
bottom: 0;
}
#page-engine .text textarea {
border: 1px solid #c8c8c8;
padding: 5px;
height: 100%;
width: 100%;
font-size: 1.1em;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-top-right-radius: 0;
border-top-left-radius: 0;
-moz-border-radius-topright: 0;
-moz-border-radius-topleft: 0;
-webkit-border-top-right-radius: 0;
-webkit-border-top-left-radius: 0;
}
#page-engine .muc-ask {
background-color: #e8f1f3;
height: 64px;
font-size: 0.9em;
right: 0;
z-index: 2;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
-moz-border-radius-bottomleft: 3px;
-moz-border-radius-bottomright: 3px;
-webkit-border-bottom-left-radius: 3px;
-webkit-border-bottom-right-radius: 3px;
}
#page-engine .muc-ask label {
color: #224249;
margin: 23px 10px 0 16px;
font-weight: bold;
}
#page-engine .muc-ask input {
width: 200px;
margin: 19px 10px 0 10px;
padding: 3px;
}
#page-engine .tooltip {
position: absolute;
bottom: 84px;
margin-left: -13px;
z-index: 40;
font-size: 0.8em;
color: white;
}
#page-engine .tooltip a {
color: white;
text-decoration: underline;
}
#page-engine .tooltip-subitem {
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.8);
padding: 10px;
width: 200px;
height: 110px;
text-shadow: 0 1px 1px black;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
#page-engine .tooltip-subarrow {
background-position: 0 -251px;
opacity: 0.8;
height: 10px;
width: 18px;
margin-left: 12px;
}
#page-engine .tooltip .tooltip-top {
margin-bottom: 8px;
font-weight: bold;
}
#page-engine .tooltip label {
margin-bottom: 4px;
float: left;
clear: both;
}
#page-engine .tooltip label input[type=checkbox] {
margin: 0 6px 0 0;
float: left;
}
#page-engine .tooltip label.select {
margin-top: 5px;
}
#page-engine .tooltip input,
#page-engine .tooltip select {
float: left;
}
#page-engine .tooltip select {
width: 100px;
}
#page-engine .tooltip .tooltip-actionlog:hover,
#page-engine .tooltip .tooltip-actionlog:focus {
cursor: pointer;
text-decoration: underline;
}

View file

@ -0,0 +1,209 @@
/*
Jappix - An open social platform
This is the page-switch CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 22/05/11
*/
#page-switch {
position: absolute;
top: 15px;
left: 10px;
right: 10px;
z-index: 9;
}
#page-switch .chans {
position: absolute;
left: 0;
right: 40px;
top: 0;
height: 25px;
overflow: hidden;
}
#page-switch .more {
position: absolute;
right: 0;
top: 0;
}
#page-switch .more-button {
background-position: 6px -1372px;
background-color: #d9e7ea;
width: 7px;
height: 17px;
padding: 1px 6px;
font-size: 0.9em;
text-decoration: none;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
#page-switch .more-content {
background-color: #d9e7ea;
width: 200px;
max-height: 400px;
overflow: auto;
position: absolute;
margin: -2px 0 0 -181px;
padding: 4px 0;
font-size: 0.95em;
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
-moz-border-radius-topleft: 3px;
-moz-border-radius-bottomleft: 3px;
-moz-border-radius-bottomright: 3px;
-webkit-border-top-left-radius: 3px;
-webkit-border-bottom-left-radius: 3px;
-webkit-border-bottom-right-radius: 3px;
}
#page-switch .switcher {
background-color: #d9e7ea;
color: #17353b;
height: 15px;
padding: 5px 10px 5px 5px;
margin: 0 2px;
font-size: 0.85em;
float: left;
border-top-right-radius: 3px;
border-top-left-radius: 3px;
-moz-border-radius-topright: 3px;
-moz-border-radius-topleft: 3px;
-webkit-border-top-right-radius: 3px;
-webkit-border-top-left-radius: 3px;
}
#page-switch .more-content .switcher {
background-color: #d9e7ea;
float: none;
margin: 0;
font-size: 0.9em;
border-radius: 0;
-moz-border-radius: 0;
-webkit-border-radius: 0;
}
#page-switch .more-content .switcher .exit {
display: block;
}
#page-switch .more-button:hover,
#page-switch .more-button:focus,
#page-switch .switcher:hover,
#page-switch .switcher:focus,
#page-switch .more-content .switcher:hover,
#page-switch .more-content .switcher:focus {
background-color: #cedee1;
cursor: pointer;
}
#page-switch .more-button:active,
#page-switch .switcher:active,
#page-switch .more-content .switcher:active {
background-color: #c3d3d7;
}
#page-switch .switcher.activechan {
background-color: #e8f1f3;
}
#page-switch .more-content .switcher.activechan {
background-color: #d1e0e3;
}
#page-switch .icon {
height: 16px;
width: 16px;
float: left;
}
#page-switch .name {
float: left;
margin-left: 4px;
max-height: 16px;
max-width: 140px;
overflow: hidden;
}
#page-switch .exit {
display: none;
background-color: #bdd9dc;
border: 1px solid #80aab0;
color: #355e64;
height: 14px;
width: 13px;
margin-left: 10px;
font-size: 0.85em;
text-align: center;
text-decoration: none;
float: right;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
#page-switch .exit:hover,
#page-switch .exit:focus {
background-color: #aac7cb;
}
#page-switch .exit:active {
background-color: #9bbdc1;
}
#page-switch .activechan .exit {
display: block;
float: right;
}
#page-switch .chan-newmessage {
background-color: #f6edc3 !important;
}
#page-switch .chan-newmessage:hover,
#page-switch .chan-newmessage:focus {
background-color: #f1eac0 !important;
}
#page-switch .chan-newmessage:active {
background-color: #ede4b8 !important;
}
#page-switch .composing,
#page-engine .list .user.composing {
color: #217021 !important;
}
#page-switch .paused,
#page-switch .chan-unread .name,
#page-engine .list .user.paused {
color: #2431ac !important;
}
#page-switch .active,
#page-engine .list .user.active {
color: #353535 !important;
}
#page-switch .inactive,
#page-engine .list .user.inactive {
color: #585858 !important;
}
#page-switch .gone {
color: #851313 !important;
}
#page-switch .channel .icon {
background-position: 0 -55px;
}

View file

@ -0,0 +1,612 @@
/*
Jappix - An open social platform
This is the popup CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 02/05/11
*/
.lock {
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.6);
left: 0;
right: 0;
top: 0;
bottom: 0;
position: fixed;
z-index: 9999;
}
.popup {
background-color: rgb(20,20,20);
background-color: rgba(20,20,20,0.95);
margin-top: -250px;
margin-left: -330px;
width: 640px;
height: 500px;
padding: 0 10px;
position: absolute;
z-index: 10000;
left: 50%;
top: 50%;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
box-shadow: 0 0 35px #232323;
-moz-box-shadow: 0 0 35px #232323;
-webkit-box-shadow: 0 0 35px #232323;
}
.popup.large {
margin-left: -460px;
width: 920px;
}
.popup .top {
width: 600px;
height: 45px;
font-size: 1.2em;
padding-top: 9px;
color: white;
margin: 14px 0 0 40px;
text-transform: uppercase;
text-decoration: none;
font-weight: bold;
text-shadow: 0 2px 2px black;
}
.popup .tab {
width: 620px;
height: 25px;
margin: -5px 10px 0 10px;
position: relative;
z-index: 1;
}
.popup .tab a {
background-color: #d9e7ea;
color: #204249;
width: 180px;
height: 17px;
padding: 4px 4px 4px 16px;
margin-left: 5px;
font-size: 0.94em;
overflow: hidden;
float: left;
border-top-right-radius: 3px;
border-top-left-radius: 3px;
-moz-border-radius-topright: 3px;
-moz-border-radius-topleft: 3px;
-webkit-border-top-right-radius: 3px;
-webkit-border-top-left-radius: 3px;
}
.popup .tab a:hover,
.popup .tab a:focus {
background-color: #cedee1;
text-decoration: none;
}
.popup .tab a:active {
background-color: #c3d3d7;
text-decoration: none;
}
.popup .tab a.tab-active {
background-color: #e4eef9 !important;
}
.popup .one-lap {
display: none;
}
.popup .one-lap.lap-active {
display: block;
}
.popup .content {
background: #e4eef9;
background: -moz-linear-gradient(top, #e4eef9, #D0E5FA);
background: -webkit-gradient(linear, left top, left bottom, from(#e4eef9), to(#D0E5FA));
height: 358px;
width: 640px;
position: absolute;
left: 10px;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
box-shadow: 0 0 20px black;
-moz-box-shadow: 0 0 20px black;
-webkit-box-shadow: 0 0 20px black;
}
.popup .content,
.popup .content a {
color: #112a2f;
}
.popup.large div.comments {
background-color: #f4f4f4;
width: 272px;
margin: 0;
position: absolute;
right: 10px;
top: 63px;
bottom: 10px;
overflow-x: hidden;
overflow-y: auto;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
.popup.large div.comments div.comments-content {
font-size: 0.8em;
}
.popup.large div.comments input {
width: 185px;
min-width: 0;
}
.popup.large div.comments .one-comment {
padding-bottom: 4px;
}
.popup.large div.comments .one-comment a {
text-decoration: underline;
}
.popup.large div.comments div.comments-content {
border-top-right-radius: 3px;
border-top-left-radius: 3px;
-moz-border-radius-topright: 3px;
-moz-border-radius-topleft: 3px;
-webkit-border-top-right-radius: 3px;
-webkit-border-top-left-radius: 3px;
}
.popup .head {
background: #f1f6fd;
border: 1px #9dc4fc solid;
width: 606px;
height: 24px;
margin: 0 10px 10px 10px;
padding: 6px;
}
.popup .head-text {
float: left;
font-size: 0.9em;
margin: 3px;
}
.popup .head-actions {
float: right;
margin-top: 2px;
}
.popup .head-actions a {
font-size: 0.9em;
margin: 0 4px;
}
.popup .actions a {
color: #30575f;
font-size: 0.9em;
margin-left: 5px;
}
.popup .head .head-input {
float: right;
width: 200px;
padding: 2px;
}
.popup .head .head-select {
float: right;
height: 24px;
}
.popup .forms {
width: 390px;
height: 328px;
margin: 15px;
float: left;
}
.popup fieldset {
border: 1px #547177 solid;
margin: 0 0 15px 0;
padding: 8px 2px 3px 2px;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
}
.popup legend {
font-size: 0.9em;
margin: 0 0 0 15px;
padding: 0 2px;
text-transform: uppercase;
}
.popup label {
color: #1b1b1b;
width: 150px;
margin: 0 0 10px 12px;
clear: both;
float: left;
}
.popup input,
.popup select {
margin: 0 10px 10px 0;
float: left;
}
.popup input[type=text] {
min-width: 174px;
}
.popup select {
min-height: 20px;
}
.popup .results {
height: 310px;
width: 620px;
margin: -5px 0 0 10px;
padding: 6px 0 0 0;
overflow: auto;
}
.popup .results .no-results {
margin: 6px 0;
font-size: 0.85em;
font-weight: bold;
}
.popup .results label {
width: 180px;
margin: 6px 4px 4px 4px;
}
.popup .results input,
.popup .results textarea,
.popup .results select {
margin: 4px;
}
.popup .results input,
.popup .results select {
min-width: 180px;
}
.popup .results input[type=checkbox],
.popup .results input[type=radio] {
margin-top: 7px;
}
.popup .results textarea {
width: 380px;
}
.popup .results .avatar-container {
float: left;
width: 60px;
height: 60px;
margin: 5px 12px 5px 9px;
text-align: center;
background-repeat: no-repeat;
}
.popup .results img.avatar {
max-width: 60px;
max-height: 60px;
}
.popup .results .one-icon {
height: 16px;
width: 16px;
margin: 10px 3px 0 8px;
float: left;
}
.popup .results .one-icon.account,
.popup .results .one-icon.auth {
background-position: 0 -777px;
}
.popup .results .one-icon.automation,
.popup .results .one-icon.client {
background-position: 0 -1500px;
}
.popup .results .one-icon.collaboration {
background-position: 0 -1520px;
}
.popup .results .one-icon.proxy,
.popup .results .one-icon.server,
.popup .results .one-icon.others {
background-position: 0 -1540px;
}
.popup .results .one-icon.component,
.popup .results .one-icon.gateway {
background-position: 0 -1560px;
}
.popup .results .one-icon.conference {
background-position: 0 -1082px;
}
.popup .results .one-icon.directory {
background-position: 0 -876px;
}
.popup .results .one-icon.headline,
.popup .results .one-icon.hierarchy {
background-position: 0 -1580px;
}
.popup .results .one-icon.pubsub,
.popup .results .one-icon.store {
background-position: 0 -1600px;
}
.popup .results .one-icon.loading {
background-position: 0 -1620px;
}
.popup .results .one-icon.down {
background-position: 0 -1640px;
}
.popup .results .one-host {
font-weight: bold;
width: 170px;
}
.popup .results .one-type {
width: 210px;
}
.popup .results .one-type,
.popup .results .one-host {
float: left;
overflow: hidden;
margin: 9px 8px;
}
.popup .results .one-jid,
.popup .results .one-ctry,
.popup .results .one-fn {
margin: 4px;
width: 400px;
}
.popup .results .one-fn {
font-weight: bold;
}
.popup .results .one-jid {
margin-top: 8px;
font-size: 0.9em;
}
.popup .results .one-name {
float: left;
margin: 4px;
}
.popup a.one-button {
display: none;
background-color: #f1f6fd;
border: 1px solid #b9cbcf;
margin-top: 1px;
padding: 4px 8px;
text-decoration: none;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
.popup a.one-button:hover,
.popup a.one-button:focus {
border: 1px solid #95b1b7;
}
.popup a.one-button:active {
border: 1px solid #77989f;
}
.popup .results .oneresult:hover a.one-button {
display: block;
}
.popup .results a.one-button,
#inbox .one-message a.one-button {
float: right;
padding: 3px 6px;
margin-right: 4px;
}
.popup .results a.one-vjud {
position: absolute;
right: 4px;
}
.popup .results a.one-add {
top: 8px;
}
.popup .results a.one-chat {
top: 42px;
}
.popup .results .one-next {
float: right;
margin: 4px 8px 4px 4px;
font-weight: bold;
}
.popup .results .one-actions {
width: 148px;
margin: 4px;
float: left;
}
.popup .results .one-actions a {
width: 16px;
height: 16px;
padding: 2px 2px 4px 5px !important;
margin-top: 2px;
}
.popup .results .one-actions a.browse {
background-position: 3px -1396px;
}
.popup .results .one-actions a.command {
background-position: 3px -1415px;
}
.popup .results .one-actions a.subscribe {
background-position: 4px -1435px;
}
.popup .results .one-actions a.join {
background-position: 3px -1455px;
}
.popup .results .one-actions a.search {
background-position: 4px -1475px;
}
.popup .results a.submit,
.popup .results a.cancel,
.popup .results a.back {
margin-right: 8px;
float: right;
}
.popup .onetitle {
font-size: 0.9em;
padding: 4px;
font-weight: bold;
}
.popup .oneinstructions {
font-size: 0.9em;
padding: 4px;
margin: 8px 0;
}
.popup .oneresult {
font-size: 0.9em;
padding: 3px 0 4px 4px;
border-bottom: 1px #9dc4fc solid;
overflow: hidden;
position: relative;
}
.popup .oneresult:hover {
background: #e9f1fd;
}
.popup .oneresult[onclick]:hover {
cursor: pointer;
}
.popup .oneresult[onclick]:active {
background: #f1f6fd;
}
.popup .infos {
background-color: rgb(255,239,104);
background-color: rgba(255,239,104,0.8);
border: 1px #decb2f solid;
color: #3f3f3f;
padding: 8px;
margin: 10px;
font-size: 0.8em;
}
.popup .infos p {
margin-top: 10px;
}
.popup .infos p.infos-title {
font-weight: bold;
}
.popup .bottom {
width: 640px;
height: 40px;
position: absolute;
bottom: 8px;
}
.popup .wait {
display: none;
margin: 8px 0 0 3px;
float: left;
}
a.finish {
border: 1px solid white;
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.1);
color: white;
padding: 4px 8px;
margin-right: 7px;
font-size: 0.95em;
text-align: center;
text-decoration: none;
text-shadow: 0 1px 1px black;
border-radius: 3px;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
box-shadow: 0 0 5px black;
-moz-box-shadow: 0 0 5px black;
-webkit-box-shadow: 0 0 5px black;
}
a.finish:hover,
a.finish:focus {
cursor: pointer;
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.2);
box-shadow: 0 0 15px black;
-moz-box-shadow: 0 0 15px black;
-webkit-box-shadow: 0 0 15px black;
}
a.finish:active {
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.3);
}
a.finish.disabled {
opacity: 0.2;
}
a.finish.disabled:hover,
a.finish.disabled:focus,
a.finish.disabled:active {
cursor: default;
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.1);
}
.popup a.finish {
margin-top: 6px;
float: right;
}

View file

@ -0,0 +1,197 @@
/*
Jappix - An open social platform
This is the privacy CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 16/02/11
*/
#privacy .content {
padding: 10px 0 10px 0;
}
#privacy .privacy-head div.list-left,
#privacy .privacy-head div.list-center,
#privacy .privacy-head div.list-right,
#privacy .privacy-first {
float: left;
}
#privacy .privacy-head div.list-left {
margin-left: 5px;
}
#privacy .privacy-head div.list-center {
border-right: 1px dotted #1b393f;
height: 24px;
width: 1px;
margin-right: 15px;
padding-left: 18px;
}
#privacy .privacy-head span,
#privacy .privacy-head a,
#privacy .privacy-item span,
#privacy .privacy-item a {
float: left;
}
#privacy .privacy-head span {
font-size: 0.9em;
font-weight: bold;
margin: 3px 10px 0 0;
}
#privacy .privacy-head input,
#privacy .privacy-head select {
width: 180px;
}
#privacy .privacy-head input {
margin-top: 1px;
}
#privacy .privacy-head select,
#privacy .privacy-item select {
margin-top: -2px;
}
#privacy .privacy-head span.left-space {
margin-left: 16px;
}
#privacy .privacy-head a,
#privacy .privacy-item a {
width: 20px;
height: 20px;
padding: 0;
display: block;
}
#privacy .privacy-item a.item-add {
background-position: 2px -1178px;
}
#privacy .privacy-head a.list-remove,
#privacy .privacy-item a.item-remove {
background-position: 2px -1197px;
}
#privacy .privacy-item a.item-save {
background-position: 3px -126px;
width: auto;
height: 19px;
padding: 1px 7px 0 21px;
}
#privacy .privacy-item,
#privacy form,
#privacy .privacy-active {
clear: both;
}
#privacy .privacy-item {
margin: 17px 12px;
font-size: 0.9em;
}
#privacy .privacy-item span {
font-weight: bold;
}
#privacy .privacy-item select {
width: 300px;
margin: -4px 30px 0 10px;
}
#privacy .privacy-item a {
margin: -2px 6px 0 0;
}
#privacy .privacy-first,
#privacy .privacy-second,
#privacy .privacy-third {
height: 195px;
font-size: 0.9em;
margin: 10px 0 0 10px;
float: left;
}
#privacy .privacy-first,
#privacy .privacy-second {
border-right: 1px dotted #1b393f;
padding-right: 14px;
}
#privacy .privacy-first {
width: 125px;
}
#privacy .privacy-first label {
margin: 50px 0 0 15px;
}
#privacy .privacy-first label input {
margin-top: 2px;
}
#privacy .privacy-second {
width: 205px;
}
#privacy .privacy-second label {
margin: 2px 0 0 12px;
}
#privacy .privacy-second input[type=radio],
#privacy .privacy-third input[type=checkbox] {
margin-top: 2px;
margin-bottom: 2px;
}
#privacy .privacy-second input[type=text],
#privacy .privacy-second select {
width: 170px;
margin: 2px 0 11px 12px;
float: none;
}
#privacy .privacy-third label {
width: auto;
margin-top: 11px;
}
#privacy .privacy-third {
width: 240px;
}
#privacy .privacy-active {
margin: 34px 16px 0 16px;
font-size: 0.9em;
}
#privacy .privacy-active-elements {
float: right;
}
#privacy .privacy-active input[type=text] {
width: 30px;
margin: 0 0 0 8px;
float: none;
}
#privacy .privacy-active input[type=checkbox] {
margin: 2px 8px 0 0;
float: left;
}
#privacy .privacy-active label {
width: auto;
margin: 0 15px 0 0;
clear: none;
}

View file

@ -0,0 +1,53 @@
/*
Jappix - An open social platform
This is the Roster Item Exchange tool CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 05/02/11
*/
#rosterx .content {
padding: 10px 0 10px 0;
}
#rosterx .rosterx-head a {
font-size: 0.9em;
margin: 3px 4px;
float: left;
}
#rosterx .oneresult:hover {
cursor: pointer;
}
#rosterx .oneresult span {
margin: 2px 5px 0 5px;
overflow: hidden;
float: left;
}
#rosterx .oneresult span.name {
width: 230px;
font-weight: bold;
}
#rosterx .oneresult span.xid {
width: 270px;
font-size: 0.9em;
}
#rosterx .oneresult span.action {
width: 16px;
height: 16px;
margin-top: 4px;
float: right;
}
#rosterx .oneresult span.action.modify {
background-position: 0 -1244px;
}

View file

@ -0,0 +1,60 @@
/*
Jappix - An open social platform
This is the search tool CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 23/01/11
*/
.search {
position: relative;
}
.search input.suggested {
border-bottom: 1px solid white;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
-moz-border-radius-bottomright: 0;
-moz-border-radius-bottomleft: 0;
-webkit-border-bottom-right-radius: 0;
-webkit-border-bottom-left-radius: 0;
}
.search ul {
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.9);
border-color: #e1a014;
border-style: solid;
border-width: 0 1px 1px 1px;
position: absolute;
z-index: 1;
padding: 3px 0;
list-style: none;
overflow: auto;
border-bottom-right-radius: 3px;
border-bottom-left-radius: 3px;
-moz-border-radius-bottomright: 3px;
-moz-border-radius-bottomleft: 3px;
-webkit-border-bottom-right-radius: 3px;
-webkit-border-bottom-left-radius: 3px;
}
.search ul li {
padding: 2px 6px;
color: #3d3d3d;
text-shadow: none;
}
.search ul li:hover {
cursor: pointer;
}
.search ul li.hovered {
background-color: rgb(225,160,20);
background-color: rgba(225,160,20,0.3);
}

View file

@ -0,0 +1,196 @@
/*
Jappix - An open social platform
This is the smileys CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 16/02/11
*/
.emoticon {
width: 16px;
height: 16px;
}
a.emoticon {
margin: 2px;
float: left;
}
a.emoticon:hover,
a.emoticon:focus {
opacity: 0.8;
}
a.emoticon:active {
opacity: 0.7;
}
img.emoticon {
border: 0 none;
vertical-align: bottom;
}
.emoticon-biggrin {
background-position: 0 0;
}
.emoticon-devil {
background-position: -16px 0;
}
.emoticon-coolglasses {
background-position: -32px 0;
}
.emoticon-tongue {
background-position: -48px 0;
}
.emoticon-smile {
background-position: -64px 0;
}
.emoticon-wink {
background-position: -80px 0;
}
.emoticon-blush {
background-position: -96px 0;
}
.emoticon-stare {
background-position: -112px 0;
}
.emoticon-frowning {
background-position: -128px 0;
}
.emoticon-oh {
background-position: -144px 0;
}
.emoticon-unhappy {
background-position: -160px 0;
}
.emoticon-cry {
background-position: -176px 0;
}
.emoticon-angry {
background-position: -192px 0;
}
.emoticon-puke {
background-position: -208px 0;
}
.emoticon-hugright {
background-position: -224px 0;
}
.emoticon-hugleft {
background-position: -240px 0;
}
.emoticon-lion {
background-position: -256px 0;
}
.emoticon-pussy {
background-position: -272px 0;
}
.emoticon-bat {
background-position: -288px 0;
}
.emoticon-kiss {
background-position: -304px 0;
}
.emoticon-heart {
background-position: -320px 0;
}
.emoticon-brheart {
background-position: -336px 0;
}
.emoticon-flower {
background-position: -352px 0;
}
.emoticon-brflower {
background-position: -368px 0;
}
.emoticon-thumbup {
background-position: -384px 0;
}
.emoticon-thumbdown {
background-position: -400px 0;
}
.emoticon-lamp {
background-position: -416px 0;
}
.emoticon-coffee {
background-position: -432px 0;
}
.emoticon-drink {
background-position: -448px 0;
}
.emoticon-beer {
background-position: -464px 0;
}
.emoticon-boy {
background-position: -480px 0;
}
.emoticon-girl {
background-position: -496px 0;
}
.emoticon-phone {
background-position: -512px 0;
}
.emoticon-photo {
background-position: -528px 0;
}
.emoticon-music {
background-position: -544px 0;
}
.emoticon-cuffs {
background-position: -560px 0;
}
.emoticon-mail {
background-position: -576px 0;
}
.emoticon-rainbow {
background-position: -592px 0;
}
.emoticon-star {
background-position: -608px 0;
}
.emoticon-moon {
background-position: -624px 0;
}

View file

@ -0,0 +1,71 @@
/*
Jappix - An open social platform
This is the SVG stats CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Erwan Briand, Vanaryon
Last revision: 20/11/10
*/
svg {
background-color: #e8f1f3;
}
.refline {
stroke: #596171;
stroke-width: 2px;
}
.refleft {
fill: #000000;
font-family: "Inconsolata", "DejaVu Serif sans", Verdana, sans-serif;
font-size: 8px;
}
.reftext {
fill: #586070;
font-family: "Inconsolata", "DejaVu Serif sans", Verdana, sans-serif;
font-size: 10px;
}
.bubbletextblue,
.bubbletextred {
fill: none;
font-family: "Inconsolata", "DejaVu Serif sans", Verdana, sans-serif;
font-size: 8px;
text-anchor: end;
}
.bluebar {
fill: "#6C84C0";
fill-opacity: "0.6";
}
.gbar:hover .bluebar {
fill: #2A3F73;
}
.gbar:hover .redbar {
fill: #C70705;
}
.gbar:hover #bubble {
fill: white;
stroke: grey;
}
.gbar:hover .bubbletextblue {
fill: #2A3F73;
}
.gbar:hover .bubbletextred {
fill: #C70705;
}
.gbar:hover .reftext {
fill: #000000;
}

View file

@ -0,0 +1,346 @@
/*
Jappix - An open social platform
This is the tools CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 27/08/11
*/
#top-content .tools {
background-color: rgb(232,241,243);
background-color: rgba(232,241,243,0.6);
padding: 3px 8px 5px 8px;
min-width: 10px;
height: 17px;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
-moz-border-radius-bottomleft: 4px;
-moz-border-radius-bottomright: 4px;
-webkit-border-bottom-left-radius: 4px;
-webkit-border-bottom-right-radius: 4px;
}
#top-content .tools a {
color: black;
padding: 0 3px;
margin: 0 1.5px;
}
#top-content .tools a:hover,
#top-content .tools a:focus {
cursor: pointer;
text-decoration: underline;
}
#top-content .tools-logo {
background-position: 9px 2px;
width: 74px;
float: left;
}
#top-content .tools-all {
float: right;
text-align: right;
margin-left: 8px;
font-size: 0.9em;
color: black;
}
#top-content .notifications {
background-position: 7px -1264px;
}
#top-content .music {
background-position: 6px -1286px;
}
#top-content .notifications:hover,
#top-content .music:hover {
cursor: pointer;
}
#top-content .music:hover,
#top-content .notifications:hover,
#top-content .music:focus,
#top-content .notifications:focus {
background-color: rgb(232,241,243);
background-color: rgba(232,241,243,0.7);
}
#top-content .music:active,
#top-content .notifications:active {
background-color: rgb(232,241,243);
background-color: rgba(232,241,243,0.8);
}
#top-content .actived,
#top-content .actived:hover,
#top-content .actived:focus,
#top-content .actived:active {
background-color: rgb(232,241,243) !important;
background-color: rgba(232,241,243,0.9) !important;
}
#top-content .notify {
background-color: #c60505;
color: white;
font-size: 0.7em;
font-weight: bold;
margin-left: -10px;
padding: 1px 4px;
position: absolute;
bottom: -2px;
border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
}
#top-content .tools-content {
display: none;
position: absolute;
top: 25px;
margin-left: -8px;
}
.tools-content-subarrow {
background-position: 0 -241px;
opacity: 0.8;
height: 10px;
width: 18px;
margin-left: 12px;
}
.tools-content-subitem {
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.8);
padding: 14px 6px 6px 6px;
border-radius: 5px;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
.notifications-content {
width: 240px;
}
.notifications-content .tools-content-subitem {
max-height: 250px;
color: white;
text-shadow: 0 1px 1px black;
text-align: left;
overflow-x: none;
overflow-y: auto;
}
.notifications-content .empty {
color: white;
font-size: 0.9em;
text-decoration: underline;
margin: -8px 4px 2px 0;
display: none;
float: right;
}
.notifications-content .nothing {
font-size: 0.9em;
margin: 5px;
}
.notifications-content .one-notification {
padding: 6px 4px;
font-size: 0.85em;
clear: both;
border-radius: 2px;
-moz-border-radius: 2px;
-webkit-border-radius: 2px;
}
.notifications-content .one-notification:hover,
.notifications-content .one-notification:focus {
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.1);
}
.notifications-content .one-notification:active {
background-color: rgb(255,255,255);
background-color: rgba(255,255,255,0.2);
}
.notifications-content .avatar-container {
float: left;
width: 40px;
height: 40px;
margin: 0 8px 8px 0;
text-align: center;
background-repeat: no-repeat;
}
.notifications-content .avatar {
max-width: 40px;
max-height: 40px;
}
.notifications-content .notification-text,
.notifications-content .notification-actions {
margin-left: 48px;
overflow: hidden;
}
.notifications-content .notification-actions {
margin-top: 3px;
}
.notifications-content .notification-actions a {
color: white;
font-weight: bold;
font-size: 0.9em;
text-decoration: underline;
margin-right: 8px;
}
.notifications-content .one-notification .notification-actions span.talk-images {
background-position: 0 -1828px;
width: 16px;
height: 16px;
margin: -1px 6px 0 0;
float: left;
}
.notifications-content .one-notification[data-type=subscribe] .notification-actions span.talk-images {
background-position: 0 -1796px;
}
.notifications-content .one-notification[data-type=invite_room] .notification-actions span.talk-images {
background-position: 0 -1812px;
}
.notifications-content .one-notification[data-type=send] .notification-actions span.talk-images,
.notifications-content .one-notification[data-type=send_accept] .notification-actions span.talk-images,
.notifications-content .one-notification[data-type=send_reject] .notification-actions span.talk-images,
.notifications-content .one-notification[data-type=send_fail] .notification-actions span.talk-images {
background-position: 0 -1956px;
}
.notifications-content .one-notification[data-type=rosterx] .notification-actions span.talk-images {
background-position: 0 -1844px;
}
.notifications-content .one-notification[data-type=comment] .notification-actions span.talk-images {
background-position: 0 -1860px;
}
.notifications-content .one-notification[data-type=like] .notification-actions span.talk-images {
background-position: 0 -1876px;
}
.notifications-content .one-notification[data-type=quote] .notification-actions span.talk-images {
background-position: 0 -1892px;
}
.notifications-content .one-notification[data-type=wall] .notification-actions span.talk-images {
background-position: 0 -1908px;
}
.notifications-content .one-notification[data-type=photo] .notification-actions span.talk-images {
background-position: 0 -1924px;
}
.notifications-content .one-notification[data-type=video] .notification-actions span.talk-images {
background-position: 0 -1940px;
}
.music-content {
width: 220px;
}
.music-content .tools-content-subitem {
height: 247px;
}
.music-content .player {
background: #b5d5db;
background: -moz-linear-gradient(top, #b5d5db, #adced4);
background: -webkit-gradient(linear, left top, left bottom, from(#b5d5db), to(#adced4));
height: 20px;
padding: 2px 5px;
border-top-right-radius: 4px;
border-top-left-radius: 4px;
-moz-border-radius-topright: 4px;
-moz-border-radius-topleft: 4px;
-webkit-border-top-right-radius: 4px;
-webkit-border-top-left-radius: 4px;
}
.music-content .player a {
margin: 2px;
height: 16px;
width: 16px;
float: left;
}
.music-content .player a:hover,
.music-content .player a:focus {
opacity: 0.8;
}
.music-content .player a:active {
opacity: 0.6;
}
.music-content .stop {
display: none;
background-position: 0 -270px;
}
.music-content .list {
background-color: #e8f1f3;
height: 188px;
padding: 5px;
text-align: left;
overflow-y: auto;
overflow-x: hidden;
}
.music-content p.no-results {
display: none;
color: black;
font-size: 0.9em;
}
.music-content div.special {
padding-bottom: 2px;
margin-bottom: 6px;
border-bottom: 1px solid #c3d4d7;
}
.music-content .song {
display: block;
margin: 3px 0;
font-size: 0.8em;
}
.music-content .playing {
font-weight: bold;
}
.music-content .search {
background-color: #e8f1f3;
height: 25px;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
-moz-border-radius-bottomleft: 4px;
-moz-border-radius-bottomright: 4px;
-webkit-border-bottom-right-radius: 4px;
-webkit-border-bottom-right-radius: 4px;
}
.music-content .search input {
margin: 2px;
width: 198px;
height: 15px;
}

View file

@ -0,0 +1,100 @@
/*
Jappix - An open social platform
This is the user-infos CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 27/03/11
*/
#userinfos .content {
overflow: auto;
}
#userinfos .one-lap a {
text-decoration: underline;
}
#userinfos .main-infos {
margin: 20px 20px 8px 20px;
height: 120px;
background: white;
position: relative;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
#userinfos .avatar-container {
float: left;
text-align: center;
margin: 20px 35px;
width: 80px;
height: 80px;
}
#userinfos .avatar {
max-width: 80px;
max-height: 80px;
}
#userinfos h1,
#userinfos h2,
#userinfos h3 {
width: 410px;
overflow: hidden;
}
#userinfos h1 {
font-size: 2em;
padding-top: 12px;
margin-bottom: 4px;
}
#userinfos h2 {
color: #447079;
font-size: 1.1em;
margin-bottom: 10px;
}
#userinfos h3 {
color: #6e8388;
font-size: 0.8em;
}
#userinfos .main-infos div.shortcuts {
position: absolute;
top: 10px;
right: 12px;
}
#userinfos .block-infos {
margin: 7px 20px;
float: left;
}
#userinfos .one-line {
margin: 4px 0;
font-size: 0.9em;
float: left;
}
#userinfos .one-line b {
width: 120px;
float: left;
}
#userinfos .one-line span.reset-info {
float: left;
width: 460px;
}
#userinfos textarea {
margin: 30px 0 0 30px;
width: 572px;
height: 292px;
}

View file

@ -0,0 +1,106 @@
/*
Jappix - An open social platform
This is the vCard CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 16/01/12
*/
#vcard label {
font-size: 0.94em;
margin-top: 2px;
}
#vcard #vcard-avatar input[type=file] {
margin-left: 15px;
}
#vcard .avatar-container {
float: left;
text-align: center;
margin: 20px 0 35px 35px;
max-width: 96px;
max-height: 96px;
}
#vcard .avatar {
max-width: 96px;
max-height: 96px;
}
#vcard .avatar-delete {
background-position: 3px -1195px;
margin: 12px 25px 0 025px;
padding-left: 20px;
font-size: 0.9em;
float: right;
}
#vcard .no-avatar {
width: 300px;
color: #7c2222;
padding: 10px;
margin: 15px 0 20px 40px;
background: #f8cece;
border: 1px #ba6d6d solid;
font-size: 0.8em;
}
#vcard .forms textarea {
height: 111px;
width: 358px;
margin: 5px 12px 10px 12px;
}
#vcard .forms .avatar-info {
border-width: 1px;
border-style: solid;
display: none;
width: 370px;
height: 15px;
font-size: 0.85em;
padding: 10px;
}
#vcard .forms .avatar-wait {
background-color: #9bcbed;
color: #0a3858;
border-color: #306780;
}
#vcard .forms .avatar-ok {
background-color: #c4ed9b;
color: #325213;
border-color: #578030;
}
#vcard .forms .avatar-error {
background-color: #e79595;
color: #6a0b0b;
border-color: #7c1010;
}
#vcard .infos {
width: 179px;
height: 328px;
margin: 15px 15px 15px 0;
padding: 0 8px;
float: right;
}
#vcard .infos a {
text-decoration: underline;
}
#vcard .send {
float: right;
}
#vcard .send:hover {
cursor: pointer;
}

View file

@ -0,0 +1,170 @@
/*
Jappix - An open social platform
This is the welcome tool CSS stylesheet for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 26/04/11
*/
#welcome .infos {
margin: 15px;
}
#welcome .infos p {
margin-top: 6px;
}
#welcome .infos p.infos-title {
margin-top: 0;
}
#welcome a.box {
background-color: #e4eef9;
border: 1px solid #ccdbde;
margin: 12px 11px 4px 15px;
padding: 10px;
width: 270px;
text-decoration: none;
float: left;
border-radius: 4px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
#welcome a.box.share {
width: 350px;
margin: 4px 130px;
padding: 4px 10px;
clear: both;
}
#welcome a.box.share.first {
margin-top: 0;
}
#welcome a.box.share:hover span.go {
display: block;
}
#welcome a.box:hover,
#welcome a.box:focus {
border: 1px solid #93c5fa;
}
#welcome a.box:active {
border: 1px solid #419afa;
}
#welcome a.box.enabled {
background-color: #f1f6fd;
border: 1px solid #9dc4fc;
}
#welcome a.box span {
margin: 3px 0;
display: block;
}
#welcome a.box span.logo {
height: 35px;
width: 35px;
margin-right: 15px;
float: left;
}
#welcome a.box span.logo.facebook {
background-position: 0 0;
}
#welcome a.box span.logo.twitter {
background-position: -35px 0;
}
#welcome a.box span.logo.buzz {
background-position: -70px 0;
}
#welcome a.box span.logo.identica {
background-position: -105px 0;
}
#welcome a.box span.option,
#welcome a.box span.name {
font-size: 0.9em;
font-weight: bold;
}
#welcome a.box span.description {
font-size: 0.7em;
margin-top: 7px;
}
#welcome a.box.share span.description {
margin-top: 4px;
}
#welcome a.box span.image {
height: 16px;
width: 16px;
margin: -30px 12px 0 0;
float: right;
}
#welcome a.box span.image.sound {
background-position: 0 -900px;
}
#welcome a.box span.image.geolocation {
background-position: 0 -658px;
}
#welcome a.box span.image.xmpp {
background-position: 0 -990px;
}
#welcome a.box span.image.archives,
#page-engine .text .tools-archives {
background-position: 0 -1025px;
}
#welcome a.box span.image.offline {
background-position: 0 -80px;
}
#welcome a.box span.tick,
#welcome a.box span.go {
height: 16px;
width: 16px;
display: none;
float: right;
}
#welcome a.box span.tick {
background-position: 0 -1661px;
margin: -52px -15px 0 0;
}
#welcome a.box span.go {
background-position: 0 -1120px;
margin: -28px 5px 0 0;
}
#welcome a.box.enabled span.tick {
display: block;
}
#welcome div.results {
margin: -7px 15px;
padding: 0;
height: 272px;
overflow: auto;
}
#welcome .bottom .finish.save {
display: none;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 B

View file

@ -0,0 +1,85 @@
/*
Jappix - An open social platform
These are the Ad-Hoc JS scripts for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 11/07/11
*/
// Opens the adhoc popup
function openAdHoc() {
// Popup HTML content
var html =
'<div class="top">' + _e("Commands") + '</div>' +
'<div class="content">' +
'<div class="adhoc-head"></div>' +
'<div class="results adhoc-results"></div>' +
'</div>' +
'<div class="bottom">' +
'<div class="wait wait-medium"></div>' +
'<a href="#" class="finish">' + _e("Close") + '</a>' +
'</div>';
// Create the popup
createPopup('adhoc', html);
// Associate the events
launchAdHoc();
return false;
}
// Quits the adhoc popup
function closeAdHoc() {
// Destroy the popup
destroyPopup('adhoc');
return false;
}
// Retrieves an entity adhoc command
function retrieveAdHoc(xid) {
// Open the popup
openAdHoc();
// Add a XID marker
$('#adhoc .adhoc-head').html('<b>' + getBuddyName(xid).htmlEnc() + '</b> (' + xid.htmlEnc() + ')');
// Get the highest entity resource
var highest = getHighestResource(xid);
if(highest)
xid = highest;
// Start a new adhoc command
dataForm(xid, 'command', '', '', 'adhoc');
return false;
}
// Starts an adhoc command on the user server
function serverAdHoc(server) {
// Open the popup
openAdHoc();
// Add a XID marker
$('#adhoc .adhoc-head').html('<b>' + server.htmlEnc() + '</b>');
// Start a new adhoc command
dataForm(server, 'command', '', '', 'adhoc');
}
// Plugin launcher
function launchAdHoc() {
// Click event
$('#adhoc .bottom .finish').click(closeAdHoc);
}

View file

@ -0,0 +1,131 @@
/*
Jappix - An open social platform
These are the anonymous mode JS script for Jappix
-------------------------------------------------
License: AGPL
Authors: Vanaryon, LinkMauve
Last revision: 02/10/11
*/
// Connected to an anonymous session
function anonymousConnected(con) {
logThis('Jappix (anonymous) is now connected.', 3);
// Connected marker
CONNECTED = true;
CURRENT_SESSION = true;
RECONNECT_TRY = 0;
RECONNECT_TIMER = 0;
// Not resumed?
if(!RESUME) {
// Create the app
createTalkPage();
// Send our first presence
firstPresence('');
// Set last activity stamp
LAST_ACTIVITY = getTimeStamp();
// Create the new groupchat
checkChatCreate(generateXID(ANONYMOUS_ROOM, 'groupchat'), 'groupchat');
// Remove some nasty elements for the anonymous mode
$('.tools-mucadmin, .tools-add').remove();
}
// Resumed
else {
// Send again our presence
presenceSend();
// Change the title
updateTitle();
}
// Remove the waiting icon
removeGeneralWait();
}
// Disconnected from an anonymous session
function anonymousDisconnected() {
logThis('Jappix (anonymous) is now disconnected.', 3);
}
// Logins to a anonymous account
function anonymousLogin(server) {
try {
// We define the http binding parameters
oArgs = new Object();
if(HOST_BOSH_MAIN)
oArgs.httpbase = HOST_BOSH_MAIN;
else
oArgs.httpbase = HOST_BOSH;
// We create the new http-binding connection
con = new JSJaCHttpBindingConnection(oArgs);
// And we handle everything that happen
con.registerHandler('message', handleMessage);
con.registerHandler('presence', handlePresence);
con.registerHandler('iq', handleIQ);
con.registerHandler('onconnect', anonymousConnected);
con.registerHandler('onerror', handleError);
con.registerHandler('ondisconnect', anonymousDisconnected);
// We set the anonymous connection parameters
oArgs = new Object();
oArgs.domain = server;
oArgs.authtype = 'saslanon';
oArgs.resource = JAPPIX_RESOURCE + ' Anonymous (' + (new Date()).getTime() + ')';
oArgs.secure = true;
oArgs.xmllang = XML_LANG;
// We connect !
con.connect(oArgs);
// Change the page title
pageTitle('wait');
}
catch(e) {
// Logs errors
logThis('Error while anonymous loggin in: ' + e, 1);
// Reset Jappix
anonymousDisconnected();
// Open an unknown error
openThisError(2);
}
finally {
return false;
}
}
// Plugin launcher
function launchAnonymous() {
logThis('Anonymous mode detected, connecting...', 3);
// We add the login wait div
showGeneralWait();
// Get the vars
if(LINK_VARS['r'])
ANONYMOUS_ROOM = LINK_VARS['r'];
if(LINK_VARS['n'])
ANONYMOUS_NICK = LINK_VARS['n'];
// Fire the login action
anonymousLogin(HOST_ANONYMOUS);
}
// Launch this plugin!
$(document).ready(launchAnonymous);

View file

@ -0,0 +1,418 @@
/*
Jappix - An open social platform
These are the archives functions for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 03/03/11
*/
// Opens the archive tools
function openArchives() {
// Popup HTML content
var html =
'<div class="top">' + _e("Message archives") + '</div>' +
'<div class="content">' +
'<div class="filter">' +
'<select class="friend" multiple=""></select>' +
'<div class="date"></div>' +
'</div>' +
'<div class="current">' +
'<span class="name"></span>' +
'<span class="time">' + _e("Please select a friend to view the chat history.") + '</span>' +
'</div>' +
'<div class="logs" id="chat-content-archives"></div>' +
'</div>' +
'<div class="bottom">' +
'<div class="wait wait-medium"></div>' +
'<a href="#" class="finish">' + _e("Close") + '</a>' +
'</div>';
// Create the popup
createPopup('archives', html);
// Associate the events
launchArchives();
// Get all the buddies in our roster
var buddies = getAllBuddies();
var options = '';
for(i in buddies) {
var current = buddies[i];
// Add the current buddy
options += '<option value="' + encodeQuotes(current) + '">' + getBuddyName(current).htmlEnc() + '</option>';
}
// Can append the buddy HTML code?
if(options)
$('#archives .filter .friend').append(options);
return false;
}
// Closes the archive tools
function closeArchives() {
// Destroy the popup
destroyPopup('archives');
return false;
}
// Gets the archives list for a buddy
function getListArchives(xid) {
// Reset the archives viewer
$('#archives .logs').empty();
// Show the waiting icon
$('#archives .wait').show();
// Apply the ID
var id = genID();
$('#archives').attr('data-session', id);
// New IQ
var iq = new JSJaCIQ();
iq.setType('get');
iq.setID(id);
var list = iq.appendNode('list', {'xmlns': NS_URN_ARCHIVE, 'with': xid});
var set = list.appendChild(iq.buildNode('set', {'xmlns': NS_RSM}));
set.appendChild(iq.buildNode('max', {'xmlns': NS_RSM}, '0'));
con.send(iq, handleListArchives);
logThis('Getting archives list for: ' + xid + '...');
}
// Handles the archives list for a buddy
function handleListArchives(iq) {
// Hide the waiting icon
$('#archives .wait').hide();
// Any error?
if(handleErrorReply(iq) || !exists('#archives[data-session=' + iq.getID() + ']'))
return;
// Get the last archive date
var last = $(iq.getNode()).find('list set changed').text();
// Any last archive?
if(last) {
// Read the date
var date = Date.jab2date(last);
// Change the datepicker value
$('#archives .filter .date').DatePickerSetDate(date, true);
// Retrieve the archives
checkChangeArchives();
}
logThis('Got archives list.', 2);
}
// Gets the archives for a day
function getDayArchives(xid, date) {
// Reset the archives viewer
$('#archives .logs').empty();
// Show the waiting icon
$('#archives .wait').show();
// Apply the ID
var id = genID();
$('#archives').attr('data-session', id);
// New IQ
var iq = new JSJaCIQ();
iq.setType('get');
iq.setID(id);
iq.appendNode('list', {'xmlns': NS_URN_ARCHIVE, 'with': xid, 'start': date + 'T00:00:00Z', 'end': date + 'T23:59:59Z'});
con.send(iq, handleDayArchives);
logThis('Getting day archives (' + date + ') for: ' + xid + '...');
}
// Handles the archives for a day
function handleDayArchives(iq) {
// Hide the waiting icon
$('#archives .wait').hide();
// Any error?
if(handleErrorReply(iq) || !exists('#archives[data-session=' + iq.getID() + ']'))
return;
// Get each archive thread
$(iq.getNode()).find('chat').each(function() {
// Current values
var xid = $(this).attr('with');
var start = $(this).attr('start');
if(xid && start)
$('#archives .logs').append('<input class="archives-pending" type="hidden" data-with="' + encodeQuotes(xid) + '" data-start="' + encodeQuotes(start) + '" />');
});
// Display the day
var date = parseDay($('#archives .filter .date').DatePickerGetDate(true) + 'T00:00:00Z' + getDateTZO());
// Try to get the first thread
var pending = '#archives input.archives-pending:first';
if(!exists(pending))
date = printf(_e("Nothing found for: %s"), date);
else {
retrieveArchives($(pending).attr('data-with'), $(pending).attr('data-start'));
$(pending).remove();
}
$('#archives .current .time').text(date);
logThis('Got day archives.', 2);
}
// Retrieves a specified archive collection
function retrieveArchives(xid, start) {
// Show the waiting icon
$('#archives .wait').show();
// Apply the ID
var id = genID();
$('#archives').attr('data-session', id);
// New IQ
var iq = new JSJaCIQ();
iq.setType('get');
iq.setID(id);
var list = iq.appendNode('retrieve', {'xmlns': NS_URN_ARCHIVE, 'with': xid, 'start': start});
con.send(iq, handleRetrieveArchives);
logThis('Retrieving archives (start: ' + start + ') for: ' + xid + '...');
}
// Handles a specified archive collection
function handleRetrieveArchives(iq) {
// Hide the waiting icon
$('#archives .wait').hide();
// Any error?
if(handleErrorReply(iq) || !exists('#archives[data-session=' + iq.getID() + ']'))
return;
// Get the node
var chat = $(iq.getNode()).find('chat:first');
// Get the buddy XID
var xid = bareXID(chat.attr('with'));
// Get the start date & stamp
var start_date = Date.jab2date(chat.attr('start'));
var start_stamp = extractStamp(start_date);
// Parse the result chat
chat.find('to, from').each(function() {
var node = (this).nodeName;
var stamp = start_stamp + parseInt($(this).attr('secs'));
var date = extractTime(new Date(stamp * 1000));
var body = $(this).find('body').text();
// Is it my message?
if((node == 'to') && body)
displayMessage('chat', getXID(), 'archives', getBuddyName(getXID()).htmlEnc(), body, date, start_stamp, 'user-message', true, '', 'me');
// Is it a buddy message?
else if((node == 'from') && body)
displayMessage('chat', xid, 'archives', getBuddyName(xid).htmlEnc(), body, date, start_stamp, 'user-message', true, '', 'him');
});
// Not the latest thread?
var pending = '#archives input.archives-pending:first';
if(exists(pending)) {
retrieveArchives($(pending).attr('data-with'), $(pending).attr('data-start'));
$(pending).remove();
}
// Everything has been retrieved, get the avatars
else {
getAvatar(getXID(), 'cache', 'true', 'forget');
getAvatar(xid, 'cache', 'true', 'forget');
}
logThis('Got archives.', 2);
}
// Gets the archiving configuration
function getConfigArchives() {
// Lock the archiving options
$('#archiving').attr('checked', false).attr('disabled', true);
// Get the archiving configuration
var iq = new JSJaCIQ();
iq.setType('get');
iq.appendNode('pref', {'xmlns': NS_URN_ARCHIVE});
con.send(iq, handleGetConfigArchives);
}
// Handles the archiving configuration
function handleGetConfigArchives(iq) {
// Reset the options stuffs
waitOptions('archives');
// Unlock the archiving options
$('#archiving').removeAttr('disabled');
// End if not a result
if(!iq || (iq.getType() != 'result'))
return;
// Extract the preferences from the IQ
var enabled = $(iq.getNode()).find('pref auto').attr('save');
// Define the input enabling/disabling vars
var checked = true;
if(enabled != 'true')
checked = false;
// Apply the values
$('#archiving').attr('checked', checked);
}
// Configures the archiving on the server
function configArchives(enabled) {
// Configure the auto element
var iq = new JSJaCIQ();
iq.setType('set');
iq.appendNode('auto', {'xmlns': NS_URN_ARCHIVE, 'save': enabled});
con.send(iq, handleConfigArchives);
// Configure the default element
var iq = new JSJaCIQ();
iq.setType('set');
var pref = iq.appendNode('pref', {'xmlns': NS_URN_ARCHIVE});
pref.appendChild(iq.appendNode('default', {'xmlns': NS_URN_ARCHIVE, 'otr': 'concede', 'save': 'body'}));
con.send(iq);
// Configure the method element
var iq = new JSJaCIQ();
iq.setType('set');
var mType = new Array('auto', 'local', 'manual');
var mUse = new Array('prefer', 'concede', 'concede');
var pref = iq.appendNode('pref', {'xmlns': NS_URN_ARCHIVE});
for(i in mType)
pref.appendChild(iq.appendNode('method', {'xmlns': NS_URN_ARCHIVE, 'type': mType[i], 'use': mUse[i]}));
con.send(iq);
// Logger
logThis('Configuring archives...', 3);
}
// Handles the archives configuration
function handleConfigArchives(iq) {
if(!iq || (iq.getType() != 'result'))
logThis('Archives not configured.', 2);
else
logThis('Archives configured.', 3);
}
// Checks if the datepicker has changed
function checkChangeArchives() {
var xid = $('#archives .filter .friend').val();
var date = $('#archives .filter .date').DatePickerGetDate(true);
// No XID?
if(!xid || !xid.length)
return;
// Too many value?
if(xid.length > 1) {
$('#archives .filter .friend').val(xid[0]);
return;
}
// Get the first XID
xid = xid[0];
// Get the archives
getDayArchives(xid, date);
}
// Update the archives with the selected XID
function updateArchives() {
// Read the values
var xid = $('#archives .filter .friend').val();
var date = $('#archives .filter .date').DatePickerGetDate(true);
// No XID?
if(!xid || !xid.length)
return;
// Too many value?
if(xid.length > 1) {
$('#archives .filter .friend').val(xid[0]);
return;
}
// Get the first XID
xid = xid[0];
// Apply the current marker
$('#archives .current .name').text(getBuddyName(xid));
$('#archives .current .time').text(parseDay(date + 'T00:00:00Z' + getDateTZO()));
// Get the archives
getListArchives(xid, date);
}
// Plugin launcher
function launchArchives() {
// Current date
var current_date = explodeThis('T', getXMPPTime(), 0);
// Datepicker
$('#archives .filter .date').DatePicker({
flat: true,
date: current_date,
current: current_date,
calendars: 1,
starts: 1,
onChange: checkChangeArchives
});
// Click events
$('#archives .bottom .finish').click(function() {
return closeArchives();
});
// Change event
$('#archives .filter .friend').change(updateArchives);
}

View file

@ -0,0 +1,46 @@
/*
Jappix - An open social platform
These are the audio JS scripts for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 10/08/11
*/
// Plays the given sound ID
function soundPlay(num) {
try {
// Not supported!
if((BrowserDetect.browser == 'Explorer') && (BrowserDetect.version < 9))
return false;
// If the sounds are enabled
if(getDB('options', 'sounds') == '1') {
// If the audio elements aren't yet in the DOM
if(!exists('#audio')) {
$('body').append(
'<div id="audio">' +
'<audio id="new-chat" src="./snd/new-chat.oga" type="audio/ogg" />' +
'<audio id="receive-message" src="./snd/receive-message.oga" type="audio/ogg" />' +
'<audio id="notification" src="./snd/notification.oga" type="audio/ogg" />' +
'</div>'
);
}
// We play the target sound
var playThis = document.getElementById('audio').getElementsByTagName('audio')[num];
playThis.load();
playThis.play();
}
}
catch(e) {}
finally {
return false;
}
}

View file

@ -0,0 +1,99 @@
/*
Jappix - An open social platform
These are the autocompletion tools JS script for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 12/11/10
*/
// Sort an array with insensitivity to the case
function caseInsensitiveSort(a, b) {
// Put the two strings into lower case
a = a.toLowerCase();
b = b.toLowerCase();
// Process the sort
if(a > b)
return 1;
if(a < b)
return -1;
}
// Creates an array with the autocompletion results
function processAutocompletion(query, id) {
// Replace forbidden characters in regex
query = escapeRegex(query);
// Create an empty array
var results = new Array();
// Search in the roster
$('#' + id + ' .user').each(function() {
var nick = $(this).find('.name').text();
var regex = new RegExp('(^)' + query, 'gi');
if(nick.match(regex))
results.push(nick);
});
// Sort the array
results = results.sort(caseInsensitiveSort);
// Return the results array
return results;
}
// Resets the autocompletion tools
function resetAutocompletion(hash) {
$('#' + hash + ' .message-area').removeAttr('data-autocompletion-pointer').removeAttr('data-autocompletion-query');
}
// Autocompletes the chat input nick
function createAutocompletion(hash) {
// Initialize
var vSelector = $('#' + hash + ' .message-area');
var value = vSelector.val();
if(!value)
resetAutocompletion(hash);
var query = vSelector.attr('data-autocompletion-query');
// The autocompletion has not been yet launched
if(query == undefined) {
query = value;
vSelector.attr('data-autocompletion-query', query);
}
// Get the pointer
var pointer = vSelector.attr('data-autocompletion-pointer');
var i = 0;
if(pointer)
i = parseInt(pointer);
// We get the nickname
var nick = processAutocompletion(query, hash)[i];
// Shit, this is my nick!
if((nick != undefined) && (nick.toLowerCase() == getMUCNick(hash).toLowerCase())) {
// Increment
i++;
// Get the next nick
nick = processAutocompletion(query, hash)[i];
}
// We quote the nick
if(nick != undefined) {
// Increment
i++;
quoteMyNick(hash, nick);
// Put a pointer
vSelector.attr('data-autocompletion-pointer', i);
}
}

View file

@ -0,0 +1,205 @@
/*
Jappix - An open social platform
These are the avatar JS scripts for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 01/03/11
*/
// Requests the avatar of a given user
var AVATAR_PENDING = [];
function getAvatar(xid, mode, enabled, photo) {
/* REF: http://xmpp.org/extensions/xep-0153.html */
// No need to get the avatar, another process is yet running
if(existArrayValue(AVATAR_PENDING, xid))
return false;
// Initialize: XML data is in one SQL entry, because some browser are sloooow with SQL requests
var xml = XMLFromString(getPersistent('avatar', xid));
var forced = false;
// Retrieving forced?
if($(xml).find('forced').text() == 'true')
forced = true;
// No avatar in presence
if(!photo && !forced && (enabled == 'true')) {
// Pending marker
AVATAR_PENDING.push(xid);
// Reset the avatar
resetAvatar(xid, hex_md5(xid));
logThis('No avatar for: ' + xid, 2);
}
// Try to catch the avatar
else {
// Define some stuffs
var type = $(xml).find('type').text();
var binval = $(xml).find('binval').text();
var checksum = $(xml).find('checksum').text();
var updated = false;
// Process the checksum of the avatar
if((checksum == photo) || (photo == 'forget') || forced)
updated = true;
// If the avatar is yet stored and a new retrieving is not needed
if((mode == 'cache') && type && binval && checksum && updated) {
// Pending marker
AVATAR_PENDING.push(xid);
// Display the cache avatar
displayAvatar(xid, hex_md5(xid), type, binval);
logThis('Read avatar from cache: ' + xid, 3);
}
// Else if the request has not yet been fired, we get it
else if((!updated || (mode == 'cache' && !updated) || (mode == 'force') || (photo = 'forget')) && (enabled != 'false')) {
// Pending marker
AVATAR_PENDING.push(xid);
// Get the latest avatar
var iq = new JSJaCIQ();
iq.setType('get');
iq.setTo(xid);
iq.appendNode('vCard', {'xmlns': NS_VCARD});
con.send(iq, handleAvatar);
logThis('Get avatar from server: ' + xid, 3);
}
}
return true;
}
// Handles the avatar
function handleAvatar(iq) {
// Extract the XML values
var handleXML = iq.getNode();
var handleFrom = fullXID(getStanzaFrom(iq));
// Is this me? Remove the resource!
if(bareXID(handleFrom) == getXID())
handleFrom = bareXID(handleFrom);
// Get some other values
var hash = hex_md5(handleFrom);
var find = $(handleXML).find('vCard');
var aChecksum = 'none';
var oChecksum = null;
// Read our own checksum
if(handleFrom == getXID()) {
oChecksum = getDB('checksum', 1);
// Avoid the "null" value
if(!oChecksum)
oChecksum = '';
}
// vCard not empty?
if(find.size()) {
// We get our profile details
if(handleFrom == getXID()) {
// Get the names
var names = generateBuddyName(iq);
// Write the values to the database
setDB('profile', 'name', names[0]);
setDB('profile', 'nick', names[1]);
}
// We get the avatar
var aType = find.find('TYPE:first').text();
var aBinval = find.find('BINVAL:first').text();
// No binval?
if(!aBinval) {
aType = 'none';
aBinval = 'none';
}
// Enough data
else {
// No type?
if(!aType)
aType = 'image/png';
// Process the checksum
else
aChecksum = hex_sha1(Base64.decode(aBinval));
}
// We display the user avatar
displayAvatar(handleFrom, hash, aType, aBinval);
// Store the avatar
setPersistent('avatar', handleFrom, '<avatar><type>' + aType + '</type><binval>' + aBinval + '</binval><checksum>' + aChecksum + '</checksum><forced>false</forced></avatar>');
logThis('Avatar retrieved from server: ' + handleFrom, 3);
}
// vCard is empty
else
resetAvatar(handleFrom);
// We got a new checksum for us?
if(((oChecksum != null) && (oChecksum != aChecksum)) || !FIRST_PRESENCE_SENT) {
// Define a proper checksum
var pChecksum = aChecksum;
if(pChecksum == 'none')
pChecksum = '';
// Update our temp. checksum
setDB('checksum', 1, pChecksum);
// Send the stanza
if(FIRST_PRESENCE_SENT)
presenceSend(pChecksum);
else
getStorage(NS_OPTIONS);
}
}
// Reset the avatar of an user
function resetAvatar(xid, hash) {
// Store the empty avatar
setPersistent('avatar', xid, '<avatar><type>none</type><binval>none</binval><checksum>none</checksum><forced>false</forced></avatar>');
// Display the empty avatar
displayAvatar(xid, hash, 'none', 'none');
}
// Displays the avatar of an user
function displayAvatar(xid, hash, type, binval) {
// Initialize the vars
var container = hash + ' .avatar-container';
var code = '<img class="avatar" src="';
// If the avatar exists
if((type != 'none') && (binval != 'none'))
code += 'data:' + type + ';base64,' + binval;
else
code += './img/others/default-avatar.png';
code += '" alt="" />';
// Replace with the new avatar (in the roster and in the chat)
$('.' + container).html(code);
// We can remove the pending marker
removeArrayValue(AVATAR_PENDING, xid);
}

View file

@ -0,0 +1,80 @@
// This code was written by Tyler Akins and has been placed in the
// public domain. It would be nice if you left this header intact.
// Base64 code from Tyler Akins -- http://rumkin.com
var Base64 = (function () {
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var obj = {
/**
* Encodes a string in base64
* @param {String} input The string to encode in base64.
*/
encode: function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
do {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) +
keyStr.charAt(enc3) + keyStr.charAt(enc4);
} while (i < input.length);
return output;
},
/**
* Decodes a base64 string.
* @param {String} input The string to decode.
*/
decode: function (input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
do {
enc1 = keyStr.indexOf(input.charAt(i++));
enc2 = keyStr.indexOf(input.charAt(i++));
enc3 = keyStr.indexOf(input.charAt(i++));
enc4 = keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
} while (i < input.length);
return output;
}
};
return obj;
})();

View file

@ -0,0 +1,141 @@
/*
Jappix - An open social platform
These are the notification board JS script for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 12/03/11
*/
// Creates a board panel
function createBoard(type, id) {
// Text var
var text = '';
// Info
if(type == 'info') {
switch(id) {
// Password change
case 1:
text = _e("Your password has been changed, now you can connect to your account with your new login data.");
break;
// Account deletion
case 2:
text = _e("Your XMPP account has been removed, bye!");
break;
// Account logout
case 3:
text = _e("You have been logged out of your XMPP account, have a nice day!");
break;
// Groupchat join
case 4:
text = _e("The room you joined seems not to exist. You should create it!");
break;
// Groupchat removal
case 5:
text = _e("The groupchat has been removed, now someone else will be able to recreate it.");
break;
// Non-existant groupchat user
case 6:
text = _e("The user that you want to reach is not present in the room.");
break;
}
}
// Error
else {
switch(id) {
// Custom error
case 1:
text = '<b>' + _e("Error") + '</b> &raquo; <span></span>';
break;
// Network error
case 2:
text = _e("Jappix has been interrupted by a network issue, a bug or bad login (check that you entered the right credentials), sorry for the inconvenience.");
break;
// List retrieving error
case 3:
text = _e("The element list on this server could not be obtained!");
break;
// Attaching error
case 4:
text = printf(_e("An error occured while uploading your file: maybe it is too big (%s maximum) or forbidden!"), JAPPIX_MAX_UPLOAD);
break;
}
}
// No text?
if(!text)
return false;
// Append the content
$('#board').append('<div class="one-board ' + type + '" data-id="' + id + '">' + text + '</div>');
// Events (click and auto-hide)
$('#board .one-board.' + type + '[data-id=' + id + ']')
.click(function() {
closeThisBoard(this);
})
.oneTime('5s', function() {
closeThisBoard(this);
})
.slideDown();
return true;
}
// Destroys the existing board notifications
function destroyBoard() {
$('#board').empty();
}
// Executes a given action on the notification board
function actionBoard(id, type) {
// In a first, we destroy other boards
destroyBoard();
// Then we display the board
createBoard(type, id);
}
// Opens a given error ID
function openThisError(id) {
actionBoard(id, 'error');
}
// Opens a given info ID
function openThisInfo(id) {
actionBoard(id, 'info');
}
// Closes a given board
function closeThisBoard(board) {
$(board).slideUp('normal', function() {
$(this).remove();
});
}

View file

@ -0,0 +1,124 @@
/* BROWSER DETECT
* http://www.quirksmode.org/js/detect.html
*/
var BrowserDetect = {
init: function () {
this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
this.version = this.searchVersion(navigator.userAgent)
|| this.searchVersion(navigator.appVersion)
|| "an unknown version";
this.OS = this.searchString(this.dataOS) || "an unknown OS";
},
searchString: function (data) {
for (var i=0;i<data.length;i++) {
var dataString = data[i].string;
var dataProp = data[i].prop;
this.versionSearchString = data[i].versionSearch || data[i].identity;
if (dataString) {
if (dataString.indexOf(data[i].subString) != -1)
return data[i].identity;
}
else if (dataProp)
return data[i].identity;
}
},
searchVersion: function (dataString) {
var index = dataString.indexOf(this.versionSearchString);
if (index == -1) return;
return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
},
dataBrowser: [
{
string: navigator.userAgent,
subString: "Chrome",
identity: "Chrome"
},
{ string: navigator.userAgent,
subString: "OmniWeb",
versionSearch: "OmniWeb/",
identity: "OmniWeb"
},
{
string: navigator.vendor,
subString: "Apple",
identity: "Safari",
versionSearch: "Version"
},
{
prop: window.opera,
identity: "Opera"
},
{
string: navigator.vendor,
subString: "iCab",
identity: "iCab"
},
{
string: navigator.vendor,
subString: "KDE",
identity: "Konqueror"
},
{
string: navigator.userAgent,
subString: "Firefox",
identity: "Firefox"
},
{
string: navigator.vendor,
subString: "Camino",
identity: "Camino"
},
{ // for newer Netscapes (6+)
string: navigator.userAgent,
subString: "Netscape",
identity: "Netscape"
},
{
string: navigator.userAgent,
subString: "MSIE",
identity: "Explorer",
versionSearch: "MSIE"
},
{
string: navigator.userAgent,
subString: "Gecko",
identity: "Mozilla",
versionSearch: "rv"
},
{ // for older Netscapes (4-)
string: navigator.userAgent,
subString: "Mozilla",
identity: "Netscape",
versionSearch: "Mozilla"
}
],
dataOS : [
{
string: navigator.platform,
subString: "Win",
identity: "Windows"
},
{
string: navigator.platform,
subString: "Mac",
identity: "Mac"
},
{
string: navigator.userAgent,
subString: "iPhone",
identity: "iPhone/iPod"
},
{
string: navigator.platform,
subString: "Linux",
identity: "Linux"
}
]
};
BrowserDetect.init();

View file

@ -0,0 +1,59 @@
/*
Jappix - An open social platform
These are the bubble JS scripts for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 11/12/10
*/
// Closes all the opened bubbles
function closeBubbles() {
// Destroy all the elements
$('.bubble.hidable:visible').hide();
$('.bubble.removable').remove();
$('body').die('click');
return false;
}
// Click function when a bubble is opened
function showBubble(selector) {
// Hidable bubbles special things
if($(selector).is('.hidable')) {
// This bubble is yet displayed? So abort!
if($(selector).is(':visible'))
return closeBubbles();
// Close all the bubbles
closeBubbles();
// Show the requested bubble
$(selector).show();
}
// Removable bubbles special things
else {
// This bubble is yet added? So abort!
if(exists(selector))
return closeBubbles();
// Close all the bubbles
closeBubbles();
}
// Creates a new click event to close the bubble
$('body').live('click', function(evt) {
var target = evt.target;
// If this is a click away from a bubble
if(!$(target).parents('.ibubble').size())
closeBubbles();
});
return false;
}

View file

@ -0,0 +1,349 @@
/*
Jappix - An open social platform
These are the CAPS JS script for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 26/08/11
*/
// Returns an array of the Jappix disco#infos
function myDiscoInfos() {
var fArray = new Array(
NS_MUC,
NS_MUC_USER,
NS_MUC_ADMIN,
NS_MUC_OWNER,
NS_MUC_CONFIG,
NS_DISCO_INFO,
NS_DISCO_ITEMS,
NS_PUBSUB_RI,
NS_BOSH,
NS_CAPS,
NS_MOOD,
NS_ACTIVITY,
NS_TUNE,
NS_GEOLOC,
NS_NICK,
NS_URN_ADATA,
NS_URN_AMETA,
NS_URN_MBLOG,
NS_URN_INBOX,
NS_MOOD + NS_NOTIFY,
NS_ACTIVITY + NS_NOTIFY,
NS_TUNE + NS_NOTIFY,
NS_GEOLOC + NS_NOTIFY,
NS_URN_MBLOG + NS_NOTIFY,
NS_URN_INBOX + NS_NOTIFY,
NS_URN_DELAY,
NS_ROSTER,
NS_ROSTERX,
NS_HTTP_AUTH,
NS_CHATSTATES,
NS_XHTML_IM,
NS_IPV6,
NS_LAST,
NS_PRIVATE,
NS_REGISTER,
NS_SEARCH,
NS_COMMANDS,
NS_VERSION,
NS_XDATA,
NS_VCARD,
NS_URN_TIME,
NS_URN_PING,
NS_URN_ARCHIVE,
NS_URN_AR_PREF,
NS_URN_RECEIPTS,
NS_PRIVACY,
NS_IQOOB,
NS_XOOB
);
return fArray;
}
// Gets the disco#infos of an entity
function getDiscoInfos(to, caps) {
// No CAPS
if(!caps) {
logThis('No CAPS: ' + to, 2);
displayDiscoInfos(to, '');
return false;
}
// Get the stored disco infos
var xml = XMLFromString(getPersistent('caps', caps));
// Yet stored
if(xml) {
logThis('CAPS from cache: ' + to, 3);
displayDiscoInfos(to, xml);
return true;
}
logThis('CAPS from the network: ' + to, 3);
// Not stored: get the disco#infos
var iq = new JSJaCIQ();
iq.setTo(to);
iq.setType('get');
iq.setQuery(NS_DISCO_INFO);
con.send(iq, handleDiscoInfos);
return true;
}
// Handles the disco#infos of an entity
function handleDiscoInfos(iq) {
if(!iq || (iq.getType() == 'error'))
return;
// IQ received, get some values
var from = fullXID(getStanzaFrom(iq));
var query = iq.getQuery();
// Generate the CAPS-processing values
var identities = new Array();
var features = new Array();
var data_forms = new Array();
// Identity values
$(query).find('identity').each(function() {
var pCategory = $(this).attr('category');
var pType = $(this).attr('type');
var pLang = $(this).attr('xml:lang');
var pName = $(this).attr('name');
if(!pCategory)
pCategory = '';
if(!pType)
pType = '';
if(!pLang)
pLang = '';
if(!pName)
pName = '';
identities.push(pCategory + '/' + pType + '/' + pLang + '/' + pName);
});
// Feature values
$(query).find('feature').each(function() {
var pVar = $(this).attr('var');
// Add the current value to the array
if(pVar)
features.push(pVar);
});
// Data-form values
$(query).find('x[xmlns=' + NS_XDATA + ']').each(function() {
// Initialize some stuffs
var pString = '';
var sortVar = new Array();
// Add the form type field
$(this).find('field[var=FORM_TYPE] value').each(function() {
var cText = $(this).text();
if(cText)
pString += cText + '<';
});
// Add the var attributes into an array
$(this).find('field:not([var=FORM_TYPE])').each(function() {
var cVar = $(this).attr('var');
if(cVar)
sortVar.push(cVar);
});
// Sort the var attributes
sortVar = sortVar.sort();
// Loop this sorted var attributes
for(i in sortVar) {
// Initialize the value sorting
var sortVal = new Array();
// Append it to the string
pString += sortVar[i] + '<';
// Add each value to the array
$(this).find('field[var=' + sortVar[i] + '] value').each(function() {
sortVal.push($(this).text());
});
// Sort the values
sortVal = sortVal.sort();
// Append the values to the string
for(j in sortVal)
pString += sortVal[j] + '<';
}
// Any string?
if(pString) {
// Remove the undesired double '<' from the string
if(pString.match(/(.+)(<)+$/))
pString = pString.substring(0, pString.length - 1);
// Add the current string to the array
data_forms.push(pString);
}
});
// Process the CAPS
var caps = processCaps(identities, features, data_forms);
// Get the XML string
var xml = xmlToString(query);
// Store the disco infos
setPersistent('caps', caps, xml);
// This is our server
if(from == getServer()) {
// Handle the features
handleFeatures(xml);
logThis('Got our server CAPS', 3);
}
else {
// Display the disco infos
displayDiscoInfos(from, xml);
logThis('Got CAPS: ' + from, 3);
}
}
// Displays the disco#infos everywhere needed for an entity
function displayDiscoInfos(from, xml) {
// Generate the chat path
var xid = bareXID(from);
// This comes from a private groupchat chat?
if(isPrivate(xid))
xid = from;
hash = hex_md5(xid);
// Support indicators
var xhtml_im = false;
var iq_oob = false;
var x_oob = false;
var receipts = false;
// Display the supported features
$(xml).find('feature').each(function() {
var current = $(this).attr('var');
// xHTML-IM
if(current == NS_XHTML_IM)
xhtml_im = true;
// Out of Band Data (IQ)
if(current == NS_IQOOB)
iq_oob = true;
// Out of Band Data (X)
if(current == NS_XOOB)
x_oob = true;
// Receipts
else if(current == NS_URN_RECEIPTS)
receipts = true;
});
// Paths
var path = $('#' + hash);
var message_area = path.find('.message-area');
var style = path.find('.chat-tools-style');
var file = path.find('.chat-tools-file');
// Apply xHTML-IM
if(xhtml_im)
style.show();
else {
// Remove the tooltip elements
style.hide();
style.find('.bubble-style').remove();
// Reset the markers
message_area.removeAttr('style')
.removeAttr('data-color')
.removeAttr('data-bold')
.removeAttr('data-italic')
.removeAttr('data-underline');
}
// Apply Out of Band Data
if(iq_oob || x_oob) {
file.show();
// Set a marker
if(iq_oob)
file.attr('data-oob', 'iq');
else
file.attr('data-oob', 'x');
}
else {
// Remove the tooltip elements
file.hide();
file.find('.bubble-style').remove();
// Reset the marker
file.removeAttr('data-oob');
}
// Apply receipts
if(receipts)
message_area.attr('data-receipts', 'true');
else
message_area.removeAttr('data-receipts');
}
// Generates the CAPS hash
function processCaps(cIdentities, cFeatures, cDataForms) {
// Initialize
var cString = '';
// Sort the arrays
cIdentities = cIdentities.sort();
cFeatures = cFeatures.sort();
cDataForms = cDataForms.sort();
// Process the sorted identity string
for(a in cIdentities)
cString += cIdentities[a] + '<';
// Process the sorted feature string
for(b in cFeatures)
cString += cFeatures[b] + '<';
// Process the sorted data-form string
for(c in cDataForms)
cString += cDataForms[c] + '<';
// Process the SHA-1 hash
var cHash = b64_sha1(cString);
return cHash;
}
// Generates the Jappix CAPS hash
function myCaps() {
return processCaps(new Array('client/web//Jappix'), myDiscoInfos(), new Array());
}

View file

@ -0,0 +1,297 @@
/*
Jappix - An open social platform
These are the chat JS scripts for Jappix
-------------------------------------------------
License: AGPL
Authors: Vanaryon, Eric
Last revision: 16/10/11
*/
// Correctly opens a new chat
function checkChatCreate(xid, type, nickname, password, title) {
// No XID?
if(!xid)
return false;
// We generate some stuffs
var hash = hex_md5(xid);
var name;
// Gets the name of the user/title of the room
if(title)
name = title;
else {
// Private groupchat chat
if(type == 'private')
name = thisResource(xid);
// XMPP-ID
else if(xid.indexOf('@') != -1)
name = getBuddyName(xid);
// Gateway
else
name = xid;
}
// If the target div does not exist
if(!exists('#' + hash)) {
// We check the type of the chat to open
if((type == 'chat') || (type == 'private'))
chatCreate(hash, xid, name, type);
else if(type == 'groupchat') {
// Try to read the room stored configuration
if(!isAnonymous() && (!nickname || !password || !title)) {
// Catch the room data
var fData = $(XMLFromString(getDB('favorites', xid)));
var fNick = fData.find('nick').text();
var fPwd = fData.find('password').text();
var fName = fData.find('name').text();
// Apply the room data
if(!nickname && fNick)
nickname = fNick;
if(!password && fPwd)
password = fPwd;
if(!title && fName)
name = fName;
}
groupchatCreate(hash, xid, name, nickname, password);
}
}
// Switch to the newly-created chat
switchChan(hash);
return false;
}
// Generates the chat DOM elements
function generateChat(type, id, xid, nick) {
// Generate some stuffs
var path = '#' + id + ' .';
var escaped_xid = escape(xid);
// Special code
var specialAttributes, specialAvatar, specialName, specialCode, specialLink, specialDisabled, specialStyle;
// Groupchat special code
if(type == 'groupchat') {
specialAttributes = ' data-type="groupchat"';
specialAvatar = '';
specialName = '<p class="bc-infos"><b>' + _e("Subject") + '</b> <span class="muc-topic">' + _e("no subject defined for this room.") + '</span></p>';
specialCode = '<div class="content groupchat-content" id="chat-content-' + id + '"></div><div class="list"><div class="moderator role"><p class="title">' + _e("Moderators") + '</p></div><div class="participant role"><p class="title">' + _e("Participants") + '</p></div><div class="visitor role"><p class="title">' + _e("Visitors") + '</p></div><div class="none role"><p class="title">' + _e("Others") + '</p></div></div>';
specialLink = '<a href="#" class="tools-mucadmin tools-tooltip talk-images chat-tools-content" title="' + _e("Administration panel for this room") + '"></a>';
specialStyle = '';
// Is this a gateway?
if(xid.match(/%/))
specialDisabled = '';
else
specialDisabled = ' disabled=""';
}
// Chat (or other things?!) special code
else {
specialAttributes = ' data-type="chat"';
specialAvatar = '<div class="avatar-container"><img class="avatar" src="' + './img/others/default-avatar.png' + '" alt="" /></div>';
specialName = '<div class="bc-pep"></div><p class="bc-infos"><span class="unavailable show talk-images"></span></p>';
specialCode = '<div class="content" id="chat-content-' + id + '"></div>';
specialLink = '<a href="#" class="tools-archives tools-tooltip talk-images chat-tools-content" title="' + _e("View chat history") + '"></a><a href="#" class="tools-infos tools-tooltip talk-images chat-tools-content" title="' + _e("Show user profile") + '"></a>';
specialStyle = ' style="display: none;"';
specialDisabled = '';
}
// Not a groupchat private chat, we can use the buddy add icon
if((type == 'chat') || (type == 'groupchat')) {
var addTitle;
if(type == 'chat')
addTitle = _e("Add this contact to your friends");
else
addTitle = _e("Add this groupchat to your favorites");
specialLink += '<a href="#" class="tools-add tools-tooltip talk-images chat-tools-content" title="' + addTitle + '"></a>';
}
// IE DOM parsing bug fix
var specialStylePicker = '<div class="chat-tools-content chat-tools-style"' + specialStyle + '>' +
'<a href="#" class="tools-style tools-tooltip talk-images"></a>' +
'</div>';
if((BrowserDetect.browser == 'Explorer') && (BrowserDetect.version < 9))
specialStylePicker = '';
// Append the chat HTML code
$('#page-engine').append(
'<div id="' + id + '" class="page-engine-chan chat one-counter"' + specialAttributes + ' data-xid="' + escaped_xid + '">' +
'<div class="top ' + id + '">' +
specialAvatar +
'<div class="name">' +
'<p class="bc-name bc-name-nick">' + nick.htmlEnc() + '</p>' +
specialName +
'</div>' +
'</div>' +
specialCode +
'<div class="text">' +
'<div class="footer">' +
'<div class="chat-tools-content chat-tools-smileys">' +
'<a href="#" class="tools-smileys tools-tooltip talk-images"></a>' +
'</div>' +
specialStylePicker +
'<div class="chat-tools-content chat-tools-file">' +
'<a href="#" class="tools-file tools-tooltip talk-images"></a>' +
'</div>' +
'<div class="chat-tools-content chat-tools-save">' +
'<a href="#" class="tools-save tools-tooltip talk-images"></a>' +
'</div>' +
'<a href="#" class="tools-clear tools-tooltip talk-images chat-tools-content" title="' + _e("Clean current chat") + '"></a>' +
specialLink +
'</div>' +
'<div class="compose">' +
'<textarea class="message-area focusable" ' + specialDisabled + ' data-to="' + escaped_xid + '" /></textarea>' +
'</div>' +
'</div>' +
'</div>'
);
// Click event: chat cleaner
$(path + 'tools-clear').click(function() {
cleanChat(id);
});
// Click event: user-infos
$(path + 'tools-infos').click(function() {
openUserInfos(xid);
});
}
// Generates the chat switch elements
function generateSwitch(type, id, xid, nick) {
// Path to the element
var chat_switch = '#page-switch .';
// Special code
var specialClass = ' unavailable';
var show_close = true;
// Groupchat
if(type == 'groupchat') {
specialClass = ' groupchat-default';
if(isAnonymous() && (xid == generateXID(ANONYMOUS_ROOM, 'groupchat')))
show_close = false;
}
// Generate the HTML code
var html = '<div class="' + id + ' switcher chan" onclick="return switchChan(\'' + encodeOnclick(id) + '\')">' +
'<div class="icon talk-images' + specialClass + '"></div>' +
'<div class="name">' + nick.htmlEnc() + '</div>';
// Show the close button if not MUC and not anonymous
if(show_close)
html += '<div class="exit" title="' + _e("Close this tab") + '" onclick="return quitThisChat(\'' + encodeOnclick(xid) + '\', \'' + encodeOnclick(id) + '\', \'' + encodeOnclick(type) + '\');">x</div>';
// Close the HTML
html += '</div>';
// Append the HTML code
$(chat_switch + 'chans, ' + chat_switch + 'more-content').append(html);
}
// Cleans given the chat lines
function cleanChat(chat) {
$('#page-engine #' + chat + ' .content .one-group').remove();
$(document).oneTime(10, function() {
$('#page-engine #' + chat + ' .text .message-area').focus();
});
}
// Creates a new chat
function chatCreate(hash, xid, nick, type) {
logThis('New chat: ' + xid, 3);
// Create the chat content
generateChat(type, hash, xid, nick);
// Create the chat switcher
generateSwitch(type, hash, xid, nick);
// If the user is not in our buddy-list
if(type == 'chat') {
// Add button
if(!exists('#buddy-list .buddy[data-xid=' + escape(xid) + ']'))
$('#' + hash + ' .tools-add').click(function() {
// Hide the icon (to tell the user all is okay)
$(this).hide();
// Send the subscribe request
addThisContact(xid, nick);
}).show();
// Archives button
else if(enabledArchives() || enabledArchives('auto') || enabledArchives('manual') || enabledArchives('manage'))
$('#' + hash + ' .tools-archives').click(function() {
// Open the archives popup
openArchives();
// Get the archives for this user
$('#archives .filter .friend').val(xid);
updateArchives();
}).show();
}
// We catch the user's informations (like this avatar, vcard, and so on...)
getUserInfos(hash, xid, nick, type);
// The icons-hover functions
tooltipIcons(xid, hash);
// The event handlers
var inputDetect = $('#page-engine #' + hash + ' .message-area');
inputDetect.focus(function() {
chanCleanNotify(hash);
})
inputDetect.keypress(function(e) {
// Enter key
if(e.keyCode == 13) {
// Add a new line
if(e.shiftKey)
inputDetect.val(inputDetect.val() + '\n');
// Send the message
else {
// Send the message
sendMessage(hash, 'chat');
// Reset the composing database entry
setDB('chatstate', xid, 'off');
}
return false;
}
});
// Chatstate events
eventsChatState(inputDetect, xid, hash);
}

View file

@ -0,0 +1,174 @@
/*
Jappix - An open social platform
These are the chatstate JS script for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 25/08/11
*/
// Sends a given chatstate to a given entity
function chatStateSend(state, xid, hash) {
var user_type = $('#' + hash).attr('data-type');
// If the friend client supports chatstates and is online
if((user_type == 'groupchat') || ((user_type == 'chat') && $('#' + hash + ' .message-area').attr('data-chatstates') && !exists('#page-switch .' + hash + ' .unavailable'))) {
// Already sent?
if(getDB('currentchatstate', xid) == state)
return;
// Write the state
setDB('currentchatstate', xid, state);
// New message stanza
var aMsg = new JSJaCMessage();
aMsg.setTo(xid);
aMsg.setType(user_type);
// Append the chatstate node
aMsg.appendNode(state, {'xmlns': NS_CHATSTATES});
// Send this!
con.send(aMsg);
}
}
// Displays a given chatstate in a given chat
function displayChatState(state, hash, type) {
// Groupchat?
if(type == 'groupchat') {
resetChatState(hash, type);
// "gone" state not allowed
if(state != 'gone')
$('#page-engine .page-engine-chan .user.' + hash).addClass(state);
}
// Chat
else {
// We change the buddy name color in the page-switch
resetChatState(hash, type);
$('#page-switch .' + hash + ' .name').addClass(state);
// We generate the chatstate text
var text = '';
switch(state) {
// Active
case 'active':
text = _e("Your friend is paying attention to the conversation.");
break;
// Composing
case 'composing':
text = _e("Your friend is writing a message...");
break;
// Paused
case 'paused':
text = _e("Your friend stopped writing a message.");
break;
// Inactive
case 'inactive':
text = _e("Your friend is doing something else.");
break;
// Gone
case 'gone':
text = _e("Your friend closed the chat.");
break;
}
// We reset the previous state
$('#' + hash + ' .chatstate').remove();
// We create the chatstate
$('#' + hash + ' .content').after('<div class="' + state + ' chatstate">' + text + '</div>');
}
}
// Resets the chatstate switcher marker
function resetChatState(hash, type) {
// Define the selector
var selector;
if(type == 'groupchat')
selector = $('#page-engine .page-engine-chan .user.' + hash);
else
selector = $('#page-switch .' + hash + ' .name');
// Reset!
selector.removeClass('active')
selector.removeClass('composing')
selector.removeClass('paused')
selector.removeClass('inactive')
selector.removeClass('gone');
}
// Adds the chatstate events
function eventsChatState(target, xid, hash) {
target.keyup(function(e) {
if(e.keyCode != 13) {
// Composing a message
if($(this).val() && (getDB('chatstate', xid) != 'on')) {
// We change the state detect input
setDB('chatstate', xid, 'on');
// We send the friend a "composing" chatstate
chatStateSend('composing', xid, hash);
}
// Stopped composing a message
else if(!$(this).val() && (getDB('chatstate', xid) == 'on')) {
// We change the state detect input
setDB('chatstate', xid, 'off');
// We send the friend an "active" chatstate
chatStateSend('active', xid, hash);
}
}
});
target.change(function() {
// Reset the composing database entry
setDB('chatstate', xid, 'off');
});
target.focus(function() {
// Not needed
if(target.is(':disabled'))
return;
// Nothing in the input, user is active
if(!$(this).val())
chatStateSend('active', xid, hash);
// Something was written, user started writing again
else
chatStateSend('composing', xid, hash);
});
target.blur(function() {
// Not needed
if(target.is(':disabled'))
return;
// Nothing in the input, user is inactive
if(!$(this).val())
chatStateSend('inactive', xid, hash);
// Something was written, user paused
else
chatStateSend('paused', xid, hash);
});
}

View file

@ -0,0 +1,311 @@
/*
Jappix - An open social platform
These are the common JS script for Jappix
-------------------------------------------------
License: AGPL
Authors: Vanaryon, olivierm
Last revision: 24/06/11
*/
// Checks if an element exists in the DOM
function exists(selector) {
if(jQuery(selector).size() > 0)
return true;
else
return false;
}
// Checks if Jappix is connected
function isConnected() {
if((typeof con != 'undefined') && con && con.connected())
return true;
return false;
}
// Checks if Jappix has focus
function isFocused() {
try {
if(document.hasFocus())
return true;
return false;
}
catch(e) {
return true;
}
}
// Generates the good XID
function generateXID(xid, type) {
// XID needs to be transformed
if(xid && (xid.indexOf('@') == -1)) {
// Groupchat
if(type == 'groupchat')
return xid + '@' + HOST_MUC;
// One-to-one chat
if(xid.indexOf('.') == -1)
return xid + '@' + HOST_MAIN;
// It might be a gateway?
return xid;
}
// Nothing special (yet bare XID)
return xid;
}
// Gets the asked translated string
function _e(string) {
return string;
}
// Replaces '%s' to a given value for a translated string
function printf(string, value) {
return string.replace('%s', value);
}
// Properly explodes a string with a given character
function explodeThis(toEx, toStr, i) {
// Get the index of our char to explode
var index = toStr.indexOf(toEx);
// We split if necessary the string
if(index != -1) {
if(i == 0)
toStr = toStr.substr(0, index);
else
toStr = toStr.substr(index + 1);
}
// We return the value
return toStr;
}
// Cuts the resource of a XID
function cutResource(aXID) {
return explodeThis('/', aXID, 0);
}
// Gets the resource of a XID
function thisResource(aXID) {
// Any resource?
if(aXID.indexOf('/') != -1)
return explodeThis('/', aXID, 1);
// No resource
return '';
}
// Does stringprep on a string
function stringPrep(string) {
// Replacement arrays
var invalid = new Array('Š', 'š', 'Đ', 'đ', 'Ž', 'ž', 'Č', 'č', 'Ć', 'ć', 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'Þ', 'ß', 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ý', 'þ', 'ÿ', 'Ŕ', 'ŕ');
var valid = new Array('S', 's', 'Dj', 'dj', 'Z', 'z', 'C', 'c', 'C', 'c', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 'B', 'Ss', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'o', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'y', 'b', 'y', 'R', 'r');
// Compute a new string
for(i in invalid)
string = string.replace(invalid[i], valid[i]);
return string;
}
// Encodes quotes in a string
function encodeQuotes(str) {
return (str + '').replace(/"/g, '&quot;');
}
// Gets the bare XID from a XID
function bareXID(xid) {
// Cut the resource
xid = cutResource(xid);
// Launch the stringprep
xid = stringPrep(xid);
// Set the XID to lower case
xid = xid.toLowerCase();
return xid;
}
// Gets the full XID from a XID
function fullXID(xid) {
// Normalizes the XID
var full = bareXID(xid);
var resource = thisResource(xid);
// Any resource?
if(resource)
full += '/' + resource;
return full;
}
// Gets the nick from a XID
function getXIDNick(aXID) {
return explodeThis('@', aXID, 0);
}
// Gets the host from a XID
function getXIDHost(aXID) {
return explodeThis('@', aXID, 1);
}
// Checks if we are in developer mode
function isDeveloper() {
if(DEVELOPER == 'on')
return true;
return false;
}
// Checks if anonymous mode is allowed
function allowedAnonymous() {
if(ANONYMOUS == 'on')
return true;
return false;
}
// Checks if host is locked
function lockHost() {
if(LOCK_HOST == 'on')
return true;
return false;
}
// Gets the full XID of the user
function getXID() {
// Return the XID of the user
if(con.username && con.domain)
return con.username + '@' + con.domain;
return '';
}
// Generates the colors for a given user XID
function generateColor(xid) {
var colors = new Array(
'ac0000',
'a66200',
'007703',
'00705f',
'00236b',
'4e005c'
);
var number = 0;
for(var i = 0; i < xid.length; i++)
number += xid.charCodeAt(i);
var color = '#' + colors[number % (colors.length)];
return color;
}
// Checks if the XID is a gateway
function isGateway(xid) {
if(xid.indexOf('@') != -1)
return false;
return true;
}
// Gets the from attribute of a stanza (overrides some servers like Prosody missing from attributes)
function getStanzaFrom(stanza) {
var from = stanza.getFrom();
// No from, we assume this is our XID
if(!from)
from = getXID();
return from;
}
// Logs a given data in the console
function logThis(data, level) {
// Console not available
if(!isDeveloper() || (typeof(console) == 'undefined'))
return false;
// Switch the log level
switch(level) {
// Debug
case 0:
console.debug(data);
break;
// Error
case 1:
console.error(data);
break;
// Warning
case 2:
console.warn(data);
break;
// Information
case 3:
console.info(data);
break;
// Default log level
default:
console.log(data);
break;
}
return true;
}
// Gets the current Jappix app. location
function getJappixLocation() {
var url = window.location.href;
// If the URL has variables, remove them
if(url.indexOf('?') != -1)
url = url.split('?')[0];
if(url.indexOf('#') != -1)
url = url.split('#')[0];
// No "/" at the end
if(!url.match(/(.+)\/$/))
url += '/';
return url;
}
// Removes spaces at the beginning & the end of a string
function trim(str) {
return str.replace(/^\s+/g,'').replace(/\s+$/g,'');
}
// Adds a zero to a date when needed
function padZero(i) {
// Negative number (without first 0)
if(i > -10 && i < 0)
return '-0' + (i * -1);
// Positive number (without first 0)
if(i < 10 && i >= 0)
return '0' + i;
// All is okay
return i;
}

View file

@ -0,0 +1,526 @@
/*
Jappix - An open social platform
These are the connection JS script for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 29/08/11
*/
// Does the user login
var CURRENT_SESSION = false;
function doLogin(lNick, lServer, lPass, lResource, lPriority, lRemember) {
try {
// We remove the not completed class to avoid problems
$('#home .loginer input').removeClass('please-complete');
// We add the login wait div
showGeneralWait();
// We define the http binding parameters
oArgs = new Object();
if(HOST_BOSH_MAIN)
oArgs.httpbase = HOST_BOSH_MAIN;
else
oArgs.httpbase = HOST_BOSH;
// We create the new http-binding connection
con = new JSJaCHttpBindingConnection(oArgs);
// And we handle everything that happen
setupCon(con);
// Generate a resource
var random_resource = getDB('session', 'resource');
if(!random_resource)
random_resource = lResource + ' (' + (new Date()).getTime() + ')';
// We retrieve what the user typed in the login inputs
oArgs = new Object();
oArgs.domain = trim(lServer);
oArgs.username = trim(lNick);
oArgs.resource = random_resource;
oArgs.pass = lPass;
oArgs.secure = true;
oArgs.xmllang = XML_LANG;
// Store the resource (for reconnection)
setDB('session', 'resource', random_resource);
// Generate a session XML to be stored
session_xml = '<session><stored>true</stored><domain>' + lServer.htmlEnc() + '</domain><username>' + lNick.htmlEnc() + '</username><resource>' + lResource.htmlEnc() + '</resource><password>' + lPass.htmlEnc() + '</password><priority>' + lPriority.htmlEnc() + '</priority></session>';
// Save the session parameters (for reconnect if network issue)
CURRENT_SESSION = session_xml;
// Remember me?
if(lRemember)
setDB('remember', 'session', 1);
// We store the infos of the user into the data-base
setDB('priority', 1, lPriority);
// We connect !
con.connect(oArgs);
// Change the page title
pageTitle('wait');
logThis('Jappix is connecting...', 3);
}
catch(e) {
// Logs errors
logThis('Error while logging in: ' + e, 1);
// Reset Jappix
destroyTalkPage();
// Open an unknown error
openThisError(2);
}
finally {
return false;
}
}
// Handles the user registration
function handleRegistered() {
logThis('A new account has been registered.', 3);
// We remove the waiting image
removeGeneralWait();
// Reset the title
pageTitle('home');
// We show the success information
$('#home .registerer .success').fadeIn('fast');
// We quit the session
logout();
}
// Does the user registration
function doRegister(username, domain, pass) {
logThis('Trying to register an account...', 3);
try {
// We define the http binding parameters
oArgs = new Object();
if(HOST_BOSH_MAIN)
oArgs.httpbase = HOST_BOSH_MAIN;
else
oArgs.httpbase = HOST_BOSH;
// We create the new http-binding connection
con = new JSJaCHttpBindingConnection(oArgs);
// We setup the connection !
con.registerHandler('onconnect', handleRegistered);
con.registerHandler('onerror', handleError);
// We retrieve what the user typed in the register inputs
oArgs = new Object();
oArgs.domain = trim(domain);
oArgs.username = trim(username);
oArgs.resource = JAPPIX_RESOURCE + ' Register (' + (new Date()).getTime() + ')';
oArgs.pass = pass;
oArgs.register = true;
oArgs.secure = true;
oArgs.xmllang = XML_LANG;
con.connect(oArgs);
// We change the registered information text
$('#home .homediv.registerer').append(
'<div class="info success">' +
_e("You have been registered, here is your XMPP address:") + ' <b>' + con.username.htmlEnc() + '@' + con.domain.htmlEnc() + '</b> - <a href="#">' + _e("Login") + '</a>' +
'</div>'
);
// Login link
$('#home .homediv.registerer .success a').click(function() {
return doLogin(con.username, con.domain, con.pass, con.resource, '10', false);
});
// Show the waiting image
showGeneralWait();
// Change the page title
pageTitle('wait');
}
catch(e) {
// Logs errors
logThis(e, 1);
}
finally {
return false;
}
}
// Does the user anonymous login
function doAnonymous() {
logThis('Trying to login anonymously...', 3);
var aPath = '#home .anonymouser ';
var room = $(aPath + '.room').val();
var nick = $(aPath + '.nick').val();
// If the form is correctly completed
if(room && nick) {
// We remove the not completed class to avoid problems
$('#home .anonymouser input').removeClass('please-complete');
// Redirect the user to the anonymous room
window.location.href = JAPPIX_LOCATION + '?r=' + room + '&n=' + nick;
}
// We check if the form is entirely completed
else {
$(aPath + 'input[type=text]').each(function() {
var select = $(this);
if(!select.val())
$(document).oneTime(10, function() {
select.addClass('please-complete').focus();
});
else
select.removeClass('please-complete');
});
}
return false;
}
// Handles the user connected event
var CONNECTED = false;
function handleConnected() {
logThis('Jappix is now connected.', 3);
// Connection markers
CONNECTED = true;
RECONNECT_TRY = 0;
RECONNECT_TIMER = 0;
// We hide the home page
$('#home').hide();
// Not resumed?
if(!RESUME) {
// Remember the session?
if(getDB('remember', 'session'))
setPersistent('session', 1, CURRENT_SESSION);
// We show the chatting app.
createTalkPage();
// We reset the homepage
switchHome('default');
// We get all the other things
getEverything();
// Set last activity stamp
LAST_ACTIVITY = getTimeStamp();
}
// Resumed
else {
// Send our presence
presenceSend();
// Change the title
updateTitle();
}
// Remove the waiting item
removeGeneralWait();
}
// Handles the user disconnected event
function handleDisconnected() {
logThis('Jappix is now disconnected.', 3);
// Normal disconnection
if(!CURRENT_SESSION && !CONNECTED)
destroyTalkPage();
}
// Setups the normal connection
function setupCon(con) {
// We setup all the necessary handlers for the connection
con.registerHandler('message', handleMessage);
con.registerHandler('presence', handlePresence);
con.registerHandler('iq', handleIQ);
con.registerHandler('onconnect', handleConnected);
con.registerHandler('onerror', handleError);
con.registerHandler('ondisconnect', handleDisconnected);
}
// Logouts from the server
function logout() {
// We are not connected
if(!isConnected())
return false;
// Disconnect from the XMPP server
con.disconnect();
logThis('Jappix is disconnecting...', 3);
}
// Terminates a session
function terminate() {
if(!isConnected())
return;
// Clear temporary session storage
resetConMarkers();
// Show the waiting item (useful if BOSH is sloooow)
showGeneralWait();
// Change the page title
pageTitle('wait');
// Disconnect from the XMPP server
logout();
}
// Quitss a session
function quit() {
if(!isConnected())
return;
// We show the waiting image
showGeneralWait();
// Change the page title
pageTitle('wait');
// We disconnect from the XMPP server
logout();
}
// Creates the reconnect pane
var RECONNECT_TRY = 0;
var RECONNECT_TIMER = 0;
function createReconnect(mode) {
logThis('This is not a normal disconnection, show the reconnect pane...', 1);
// Reconnect pane not yet displayed?
if(!exists('#reconnect')) {
// Blur the focused input/textarea/select
$('input, select, textarea').blur();
// Create the HTML code
var html = '<div id="reconnect" class="lock">' +
'<div class="pane">' +
_e("Due to a network issue, you were disconnected. What do you want to do now?");
// Can we cancel reconnection?
if(mode == 'normal')
html += '<a href="#" class="finish cancel">' + _e("Cancel") + '</a>';
html += '<a href="#" class="finish reconnect">' + _e("Reconnect") + '</a>' +
'</div></div>';
// Append the code
$('body').append(html);
// Click events
if(mode == 'normal')
$('#reconnect a.finish.cancel').click(function() {
return cancelReconnect();
});
$('#reconnect a.finish.reconnect').click(function() {
return acceptReconnect(mode);
});
// Try to reconnect automatically after a while
if(RECONNECT_TRY < 5)
RECONNECT_TIMER = 5 + (5 * RECONNECT_TRY);
else
RECONNECT_TIMER = 120;
// Change the try number
RECONNECT_TRY++;
// Fire the event!
$('#reconnect a.finish.reconnect').everyTime('1s', function() {
// We can reconnect!
if(RECONNECT_TIMER == 0)
return acceptReconnect(mode);
// Button text
if(RECONNECT_TIMER <= 10)
$(this).text(_e("Reconnect") + ' (' + RECONNECT_TIMER + ')');
// Remove 1 second
RECONNECT_TIMER--;
});
// Page title
updateTitle();
}
}
// Reconnects the user if he was disconnected (network issue)
var RESUME = false;
function acceptReconnect(mode) {
logThis('Trying to reconnect the user...', 3);
// Resume marker
RESUME = true;
// Show waiting item
showGeneralWait();
// Reset some various stuffs
var groupchats = '#page-engine .page-engine-chan[data-type=groupchat]';
$(groupchats + ' .list .role').hide();
$(groupchats + ' .one-group, ' + groupchats + ' .list .user').remove();
$(groupchats).attr('data-initial', 'false');
// Stop the timer
$('#reconnect a.finish.reconnect').stopTime();
// Remove the reconnect pane
$('#reconnect').remove();
// Try to login again
if(mode == 'normal')
loginFromSession(XMLFromString(CURRENT_SESSION));
else if(mode == 'anonymous')
anonymousLogin(HOST_ANONYMOUS);
return false;
}
// Cancel the reconnection of user account (network issue)
function cancelReconnect() {
logThis('User has canceled automatic reconnection...', 3);
// Stop the timer
$('#reconnect a.finish.reconnect').stopTime();
// Remove the reconnect pane
$('#reconnect').remove();
// Destroy the talk page
destroyTalkPage();
// Renitialize the previous session parameters
resetConMarkers();
return false;
}
// Clears session reminder database
function clearLastSession() {
// Clear temporary storage
resetConMarkers();
// Clear persistent storage
if($(XMLFromString(getPersistent('session', 1))).find('stored').text() == 'true')
removePersistent('session', 1);
}
// Resets the connection markers
function resetConMarkers() {
CURRENT_SESSION = false;
CONNECTED = false;
RESUME = false;
RECONNECT_TRY = 0;
RECONNECT_TIMER = 0;
}
// Logins from a saved session
function loginFromSession(data) {
// Select the data
var session = $(data);
// Fire the login event
doLogin(
session.find('username').text(),
session.find('domain').text(),
session.find('password').text(),
session.find('resource').text(),
session.find('priority').text(),
false
);
}
// Quits a session normally
function normalQuit() {
// Reset our database
clearLastSession();
// We quit the current session
quit();
// We show an info
openThisInfo(3);
return false;
}
// Gets all the users stuffs
function getEverything() {
getFeatures();
getRoster();
listPrivacy();
getStorage(NS_ROSTERNOTES);
}
// Plugin launcher
function launchConnection() {
// Logouts when Jappix is closed
$(window).bind('beforeunload', terminate);
// Nothing to do when anonymous!
if(isAnonymous())
return;
// Try to resume a stored session, if not anonymous
var session = XMLFromString(getPersistent('session', 1));
if($(session).find('stored').text() == 'true') {
// Hide the homepage
$('#home').hide();
// Show the waiting icon
showGeneralWait();
// Login!
loginFromSession(session);
logThis('Saved session found, resuming it...', 3);
}
// Not connected, maybe a XMPP link is submitted?
else if((parent.location.hash != '#OK') && LINK_VARS['x']) {
switchHome('loginer');
logThis('A XMPP link is set, switch to login page.', 3);
}
}
// Launch this plugin!
$(document).ready(launchConnection);

View file

@ -0,0 +1,211 @@
/*
Jappix - An open social platform
These are the constants JS scripts for Jappix
-------------------------------------------------
License: AGPL
Authors: Stefan Strigler, Vanaryon
Last revision: 26/08/11
*/
// XMPP XMLNS attributes
var NS_PROTOCOL = 'http://jabber.org/protocol/';
var NS_FEATURES = 'http://jabber.org/features/';
var NS_CLIENT = 'jabber:client';
var NS_IQ = 'jabber:iq:';
var NS_X = 'jabber:x:';
var NS_IETF = 'urn:ietf:params:xml:ns:xmpp-';
var NS_XMPP = 'urn:xmpp:';
var NS_STORAGE = 'storage:';
var NS_BOOKMARKS = NS_STORAGE + 'bookmarks';
var NS_ROSTERNOTES = NS_STORAGE + 'rosternotes';
var NS_JAPPIX = 'jappix:';
var NS_INBOX = NS_JAPPIX + 'inbox';
var NS_OPTIONS = NS_JAPPIX + 'options';
var NS_DISCO_ITEMS = NS_PROTOCOL + 'disco#items';
var NS_DISCO_INFO = NS_PROTOCOL + 'disco#info';
var NS_VCARD = 'vcard-temp';
var NS_VCARD_P = NS_VCARD + ':x:update';
var NS_AUTH = NS_IQ + 'auth';
var NS_AUTH_ERROR = NS_IQ + 'auth:error';
var NS_REGISTER = NS_IQ + 'register';
var NS_SEARCH = NS_IQ + 'search';
var NS_ROSTER = NS_IQ + 'roster';
var NS_PRIVACY = NS_IQ + 'privacy';
var NS_PRIVATE = NS_IQ + 'private';
var NS_VERSION = NS_IQ + 'version';
var NS_TIME = NS_IQ + 'time';
var NS_LAST = NS_IQ + 'last';
var NS_IQDATA = NS_IQ + 'data';
var NS_XDATA = NS_X + 'data';
var NS_IQOOB = NS_IQ + 'oob';
var NS_XOOB = NS_X + 'oob';
var NS_DELAY = NS_X + 'delay';
var NS_EXPIRE = NS_X + 'expire';
var NS_EVENT = NS_X + 'event';
var NS_XCONFERENCE = NS_X + 'conference';
var NS_STATS = NS_PROTOCOL + 'stats';
var NS_MUC = NS_PROTOCOL + 'muc';
var NS_MUC_USER = NS_MUC + '#user';
var NS_MUC_ADMIN = NS_MUC + '#admin';
var NS_MUC_OWNER = NS_MUC + '#owner';
var NS_MUC_CONFIG = NS_MUC + '#roomconfig';
var NS_PUBSUB = NS_PROTOCOL + 'pubsub';
var NS_PUBSUB_EVENT = NS_PUBSUB + '#event';
var NS_PUBSUB_OWNER = NS_PUBSUB + '#owner';
var NS_PUBSUB_NMI = NS_PUBSUB + '#node-meta-info';
var NS_PUBSUB_NC = NS_PUBSUB + '#node_config';
var NS_PUBSUB_RI = NS_PUBSUB + '#retrieve-items';
var NS_COMMANDS = NS_PROTOCOL + 'commands';
var NS_BOSH = NS_PROTOCOL + 'httpbind';
var NS_STREAM = 'http://etherx.jabber.org/streams';
var NS_URN_TIME = NS_XMPP + 'time';
var NS_URN_PING = NS_XMPP + 'ping';
var NS_URN_ADATA = NS_XMPP + 'avatar:data';
var NS_URN_AMETA = NS_XMPP + 'avatar:metadata';
var NS_URN_MBLOG = NS_XMPP + 'microblog:0';
var NS_URN_INBOX = NS_XMPP + 'inbox';
var NS_URN_ARCHIVE = NS_XMPP + 'archive';
var NS_URN_AR_PREF = NS_URN_ARCHIVE + ':pref';
var NS_URN_AR_AUTO = NS_URN_ARCHIVE + ':auto';
var NS_URN_AR_MANUAL = NS_URN_ARCHIVE + ':manual';
var NS_URN_AR_MANAGE = NS_URN_ARCHIVE + ':manage';
var NS_URN_DELAY = NS_XMPP + 'delay';
var NS_URN_RECEIPTS = NS_XMPP + 'receipts';
var NS_RSM = NS_PROTOCOL + 'rsm';
var NS_IPV6 = 'ipv6';
var NS_XHTML = 'http://www.w3.org/1999/xhtml';
var NS_XHTML_IM = NS_PROTOCOL + 'xhtml-im';
var NS_CHATSTATES = NS_PROTOCOL + 'chatstates';
var NS_HTTP_AUTH = NS_PROTOCOL + 'http-auth';
var NS_ROSTERX = NS_PROTOCOL + 'rosterx';
var NS_MOOD = NS_PROTOCOL + 'mood';
var NS_ACTIVITY = NS_PROTOCOL + 'activity';
var NS_TUNE = NS_PROTOCOL + 'tune';
var NS_GEOLOC = NS_PROTOCOL + 'geoloc';
var NS_NICK = NS_PROTOCOL + 'nick';
var NS_NOTIFY = '+notify';
var NS_CAPS = NS_PROTOCOL + 'caps';
var NS_ATOM = 'http://www.w3.org/2005/Atom';
var NS_STANZAS = NS_IETF + 'stanzas';
var NS_STREAMS = NS_IETF + 'streams';
var NS_TLS = NS_IETF + 'tls';
var NS_SASL = NS_IETF + 'sasl';
var NS_SESSION = NS_IETF + 'session';
var NS_BIND = NS_IETF + 'bind';
var NS_FEATURE_IQAUTH = NS_FEATURES + 'iq-auth';
var NS_FEATURE_IQREGISTER = NS_FEATURES + 'iq-register';
var NS_FEATURE_COMPRESS = NS_FEATURES + 'compress';
var NS_COMPRESS = NS_PROTOCOL + 'compress';
// Available locales
var LOCALES_AVAILABLE_ID = new Array();
var LOCALES_AVAILABLE_NAMES = new Array();
// XML lang
var XML_LANG = null;
// Jappix parameters
var JAPPIX_STATIC = null;
var JAPPIX_VERSION = null;
var JAPPIX_MAX_FILE_SIZE = null;
var JAPPIX_MAX_UPLOAD = null;
// Jappix main configuration
var SERVICE_NAME = null;
var SERVICE_DESC = null;
var JAPPIX_RESOURCE = null;
var LOCK_HOST = null;
var ANONYMOUS = null;
var REGISTRATION = null;
var BOSH_PROXY = null;
var MANAGER_LINK = null;
var GROUPCHATS_JOIN = null;
var ENCRYPTION = null;
var HTTPS_STORAGE = null;
var HTTPS_FORCE = null;
var COMPRESSION = null;
var MULTI_FILES = null;
var DEVELOPER = null;
// Jappix hosts configuration
var HOST_MAIN = null;
var HOST_MUC = null;
var HOST_PUBSUB = null;
var HOST_VJUD = null;
var HOST_ANONYMOUS = null;
var HOST_BOSH = null;
var HOST_BOSH_MAIN = null;
var HOST_BOSH_MINI = null;
var HOST_STATIC = null;
var HOST_UPLOAD = null;
// Anonymous mode
var ANONYMOUS_ROOM = null;
var ANONYMOUS_NICK = null;
// Node parameters
var JAPPIX_LOCATION = getJappixLocation();
// XMPP error stanzas
function STANZA_ERROR(code, type, cond) {
if (window == this)
return new STANZA_ERROR(code, type, cond);
this.code = code;
this.type = type;
this.cond = cond;
}
var ERR_BAD_REQUEST =
STANZA_ERROR('400', 'modify', 'bad-request');
var ERR_CONFLICT =
STANZA_ERROR('409', 'cancel', 'conflict');
var ERR_FEATURE_NOT_IMPLEMENTED =
STANZA_ERROR('501', 'cancel', 'feature-not-implemented');
var ERR_FORBIDDEN =
STANZA_ERROR('403', 'auth', 'forbidden');
var ERR_GONE =
STANZA_ERROR('302', 'modify', 'gone');
var ERR_INTERNAL_SERVER_ERROR =
STANZA_ERROR('500', 'wait', 'internal-server-error');
var ERR_ITEM_NOT_FOUND =
STANZA_ERROR('404', 'cancel', 'item-not-found');
var ERR_JID_MALFORMED =
STANZA_ERROR('400', 'modify', 'jid-malformed');
var ERR_NOT_ACCEPTABLE =
STANZA_ERROR('406', 'modify', 'not-acceptable');
var ERR_NOT_ALLOWED =
STANZA_ERROR('405', 'cancel', 'not-allowed');
var ERR_NOT_AUTHORIZED =
STANZA_ERROR('401', 'auth', 'not-authorized');
var ERR_PAYMENT_REQUIRED =
STANZA_ERROR('402', 'auth', 'payment-required');
var ERR_RECIPIENT_UNAVAILABLE =
STANZA_ERROR('404', 'wait', 'recipient-unavailable');
var ERR_REDIRECT =
STANZA_ERROR('302', 'modify', 'redirect');
var ERR_REGISTRATION_REQUIRED =
STANZA_ERROR('407', 'auth', 'registration-required');
var ERR_REMOTE_SERVER_NOT_FOUND =
STANZA_ERROR('404', 'cancel', 'remote-server-not-found');
var ERR_REMOTE_SERVER_TIMEOUT =
STANZA_ERROR('504', 'wait', 'remote-server-timeout');
var ERR_RESOURCE_CONSTRAINT =
STANZA_ERROR('500', 'wait', 'resource-constraint');
var ERR_SERVICE_UNAVAILABLE =
STANZA_ERROR('503', 'cancel', 'service-unavailable');
var ERR_SUBSCRIPTION_REQUIRED =
STANZA_ERROR('407', 'auth', 'subscription-required');
var ERR_UNEXPECTED_REQUEST =
STANZA_ERROR('400', 'wait', 'unexpected-request');

View file

@ -0,0 +1,921 @@
/*
Jappix - An open social platform
These are the dataform JS scripts for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 28/08/11
*/
// Gets the defined dataform elements
function dataForm(host, type, node, action, target) {
// Clean the current session
cleanDataForm(target);
// We tell the user that a search has been launched
$('#' + target + ' .wait').show();
// If we have enough data
if(host && type) {
// Generate a session ID
var sessionID = Math.round(100000.5 + (((900000.49999) - (100000.5)) * Math.random()));
var id = target + '-' + sessionID + '-' + genID();
$('.' + target + '-results').attr('data-session', target + '-' + sessionID);
// We request the service item
var iq = new JSJaCIQ();
iq.setID(id);
iq.setTo(host);
iq.setType('get');
// MUC admin query
if(type == 'muc') {
iq.setQuery(NS_MUC_OWNER);
con.send(iq, handleDataFormMuc);
}
// Browse query
else if(type == 'browse') {
var iqQuery = iq.setQuery(NS_DISCO_ITEMS);
if(node)
iqQuery.setAttribute('node', node);
con.send(iq, handleDataFormBrowse);
}
// Command
else if(type == 'command') {
var items;
if(node)
items = iq.appendNode('command', {'node': node, 'xmlns': NS_COMMANDS});
else {
items = iq.setQuery(NS_DISCO_ITEMS);
items.setAttribute('node', NS_COMMANDS);
}
if(action && node) {
iq.setType('set');
items.setAttribute('action', action);
}
con.send(iq, handleDataFormCommand);
}
// Search query
else if(type == 'search') {
iq.setQuery(NS_SEARCH);
con.send(iq, handleDataFormSearch);
}
// Subscribe query
else if(type == 'subscribe') {
iq.setQuery(NS_REGISTER);
con.send(iq, handleDataFormSubscribe);
}
// Join
else if(type == 'join') {
if(target == 'discovery')
closeDiscovery();
checkChatCreate(host, 'groupchat');
}
}
return false;
}
// Sends a given dataform
function sendDataForm(type, action, x_type, id, xid, node, sessionid, target) {
// Path
var pathID = '#' + target + ' .results[data-session=' + id + ']';
// New IQ
var iq = new JSJaCIQ();
iq.setTo(xid);
iq.setType('set');
// Set the correct query
var query;
if(type == 'subscribe')
iqQuery = iq.setQuery(NS_REGISTER);
else if(type == 'search')
iqQuery = iq.setQuery(NS_SEARCH);
else if(type == 'command')
iqQuery = iq.appendNode('command', {'xmlns': NS_COMMANDS, 'node': node, 'sessionid': sessionid, 'action': action});
else if(type == 'x')
iqQuery = iq.setQuery(NS_MUC_OWNER);
// Build the XML document
if(action != 'cancel') {
// No X node
if(exists('input.register-special') && (type == 'subscribe')) {
$('input.register-special').each(function() {
var iName = $(this).attr('name');
var iValue = $(this).val();
iqQuery.appendChild(iq.buildNode(iName, {'xmlns': NS_REGISTER}, iValue));
});
}
// Can create the X node
else {
var iqX = iqQuery.appendChild(iq.buildNode('x', {'xmlns': NS_XDATA, 'type': x_type}));
// Each input
$(pathID + ' .oneresult input, ' + pathID + ' .oneresult textarea, ' + pathID + ' .oneresult select').each(function() {
// Get the current input value
var iVar = $(this).attr('name');
var iType = $(this).attr('data-type');
var iValue = $(this).val();
// Build a new field node
var field = iqX.appendChild(iq.buildNode('field', {'var': iVar, 'type': iType, 'xmlns': NS_XDATA}));
// Boolean input?
if(iType == 'boolean') {
if($(this).filter(':checked').size())
iValue = '1';
else
iValue = '0';
}
// JID-multi input?
if(iType == 'jid-multi') {
// Values array
var xid_arr = [iValue];
var xid_check = [];
// Try to split it
if(iValue.indexOf(',') != -1)
xid_arr = iValue.split(',');
// Append each value to the XML document
for(i in xid_arr) {
// Get the current value
xid_current = trim(xid_arr[i]);
// No current value?
if(!xid_current)
continue;
// Add the current value
if(!existArrayValue(xid_check, xid_current)) {
xid_check.push(xid_current);
field.appendChild(iq.buildNode('value', {'xmlns': NS_XDATA}, xid_current));
}
}
}
// List-multi selector?
else if(iType == 'list-multi') {
// Any value?
if(iValue && iValue.length) {
for(i in iValue)
field.appendChild(iq.buildNode('value', {'xmlns': NS_XDATA}, iValue[i]));
}
}
// Other inputs?
else
field.appendChild(iq.buildNode('value', {'xmlns': NS_XDATA}, iValue));
});
}
}
// Clean the current session
cleanDataForm(target);
// Show the waiting item
$('#' + target + ' .wait').show();
// Change the ID of the current discovered item
var iqID = target + '-' + genID();
$('#' + target + ' .' + target + '-results').attr('data-session', iqID);
iq.setID(iqID);
// Send the IQ
if(type == 'subscribe')
con.send(iq, handleDataFormSubscribe);
else if(type == 'search')
con.send(iq, handleDataFormSearch);
else if(type == 'command')
con.send(iq, handleDataFormCommand);
else
con.send(iq);
return false;
}
// Displays the good dataform buttons
function buttonsDataForm(type, action, id, xid, node, sessionid, target, pathID) {
// No need to use buttons?
if(type == 'muc')
return;
// Override the "undefined" output
if(!id)
id = '';
if(!xid)
xid = '';
if(!node)
node = '';
if(!sessionid)
sessionid = '';
// We generate the buttons code
var buttonsCode = '<div class="oneresult ' + target + '-oneresult ' + target + '-formtools">';
if(action == 'submit') {
if((target == 'adhoc') && (type == 'command')) {
buttonsCode += '<a href="#" class="submit" onclick="return sendDataForm(\'' + encodeOnclick(type) + '\', \'execute\', \'submit\', \'' + encodeOnclick(id) + '\', \'' + encodeOnclick(xid) + '\', \'' + encodeOnclick(node) + '\', \'' + encodeOnclick(sessionid) + '\', \'' + encodeOnclick(target) + '\');">' + _e("Submit") + '</a>';
// When keyup on one text input
$(pathID + ' input').keyup(function(e) {
if(e.keyCode == 13) {
sendDataForm(type, 'execute', 'submit', id, xid, node, sessionid, target);
return false;
}
});
}
else {
buttonsCode += '<a href="#" class="submit" onclick="return sendDataForm(\'' + encodeOnclick(type) + '\', \'submit\', \'submit\', \'' + encodeOnclick(id) + '\', \'' + encodeOnclick(xid) + '\', \'' + encodeOnclick(node) + '\', \'' + encodeOnclick(sessionid) + '\', \'' + encodeOnclick(target) + '\');">' + _e("Submit") + '</a>';
// When keyup on one text input
$(pathID + ' input').keyup(function(e) {
if(e.keyCode == 13) {
sendDataForm(type, 'submit', 'submit', id, xid, node, sessionid, target);
return false;
}
});
}
}
if((action == 'submit') && (type != 'subscribe') && (type != 'search'))
buttonsCode += '<a href="#" class="submit" onclick="return sendDataForm(\'' + encodeOnclick(type) + '\', \'cancel\', \'cancel\', \'' + encodeOnclick(id) + '\', \'' + encodeOnclick(xid) + '\', \'' + encodeOnclick(node) + '\', \'' + encodeOnclick(sessionid) + '\', \'' + encodeOnclick(target) + '\');">' + _e("Cancel") + '</a>';
if(((action == 'back') || (type == 'subscribe') || (type == 'search')) && (target == 'discovery'))
buttonsCode += '<a href="#" class="back" onclick="return startDiscovery();">' + _e("Close") + '</a>';
if((action == 'back') && ((target == 'welcome') || (target == 'directory')))
buttonsCode += '<a href="#" class="back" onclick="return dataForm(HOST_VJUD, \'search\', \'\', \'\', \'' + target + '\');">' + _e("Previous") + '</a>';
if((action == 'back') && (target == 'adhoc'))
buttonsCode += '<a href="#" class="back" onclick="return dataForm(\'' + encodeOnclick(xid) + '\', \'command\', \'\', \'\', \'adhoc\');">' + _e("Previous") + '</a>';
buttonsCode += '</div>';
// We display the buttons code
$(pathID).append(buttonsCode);
// If no submit link, lock the form
if(!exists(pathID + ' a.submit'))
$(pathID + ' input, ' + pathID + ' textarea').attr('readonly', true);
}
// Handles the MUC dataform
function handleDataFormMuc(iq) {
handleErrorReply(iq);
handleDataFormContent(iq, 'muc');
}
// Handles the browse dataform
function handleDataFormBrowse(iq) {
handleErrorReply(iq);
handleDataFormContent(iq, 'browse');
}
// Handles the command dataform
function handleDataFormCommand(iq) {
handleErrorReply(iq);
handleDataFormContent(iq, 'command');
}
// Handles the subscribe dataform
function handleDataFormSubscribe(iq) {
handleErrorReply(iq);
handleDataFormContent(iq, 'subscribe');
}
// Handles the search dataform
function handleDataFormSearch(iq) {
handleErrorReply(iq);
handleDataFormContent(iq, 'search');
}
// Handles the dataform content
function handleDataFormContent(iq, type) {
// Get the ID
var sID = iq.getID();
// Get the target
var splitted = sID.split('-');
var target = splitted[0];
var sessionID = target + '-' + splitted[1];
var from = fullXID(getStanzaFrom(iq));
var pathID = '#' + target + ' .results[data-session=' + sessionID + ']';
// If an error occured
if(!iq || (iq.getType() != 'result'))
noResultDataForm(pathID);
// If we got something okay
else {
var handleXML = iq.getNode();
if(type == 'browse') {
if($(handleXML).find('item').attr('jid')) {
// Get the query node
var queryNode = $(handleXML).find('query').attr('node');
$(handleXML).find('item').each(function() {
// We parse the received xml
var itemHost = $(this).attr('jid');
var itemNode = $(this).attr('node');
var itemName = $(this).attr('name');
var itemHash = hex_md5(itemHost);
// Node
if(itemNode)
$(pathID).append(
'<div class="oneresult ' + target + '-oneresult" onclick="return dataForm(\'' + encodeOnclick(itemHost) + '\', \'browse\', \'' + encodeOnclick(itemNode) + '\', \'\', \'' + encodeOnclick(target) + '\');">' +
'<div class="one-name">' + itemNode.htmlEnc() + '</div>' +
'</div>'
);
// Item
else if(queryNode && itemName)
$(pathID).append(
'<div class="oneresult ' + target + '-oneresult">' +
'<div class="one-name">' + itemName.htmlEnc() + '</div>' +
'</div>'
);
// Item with children
else {
// We display the waiting element
$(pathID + ' .disco-wait .disco-category-title').after(
'<div class="oneresult ' + target + '-oneresult ' + itemHash + '">' +
'<div class="one-icon loading talk-images"></div>' +
'<div class="one-host">' + itemHost + '</div>' +
'<div class="one-type">' + _e("Requesting this service...") + '</div>' +
'</div>'
);
// We display the category
$('#' + target + ' .disco-wait').show();
// We ask the server what's the service type
getDataFormType(itemHost, itemNode, sessionID);
}
});
}
// Else, there are no items for this query
else
noResultDataForm(pathID);
}
else if((type == 'muc') || (type == 'search') || (type == 'subscribe') || ((type == 'command') && $(handleXML).find('command').attr('xmlns'))) {
// Get some values
var xCommand = $(handleXML).find('command');
var bNode = xCommand.attr('node');
var bSession = xCommand.attr('sessionid');
var bStatus = xCommand.attr('status');
var xRegister = $(handleXML).find('query[xmlns=' + NS_REGISTER + ']').text();
var xElement = $(handleXML).find('x');
// Search done
if((xElement.attr('type') == 'result') && (type == 'search')) {
var bPath = pathID;
// Display the result
$(handleXML).find('item').each(function() {
var bXID = $(this).find('field[var=jid] value:first').text();
var bName = $(this).find('field[var=fn] value:first').text();
var bCountry = $(this).find('field[var=ctry] value:first').text();
var dName = bName;
// Override "undefined" value
if(!bXID)
bXID = '';
if(!bName)
bName = _e("Unknown name");
if(!bCountry)
bCountry = _e("Unknown country");
// User hash
var bHash = hex_md5(bXID);
// HTML code
var bHTML = '<div class="oneresult ' + target + '-oneresult ' + bHash + '">' +
'<div class="avatar-container">' +
'<img class="avatar" src="' + './img/others/default-avatar.png' + '" alt="" />' +
'</div>' +
'<div class="one-fn">' + bName + '</div>' +
'<div class="one-ctry">' + bCountry + '</div>' +
'<div class="one-jid">' + bXID + '</div>' +
'<div class="buttons-container">';
// The buddy is not in our buddy list?
if(!exists('#buddy-list .buddy[data-xid=' + escape(bXID) + ']'))
bHTML += '<a href="#" class="one-add one-vjud one-button talk-images">' + _e("Add") + '</a>';
// Chat button, if not in welcome/directory mode
if(target == 'discovery')
bHTML += '<a href="#" class="one-chat one-vjud one-button talk-images">' + _e("Chat") + '</a>';
// Close the HTML element
bHTML += '</div></div>';
$(bPath).append(bHTML);
// Click events
$(bPath + ' .' + bHash + ' a').click(function() {
// Buddy add
if($(this).is('.one-add')) {
$(this).hide();
addThisContact(bXID, dName);
}
// Buddy chat
if($(this).is('.one-chat')) {
if(target == 'discovery')
closeDiscovery();
checkChatCreate(bXID , 'chat', '', '', dName);
}
return false;
});
// Get the user's avatar
if(bXID)
getAvatar(bXID, 'cache', 'true', 'forget');
});
// No result?
if(!$(handleXML).find('item').size())
noResultDataForm(pathID);
// Previous button
buttonsDataForm(type, 'back', sessionID, from, bNode, bSession, target, pathID);
}
// Command to complete
else if(xElement.attr('xmlns') || ((type == 'subscribe') && xRegister)) {
// We display the elements
fillDataForm(handleXML, sessionID);
// We display the buttons
if(bStatus != 'completed')
buttonsDataForm(type, 'submit', sessionID, from, bNode, bSession, target, pathID);
else
buttonsDataForm(type, 'back', sessionID, from, bNode, bSession, target, pathID);
}
// Command completed or subscription done
else if(((bStatus == 'completed') && (type == 'command')) || (!xRegister && (type == 'subscribe'))) {
// Display the good text
var cNote = $(xCommand).find('note');
// Any note?
if(cNote.size()) {
cNote.each(function() {
$(pathID).append(
'<div class="onetitle ' + target + '-oneresult">' + $(this).text().htmlEnc() + '</div>'
);
});
}
// Default text
else
$(pathID).append('<div class="oneinstructions ' + target + '-oneresult">' + _e("Your form has been sent.") + '</div>');
// Display the back button
buttonsDataForm(type, 'back', sessionID, from, '', '', target, pathID);
// Add the gateway to our roster if subscribed
if(type == 'subscribe')
addThisContact(from);
}
// Command canceled
else if((bStatus == 'canceled') && (type == 'command')) {
if(target == 'discovery')
startDiscovery();
else if(target == 'adhoc')
dataForm(from, 'command', '', '', 'adhoc');
}
// No items for this query
else
noResultDataForm(pathID);
}
else if(type == 'command') {
if($(handleXML).find('item').attr('jid')) {
// We display the elements
$(handleXML).find('item').each(function() {
// We parse the received xml
var itemHost = $(this).attr('jid');
var itemNode = $(this).attr('node');
var itemName = $(this).attr('name');
var itemHash = hex_md5(itemHost);
// We display the waiting element
$(pathID).prepend(
'<div class="oneresult ' + target + '-oneresult ' + itemHash + '" onclick="return dataForm(\'' + encodeOnclick(itemHost) + '\', \'command\', \'' + encodeOnclick(itemNode) + '\', \'execute\', \'' + encodeOnclick(target) + '\');">' +
'<div class="one-name">' + itemName + '</div>' +
'<div class="one-next">»</div>' +
'</div>'
);
});
}
// Else, there are no items for this query
else
noResultDataForm(pathID);
}
}
// Focus on the first input
$(document).oneTime(10, function() {
$(pathID + ' input:visible:first').focus();
});
// Hide the wait icon
$('#' + target + ' .wait').hide();
}
// Fills the dataform elements
function fillDataForm(xml, id) {
/* REF: http://xmpp.org/extensions/xep-0004.html */
// Initialize new vars
var target = id.split('-')[0];
var pathID = '#' + target + ' .results[data-session=' + id + ']';
var selector, is_dataform;
// Is it a dataform?
if($(xml).find('x[xmlns=' + NS_XDATA + ']').size())
is_dataform = true;
else
is_dataform = false;
// Determines the good selector to use
if(is_dataform)
selector = $(xml).find('x[xmlns=' + NS_XDATA + ']');
else
selector = $(xml);
// Form title
selector.find('title').each(function() {
$(pathID).append(
'<div class="onetitle ' + target + '-oneresult">' + $(this).text().htmlEnc() + '</div>'
);
});
// Form instructions
selector.find('instructions').each(function() {
$(pathID).append(
'<div class="oneinstructions ' + target + '-oneresult">' + $(this).text().htmlEnc() + '</div>'
);
});
// Register?
if(!is_dataform) {
// Items to detect
var reg_names = [_e("Nickname"), _e("Name"), _e("Password"), _e("E-mail")];
var reg_ids = ['username', 'name', 'password', 'email'];
// Append these inputs
for(a in reg_names) {
selector.find(reg_ids[a]).each(function() {
$(pathID).append(
'<div class="oneresult ' + target + '-oneresult">' +
'<label>' + reg_names[a] + '</label>' +
'<input name="' + reg_ids[a] + '" type="text" class="register-special dataform-i" />' +
'</div>'
);
});
}
return false;
}
// Dataform?
selector.find('field').each(function() {
// We parse the received xml
var type = $(this).attr('type');
var label = $(this).attr('label');
var field = $(this).attr('var');
var value = $(this).find('value:first').text();
var required = '';
// No value?
if(!field)
return;
// Required input?
if($(this).find('required').size())
required = ' required=""';
// Compatibility fix
if(!label)
label = field;
if(!type)
type = '';
// Generate some values
var input;
var hideThis = '';
// Fixed field
if(type == 'fixed')
$(pathID).append('<div class="oneinstructions">' + value.htmlEnc() + '</div>');
else {
// Hidden field
if(type == 'hidden') {
hideThis = ' style="display: none;"';
input = '<input name="' + encodeQuotes(field) + '" data-type="' + encodeQuotes(type) + '" type="hidden" class="dataform-i" value="' + encodeQuotes(value) + '" ' + required + ' />';
}
// Boolean field
else if(type == 'boolean') {
var checked;
if(value == '1')
checked = 'checked';
else
checked = '';
input = '<input name="' + encodeQuotes(field) + '" type="checkbox" data-type="' + encodeQuotes(type) + '" class="dataform-i df-checkbox" ' + checked + required + ' />';
}
// List-single/list-multi field
else if((type == 'list-single') || (type == 'list-multi')) {
var multiple = '';
// Multiple options?
if(type == 'list-multi')
multiple = ' multiple=""';
// Append the select field
input = '<select name="' + encodeQuotes(field) + '" data-type="' + encodeQuotes(type) + '" class="dataform-i"' + required + multiple + '>';
var selected;
// Append the available options
$(this).find('option').each(function() {
var nLabel = $(this).attr('label');
var nValue = $(this).find('value').text();
// No label?
if(!nLabel)
nLabel = nValue;
// If this is the selected value
if(nValue == value)
selected = 'selected';
else
selected = '';
input += '<option ' + selected + ' value="' + encodeQuotes(nValue) + '">' + nLabel.htmlEnc() + '</option>';
});
input += '</select>';
}
// Text-multi field
else if(type == 'text-multi')
input = '<textarea rows="8" cols="60" data-type="' + encodeQuotes(type) + '" name="' + encodeQuotes(field) + '" class="dataform-i"' + required + '>' + value.htmlEnc() + '</textarea>';
// JID-multi field
else if(type == 'jid-multi') {
// Put the XID into an array
var xid_arr = [];
$(this).find('value').each(function() {
var cValue = $(this).text();
if(!existArrayValue(xid_arr, cValue))
xid_arr.push(cValue);
});
// Sort the array
xid_arr.sort();
// Create the input
var xid_value = '';
if(xid_arr.length) {
for(i in xid_arr) {
// Any pre-value
if(xid_value)
xid_value += ', ';
// Add the current XID
xid_value += xid_arr[i];
}
}
input = '<input name="' + encodeQuotes(field) + '" data-type="' + encodeQuotes(type) + '" type="text" class="dataform-i" value="' + encodeQuotes(xid_value) + '" placeholder="jack@jappix.com, jones@jappix.com"' + required + ' />';
}
// Other stuffs that are similar
else {
// Text-single field
var iType = 'text';
// Text-private field
if(type == 'text-private')
iType = 'password';
// JID-single field
else if(type == 'jid-single')
iType = 'email';
input = '<input name="' + encodeQuotes(field) + '" data-type="' + encodeQuotes(type) + '" type="' + iType + '" class="dataform-i" value="' + encodeQuotes(value) + '"' + required + ' />';
}
// Append the HTML markup for this field
$(pathID).append(
'<div class="oneresult ' + target + '-oneresult"' + hideThis + '>' +
'<label>' + label.htmlEnc() + '</label>' +
input +
'</div>'
);
}
});
return false;
}
// Gets the dataform type
function getDataFormType(host, node, id) {
var iq = new JSJaCIQ();
iq.setID(id + '-' + genID());
iq.setTo(host);
iq.setType('get');
var iqQuery = iq.setQuery(NS_DISCO_INFO);
if(node)
iqQuery.setAttribute('node', node);
con.send(iq, handleThisBrowse);
}
// Handles the browse stanza
function handleThisBrowse(iq) {
/* REF: http://xmpp.org/registrar/disco-categories.html */
var id = iq.getID();
var splitted = id.split('-');
var target = splitted[0];
var sessionID = target + '-' + splitted[1];
var from = fullXID(getStanzaFrom(iq));
var hash = hex_md5(from);
var handleXML = iq.getQuery();
var pathID = '#' + target + ' .results[data-session=' + sessionID + ']';
// We first remove the waiting element
$(pathID + ' .disco-wait .' + hash).remove();
if($(handleXML).find('identity').attr('type')) {
var category = $(handleXML).find('identity').attr('category');
var type = $(handleXML).find('identity').attr('type');
var named = $(handleXML).find('identity').attr('name');
if(named)
gName = named;
else
gName = '';
var one, two, three, four, five;
// Get the features that this entity supports
var findFeature = $(handleXML).find('feature');
for(i in findFeature) {
var current = findFeature.eq(i).attr('var');
switch(current) {
case NS_SEARCH:
one = 1;
break;
case NS_MUC:
two = 1;
break;
case NS_REGISTER:
three = 1;
break;
case NS_COMMANDS:
four = 1;
break;
case NS_DISCO_ITEMS:
five = 1;
break;
default:
break;
}
}
var buttons = Array(one, two, three, four, five);
// We define the toolbox links depending on the supported features
var tools = '';
var aTools = Array('search', 'join', 'subscribe', 'command', 'browse');
var bTools = Array(_e("Search"), _e("Join"), _e("Subscribe"), _e("Command"), _e("Browse"));
for(i in buttons) {
if(buttons[i])
tools += '<a href="#" class="one-button ' + aTools[i] + ' talk-images" onclick="return dataForm(\'' + encodeOnclick(from) + '\', \'' + encodeOnclick(aTools[i]) + '\', \'\', \'\', \'' + encodeOnclick(target) + '\');" title="' + encodeOnclick(bTools[i]) + '"></a>';
}
// As defined in the ref, we detect the type of each category to put an icon
switch(category) {
case 'account':
case 'auth':
case 'automation':
case 'client':
case 'collaboration':
case 'component':
case 'conference':
case 'directory':
case 'gateway':
case 'headline':
case 'hierarchy':
case 'proxy':
case 'pubsub':
case 'server':
case 'store':
break;
default:
category = 'others';
}
// We display the item we found
$(pathID + ' .disco-' + category + ' .disco-category-title').after(
'<div class="oneresult ' + target + '-oneresult ' + hash + '">' +
'<div class="one-icon ' + category + ' talk-images"></div>' +
'<div class="one-host">' + from + '</div>' +
'<div class="one-type">' + gName + '</div>' +
'<div class="one-actions">' + tools + '</div>' +
'</div>'
);
// We display the category
$(pathID + ' .disco-' + category).show();
}
else {
$(pathID + ' .disco-others .disco-category-title').after(
'<div class="oneresult ' + target + '-oneresult">' +
'<div class="one-icon down talk-images"></div>' +
'<div class="one-host">' + from + '</div>' +
'<div class="one-type">' + _e("Service offline or broken") + '</div>' +
'</div>'
);
// We display the category
$(pathID + ' .disco-others').show();
}
// We hide the waiting stuffs if there's no remaining loading items
if(!$(pathID + ' .disco-wait .' + target + '-oneresult').size())
$(pathID + ' .disco-wait, #' + target + ' .wait').hide();
}
// Cleans the current data-form popup
function cleanDataForm(target) {
if(target == 'discovery')
cleanDiscovery();
else
$('#' + target + ' div.results').empty();
}
// Displays the no result indicator
function noResultDataForm(path) {
$(path).prepend('<p class="no-results">' + _e("Sorry, but the entity didn't return any result!") + '</p>');
}

View file

@ -0,0 +1,209 @@
/*
Jappix - An open social platform
These are the temporary/persistent data store functions
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 23/06/11
*/
// Temporary: returns whether it is available or not
function hasDB() {
if(window.sessionStorage)
return true;
return false;
}
// Temporary: used to read a database entry
function getDB(type, id) {
try {
return sessionStorage.getItem(type + '_' + id);
}
catch(e) {
logThis('Error while getting a temporary database entry (' + type + ' -> ' + id + '): ' + e, 1);
return null;
}
}
// Temporary: used to update a database entry
function setDB(type, id, value) {
try {
sessionStorage.setItem(type + '_' + id, value);
return true;
}
catch(e) {
logThis('Error while writing a temporary database entry (' + type + ' -> ' + id + '): ' + e, 1);
return false;
}
}
// Temporary: used to remove a database entry
function removeDB(type, id) {
try {
sessionStorage.removeItem(type + '_' + id);
return true;
}
catch(e) {
logThis('Error while removing a temporary database entry (' + type + ' -> ' + id + '): ' + e, 1);
return false;
}
}
// Temporary: used to check a database entry exists
function existDB(type, id) {
var read = getDB(type, id);
if(read != null)
return true;
return false;
}
// Temporary: used to clear all the database
function resetDB() {
try {
sessionStorage.clear();
logThis('Temporary database cleared.', 3);
return true;
}
catch(e) {
logThis('Error while clearing temporary database: ' + e, 1);
return false;
}
}
// Persistent: returns whether it is available or not
function hasPersistent() {
if(window.localStorage)
return true;
return false;
}
// Persistent: used to read a database entry
function getPersistent(type, id) {
try {
return localStorage.getItem(type + '_' + id);
}
catch(e) {
logThis('Error while getting a persistent database entry (' + type + ' -> ' + id + '): ' + e, 1);
return null;
}
}
// Persistent: used to update a database entry
function setPersistent(type, id, value) {
try {
localStorage.setItem(type + '_' + id, value);
return true;
}
// Database might be full
catch(e) {
logThis('Retrying: could not write a persistent database entry (' + type + ' -> ' + id + '): ' + e, 2);
// Flush it!
flushPersistent();
// Set the item again
try {
localStorage.setItem(type + '_' + id, value);
return true;
}
// New error!
catch(e) {
logThis('Aborted: error while writing a persistent database entry (' + type + ' -> ' + id + '): ' + e, 1);
return false;
}
}
}
// Persistent: used to remove a database entry
function removePersistent(type, id) {
try {
localStorage.removeItem(type + '_' + id);
return true;
}
catch(e) {
logThis('Error while removing a persistent database entry (' + type + ' -> ' + id + '): ' + e, 1);
return false;
}
}
// Persistent: used to check a database entry exists
function existPersistent(type, id) {
var read = getPersistent(type, id);
if(read != null)
return true;
return false;
}
// Persistent: used to clear all the database
function resetPersistent() {
try {
localStorage.clear();
logThis('Persistent database cleared.', 3);
return true;
}
catch(e) {
logThis('Error while clearing persistent database: ' + e, 1);
return false;
}
}
// Persistent: used to flush the database
function flushPersistent() {
try {
// Get the stored session entry
var session = getPersistent('session', 1);
// Clear the persistent database
localStorage.clear();
// Restaure the stored session entry
if(session)
setPersistent('session', 1, session);
logThis('Persistent database flushed.', 3);
return true;
}
catch(e) {
logThis('Error while flushing persistent database: ' + e, 1);
return false;
}
}

View file

@ -0,0 +1,212 @@
/*
Jappix - An open social platform
These are the date related JS scripts for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 17/08/11
*/
// Gets a stamp from a date
function extractStamp(date) {
return Math.round(date.getTime() / 1000);
}
// Gets the time from a date
function extractTime(date) {
return date.toLocaleTimeString();
}
// Gets the actual date stamp
function getTimeStamp() {
return extractStamp(new Date());
}
// Gets the last user activity in seconds
var LAST_ACTIVITY = 0;
function getLastActivity() {
// Last activity not yet initialized?
if(LAST_ACTIVITY == 0)
return 0;
return getTimeStamp() - LAST_ACTIVITY;
}
// Gets the last user available presence in seconds
var PRESENCE_LAST_ACTIVITY = 0;
function getPresenceLast() {
// Last presence stamp not yet initialized?
if(PRESENCE_LAST_ACTIVITY == 0)
return 0;
return getTimeStamp() - PRESENCE_LAST_ACTIVITY;
}
// Generates the time for XMPP
function getXMPPTime(location) {
/* FROM : http://trac.jwchat.org/jsjac/browser/branches/jsjac_1.0/jsextras.js?rev=221 */
// Initialize
var jInit = new Date();
var year, month, day, hours, minutes, seconds;
// Gets the UTC date
if(location == 'utc') {
year = jInit.getUTCFullYear();
month = jInit.getUTCMonth();
day = jInit.getUTCDate();
hours = jInit.getUTCHours();
minutes = jInit.getUTCMinutes();
seconds = jInit.getUTCSeconds();
}
// Gets the local date
else {
year = jInit.getFullYear();
month = jInit.getMonth();
day = jInit.getDate();
hours = jInit.getHours();
minutes = jInit.getMinutes();
seconds = jInit.getSeconds();
}
// Generates the date string
var jDate = year + '-';
jDate += padZero(month + 1) + '-';
jDate += padZero(day) + 'T';
jDate += padZero(hours) + ':';
jDate += padZero(minutes) + ':';
jDate += padZero(seconds) + 'Z';
// Returns the date string
return jDate;
}
// Generates then human time
function getCompleteTime() {
var init = new Date();
var time = padZero(init.getHours()) + ':';
time += padZero(init.getMinutes()) + ':';
time += padZero(init.getSeconds());
return time;
}
// Gets the TZO of a date
function getDateTZO() {
// Get the date
var date = new Date();
var offset = date.getTimezoneOffset();
// Default vars
var sign = '';
var hours = 0;
var minutes = 0;
// Process a neutral offset
if(offset < 0) {
offset = offset * -1;
sign = '+';
}
// Get the values
var n_date = new Date(offset * 60 * 1000);
hours = n_date.getHours() - 1;
minutes = n_date.getMinutes();
// Process the TZO
tzo = sign + padZero(hours) + ':' + padZero(minutes);
// Return the processed value
return tzo;
}
// Parses a XMPP date (yyyy-mm-dd, hh-mm-ss) into an human-readable one
function parseDate(to_parse) {
var date = Date.jab2date(to_parse);
var parsed = date.toLocaleDateString() + ' (' + date.toLocaleTimeString() + ')';
return parsed;
}
// Parses a XMPP date (yyyy-mm-dd) into an human-readable one
function parseDay(to_parse) {
var date = Date.jab2date(to_parse);
var parsed = date.toLocaleDateString();
return parsed;
}
// Parses a XMPP date (hh-mm-ss) into an human-readable one
function parseTime(to_parse) {
var date = Date.jab2date(to_parse);
var parsed = date.toLocaleTimeString();
return parsed;
}
// Parses a XMPP date stamp into a relative one
function relativeDate(to_parse) {
// Get the current date
var current_date = Date.jab2date(getXMPPTime('utc'));
var current_day = current_date.getDate();
var current_stamp = current_date.getTime();
// Parse the given date
var old_date = Date.jab2date(to_parse);
var old_day = old_date.getDate();
var old_stamp = old_date.getTime();
var old_time = old_date.toLocaleTimeString();
// Get the day number between the two dates
var days = Math.round((current_stamp - old_stamp) / 86400000);
// Invalid date?
if(isNaN(old_stamp) || isNaN(days))
return getCompleteTime();
// Is it today?
if(current_day == old_day)
return old_time;
// It is yesterday?
if(days <= 1)
return _e("Yesterday") + ' - ' + old_time;
// Is it less than a week ago?
if(days <= 7)
return printf(_e("%s days ago"), days) + ' - ' + old_time;
// Another longer period
return old_date.toLocaleDateString() + ' - ' + old_time;
}
// Reads a message delay
function readMessageDelay(node) {
// Initialize
var delay, d_delay;
// Read the delay
d_delay = jQuery(node).find('delay[xmlns=' + NS_URN_DELAY + ']:first').attr('stamp');
// New delay (valid XEP)
if(d_delay)
delay = d_delay;
// Old delay (obsolete XEP!)
else {
// Try to read the old-school delay
var x_delay = jQuery(node).find('x[xmlns=' + NS_DELAY + ']:first').attr('stamp');
if(x_delay)
delay = x_delay.replace(/^(\w{4})(\w{2})(\w{2})T(\w{2}):(\w{2}):(\w{2})Z?(\S+)?/, '$1-$2-$3T$4:$5:$6Z$7');
}
return delay;
}

View file

@ -0,0 +1,87 @@
/*
Jappix - An open social platform
These are the directory JS scripts for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 03/03/11
*/
// Opens the directory popup
function openDirectory() {
// Popup HTML content
var html =
'<div class="top">' + _e("User directory") + '</div>' +
'<div class="content">' +
'<div class="directory-head">' +
'<div class="directory-server-text">' + _e("Server to query") + '</div>' +
'<input name="directory-server-input" class="directory-server-input" value="' + encodeQuotes(HOST_VJUD) + '" />' +
'</div>' +
'<div class="results directory-results"></div>' +
'</div>' +
'<div class="bottom">' +
'<div class="wait wait-medium"></div>' +
'<a href="#" class="finish">' + _e("Close") + '</a>' +
'</div>';
// Create the popup
createPopup('directory', html);
// Associate the events
launchDirectory();
// Start a search!
startDirectory();
return false;
}
// Quits the directory popup
function closeDirectory() {
// Destroy the popup
destroyPopup('directory');
return false;
}
// Launches a directory search
function startDirectory() {
// Get the server to query
var server = $('#directory .directory-server-input').val();
// Launch the search!
dataForm($('#directory .directory-server-input').val(), 'search', '', '', 'directory');
logThis('Directory search launched: ' + server);
return false;
}
// Plugin launcher
function launchDirectory() {
// Click event
$('#directory .bottom .finish').click(closeDirectory);
// Keyboard event
$('#directory .directory-server-input').keyup(function(e) {
if(e.keyCode == 13) {
// No value?
if(!$(this).val())
$(this).val(HOST_VJUD);
// Start the directory search
startDirectory();
return false;
}
});
}

View file

@ -0,0 +1,169 @@
/*
Jappix - An open social platform
These are the discovery JS scripts for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 03/03/11
*/
// Opens the discovery popup
function openDiscovery() {
// Popup HTML content
var html =
'<div class="top">' + _e("Service discovery") + '</div>' +
'<div class="content">' +
'<div class="discovery-head">' +
'<div class="disco-server-text">' + _e("Server to query") + '</div>' +
'<input name="disco-server-input" class="disco-server-input" value="' + encodeQuotes(HOST_MAIN) + '" />' +
'</div>' +
'<div class="results discovery-results">' +
'<div class="disco-category disco-account">' +
'<p class="disco-category-title">' + _e("Accounts") + '</p>' +
'</div>' +
'<div class="disco-category disco-auth">' +
'<p class="disco-category-title">' + _e("Authentications") + '</p>' +
'</div>' +
'<div class="disco-category disco-automation">' +
'<p class="disco-category-title">' + _e("Automation") + '</p>' +
'</div>' +
'<div class="disco-category disco-client">' +
'<p class="disco-category-title">' + _e("Clients") + '</p>' +
'</div>' +
'<div class="disco-category disco-collaboration">' +
'<p class="disco-category-title">' + _e("Collaboration") + '</p>' +
'</div>' +
'<div class="disco-category disco-component">' +
'<p class="disco-category-title">' + _e("Components") + '</p>' +
'</div>' +
'<div class="disco-category disco-conference">' +
'<p class="disco-category-title">' + _e("Rooms") + '</p>' +
'</div>' +
'<div class="disco-category disco-directory">' +
'<p class="disco-category-title">' + _e("Directories") + '</p>' +
'</div>' +
'<div class="disco-category disco-gateway">' +
'<p class="disco-category-title">' + _e("Gateways") + '</p>' +
'</div>' +
'<div class="disco-category disco-headline">' +
'<p class="disco-category-title">' + _e("News") + '</p>' +
'</div>' +
'<div class="disco-category disco-hierarchy">' +
'<p class="disco-category-title">' + _e("Hierarchy") + '</p>' +
'</div>' +
'<div class="disco-category disco-proxy">' +
'<p class="disco-category-title">' + _e("Proxies") + '</p>' +
'</div>' +
'<div class="disco-category disco-pubsub">' +
'<p class="disco-category-title">' + _e("Publication/Subscription") + '</p>' +
'</div>' +
'<div class="disco-category disco-server">' +
'<p class="disco-category-title">' + _e("Server") + '</p>' +
'</div>' +
'<div class="disco-category disco-store">' +
'<p class="disco-category-title">' + _e("Storage") + '</p>' +
'</div>' +
'<div class="disco-category disco-others">' +
'<p class="disco-category-title">' + _e("Others") + '</p>' +
'</div>' +
'<div class="disco-category disco-wait">' +
'<p class="disco-category-title">' + _e("Loading") + '</p>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="bottom">' +
'<div class="wait wait-medium"></div>' +
'<a href="#" class="finish">' + _e("Close") + '</a>' +
'</div>';
// Create the popup
createPopup('discovery', html);
// Associate the events
launchDiscovery();
// We request a disco to the default server
startDiscovery();
return false;
}
// Quits the discovery popup
function closeDiscovery() {
// Destroy the popup
destroyPopup('discovery');
return false;
}
// Launches a discovery
function startDiscovery() {
/* REF: http://xmpp.org/extensions/xep-0030.html */
// We get the server to query
var discoServer = $('#discovery .disco-server-input').val();
// We launch the items query
dataForm(discoServer, 'browse', '', '', 'discovery');
logThis('Service discovery launched: ' + discoServer);
return false;
}
// Cleans the discovery results
function cleanDiscovery() {
// We remove the results
$('#discovery .discovery-oneresult, #discovery .oneinstructions, #discovery .onetitle, #discovery .no-results').remove();
// We clean the user info
$('#discovery .disco-server-info').text('');
// We hide the wait icon, the no result alert and the results
$('#discovery .wait, #discovery .disco-category').hide();
}
// Plugin launcher
function launchDiscovery() {
// Click event
$('#discovery .bottom .finish').click(closeDiscovery);
// Keyboard event
$('#discovery .disco-server-input').keyup(function(e) {
if(e.keyCode == 13) {
// No value?
if(!$(this).val())
$(this).val(HOST_MAIN);
// Start the discovery
startDiscovery();
return false;
}
});
}

View file

@ -0,0 +1,139 @@
/*
Jappix - An open social platform
These are the error functions for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 02/04/11
*/
// Shows the given error output
function showError(condition, reason, type) {
// Enough data to output the error
if(condition || reason) {
// Initialize the error text
var eText = '';
// Any error condition
if(condition)
eText += condition;
// Any error type
if(type && eText)
eText += ' (' + type + ')';
// Any error reason
if(reason) {
if(eText)
eText += ' - ';
eText += reason;
}
// We reveal the error
openThisError(1);
// Create the error text
$('#board .one-board.error[data-id=1] span').text(eText);
}
// Not enough data to output the error: output a generic board
else
openThisError(2);
}
// Handles the error from a packet and return true if any error
function handleError(packet) {
/* REF: http://xmpp.org/extensions/xep-0086.html */
// Initialize
var type, code, reason, condition;
var node = $(packet);
// First level error (connection error)
if(node.is('error')) {
// Get the value
code = node.attr('code');
// Specific error reason
switch(code) {
case '401':
reason = _e("Authorization failed");
break;
case '409':
reason = _e("Registration failed, please choose a different username");
break;
case '503':
reason = _e("Service unavailable");
break;
case '500':
reason = _e("Internal server error, try later");
break;
default:
reason = node.find('text').text();
break;
}
// Remove the general wait item (security)
removeGeneralWait();
// Show reconnect pane
if(CURRENT_SESSION && CONNECTED) {
// Anonymous?
if(isAnonymous())
createReconnect('anonymous');
else
createReconnect('normal');
}
// Show the homepage (security)
else if(!CURRENT_SESSION || !CONNECTED) {
$('#home').show();
pageTitle('home');
}
// Still connected? (security)
if(isConnected())
con.disconnect();
logThis('First level error received.', 1);
}
// Second level error (another error)
else if(node.find('error').size()) {
type = node.find('error').attr('type');
reason = node.find('error text').text();
condition = packet.getElementsByTagName('error').item(0).childNodes.item(0).nodeName.replace(/-/g, ' ');
logThis('Second level error received.', 1);
}
// No error
else
return false;
// Show the error board
showError(condition, reason, type);
// Return there's an error
return true;
}
// Handles the error reply of a packet
function handleErrorReply(packet) {
return handleError(packet.getNode());
}
// Handles the error reply for a message
function handleMessageError(packet) {
if(!handleErrorReply(packet))
handleMessage(packet);
}

View file

@ -0,0 +1,537 @@
/*
Jappix - An open social platform
These are the favorites JS scripts for Jappix
-------------------------------------------------
License: AGPL
Author: Vanaryon
Last revision: 23/06/11
*/
// Opens the favorites popup
function openFavorites() {
// Popup HTML content
var html =
'<div class="top">' + _e("Manage favorite rooms") + '</div>' +
'<div class="content">' +
'<div class="switch-fav">' +
'<div class="room-switcher room-list">' +
'<div class="icon list-icon talk-images"></div>' +
_e("Change favorites") +
'</div>' +
'<div class="room-switcher room-search">' +
'<div class="icon search-icon talk-images"></div>' +
_e("Search a room") +
'</div>' +
'</div>' +
'<div class="static-fav">' +
'<div class="favorites-edit favorites-content">' +
'<div class="head fedit-head static-fav-head">' +
'<div class="head-text fedit-head-text">' + _e("Select a favorite") + '</div>' +
'<select name="fedit-head-select" class="head-select fedit-head-select"></select>' +
'</div>' +
'<div class="results fedit-results static-fav-results">' +
'<div class="fedit-line">' +
'<label>' + _e("Name") + '</label>' +
'<input class="fedit-title" type="text" required="" />' +
'</div>' +
'<div class="fedit-line">' +
'<label>' + _e("Nickname") + '</label>' +
'<input class="fedit-nick" type="text" value="' + getNick() + '" required="" />' +
'</div>' +
'<div class="fedit-line">' +
'<label>' + _e("Room") + '</label>' +
'<input class="fedit-chan" type="text" required="" />' +
'</div>' +
'<div class="fedit-line">' +
'<label>' + _e("Server") + '</label>' +
'<input class="fedit-server" type="text" value="' + HOST_MUC + '" required="" />' +
'</div>' +
'<div class="fedit-line">' +
'<label>' + _e("Password") + '</label>' +
'<input class="fedit-password" type="password" />' +
'</div>' +
'<div class="fedit-line">' +
'<label>' + _e("Automatic") + '</label>' +
'<input type="checkbox" class="fedit-autojoin" />' +
'</div>' +
'<div class="fedit-actions">' +
'<a href="#" class="fedit-terminate fedit-add add one-button talk-images">' + _e("Add") + '</a>' +
'<a href="#" class="fedit-terminate fedit-edit one-button talk-images">' + _e("Edit") + '</a>' +
'<a href="#" class="fedit-terminate fedit-remove remove one-button talk-images">' + _e("Remove") + '</a>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="favorites-search favorites-content">' +
'<div class="head fsearch-head static-fav-head">' +
'<div class="head-text fsearch-head-text">' + _e("Search a room on") + '</div>' +
'<input type="text" class="head-input fsearch-head-server" value="' + HOST_MUC + '" />' +
'</div>' +
'<div class="results fsearch-results static-fav-results">' +
'<p class="fsearch-noresults">' + _e("No room found on this server.") + '</p>' +
'</div>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="bottom">' +
'<div class="wait wait-medium"></div>' +
'<a href="#" class="finish">' + _e("Close") + '</a>' +
'</div>';
// Create the popup
createPopup('favorites', html);
// Load the favorites
loadFavorites();
// Associate the events
launchFavorites();
}
// Resets the favorites elements
function resetFavorites() {
var path = '#favorites ';
$(path + '.wait, ' + path + '.fedit-terminate').hide();
$(path + '.fedit-add').show();
$(path + '.fsearch-oneresult').remove();
$(path + 'input').val('');
$(path + '.please-complete').removeClass('please-complete');
$(path + '.fedit-nick').val(getNick());
$(path + '.fsearch-head-server, ' + path + '.fedit-server').val(HOST_MUC);
$(path + '.fedit-autojoin').attr('checked', false);
}
// Quits the favorites popup
function quitFavorites() {
// Destroy the popup
destroyPopup('favorites');
return false;
}
// Adds a room to the favorites
function addThisFavorite(roomXID, roomName) {
// Button path
var button = '#favorites .fsearch-results div[data-xid=' + escape(roomXID) + '] a.one-button';
// Add a remove button instead of the add one
$(button + '.add').replaceWith('<a href="#" class="one-button remove talk-images">' + _e("Remove") + '</a>');
// Click event
$(button + '.remove').click(function() {
return removeThisFavorite(roomXID, roomName);
});
// Hide the add button in the (opened?) groupchat
$('#' + hex_md5(roomXID) + ' .tools-add').hide();
// Add the database entry
displayFavorites(roomXID, explodeThis(' (', roomName, 0), getNick(), '0', '');
// Publish the favorites
favoritePublish();
return false;
}
// Removes a room from the favorites
function removeThisFavorite(roomXID, roomName) {
// Button path
var button = '#favorites .fsearch-results div[data-xid=' + escape(roomXID) + '] a.one-button';
// Add a remove button instead of the add one
$(button + '.remove').replaceWith('<a href="#" class="one-button add talk-images">' + _e("Add") + '</a>');
// Click event
$(button + '.add').click(function() {
return addThisFavorite(roomXID, roomName);
});
// Show the add button in the (opened?) groupchat
$('#' + hex_md5(roomXID) + ' .tools-add').show();
// Remove the favorite
removeFavorite(roomXID, true);
// Publish the favorites
favoritePublish();
return false;
}
// Edits a favorite
function editFavorite() {
// Path to favorites
var favorites = '#favorites .';
// Reset the favorites
resetFavorites();
// Show the edit/remove button, hide the others
$(favorites + 'fedit-terminate').hide();
$(favorites + 'fedit-edit').show();
$(favorites + 'fedit-remove').show();
// We retrieve the values
var xid = $(favorites + 'fedit-head-select').val();
var data = XMLFromString(getDB('favorites', xid));
// If this is not the default room
if(xid != 'none') {
// We apply the values
$(favorites + 'fedit-title').val($(data).find('name').text());
$(favorites + 'fedit-nick').val($(data).find('nick').text());
$(favorites + 'fedit-chan').val(getXIDNick(xid));
$(favorites + 'fedit-server').val(getXIDHost(xid));
$(favorites + 'fedit-password').val($(data).find('password').text());
if($(data).find('autojoin').text() == '1')
$(favorites + 'fedit-autojoin').attr('checked', true);
}
else
resetFavorites();
}
// Adds a favorite
function addFavorite() {
// Path to favorites
var favorites = '#favorites .';
// We reset the inputs
$(favorites + 'fedit-title, ' + favorites + 'fedit-nick, ' + favorites + 'fedit-chan, ' + favorites + 'fedit-server, ' + favorites + 'fedit-password').val('');
// Show the add button, hide the others
$(favorites + 'fedit-terminate').hide();
$(favorites + 'fedit-add').show();
}
// Terminate a favorite editing
function terminateThisFavorite(type) {
// Path to favorites
var favorites = '#favorites ';
// We get the values of the current edited groupchat
var old_xid = $(favorites + '.fedit-head-select').val();
var title = $(favorites + '.fedit-title').val();
var nick = $(favorites + '.fedit-nick').val();
var room = $(favorites + '.fedit-chan').val();
var server = $(favorites + '.fedit-server').val();
var xid = room + '@' + server;
var password = $(favorites + '.fedit-password').val();
var autojoin = '0';
if($(favorites + '.fedit-autojoin').filter(':checked').size())
autojoin = '1';
// We check the missing values and send this if okay
if((type == 'add') || (type == 'edit')) {
if(title && nick && room && server) {
// Remove the edited room
if(type == 'edit')
removeFavorite(old_xid, true);
// Display the favorites
displayFavorites(xid, title, nick, autojoin, password);
// Reset the inputs
resetFavorites();
}
else {
$(favorites + 'input[required]').each(function() {
var select = $(this);
if(!select.val())
$(document).oneTime(10, function() {
select.addClass('please-complete').focus();
});
else
select.removeClass('please-complete');
});
}
}
// Must remove a favorite?
else if(type == 'remove') {
removeFavorite(old_xid, true);
// Reset the inputs
resetFavorites();
}
// Publish the new favorites
favoritePublish();
logThis('Action on this bookmark: ' + room + '@' + server + ' / ' + type, 3);
return false;
}
// Removes a favorite
function removeFavorite(xid, database) {
// We remove the target favorite everywhere needed
$('.buddy-conf-groupchat-select option[value=' + xid + ']').remove();
$('.fedit-head-select option[value=' + xid + ']').remove();
// Must remove it from database?
if(database)
removeDB('favorites', xid);
}
// Sends a favorite to the XMPP server
function favoritePublish() {
var iq = new JSJaCIQ();
iq.setType('set');
var query = iq.setQuery(NS_PRIVATE);
var storage = query.appendChild(iq.buildNode('storage', {'xmlns': NS_BOOKMARKS}));
// We generate the XML
for(var i = 0; i < sessionStorage.length; i++) {
// Get the pointer values
var current = sessionStorage.key(i);
// If the pointer is on a stored favorite
if(explodeThis('_', current, 0) == 'favorites') {
var data = XMLFromString(sessionStorage.getItem(current));
var xid = $(data).find('xid').text();
var rName = $(data).find('name').text();
var nick = $(data).find('nick').text();
var password = $(data).find('password').text();
var autojoin = $(data).find('autojoin').text();
// We create the node for this groupchat
var item = storage.appendChild(iq.buildNode('conference', {'name': rName, 'jid': xid, 'autojoin': autojoin, xmlns: NS_BOOKMARKS}));
item.appendChild(iq.buildNode('nick', {xmlns: NS_BOOKMARKS}, nick));
if(password)
item.appendChild(iq.buildNode('password', {xmlns: NS_BOOKMARKS}, password));
logThis('Bookmark sent: ' + xid, 3);
}
}
con.send(iq);
}
// Gets a list of the MUC items on a given server
function getGCList() {
var path = '#favorites .';
var gcServer = $('.fsearch-head-server').val();
// We reset some things
$(path + 'fsearch-oneresult').remove();
$(path + 'fsearch-noresults').hide();
$(path + 'wait').show();
var iq = new JSJaCIQ();
iq.setType('get');
iq.setTo(gcServer);
iq.setQuery(NS_DISCO_ITEMS);
con.send(iq, handleGCList);
}
// Handles the MUC items list
function handleGCList(iq) {
var path = '#favorites .';
var from = fullXID(getStanzaFrom(iq));
if (!iq || (iq.getType() != 'result')) {
openThisError(3);
$(path + 'wait').hide();
logThis('Error while retrieving the rooms: ' + from, 1);
}
else {
var handleXML = iq.getQuery();
if($(handleXML).find('item').size()) {
// Initialize the HTML code
var html = '';
$(handleXML).find('item').each(function() {
var roomXID = $(this).attr('jid');
var roomName = $(this).attr('name');
if(roomXID && roomName) {
// Escaped values
var escaped_xid = encodeOnclick(roomXID);
var escaped_name = encodeOnclick(roomName);
// Initialize the room HTML
html += '<div class="oneresult fsearch-oneresult" data-xid="' + escape(roomXID) + '">' +
'<div class="room-name">' + roomName.htmlEnc() + '</div>' +
'<a href="#" class="one-button join talk-images" onclick="return joinFavorite(\'' + escaped_xid + '\');">' + _e("Join") + '</a>';
// This room is yet a favorite
if(existDB('favorites', roomXID))
html += '<a href="#" class="one-button remove talk-images" onclick="return removeThisFavorite(\'' + escaped_xid + '\', \'' + escaped_name + '\');">' + _e("Remove") + '</a>';
else
html += '<a href="#" class="one-button add talk-images" onclick="return addThisFavorite(\'' + escaped_xid + '\', \'' + escaped_name + '\');">' + _e("Add") + '</a>';
// Close the room HTML
html += '</div>';
}
});
// Append this code to the popup
$(path + 'fsearch-results').append(html);
}
else
$(path + 'fsearch-noresults').show();
logThis('Rooms retrieved: ' + from, 3);
}
$(path + 'wait').hide();
}
// Joins a groupchat from favorites
function joinFavorite(room) {
quitFavorites();
checkChatCreate(room, 'groupchat', '', '', getXIDNick(room));
return false;
}
// Displays a given favorite
function displayFavorites(xid, name, nick, autojoin, password) {
// Generate the HTML code
var html = '<option value="' + encodeQuotes(xid) + '">' + name.htmlEnc() + '</option>';
// Remove the existing favorite
removeFavorite(xid, false);
// We complete the select forms
$('#buddy-list .gc-join-first-option, #favorites .fedit-head-select-first-option').after(html);
// We store the informations
var value = '<groupchat><xid>' + xid.htmlEnc() + '</xid><name>' + name.htmlEnc() + '</name><nick>' + nick.htmlEnc() + '</nick><autojoin>' + autojoin.htmlEnc() + '</autojoin><password>' + password.htmlEnc() + '</password></groupchat>';
setDB('favorites', xid, value);
}
// Loads the favorites for the popup
function loadFavorites() {
// Initialize the HTML code
var html = '';
// Read the database
for(var i = 0; i < sessionStorage.length; i++) {
// Get the pointer values
var current = sessionStorage.key(i);
// If the pointer is on a stored favorite
if(explodeThis('_', current, 0) == 'favorites') {
var data = XMLFromString(sessionStorage.getItem(current));
// Add the current favorite to the HTML code
html += '<option value="' + encodeQuotes($(data).find('xid').text()) + '">' + $(data).find('name').text().htmlEnc() + '</option>';
}
}
// Generate specific HTML code
var favorites_bubble = '<option value="none" class="gc-join-first-option" selected="">' + _e("Select a favorite") + '</option>' + html;
var favorites_popup = '<option value="none" class="fedit-head-select-first-option" selected="">' + _e("Select a favorite") + '</option>' + html;
// Append the HTML code
$('#buddy-list .buddy-conf-groupchat-select').html(favorites_bubble);
$('#favorites .fedit-head-select').html(favorites_popup);
}
// Plugin launcher
function launchFavorites() {
var path = '#favorites .';
// Keyboard events
$(path + 'fsearch-head-server').keyup(function(e) {
if(e.keyCode == 13) {
// No value?
if(!$(this).val())
$(this).val(HOST_MUC);
// Get the list
getGCList();
}
});
$(path + 'fedit-line input').keyup(function(e) {
if(e.keyCode == 13) {
// Edit a favorite
if($(path + 'fedit-edit').is(':visible'))
terminateThisFavorite('edit');
// Add a favorite
else
terminateThisFavorite('add');
}
});
// Change events
$('.fedit-head-select').change(editFavorite);
// Click events
$(path + 'room-switcher').click(function() {
$(path + 'favorites-content').hide();
resetFavorites();
});
$(path + 'room-list').click(function() {
$(path + 'favorites-edit').show();
});
$(path + 'room-search').click(function() {
$(path + 'favorites-search').show();
getGCList();
});
$(path + 'fedit-add').click(function() {
return terminateThisFavorite('add');
});
$(path + 'fedit-edit').click(function() {
return terminateThisFavorite('edit');
});
$(path + 'fedit-remove').click(function() {
return terminateThisFavorite('remove');
});
$(path + 'bottom .finish').click(function() {
return quitFavorites();
});
}

Some files were not shown because too many files have changed in this diff Show more