aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG4
-rw-r--r--Zotlabs/Lib/ActivityStreams.php43
-rw-r--r--Zotlabs/Lib/LDSignatures.php117
-rw-r--r--Zotlabs/Lib/ThreadItem.php6
-rw-r--r--Zotlabs/Module/Acl.php7
-rw-r--r--Zotlabs/Module/Display.php13
-rw-r--r--Zotlabs/Module/Item.php11
-rw-r--r--Zotlabs/Module/Oep.php2
-rw-r--r--Zotlabs/Module/Rpost.php41
-rw-r--r--Zotlabs/Module/Xrd.php2
-rw-r--r--Zotlabs/Web/CheckJS.php6
-rw-r--r--Zotlabs/Widget/Categories.php2
-rwxr-xr-xboot.php4
-rw-r--r--include/bbcode.php3
-rw-r--r--include/photos.php2
-rw-r--r--include/text.php13
-rw-r--r--view/css/conversation.css15
-rw-r--r--view/js/main.js79
-rw-r--r--view/js/mod_cards.js6
-rw-r--r--view/theme/redbasic/css/style.css7
-rwxr-xr-xview/tpl/comment_item.tpl2
-rwxr-xr-xview/tpl/conv_frame.tpl1
-rwxr-xr-xview/tpl/threaded_conversation.tpl3
23 files changed, 305 insertions, 84 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 53c23d539..f96f83b09 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+Hubzilla 2.6.2 (2017-08-31)
+ - Fix webfinger returns invalid XML (github issue #851)
+
+
Hubzilla 2.6.1 (2017-08-18)
- Fix a regression with dav clients
- Raise install requirements
diff --git a/Zotlabs/Lib/ActivityStreams.php b/Zotlabs/Lib/ActivityStreams.php
index 3bbe3b190..686f4a140 100644
--- a/Zotlabs/Lib/ActivityStreams.php
+++ b/Zotlabs/Lib/ActivityStreams.php
@@ -14,6 +14,8 @@ class ActivityStreams {
public $origin = null;
public $owner = null;
+ public $recips = null;
+
function __construct($string) {
$this->data = json_decode($string,true);
@@ -28,7 +30,7 @@ class ActivityStreams {
$this->obj = $this->get_compound_property('object');
$this->tgt = $this->get_compound_property('target');
$this->origin = $this->get_compound_property('origin');
- $this->owner = $this->get_compound_property('owner','','http://purl.org/zot/protocol');
+ $this->recips = $this->collect_recips();
if(($this->type === 'Note') && (! $this->obj)) {
$this->obj = $this->data;
@@ -41,6 +43,45 @@ class ActivityStreams {
return $this->valid;
}
+ function collect_recips($base = '',$namespace = 'https://www.w3.org/ns/activitystreams') {
+ $x = [];
+ $fields = [ 'to','cc','bto','bcc','audience'];
+ foreach($fields as $f) {
+ $y = $this->get_compound_property($f,$base,$namespace);
+ if($y)
+ $x = array_merge($x,$y);
+ }
+// not yet ready for prime time
+// $x = $this->expand($x,$base,$namespace);
+ return $x;
+ }
+
+ function expand($arr,$base = '',$namespace = 'https://www.w3.org/ns/activitystreams') {
+ $ret = [];
+
+ // right now use a hardwired recursion depth of 5
+
+ for($z = 0; $z < 5; $z ++) {
+ if(is_array($arr) && $arr) {
+ foreach($arr as $a) {
+ if(is_array($a)) {
+ $ret[] = $a;
+ }
+ else {
+ $x = $this->get_compound_property($a,$base,$namespace);
+ if($x) {
+ $ret = array_merge($ret,$x);
+ }
+ }
+ }
+ }
+ }
+
+ // @fixme de-duplicate
+
+ return $ret;
+ }
+
function get_namespace($base,$namespace) {
$key = null;
diff --git a/Zotlabs/Lib/LDSignatures.php b/Zotlabs/Lib/LDSignatures.php
new file mode 100644
index 000000000..88dfe80c0
--- /dev/null
+++ b/Zotlabs/Lib/LDSignatures.php
@@ -0,0 +1,117 @@
+<?php
+
+namespace Zotlabs\Lib;
+
+require_once('library/jsonld/jsonld.php');
+
+class LDSignatures {
+
+
+ static function verify($data,$pubkey) {
+
+ $ohash = self::hash(self::signable_options($data['signature']));
+ $dhash = self::hash(self::signable_data($data));
+
+ return rsa_verify($ohash . $dhash,base64_decode($data['signature']['signatureValue']), $pubkey);
+ }
+
+ static function dopplesign(&$data,$channel) {
+ $data['magicEnv'] = self::salmon_sign($data,$channel);
+ return self::sign($data,$channel);
+ }
+
+ static function sign($data,$channel) {
+ $options = [
+ 'type' => 'RsaSignature2017',
+ 'nonce' => random_string(64),
+ 'creator' => z_root() . '/channel/' . $channel['channel_address'] . '/public_key_pem',
+ 'created' => datetime_convert('UTC','UTC', 'now', 'Y-m-d\Th:i:s\Z')
+ ];
+
+ $ohash = self::hash(self::signable_options($options));
+ $dhash = self::hash(self::signable_data($data));
+ $options['signatureValue'] = base64_encode(rsa_sign($ohash . $dhash,$channel['channel_prvkey']));
+
+ $signed = array_merge([
+ '@context' => [ 'https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1' ],
+ ],$options);
+
+ return $signed;
+ }
+
+
+ static function signable_data($data) {
+
+ $newdata = [];
+ if($data) {
+ foreach($data as $k => $v) {
+ if(! in_array($k,[ 'signature' ])) {
+ $newopts[$k] = $v;
+ }
+ }
+ }
+ return json_encode($newdata,JSON_UNESCAPED_SLASHES);
+ }
+
+
+ static function signable_options($options) {
+
+ $newopts = [ '@context' => 'https://w3id.org/identity/v1' ];
+ if($options) {
+ foreach($options as $k => $v) {
+ if(! in_array($k,[ 'type','id','signatureValue' ])) {
+ $newopts[$k] = $v;
+ }
+ }
+ }
+ return json_encode($newopts,JSON_UNESCAPED_SLASHES);
+ }
+
+ static function hash($obj) {
+ return hash('sha256',self::normalise($obj));
+ }
+
+ static function normalise($data) {
+ if(is_string($data)) {
+ $data = json_decode($data);
+ }
+
+ if(! is_object($data))
+ return '';
+
+ return jsonld_normalize($data,[ 'algorithm' => 'URDNA2015', 'format' => 'application/nquads' ]);
+ }
+
+ static function salmon_sign($data,$channel) {
+
+ $arr = $data;
+ $data = json_encode($data,JSON_UNESCAPED_SLASHES);
+ $data = base64url_encode($data, false); // do not strip padding
+ $data_type = 'application/activity+json';
+ $encoding = 'base64url';
+ $algorithm = 'RSA-SHA256';
+ $keyhash = base64url_encode(z_root() . '/channel/' . $channel['channel_address']);
+
+ $data = str_replace(array(" ","\t","\r","\n"),array("","","",""),$data);
+
+ // precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
+
+ $precomputed = '.' . base64url_encode($data_type,false) . '.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
+
+ $signature = base64url_encode(rsa_sign($data . $precomputed,$channel['channel_prvkey']));
+
+ return ([
+ 'id' => $arr['id'],
+ 'meData' => $data,
+ 'meDataType' => $data_type,
+ 'meEncoding' => $encoding,
+ 'meAlgorithm' => $algorithm,
+ 'meCreator' => z_root() . '/channel/' . $channel['channel_address'] . '/public_key_pem',
+ 'meSignatureValue' => $signature
+ ]);
+
+ }
+
+
+
+} \ No newline at end of file
diff --git a/Zotlabs/Lib/ThreadItem.php b/Zotlabs/Lib/ThreadItem.php
index 313001cc7..f9565d339 100644
--- a/Zotlabs/Lib/ThreadItem.php
+++ b/Zotlabs/Lib/ThreadItem.php
@@ -758,9 +758,9 @@ class ThreadItem {
'$sourceapp' => \App::$sourcename,
'$observer' => get_observer_hash(),
'$anoncomments' => (($conv->get_mode() === 'channel' && perm_is_allowed($conv->get_profile_owner(),'','post_comments')) ? true : false),
- '$anonname' => [ 'anonname', t('Your full name (required)'),'','','','onBlur="commentCloseUI(this,\'' . $this->get_id() . '\')"' ],
- '$anonmail' => [ 'anonmail', t('Your email address (required)'),'','','','onBlur="commentCloseUI(this,\'' . $this->get_id() . '\')"' ],
- '$anonurl' => [ 'anonurl', t('Your website URL (optional)'),'','','','onBlur="commentCloseUI(this,\'' . $this->get_id() . '\')"' ]
+ '$anonname' => [ 'anonname', t('Your full name (required)') ],
+ '$anonmail' => [ 'anonmail', t('Your email address (required)') ],
+ '$anonurl' => [ 'anonurl', t('Your website URL (optional)') ]
));
return $comment_box;
diff --git a/Zotlabs/Module/Acl.php b/Zotlabs/Module/Acl.php
index 83fafbdff..4d7654f3d 100644
--- a/Zotlabs/Module/Acl.php
+++ b/Zotlabs/Module/Acl.php
@@ -324,11 +324,12 @@ class Acl extends \Zotlabs\Web\Controller {
$r = array();
if($r) {
- foreach($r as $g){
+ foreach($r as $g) {
- // remove RSS feeds from ACLs - they are inaccessible
- if(strpos($g['hash'],'/') && $type != 'a')
+ if(($g['network'] === 'rss') && ($type != 'a'))
continue;
+
+ $g['hash'] = urlencode($g['hash']);
if(in_array($g['hash'],$permitted) && $type == 'c' && (! $noforums)) {
$contacts[] = array(
diff --git a/Zotlabs/Module/Display.php b/Zotlabs/Module/Display.php
index b698513ba..66a09b983 100644
--- a/Zotlabs/Module/Display.php
+++ b/Zotlabs/Module/Display.php
@@ -76,7 +76,6 @@ class Display extends \Zotlabs\Web\Controller {
$o = '<div id="jot-popup">';
$o .= status_editor($a,$x);
$o .= '</div>';
-
}
// This page can be viewed by anybody so the query could be complicated
@@ -181,6 +180,7 @@ class Display extends \Zotlabs\Web\Controller {
'href' => z_root() . '/oep?f=&url=' . urlencode(z_root() . '/' . \App::$query_string),
'title' => 'oembed'
]);
+
}
$observer_hash = get_observer_hash();
@@ -190,7 +190,6 @@ class Display extends \Zotlabs\Web\Controller {
if(($update && $load) || ($checkjs->disabled())) {
-
$pager_sql = sprintf(" LIMIT %d OFFSET %d ", intval(\App::$pager['itemspage']),intval(\App::$pager['start']));
if($load || ($checkjs->disabled())) {
@@ -224,7 +223,6 @@ class Display extends \Zotlabs\Web\Controller {
if(! perm_is_allowed($sysid,$observer_hash,'view_stream'))
$sysid = 0;
-
$r = q("SELECT item.id as item_id from item
WHERE mid = '%s'
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
@@ -237,7 +235,6 @@ class Display extends \Zotlabs\Web\Controller {
dbesc($target_item['parent_mid']),
intval($sysid)
);
-
}
}
}
@@ -250,6 +247,7 @@ class Display extends \Zotlabs\Web\Controller {
$sysid = $sys['channel_id'];
if(local_channel()) {
+
$r = q("SELECT item.parent AS item_id from item
WHERE uid = %d
and parent_mid = '%s'
@@ -269,12 +267,12 @@ class Display extends \Zotlabs\Web\Controller {
// make that content unsearchable by ensuring the owner_xchan can't match
if(! perm_is_allowed($sysid,$observer_hash,'view_stream'))
$sysid = 0;
-
+
$r = q("SELECT item.parent AS item_id from item
WHERE parent_mid = '%s'
AND (((( item.allow_cid = '' AND item.allow_gid = '' AND item.deny_cid = ''
AND item.deny_gid = '' AND item_private = 0 )
- and owner_xchan in ( " . stream_perms_xchans(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
+ and uid in ( " . stream_perms_api_uids(($observer_hash) ? (PERMS_NETWORK|PERMS_PUBLIC) : PERMS_PUBLIC) . " ))
OR uid = %d )
$sql_extra )
$item_normal
@@ -292,7 +290,7 @@ class Display extends \Zotlabs\Web\Controller {
}
if($r) {
-
+
$parents_str = ids_to_querystr($r,'item_id');
if($parents_str) {
@@ -310,7 +308,6 @@ class Display extends \Zotlabs\Web\Controller {
$items = array();
}
-
if ($checkjs->disabled()) {
$o .= conversation($items, 'display', $update, 'traditional');
if ($items[0]['title'])
diff --git a/Zotlabs/Module/Item.php b/Zotlabs/Module/Item.php
index a86106b6a..3e023ae8b 100644
--- a/Zotlabs/Module/Item.php
+++ b/Zotlabs/Module/Item.php
@@ -659,14 +659,23 @@ class Item extends \Zotlabs\Web\Controller {
// BBCODE end alert
if(strlen($categories)) {
+
$cats = explode(',',$categories);
foreach($cats as $cat) {
+
+ if($webpage == ITEM_TYPE_CARD) {
+ $catlink = z_root() . '/cards/' . $channel['channel_address'] . '?f=&cat=' . urlencode(trim($cat));
+ }
+ else {
+ $catlink = $owner_xchan['xchan_url'] . '?f=&cat=' . urlencode(trim($cat));
+ }
+
$post_tags[] = array(
'uid' => $profile_uid,
'ttype' => TERM_CATEGORY,
'otype' => TERM_OBJ_POST,
'term' => trim($cat),
- 'url' => $owner_xchan['xchan_url'] . '?f=&cat=' . urlencode(trim($cat))
+ 'url' => $catlink
);
}
}
diff --git a/Zotlabs/Module/Oep.php b/Zotlabs/Module/Oep.php
index 02aa4aba9..9a1317142 100644
--- a/Zotlabs/Module/Oep.php
+++ b/Zotlabs/Module/Oep.php
@@ -1,6 +1,8 @@
<?php
namespace Zotlabs\Module;
+require_once('include/security.php');
+
// oembed provider
diff --git a/Zotlabs/Module/Rpost.php b/Zotlabs/Module/Rpost.php
index 731eab82e..56f4f23f6 100644
--- a/Zotlabs/Module/Rpost.php
+++ b/Zotlabs/Module/Rpost.php
@@ -90,8 +90,6 @@ class Rpost extends \Zotlabs\Web\Controller {
}
$plaintext = true;
- // if(feature_enabled(local_channel(),'richtext'))
- // $plaintext = false;
if(array_key_exists('type', $_REQUEST) && $_REQUEST['type'] === 'html') {
require_once('include/html2bbcode.php');
@@ -112,26 +110,25 @@ class Rpost extends \Zotlabs\Web\Controller {
}
$x = array(
- 'is_owner' => true,
- 'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''),
- 'default_location' => $channel['channel_location'],
- 'nickname' => $channel['channel_address'],
- 'lockstate' => (($acl->is_private()) ? 'lock' : 'unlock'),
- 'acl' => populate_acl($channel_acl, true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
- 'permissions' => $channel_acl,
- 'bang' => '',
- 'visitor' => true,
- 'profile_uid' => local_channel(),
- 'title' => $_REQUEST['title'],
- 'body' => $_REQUEST['body'],
- 'attachment' => $_REQUEST['attachment'],
- 'source' => ((x($_REQUEST,'source')) ? strip_tags($_REQUEST['source']) : ''),
- 'return_path' => 'rpost/return',
- 'bbco_autocomplete' => 'bbcode',
- 'editor_autocomplete'=> true,
- 'bbcode' => true,
- 'jotnets' => true
-
+ 'is_owner' => true,
+ 'allow_location' => ((intval(get_pconfig($channel['channel_id'],'system','use_browser_location'))) ? '1' : ''),
+ 'default_location' => $channel['channel_location'],
+ 'nickname' => $channel['channel_address'],
+ 'lockstate' => (($acl->is_private()) ? 'lock' : 'unlock'),
+ 'acl' => populate_acl($channel_acl, true, \Zotlabs\Lib\PermissionDescription::fromGlobalPermission('view_stream'), get_post_aclDialogDescription(), 'acl_dialog_post'),
+ 'permissions' => $channel_acl,
+ 'bang' => '',
+ 'visitor' => true,
+ 'profile_uid' => local_channel(),
+ 'title' => $_REQUEST['title'],
+ 'body' => $_REQUEST['body'],
+ 'attachment' => $_REQUEST['attachment'],
+ 'source' => ((x($_REQUEST,'source')) ? strip_tags($_REQUEST['source']) : ''),
+ 'return_path' => 'rpost/return',
+ 'bbco_autocomplete' => 'bbcode',
+ 'editor_autocomplete' => true,
+ 'bbcode' => true,
+ 'jotnets' => true
);
$editor = status_editor($a,$x);
diff --git a/Zotlabs/Module/Xrd.php b/Zotlabs/Module/Xrd.php
index 64e5042cb..60a8f58fa 100644
--- a/Zotlabs/Module/Xrd.php
+++ b/Zotlabs/Module/Xrd.php
@@ -57,7 +57,7 @@ class Xrd extends \Zotlabs\Web\Controller {
'$poco_url' => z_root() . '/poco/' . $r[0]['channel_address'],
'$photo' => z_root() . '/photo/profile/l/' . $r[0]['channel_id'],
'$modexp' => 'data:application/magic-public-key,' . $salmon_key,
- '$subscribe' => z_root() . '/follow?f=&url={uri}',
+ '$subscribe' => z_root() . '/follow?f=&amp;url={uri}',
));
diff --git a/Zotlabs/Web/CheckJS.php b/Zotlabs/Web/CheckJS.php
index 109790fa5..8179ceb15 100644
--- a/Zotlabs/Web/CheckJS.php
+++ b/Zotlabs/Web/CheckJS.php
@@ -21,9 +21,9 @@ class CheckJS {
$page = urlencode(\App::$query_string);
if($test) {
- self::$jsdisabled = 1;
+ $this->jsdisabled = 1;
if(array_key_exists('jsdisabled',$_COOKIE))
- self::$jsdisabled = $_COOKIE['jsdisabled'];
+ $this->jsdisabled = $_COOKIE['jsdisabled'];
if(! array_key_exists('jsdisabled',$_COOKIE)) {
\App::$page['htmlhead'] .= "\r\n" . '<script>document.cookie="jsdisabled=0; path=/"; var jsMatch = /\&jsdisabled=0/; if (!jsMatch.exec(location.href)) { location.href = "' . z_root() . '/nojs/0?f=&redir=' . $page . '" ; }</script>' . "\r\n";
@@ -41,7 +41,7 @@ class CheckJS {
}
function disabled() {
- return self::$jsdisabled;
+ return $this->jsdisabled;
}
diff --git a/Zotlabs/Widget/Categories.php b/Zotlabs/Widget/Categories.php
index 84deb03d6..305869706 100644
--- a/Zotlabs/Widget/Categories.php
+++ b/Zotlabs/Widget/Categories.php
@@ -19,7 +19,7 @@ class Categories {
}
$cat = ((x($_REQUEST,'cat')) ? htmlspecialchars($_REQUEST['cat'],ENT_COMPAT,'UTF-8') : '');
- $srchurl = \App::$query_string;
+ $srchurl = (($cards) ? \App::$argv[0] . '/' . \App::$argv[1] : \App::$query_string);
$srchurl = rtrim(preg_replace('/cat\=[^\&].*?(\&|$)/is','',$srchurl),'&');
$srchurl = str_replace(array('?f=','&f='),array('',''),$srchurl);
diff --git a/boot.php b/boot.php
index d9a6cd230..e52d130f9 100755
--- a/boot.php
+++ b/boot.php
@@ -49,7 +49,7 @@ require_once('include/hubloc.php');
require_once('include/attach.php');
define ( 'PLATFORM_NAME', 'hubzilla' );
-define ( 'STD_VERSION', '2.7.1' );
+define ( 'STD_VERSION', '2.7.2' );
define ( 'ZOT_REVISION', '1.3' );
define ( 'DB_UPDATE_VERSION', 1193 );
@@ -64,7 +64,7 @@ define ( 'PROJECT_BASE', __DIR__ );
* This can be used in HTML and JavaScript where needed a line break.
*/
define ( 'EOL', '<br>' . "\r\n" );
-define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
+define ( 'ATOM_TIME', 'Y-m-d\\TH:i:s\\Z' ); // aka ISO 8601 "Zulu"
define ( 'TEMPLATE_BUILD_PATH', 'store/[data]/smarty3' );
define ( 'DIRECTORY_MODE_NORMAL', 0x0000); // A directory client
diff --git a/include/bbcode.php b/include/bbcode.php
index 9f9b5c5e1..470854f06 100644
--- a/include/bbcode.php
+++ b/include/bbcode.php
@@ -1255,6 +1255,9 @@ function bbcode($Text, $preserve_nl = false, $tryoembed = true, $cache = false)
$Text = preg_replace_callback("/\[pre\](.*?)\[\/pre\]/ism", 'bb_unspacefy_and_trim', $Text);
}
+ // replace escaped links in code= blocks
+ $Text = str_replace('%eY9-!','http', $Text);
+
$Text = preg_replace('/\[\&amp\;([#a-z0-9]+)\;\]/', '&$1;', $Text);
// fix any escaped ampersands that may have been converted into links
diff --git a/include/photos.php b/include/photos.php
index f5d5fdb48..c7c8fc0a4 100644
--- a/include/photos.php
+++ b/include/photos.php
@@ -595,7 +595,7 @@ function photos_album_exists($channel_id, $observer_hash, $album) {
// partial backward compatibility with Hubzilla < 2.4 when we used the filename only
// (ambiguous which would get chosen if you had two albums of the same name in different directories)
- if(!$r) {
+ if(!$r && ctype_xdigit($album)) {
$r = q("SELECT folder, hash, is_dir, filename, os_path, display_path FROM attach WHERE filename = '%s' AND is_dir = 1 AND uid = %d $sql_extra limit 1",
dbesc(hex2bin($album)),
intval($channel_id)
diff --git a/include/text.php b/include/text.php
index dd2dc7620..ea21e2184 100644
--- a/include/text.php
+++ b/include/text.php
@@ -651,7 +651,7 @@ function logger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) {
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': ';
- $s = datetime_convert() . ':' . log_priority_str($priority) . ':' . session_id() . ':' . $where . $msg . PHP_EOL;
+ $s = datetime_convert('UTC','UTC', 'now', ATOM_TIME) . ':' . log_priority_str($priority) . ':' . session_id() . ':' . $where . $msg . PHP_EOL;
$pluginfo = array('filename' => $logfile, 'loglevel' => $level, 'message' => $s,'priority' => $priority, 'logged' => false);
if(! (App::$module == 'setup'))
@@ -679,7 +679,7 @@ function btlogger($msg, $level = LOGGER_NORMAL, $priority = LOG_INFO) {
if(file_exists(BTLOGGER_DEBUG_FILE) && is_writable(BTLOGGER_DEBUG_FILE)) {
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': ';
- $s = datetime_convert() . ':' . log_priority_str($priority) . ':' . session_id() . ':' . $where . $msg . PHP_EOL;
+ $s = datetime_convert('UTC','UTC', 'now', ATOM_TIME) . ':' . log_priority_str($priority) . ':' . session_id() . ':' . $where . $msg . PHP_EOL;
@file_put_contents(BTLOGGER_DEBUG_FILE, $s, FILE_APPEND);
}
@@ -750,7 +750,7 @@ function dlogger($msg, $level = 0) {
$where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': ';
- @file_put_contents($logfile, datetime_convert() . ':' . session_id() . ' ' . $where . $msg . PHP_EOL, FILE_APPEND);
+ @file_put_contents($logfile, datetime_convert('UTC','UTC', 'now', ATOM_TIME) . ':' . session_id() . ' ' . $where . $msg . PHP_EOL, FILE_APPEND);
}
@@ -2485,7 +2485,7 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag, $d
if(($t2) && (! $diaspora)) {
//get the id
- $tagcid = substr($newname,$t2 + 1);
+ $tagcid = urldecode(substr($newname,$t2 + 1));
if(strrpos($tagcid,' '))
$tagcid = substr($tagcid,0,strrpos($tagcid,' '));
@@ -2966,6 +2966,9 @@ function flatten_array_recursive($arr) {
* @param string $s Text to highlight
* @param string $lang Which language should be highlighted
* @return string
+ * Important: The returned text has the text pattern 'http' translated to '%eY9-!' which should be converted back
+ * after further processing. This was done to prevent oembed links from occurring inside code blocks.
+ * See include/bbcode.php
*/
function text_highlight($s, $lang) {
@@ -2986,6 +2989,8 @@ function text_highlight($s, $lang) {
else
$o = $s;
+ $o = str_replace('http','%eY9-!',$o);
+
return('<code>' . $o . '</code>');
}
diff --git a/view/css/conversation.css b/view/css/conversation.css
index d10e1e14e..dcabb5f3c 100644
--- a/view/css/conversation.css
+++ b/view/css/conversation.css
@@ -183,24 +183,19 @@ a.wall-item-name-link {
/* comment_item */
-.comment-edit-text-empty,
-.comment-edit-text-full {
+
+.comment-edit-text {
padding: 0.5rem;
width: 100%;
display: inherit;
-}
-
-.comment-edit-text-empty {
- height: 2rem;
line-height: 1;
- overflow: hidden;
+ height: 2rem;
resize: none;
}
-.comment-edit-text-full {
- height: 7rem;
+.comment-edit-text.expanded {
line-height: 1.25;
- overflow: auto;
+ height: 7rem;
resize: vertical;
}
diff --git a/view/js/main.js b/view/js/main.js
index 47815d2c6..41be3da59 100644
--- a/view/js/main.js
+++ b/view/js/main.js
@@ -1,6 +1,55 @@
function confirmDelete() { return confirm(aStr.delitem); }
+function handle_comment_form(e) {
+ e.stopPropagation();
+
+ //handle eventual expanded forms
+ var expanded = $('.comment-edit-text.expanded');
+ var i = 0;
+
+ if(expanded.length) {
+ expanded.each(function() {
+ var ex_form = $(expanded[i].form);
+ var ex_fields = ex_form.find(':input[type=text], textarea');
+ var ex_fields_empty = true;
+
+ ex_fields.each(function() {
+ if($(this).val() != '')
+ ex_fields_empty = false;
+ });
+ if(ex_fields_empty) {
+ ex_form.find('.comment-edit-text').removeClass('expanded').attr('placeholder', aStr.comment);
+ ex_form.find(':not(.comment-edit-text)').hide();
+ }
+ i++
+ });
+ }
+
+ // handle clicked form
+ var form = $(this);
+ var fields = form.find(':input[type=text], textarea');
+ var fields_empty = true;
+
+ if(form.find('.comment-edit-text').length) {
+ form.find('.comment-edit-text').addClass('expanded').removeAttr('placeholder');
+ form.find(':not(:visible)').show();
+ }
+
+ // handle click outside of form (close empty forms)
+ $(document).on('click', function(e) {
+ fields.each(function() {
+ if($(this).val() != '')
+ fields_empty = false;
+ });
+ if(fields_empty) {
+ form.find('.comment-edit-text').removeClass('expanded').attr('placeholder', aStr.comment);
+ form.find(':not(.comment-edit-text)').hide();
+ }
+ });
+}
+
+/*
function commentOpenUI(obj, id) {
$(document).unbind( "click.commentOpen", handler );
@@ -44,8 +93,7 @@ function commentCloseUI(obj, id) {
function commentOpen(obj, id) {
if(obj.value == aStr.comment) {
obj.value = '';
- $("#comment-edit-text-" + id).addClass("comment-edit-text-full");
- $("#comment-edit-text-" + id).removeClass("comment-edit-text-empty");
+ $("#comment-edit-text-" + id).addClass("expanded");
$("#mod-cmnt-wrap-" + id).show();
$("#comment-tools-" + id).show();
$("#comment-edit-anon-" + id).show();
@@ -53,12 +101,11 @@ function commentOpen(obj, id) {
}
return false;
}
-
+*/
function commentClose(obj, id) {
if(obj.value === '') {
obj.value = aStr.comment;
- $("#comment-edit-text-" + id).removeClass("comment-edit-text-full");
- $("#comment-edit-text-" + id).addClass("comment-edit-text-empty");
+ $("#comment-edit-text-" + id).removeClass("expanded");
$("#mod-cmnt-wrap-" + id).hide();
$("#comment-tools-" + id).hide();
$("#comment-edit-anon-" + id).hide();
@@ -67,6 +114,7 @@ function commentClose(obj, id) {
return false;
}
+
function showHideCommentBox(id) {
if( $('#comment-edit-form-' + id).is(':visible')) {
$('#comment-edit-form-' + id).hide();
@@ -79,8 +127,7 @@ function commentInsert(obj, id) {
var tmpStr = $("#comment-edit-text-" + id).val();
if(tmpStr == '$comment') {
tmpStr = '';
- $("#comment-edit-text-" + id).addClass("comment-edit-text-full");
- $("#comment-edit-text-" + id).removeClass("comment-edit-text-empty");
+ $("#comment-edit-text-" + id).addClass("expanded");
openMenu("comment-tools-" + id);
}
var ins = $(obj).html();
@@ -101,8 +148,7 @@ function insertbbcomment(comment, BBcode, id) {
var tmpStr = $("#comment-edit-text-" + id).val();
if(tmpStr == comment) {
tmpStr = "";
- $("#comment-edit-text-" + id).addClass("comment-edit-text-full");
- $("#comment-edit-text-" + id).removeClass("comment-edit-text-empty");
+ $("#comment-edit-text-" + id).addClass("expanded");
openMenu("comment-tools-" + id);
$("#comment-edit-text-" + id).val(tmpStr);
}
@@ -160,8 +206,7 @@ function insertCommentURL(comment, id) {
var tmpStr = $("#comment-edit-text-" + id).val();
if(tmpStr == comment) {
tmpStr = "";
- $("#comment-edit-text-" + id).addClass("comment-edit-text-full");
- $("#comment-edit-text-" + id).removeClass("comment-edit-text-empty");
+ $("#comment-edit-text-" + id).addClass("expanded");
openMenu("comment-tools-" + id);
$("#comment-edit-text-" + id).val(tmpStr);
}
@@ -183,8 +228,7 @@ function qCommentInsert(obj, id) {
var tmpStr = $("#comment-edit-text-" + id).val();
if(tmpStr == aStr.comment) {
tmpStr = '';
- $("#comment-edit-text-" + id).addClass("comment-edit-text-full");
- $("#comment-edit-text-" + id).removeClass("comment-edit-text-empty");
+ $("#comment-edit-text-" + id).addClass("expanded");
openMenu("comment-edit-submit-wrapper-" + id);
}
var ins = $(obj).val();
@@ -728,7 +772,7 @@ function collapseHeight() {
function liveUpdate() {
if(typeof profile_uid === 'undefined') profile_uid = false; /* Should probably be unified with channelId defined in head.tpl */
if((src === null) || (stopped) || (! profile_uid)) { $('.like-rotator').spin(false); return; }
- if(($('.comment-edit-text-full').length) || (in_progress)) {
+ if(($('.comment-edit-text.expanded').length) || (in_progress)) {
if(livetime) {
clearTimeout(livetime);
}
@@ -1084,8 +1128,10 @@ function post_comment(id) {
$("#comment-edit-wrapper-" + id).hide();
$("#comment-edit-text-" + id).val('');
var tarea = document.getElementById("comment-edit-text-" + id);
- if(tarea)
+ if(tarea) {
commentClose(tarea, id);
+ $(document).unbind( "click.commentOpen");
+ }
if(timer) clearTimeout(timer);
timer = setTimeout(NavUpdate,1500);
}
@@ -1312,9 +1358,10 @@ Array.prototype.remove = function(item) {
return this.push.apply(this, rest);
};
-
$(document).ready(function() {
+ $(document).on('click focus', '.comment-edit-form', handle_comment_form);
+
jQuery.timeago.settings.strings = {
prefixAgo : aStr['t01'],
prefixFromNow : aStr['t02'],
diff --git a/view/js/mod_cards.js b/view/js/mod_cards.js
index 78b2e1bd0..8b31c0f52 100644
--- a/view/js/mod_cards.js
+++ b/view/js/mod_cards.js
@@ -1,3 +1,9 @@
$(document).ready( function() {
$(".autotime").timeago();
+
+ /* autocomplete @nicknames */
+ $(".comment-edit-form textarea").editor_autocomplete(baseurl+"/acl?f=&n=1");
+ /* autocomplete bbcode */
+ $(".comment-edit-form textarea").bbco_autocomplete('bbcode');
+
}); \ No newline at end of file
diff --git a/view/theme/redbasic/css/style.css b/view/theme/redbasic/css/style.css
index 37277b612..621fa2781 100644
--- a/view/theme/redbasic/css/style.css
+++ b/view/theme/redbasic/css/style.css
@@ -1073,16 +1073,11 @@ img.mail-conv-sender-photo {
}
-.comment-edit-text-empty,
-.comment-edit-text-full {
+.comment-edit-text {
border: 1px solid #ccc;
border-radius: $radius;
}
-.comment-edit-text-empty {
- color: gray;
-}
-
.divgrow-showmore {
display: block;
border-top: 1px dashed #ccc;
diff --git a/view/tpl/comment_item.tpl b/view/tpl/comment_item.tpl
index cba4cd3c5..62530c1de 100755
--- a/view/tpl/comment_item.tpl
+++ b/view/tpl/comment_item.tpl
@@ -18,7 +18,7 @@
{{$anon_extras}}
</div>
{{/if}}
- <textarea id="comment-edit-text-{{$id}}" class="comment-edit-text-empty" name="body" onFocus="commentOpenUI(this,{{$id}});" onBlur="commentCloseUI(this,{{$id}});" ondragenter="linkdropper(event);" ondragleave="linkdropexit(event);" ondragover="linkdropper(event);" ondrop="linkdrop(event);" >{{$comment}}</textarea>
+ <textarea id="comment-edit-text-{{$id}}" class="comment-edit-text" placeholder="{{$comment}}" name="body" ondragenter="linkdropper(event);" ondragleave="linkdropexit(event);" ondragover="linkdropper(event);" ondrop="linkdrop(event);" ></textarea>
{{if $qcomment}}
<select id="qcomment-select-{{$id}}" name="qcomment-{{$id}}" class="qcomment" onchange="qCommentInsert(this,{{$id}});" >
<option value=""></option>
diff --git a/view/tpl/conv_frame.tpl b/view/tpl/conv_frame.tpl
index aa7b55e9b..1f0e00db4 100755
--- a/view/tpl/conv_frame.tpl
+++ b/view/tpl/conv_frame.tpl
@@ -3,3 +3,4 @@
<div id="conversation-end"></div>
<div id="page-spinner"></div>
+
diff --git a/view/tpl/threaded_conversation.tpl b/view/tpl/threaded_conversation.tpl
index ea5c3c281..5bc7d8386 100755
--- a/view/tpl/threaded_conversation.tpl
+++ b/view/tpl/threaded_conversation.tpl
@@ -1,8 +1,9 @@
+<div id="threads-begin"></div>
{{if $photo_item}}
{{$photo_item}}
{{/if}}
{{foreach $threads as $thread_item}}
{{include file="{{$thread_item.template}}" item=$thread_item}}
{{/foreach}}
-
+<div id="threads-end"></div>
<div id="conversation-end"></div>