diff --git a/boot.php b/boot.php index faaa124e0..3c55c377c 100644 --- a/boot.php +++ b/boot.php @@ -12,7 +12,7 @@ require_once('library/Mobile_Detect/Mobile_Detect.php'); require_once('include/features.php'); define ( 'FRIENDICA_PLATFORM', 'Friendica'); -define ( 'FRIENDICA_VERSION', '3.1.1644' ); +define ( 'FRIENDICA_VERSION', '3.1.1699' ); define ( 'DFRN_PROTOCOL_VERSION', '2.23' ); define ( 'DB_UPDATE_VERSION', 1163 ); define ( 'EOL', "
\r\n" ); @@ -383,8 +383,13 @@ if(! class_exists('App')) { 'force_max_items' => 0, 'thread_allow' => true, 'stylesheet' => '', - 'template_engine' => 'internal', + 'template_engine' => 'smarty3', ); + + // array of registered template engines ('name'=>'class name') + public $template_engines = array(); + // array of instanced template engines ('name'=>'instance') + public $template_engine_instance = array(); private $ldelim = array( 'internal' => '', @@ -401,6 +406,7 @@ if(! class_exists('App')) { private $db; private $curl_code; + private $curl_content_type; private $curl_headers; private $cached_profile_image; @@ -417,6 +423,7 @@ if(! class_exists('App')) { $this->performance["start"] = microtime(true); $this->performance["database"] = 0; $this->performance["network"] = 0; + $this->performance["file"] = 0; $this->performance["rendering"] = 0; $this->performance["parser"] = 0; $this->performance["marktime"] = 0; @@ -538,6 +545,17 @@ if(! class_exists('App')) { $mobile_detect = new Mobile_Detect(); $this->is_mobile = $mobile_detect->isMobile(); $this->is_tablet = $mobile_detect->isTablet(); + + /** + * register template engines + */ + $dc = get_declared_classes(); + foreach ($dc as $k) { + if (in_array("ITemplateEngine", class_implements($k))){ + $this->register_template_engine($k); + } + } + } function get_basepath() { @@ -673,6 +691,14 @@ if(! class_exists('App')) { return $this->curl_code; } + function set_curl_content_type($content_type) { + $this->curl_content_type = $content_type; + } + + function get_curl_content_type() { + return $this->curl_content_type; + } + function set_curl_headers($headers) { $this->curl_headers = $headers; } @@ -703,13 +729,64 @@ if(! class_exists('App')) { return $this->cached_profile_image[$avatar_image]; } + + /** + * register template engine class + * if $name is "", is used class static property $class::$name + * @param string $class + * @param string $name + */ + function register_template_engine($class, $name = '') { + if ($name===""){ + $v = get_class_vars( $class ); + if(x($v,"name")) $name = $v['name']; + } + if ($name===""){ + echo "template engine $class cannot be registered without a name.\n"; + killme(); + } + $this->template_engines[$name] = $class; + } + + /** + * return template engine instance. If $name is not defined, + * return engine defined by theme, or default + * + * @param strin $name Template engine name + * @return object Template Engine instance + */ + function template_engine($name = ''){ + if ($name!=="") { + $template_engine = $name; + } else { + $template_engine = 'smarty3'; + if (x($this->theme, 'template_engine')) { + $template_engine = $this->theme['template_engine']; + } + } + + if (isset($this->template_engines[$template_engine])){ + if(isset($this->template_engine_instance[$template_engine])){ + return $this->template_engine_instance[$template_engine]; + } else { + $class = $this->template_engines[$template_engine]; + $obj = new $class; + $this->template_engine_instance[$template_engine] = $obj; + return $obj; + } + } + + echo "template engine $template_engine is not registered!\n"; killme(); + } + function get_template_engine() { return $this->theme['template_engine']; } - function set_template_engine($engine = 'internal') { - - $this->theme['template_engine'] = 'internal'; + function set_template_engine($engine = 'smarty3') { + $this->theme['template_engine'] = $engine; + /* + $this->theme['template_engine'] = 'smarty3'; switch($engine) { case 'smarty3': @@ -719,13 +796,14 @@ if(! class_exists('App')) { default: break; } + */ } - function get_template_ldelim($engine = 'internal') { + function get_template_ldelim($engine = 'smarty3') { return $this->ldelim[$engine]; } - function get_template_rdelim($engine = 'internal') { + function get_template_rdelim($engine = 'smarty3') { return $this->rdelim[$engine]; } @@ -1878,6 +1956,13 @@ if(! function_exists('profile_tabs')){ 'title' => t('Photo Albums'), 'id' => 'photo-tab', ), + array( + 'label' => t('Videos'), + 'url' => $a->get_baseurl() . '/videos/' . $nickname, + 'sel' => ((!isset($tab)&&$a->argv[0]=='videos')?'active':''), + 'title' => t('Videos'), + 'id' => 'video-tab', + ), ); if ($is_owner){ @@ -2021,10 +2106,7 @@ function random_digits($digits) { function get_cachefile($file, $writemode = true) { $cache = get_config("system","itemcache"); - if ($cache == "") - return(""); - - if (!is_dir($cache)) + if ((! $cache) || (! is_dir($cache))) return(""); $subfolder = $cache."/".substr($file, 0, 2); diff --git a/doc/BBCode.md b/doc/BBCode.md new file mode 100644 index 000000000..c84308e5b --- /dev/null +++ b/doc/BBCode.md @@ -0,0 +1,138 @@ +Friendica BBCode tags reference +======================== + +* [Home](help) + +Inline +----- + + +
[b]bold[/b]
: bold + +
[i]italic[/i]
: italic + +
[u]underlined[/u]
: underlined + +
[s]strike[/s]
: strike + +
[color=red]red[/color]
: red + +
[url=http://www.friendica.com]Friendica[/url]
: Friendica + +
[img]http://friendica.com/sites/default/files/friendika-32.png[/img]
: Immagine/foto + +
[size=xx-small]small text[/size]
: small text + +
[size=xx-large]big text[/size]
: big text + +
[size=20]exact size[/size] (size can be any number, in pixel)
: exact size + + + + + + + +Block +----- + +
[code]code[/code]
+ +code + +

 

+ +
[quote]quote[/quote]
+ +
quote
+ +

 

+ +
[quote=Author]Author? Me? No, no, no...[/quote]
+ +Author wrote:
Author? Me? No, no, no...
+ +

 

+ +
[center]centered text[/center]
+ +
centered text
+ +

 

+ +**Table** +
[table border=1]
+ [tr] 
+   [th]Tables now[/th]
+ [/tr]
+ [tr]
+   [td]Have headers[/td]
+ [/tr]
+[/table]
+ +
Tables now
Have headers
+ +

 

+ +**List** + +
[list]
+ [*] First list element
+ [*] Second list element
+[/list]
+ + +[list] is equivalent to [ul] (unordered list). + +[ol] can be used instead of [list] to show an ordered list: + +
[ol]
+ [*] First list element
+ [*] Second list element
+[/ol]
+ + +For more options on ordered lists, you can define the style of numeration on [list] argument: +
[list=1]
: decimal + +
[list=i]
: lover case roman + +
[list=I]
: upper case roman + +
[list=a]
: lover case alphabetic + +
[list=A] 
: upper case alphabetic + + + + +Embed +------ + +You can embed video, audio and more in a message. + +
[video]url[/video]
+
[audio]url[/audio]
+ +Where *url* can be an url to youtube, vimeo, soundcloud, or other sites wich supports oembed or opengraph specifications. +*url* can be also full url to an ogg file. HTML5 tag will be used to show it. + +
[url]*url*[/url]
+ +If *url* supports oembed or opengraph specifications the embedded object will be shown (eg, documents from scribd). +Page title with a link to *url* will be shown. + + + +Special +------- + +If you need to put literal bbcode in a message, [noparse], [nobb] or [pre] are used to escape bbcode: + +
[noparse][b]bold[/b][/noparse]
: [b]bold[/b] + + diff --git a/doc/Developers.md b/doc/Developers.md index 17aff3869..b0fce47b5 100644 --- a/doc/Developers.md +++ b/doc/Developers.md @@ -1,6 +1,7 @@ Friendica Developer Guide +=================== -Here is how you can join us. +**Here is how you can join us.** First, get yourself a working git package on the system where you will be doing development. diff --git a/doc/Home.md b/doc/Home.md index e986c89ac..4c0523398 100644 --- a/doc/Home.md +++ b/doc/Home.md @@ -3,10 +3,11 @@ Friendica Documentation and Resources **Contents** -* Generell functions - first steps +* General functions - first steps * [Account Basics](help/Account-Basics) * [New User Quick Start](help/Quick-Start-guide) * [Creating posts](help/Text_editor) + * [BBCode tag reference](help/BBCode) * [Comment, sort and delete posts](help/Text_comment) * [Profiles](help/Profiles) * You and other user diff --git a/doc/Install.md b/doc/Install.md index 9455c62ba..7f9330752 100644 --- a/doc/Install.md +++ b/doc/Install.md @@ -1,4 +1,5 @@ Friendica Installation +=============== We've tried very hard to ensure that Friendica will run on commodity hosting platforms - such as those used to host Wordpress blogs and Drupal websites. But be aware that Friendica is more than a simple web application. It is a complex communications system which more closely resembles an email server than a web server. For reliability and performance, messages are delivered in the background and are queued for later delivery when sites are down. This kind of functionality requires a bit more of the host system than the typical blog. Not every PHP/MySQL hosting provider will be able to support Friendica. Many will. But **please** review the requirements and confirm these with your hosting provider prior to installation. @@ -41,6 +42,12 @@ you might have trouble getting everything to work.] - and then you can pick up the latest changes at any time with `git pull` + + - make sure folder *view/smarty3* exists and is writable by webserver + + `mkdir view/smarty3` + + `chown 777 view/smarty3` - For installing addons diff --git a/doc/Plugins.md b/doc/Plugins.md index df6004450..2ae942eae 100644 --- a/doc/Plugins.md +++ b/doc/Plugins.md @@ -1,4 +1,5 @@ -**Friendica Addon/Plugin development** +Friendica Addon/Plugin development +========================== Please see the sample addon 'randplace' for a working example of using some of these features. The facebook addon provides an example of integrating both "addon" and "module" functionality. Addons work by intercepting event hooks - which must be registered. Modules work by intercepting specific page requests (by URL path). @@ -51,7 +52,8 @@ currently being processed, and generally contains information that is being imme processed or acted on that you can use, display, or alter. Remember to declare it with '&' if you wish to alter it. -**Modules** +Modules +-------- Plugins/addons may also act as "modules" and intercept all page requests for a given URL path. In order for a plugin to act as a module it needs to define a function "plugin_name_module()" which takes no arguments and need not do anything. @@ -62,8 +64,29 @@ If this function exists, you will now receive all page requests for "http://my.w Your module functions will often contain the function plugin_name_content(&$a), which defines and returns the page body content. They may also contain plugin_name_post(&$a) which is called before the _content function and typically handles the results of POST forms. You may also have plugin_name_init(&$a) which is called very early on and often does module initialisation. +Templates +---------- -**Current hooks:** +If your plugin need some template, you can use Friendica template system. Friendica use [smarty3](http://www.smarty.net/) as template engine. + +Put your tpl files in *templates/* subfolder of your plugin. + +In your code, like in function plugin_name_content(), load template file and execute it passing needed values: + + # load template file. first argument is the template name, + # second is the plugin path relative to friendica top folder + $tpl = get_markup_template('mytemplate.tpl', 'addon/plugin_name/'); + + # apply template. first argument is the loaded template, + # second an array of 'name'=>'values' to pass to template + $output = replace_macros($tpl,array( + 'title' => 'My beautifull plugin', + )); + +See also wiki page [Quick Template Guide](https://github.com/friendica/friendica/wiki/Quick-Template-Guide) + +Current hooks: +-------------- **'authenticate'** - called when a user attempts to login. $b is an array diff --git a/doc/Text_editor.md b/doc/Text_editor.md index e2234825a..aff0ce603 100644 --- a/doc/Text_editor.md +++ b/doc/Text_editor.md @@ -1,40 +1,110 @@ + + Creating posts -================= +=========== * [Home](help) -Here you can find an overview of the different ways to create and edit your post. Attention: we've used the "diabook" theme. If you're using another theme, some of the icons may be different. +Here you can find an overview of the different ways to create and edit your post. -editor +One click on "Share" text box on top of your Home or Network page, and the post editor shows up: -The different icons +
+default editor +
Default post editor, with default Friendica theme (duepuntozero)
+
-editor This symbol is used to upload a picture from your computer. If you only want to add an adress (url), you can also use the "tree" icon at the upper part of the editor. After selecting an image, you'll see a thumbnail in the editor. +Post title is optional, you can set it clicking on "Set title". + +Posts can optionally be in one or more categories. Write categories name separated by a comma to file your new post. + +The Big Empty Textarea is where you write your new post. +You can simply enter your text there and click "Share" button, and your new post will be public on your profile page and shared to your contact. + +If plain text is not so exciting to you, Friendica understands BBCode to spice up your posts: bold, italic, images, links, lists.. +See [BBCode tags reference](help/BBCode) page to see all what you can do. + +The icons under the text area are there to help you to write posts quickly: + +editor Upload a picture from your computer. The image will be uploaded and correct bbcode tag will be added to your post.

-paper_clip This symbol is used to add files from your computer. There'll be no preview of the content. +paper_clip Add files from your computer. Same as picture, but for generic attachment to the post.

-chain This symbol is used to add a web address (url). You'll see a short preview of the website. +chain Add a web address (url). Enter an url and Friendica will add to your post a link to the url and an excerpt from the web site, if possible

-video This symbol is used to add a web address (url) of a video file. You'll see a small preview of the video. +video Add a video. Enter the url to a video (ogg) or to a video page on youtube or vimeo, and it will be embedded in your post

-mic This symbol is used to add a web address (url) of an audio file. You'll see a player in your completed post. +mic Add an audio. Same as video, but for audio

-globe This symbol is used to add your geographic location. This location will be added into a Google Maps search. That's why a note like "New York" or "10004" is already enough. +globe Set your geographic location. This location will be added into a Google Maps search. That's why a note like "New York" or "10004" is already enough.

-**Symbols of other themes** +Those icons can change with themes. Some examples: -Cleanzero cleanzero.png + + + + + + + + + + + + + + + + +
Darkbubble: darkbubble.png(inkl. smoothly, testbubble)
Frost: frost.png  
Vier: vier.png(inkl. dispy)
+

 

+

 

-(incl. more "zero"-themes, comix, easterbunny, facepark, slackr +**lock icon The lock** -Darkbubble darkbubble.png (inkl. smoothly, testbubble) +The last button, the Lock, is the most important feature in Friendica. If the lock is open, your post will be public, and will shows up on your profile page when strangers visit it. -Frost frost.png +Click on it and the *Permission settings* window (aka "*Access Control Selector*" or "*ACL Selector*") pops up. There you can select who can see the post. + +
+Permission settings window +
Permission settings window with some contact selected
+
+ +Click on "show" under contact name to hide the post to everyone but selected. + +Click on "Visible to everybody" to make the post public again. + +If you have defined some groups, you can check "show" for groups also. All contact in that group will see the post. +If you want to hide the post to one contact of a group selected for "show", click "don't show" under contact name. + +Click again on "show" or "don't show" to switch it off. + +You can search for contacts or groups with the search box. + +See also [Group and Privacy](help/Groups-and-Privacy) + + + +WYSIAWYG (What You See Is About What You Get) +-------------------------------------------------- + +Friendica can use TinyMCE as rich text editor. This way you can write beatifull post without the need to know [BBCode](help/BBCode). + +By default, rich editor is disabled. You can enable it from Settings -> [Aditional features](settings/features) page, turn on Richtext Editor and click "Submit". + +
+default editor +
Rich editor, with default Friendica theme (duepuntozero)
+
-Vier vier.png (inkl. dispy) diff --git a/doc/img/acl_win.png b/doc/img/acl_win.png new file mode 100644 index 000000000..00ad76699 Binary files /dev/null and b/doc/img/acl_win.png differ diff --git a/doc/img/camera.png b/doc/img/camera.png index af73b0d73..1f8a92c34 100644 Binary files a/doc/img/camera.png and b/doc/img/camera.png differ diff --git a/doc/img/chain.png b/doc/img/chain.png index c8f8bf1f3..6537c07d4 100644 Binary files a/doc/img/chain.png and b/doc/img/chain.png differ diff --git a/doc/img/friendica_editor.png b/doc/img/friendica_editor.png index 397c4b595..aebcf111b 100644 Binary files a/doc/img/friendica_editor.png and b/doc/img/friendica_editor.png differ diff --git a/doc/img/friendica_rich_editor.png b/doc/img/friendica_rich_editor.png new file mode 100644 index 000000000..4cd8beac9 Binary files /dev/null and b/doc/img/friendica_rich_editor.png differ diff --git a/doc/img/globe.png b/doc/img/globe.png index b8a319db0..ec1b7ff4a 100644 Binary files a/doc/img/globe.png and b/doc/img/globe.png differ diff --git a/doc/img/lock.png b/doc/img/lock.png new file mode 100644 index 000000000..b9a1cefc5 Binary files /dev/null and b/doc/img/lock.png differ diff --git a/doc/img/mic.png b/doc/img/mic.png index 616e79859..c8d4c0e38 100644 Binary files a/doc/img/mic.png and b/doc/img/mic.png differ diff --git a/doc/img/paper_clip.png b/doc/img/paper_clip.png index 1d9cc0a09..51c7cdf70 100644 Binary files a/doc/img/paper_clip.png and b/doc/img/paper_clip.png differ diff --git a/doc/img/video.png b/doc/img/video.png index be023d746..00561f1b3 100644 Binary files a/doc/img/video.png and b/doc/img/video.png differ diff --git a/include/bbcode.php b/include/bbcode.php index d16dcb6a7..5b676bbad 100644 --- a/include/bbcode.php +++ b/include/bbcode.php @@ -407,6 +407,10 @@ function bbcode($Text,$preserve_nl = false, $tryoembed = true, $simplehtml = fal $Text = preg_replace("/\[url\=([$URLSearchString]*)\](.*?)\[\/url\]/ism", '$2', $Text); //$Text = preg_replace("/\[url\=([$URLSearchString]*)\]([$URLSearchString]*)\[\/url\]/ism", '$2', $Text); + // Red compatibility, though the link can't be authenticated on Friendica + $Text = preg_replace("/\[zrl\=([$URLSearchString]*)\](.*?)\[\/zrl\]/ism", '$2', $Text); + + // we may need to restrict this further if it picks up too many strays // link acct:user@host to a webfinger profile redirector diff --git a/include/conversation.php b/include/conversation.php index 36ac57f17..2e336efab 100644 --- a/include/conversation.php +++ b/include/conversation.php @@ -377,6 +377,18 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { $page_writeable = false; $live_update_div = ''; + $arr_blocked = null; + + if(local_user()) { + $str_blocked = get_pconfig(local_user(),'system','blocked'); + if($str_blocked) { + $arr_blocked = explode(',',$str_blocked); + for($x = 0; $x < count($arr_blocked); $x ++) + $arr_blocked[$x] = trim($arr_blocked[$x]); + } + + } + $previewing = (($preview) ? ' preview ' : ''); if($mode === 'network') { @@ -493,6 +505,19 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { $tpl = 'search_item.tpl'; foreach($items as $item) { + if($arr_blocked) { + $blocked = false; + foreach($arr_blocked as $b) { + if($b && link_compare($item['author-link'],$b)) { + $blocked = true; + break; + } + } + if($blocked) + continue; + } + + $threadsid++; $comment = ''; @@ -691,6 +716,21 @@ function conversation(&$a, $items, $mode, $update, $preview = false) { $threads = array(); foreach($items as $item) { + if($arr_blocked) { + $blocked = false; + foreach($arr_blocked as $b) { + + if($b && link_compare($item['author-link'],$b)) { + $blocked = true; + break; + } + } + if($blocked) + continue; + } + + + // Can we put this after the visibility check? like_puller($a,$item,$alike,'like'); like_puller($a,$item,$dlike,'dislike'); diff --git a/include/enotify.php b/include/enotify.php index f294a4fc7..72365a762 100644 --- a/include/enotify.php +++ b/include/enotify.php @@ -17,7 +17,7 @@ function notification($params) { $product = FRIENDICA_PLATFORM; $siteurl = $a->get_baseurl(true); $thanks = t('Thank You,'); - $sitename = get_config('config','sitename'); + $sitename = $a->config['sitename']; $site_admin = sprintf( t('%s Administrator'), $sitename); $sender_name = $product; @@ -268,9 +268,15 @@ function notification($params) { $datarray['type'] = $params['type']; $datarray['verb'] = $params['verb']; $datarray['otype'] = $params['otype']; + $datarray['abort'] = false; call_hooks('enotify_store', $datarray); + if($datarray['abort']) { + pop_lang(); + return; + } + // create notification entry in DB $r = q("insert into notify (hash,name,url,photo,date,uid,link,parent,type,verb,otype) diff --git a/include/friendica_smarty.php b/include/friendica_smarty.php index b3f0d18a0..b51692675 100644 --- a/include/friendica_smarty.php +++ b/include/friendica_smarty.php @@ -1,9 +1,11 @@ "view/theme/$theme/smarty3/"); + $template_dirs = array('theme' => "view/theme/$theme/".SMARTY3_TEMPLATE_FOLDER."/"); if( x($a->theme_info,"extends") ) - $template_dirs = $template_dirs + array('extends' => "view/theme/".$a->theme_info["extends"]."/smarty3/"); - $template_dirs = $template_dirs + array('base' => 'view/smarty3/'); + $template_dirs = $template_dirs + array('extends' => "view/theme/".$a->theme_info["extends"]."/".SMARTY3_TEMPLATE_FOLDER."/"); + $template_dirs = $template_dirs + array('base' => "view/".SMARTY3_TEMPLATE_FOLDER."/"); $this->setTemplateDir($template_dirs); $this->setCompileDir('view/smarty3/compiled/'); @@ -37,7 +39,40 @@ class FriendicaSmarty extends Smarty { } return $this->fetch('file:' . $this->filename); } + + } - - +class FriendicaSmartyEngine implements ITemplateEngine { + static $name ="smarty3"; + + public function __construct(){ + if(!is_writable('view/smarty3/')){ + echo "ERROR: folder view/smarty3/ must be writable by webserver."; killme(); + } + } + + // ITemplateEngine interface + public function replace_macros($s, $r) { + $template = ''; + if(gettype($s) === 'string') { + $template = $s; + $s = new FriendicaSmarty(); + } + foreach($r as $key=>$value) { + if($key[0] === '$') { + $key = substr($key, 1); + } + $s->assign($key, $value); + } + return $s->parsed($template); + } + + public function get_template_file($file, $root=''){ + $a = get_app(); + $template_file = get_template_file($a, SMARTY3_TEMPLATE_FOLDER.'/'.$file, $root); + $template = new FriendicaSmarty(); + $template->filename = $template_file; + return $template; + } +} diff --git a/include/items.php b/include/items.php index 210e66bf7..f4f972e72 100755 --- a/include/items.php +++ b/include/items.php @@ -294,7 +294,7 @@ function construct_activity_target($item) { if(! function_exists('limit_body_size')) { function limit_body_size($body) { - logger('limit_body_size: start', LOGGER_DEBUG); +// logger('limit_body_size: start', LOGGER_DEBUG); $maxlen = get_max_import_size(); @@ -1180,19 +1180,23 @@ function item_store($arr,$force_parent = false) { ); } - tag_deliver($arr['uid'],$current_post); + $deleted = tag_deliver($arr['uid'],$current_post); - // Store the fresh generated item into the cache - $cachefile = get_cachefile($arr["guid"]."-".hash("md5", $arr['body'])); + // current post can be deleted if is for a communuty page and no mention are + // in it. + if (!$deleted) { + + // Store the fresh generated item into the cache + $cachefile = get_cachefile($arr["guid"]."-".hash("md5", $arr['body'])); - if (($cachefile != '') AND !file_exists($cachefile)) { - $s = prepare_text($arr['body']); - $a = get_app(); - $stamp1 = microtime(true); - file_put_contents($cachefile, $s); - $a->save_timestamp($stamp1, "file"); - logger('item_store: put item '.$current_post.' into cachefile '.$cachefile); - } + if (($cachefile != '') AND !file_exists($cachefile)) { + $s = prepare_text($arr['body']); + $a = get_app(); + $stamp1 = microtime(true); + file_put_contents($cachefile, $s); + $a->save_timestamp($stamp1, "file"); + logger('item_store: put item '.$current_post.' into cachefile '.$cachefile); + } $r = q('SELECT * FROM `item` WHERE id = %d', intval($current_post)); if (count($r) == 1) { @@ -1201,7 +1205,7 @@ function item_store($arr,$force_parent = false) { else { logger('item_store: new item not found in DB, id ' . $current_post); } - + } return $current_post; } @@ -1217,10 +1221,15 @@ function get_item_contact($item,$contacts) { return false; } - +/** + * look for mention tags and setup a second delivery chain for forum/community posts if appropriate + * @param int $uid + * @param int $item_id + * @return bool true if item was deleted, else false + */ function tag_deliver($uid,$item_id) { - // look for mention tags and setup a second delivery chain for forum/community posts if appropriate + // $a = get_app(); @@ -1262,8 +1271,21 @@ function tag_deliver($uid,$item_id) { } } - if(! $mention) + if(! $mention){ + if ( ($community_page || $prvgroup) && + (!$item['wall']) && (!$item['origin']) && ($item['id'] == $item['parent'])){ + // mmh.. no mention.. community page or private group... no wall.. no origin.. top-post (not a comment) + // delete it! + logger("tag_deliver: no-mention top-level post to communuty or private group. delete."); + q("DELETE FROM item WHERE id = %d and uid = %d limit 1", + intval($item_id), + intval($uid) + ); + return true; + } return; + } + // send a notification diff --git a/include/network.php b/include/network.php index e4d01c00f..d2732e039 100644 --- a/include/network.php +++ b/include/network.php @@ -101,6 +101,7 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0, $accept_ } $a->set_curl_code($http_code); + $a->set_curl_content_type($curl_info['content_type']); $body = substr($s,strlen($header)); $a->set_curl_headers($header); @@ -818,12 +819,12 @@ function add_fcontact($arr,$update = false) { } -function scale_external_images($s, $include_link = true, $scale_replace = false) { +function scale_external_images($srctext, $include_link = true, $scale_replace = false) { $a = get_app(); // Picture addresses can contain special characters - $s = htmlspecialchars_decode($s); + $s = htmlspecialchars_decode($srctext); $matches = null; $c = preg_match_all('/\[img.*?\](.*?)\[\/img\]/ism',$s,$matches,PREG_SET_ORDER); @@ -845,7 +846,9 @@ function scale_external_images($s, $include_link = true, $scale_replace = false) $scaled = str_replace($scale_replace[0], $scale_replace[1], $mtch[1]); else $scaled = $mtch[1]; - $i = fetch_url($scaled); + $i = @fetch_url($scaled); + if(! $i) + return $srctext; $cachefile = get_cachefile(hash("md5", $scaled)); if ($cachefile != '') { diff --git a/include/pgettext.php b/include/pgettext.php index 525b64a18..93dd3e4b6 100644 --- a/include/pgettext.php +++ b/include/pgettext.php @@ -1,5 +1,7 @@ r = $r; // remove comments block @@ -276,12 +279,18 @@ class Template { $count++; $s = $this->var_replace($s); } - return $s; + return template_unescape($s); } - + + public function get_template_file($file, $root='') { + $a = get_app(); + $template_file = get_template_file($a, $file, $root); + $content = file_get_contents($template_file); + return $content; + } + } -$t = new Template; function template_escape($s) { diff --git a/include/text.php b/include/text.php index 3d244c61f..7b27d8b86 100644 --- a/include/text.php +++ b/include/text.php @@ -15,39 +15,20 @@ if(! function_exists('replace_macros')) { /** * This is our template processor * - * @global Template $t * @param string|FriendicaSmarty $s the string requiring macro substitution, * or an instance of FriendicaSmarty * @param array $r key value pairs (search => replace) * @return string substituted string */ function replace_macros($s,$r) { - global $t; $stamp1 = microtime(true); $a = get_app(); - if($a->theme['template_engine'] === 'smarty3') { - $template = ''; - if(gettype($s) === 'string') { - $template = $s; - $s = new FriendicaSmarty(); - } - foreach($r as $key=>$value) { - if($key[0] === '$') { - $key = substr($key, 1); - } - $s->assign($key, $value); - } - $output = $s->parsed($template); - } - else { - $r = $t->replace($s,$r); + $t = $a->template_engine(); + $output = $t->replace_macros($s,$r); - $output = template_unescape($r); - } - $a = get_app(); $a->save_timestamp($stamp1, "rendering"); return $output; @@ -582,26 +563,13 @@ function get_markup_template($s, $root = '') { $stamp1 = microtime(true); $a = get_app(); - - if($a->theme['template_engine'] === 'smarty3') { - $template_file = get_template_file($a, 'smarty3/' . $s, $root); - - $template = new FriendicaSmarty(); - $template->filename = $template_file; - $a->save_timestamp($stamp1, "rendering"); - - return $template; - } - else { - $template_file = get_template_file($a, $s, $root); - $a->save_timestamp($stamp1, "rendering"); - - $stamp1 = microtime(true); - $content = file_get_contents($template_file); - $a->save_timestamp($stamp1, "file"); - return $content; - - } + $t = $a->template_engine(); + + $template = $t->get_template_file($s, $root); + + $a->save_timestamp($stamp1, "file"); + + return $template; }} if(! function_exists("get_template_file")) { @@ -623,6 +591,8 @@ function get_template_file($a, $filename, $root = '') { $template_file = "{$root}view/theme/$theme/$filename"; elseif (x($a->theme_info,"extends") && file_exists("{$root}view/theme/{$a->theme_info["extends"]}/$filename")) $template_file = "{$root}view/theme/{$a->theme_info["extends"]}/$filename"; + elseif (file_exists("{$root}/$filename")) + $template_file = "{$root}/$filename"; else $template_file = "{$root}view/$filename"; @@ -1315,18 +1285,49 @@ function prepare_body($item,$attach = false) { return $s; } + $as = ''; + $vhead = false; $arr = explode('[/attach],',$item['attach']); if(count($arr)) { - $s .= '
'; + $as .= '
'; foreach($arr as $r) { $matches = false; $icon = ''; $cnt = preg_match_all('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"|',$r,$matches, PREG_SET_ORDER); if($cnt) { foreach($matches as $mtch) { - $filetype = strtolower(substr( $mtch[3], 0, strpos($mtch[3],'/') )); + $mime = $mtch[3]; + + if((local_user() == $item['uid']) && ($item['contact-id'] != $a->contact['id']) && ($item['network'] == NETWORK_DFRN)) + $the_url = $a->get_baseurl() . '/redir/' . $item['contact-id'] . '?f=1&url=' . $mtch[1]; + else + $the_url = $mtch[1]; + + if(strpos($mime, 'video') !== false) { + if(!$vhead) { + $vhead = true; + $a->page['htmlhead'] .= replace_macros(get_markup_template('videos_head.tpl'), array( + '$baseurl' => $a->get_baseurl(), + )); + $a->page['end'] .= replace_macros(get_markup_template('videos_end.tpl'), array( + '$baseurl' => $a->get_baseurl(), + )); + } + + $id = end(explode('/', $the_url)); + $as .= replace_macros(get_markup_template('video_top.tpl'), array( + '$video' => array( + 'id' => $id, + 'title' => t('View Video'), + 'src' => $the_url, + 'mime' => $mime, + ), + )); + } + + $filetype = strtolower(substr( $mime, 0, strpos($mime,'/') )); if($filetype) { - $filesubtype = strtolower(substr( $mtch[3], strpos($mtch[3],'/') + 1 )); + $filesubtype = strtolower(substr( $mime, strpos($mime,'/') + 1 )); $filesubtype = str_replace('.', '-', $filesubtype); } else { @@ -1350,17 +1351,14 @@ function prepare_body($item,$attach = false) { $title = ((strlen(trim($mtch[4]))) ? escape_tags(trim($mtch[4])) : escape_tags($mtch[1])); $title .= ' ' . $mtch[2] . ' ' . t('bytes'); - if((local_user() == $item['uid']) && ($item['contact-id'] != $a->contact['id']) && ($item['network'] == NETWORK_DFRN)) - $the_url = $a->get_baseurl() . '/redir/' . $item['contact-id'] . '?f=1&url=' . $mtch[1]; - else - $the_url = $mtch[1]; - $s .= '' . $icon . ''; + $as .= '' . $icon . ''; } } } - $s .= '
'; + $as .= '
'; } + $s = $s . $as; // Look for spoiler diff --git a/include/uimport.php b/include/uimport.php index 38b177247..4fd91f80a 100644 --- a/include/uimport.php +++ b/include/uimport.php @@ -1,4 +1,5 @@ mysqli){ - $thedb = $db->getdb(); - return $thedb->insert_id; - } else { - return mysql_insert_id(); - } - } - - function last_error(){ - global $db; - return $db->error; - } - - function db_import_assoc($table, $arr){ - if (IMPORT_DEBUG) return true; - if (isset($arr['id'])) unset($arr['id']); - $cols = implode("`,`", array_map('dbesc', array_keys($arr))); - $vals = implode("','", array_map('dbesc', array_values($arr))); - $query = "INSERT INTO `$table` (`$cols`) VALUES ('$vals')"; - logger("uimport: $query",LOGGER_TRACE); - return q($query); - } +function last_insert_id() { + global $db; + if (IMPORT_DEBUG) + return 1; + if ($db->mysqli) { + $thedb = $db->getdb(); + return $thedb->insert_id; + } else { + return mysql_insert_id(); + } +} + +function last_error() { + global $db; + return $db->error; +} + +/** + * Remove columns from array $arr that aren't in table $table + * + * @param string $table Table name + * @param array &$arr Column=>Value array from json (by ref) + */ +function check_cols($table, &$arr) { + $query = sprintf("SHOW COLUMNS IN `%s`", dbesc($table)); + logger("uimport: $query", LOGGER_DEBUG); + $r = q($query); + $tcols = array(); + // get a plain array of column names + foreach ($r as $tcol) { + $tcols[] = $tcol['Field']; + } + // remove inexistent columns + foreach ($arr as $icol => $ival) { + if (!in_array($icol, $tcols)) { + unset($arr[$icol]); + } + } +} + +/** + * Import data into table $table + * + * @param string $table Table name + * @param array $arr Column=>Value array from json + */ +function db_import_assoc($table, $arr) { + if (isset($arr['id'])) + unset($arr['id']); + check_cols($table, $arr); + $cols = implode("`,`", array_map('dbesc', array_keys($arr))); + $vals = implode("','", array_map('dbesc', array_values($arr))); + $query = "INSERT INTO `$table` (`$cols`) VALUES ('$vals')"; + logger("uimport: $query", LOGGER_TRACE); + if (IMPORT_DEBUG) + return true; + return q($query); +} function import_cleanup($newuid) { - q("DELETE FROM `user` WHERE uid = %d", $newuid); - q("DELETE FROM `contact` WHERE uid = %d", $newuid); - q("DELETE FROM `profile` WHERE uid = %d", $newuid); - q("DELETE FROM `photo` WHERE uid = %d", $newuid); - q("DELETE FROM `group` WHERE uid = %d", $newuid); - q("DELETE FROM `group_member` WHERE uid = %d", $newuid); - q("DELETE FROM `pconfig` WHERE uid = %d", $newuid); - + q("DELETE FROM `user` WHERE uid = %d", $newuid); + q("DELETE FROM `contact` WHERE uid = %d", $newuid); + q("DELETE FROM `profile` WHERE uid = %d", $newuid); + q("DELETE FROM `photo` WHERE uid = %d", $newuid); + q("DELETE FROM `group` WHERE uid = %d", $newuid); + q("DELETE FROM `group_member` WHERE uid = %d", $newuid); + q("DELETE FROM `pconfig` WHERE uid = %d", $newuid); } function import_account(&$a, $file) { - logger("Start user import from ".$file['tmp_name']); - /* - STEPS - 1. checks - 2. replace old baseurl with new baseurl - 3. import data (look at user id and contacts id) - 4. archive non-dfrn contacts - 5. send message to dfrn contacts - */ + logger("Start user import from " . $file['tmp_name']); + /* + STEPS + 1. checks + 2. replace old baseurl with new baseurl + 3. import data (look at user id and contacts id) + 4. archive non-dfrn contacts + 5. send message to dfrn contacts + */ - $account = json_decode(file_get_contents($file['tmp_name']), true); - if ($account===null) { - notice(t("Error decoding account file")); - return; - } - + $account = json_decode(file_get_contents($file['tmp_name']), true); + if ($account === null) { + notice(t("Error decoding account file")); + return; + } + + + if (!x($account, 'version')) { + notice(t("Error! No version data in file! This is not a Friendica account file?")); + return; + } + + /* + // this is not required as we remove columns in json not in current db schema + if ($account['schema'] != DB_UPDATE_VERSION) { + notice(t("Error! I can't import this file: DB schema version is not compatible.")); + return; + } + */ - if (!x($account, 'version')) { - notice(t("Error! No version data in file! This is not a Friendica account file?")); - return; - } - - if ($account['schema'] != DB_UPDATE_VERSION) { - notice(t("Error! I can't import this file: DB schema version is not compatible.")); - return; - } - - // check for username $r = q("SELECT uid FROM user WHERE nickname='%s'", $account['user']['nickname']); - if ($r===false) { - logger("uimport:check nickname : ERROR : ".last_error(), LOGGER_NORMAL); + if ($r === false) { + logger("uimport:check nickname : ERROR : " . last_error(), LOGGER_NORMAL); notice(t('Error! Cannot check nickname')); return; } - if (count($r)>0) { - notice(sprintf(t("User '%s' already exists on this server!"),$account['user']['nickname'])); + if (count($r) > 0) { + notice(sprintf(t("User '%s' already exists on this server!"), $account['user']['nickname'])); return; } - $oldbaseurl = $account['baseurl']; - $newbaseurl = $a->get_baseurl(); - $olduid = $account['user']['uid']; - - unset($account['user']['uid']); - foreach($account['user'] as $k => &$v) { - $v = str_replace($oldbaseurl, $newbaseurl, $v); - } + $oldbaseurl = $account['baseurl']; + $newbaseurl = $a->get_baseurl(); + $olduid = $account['user']['uid']; - - // import user - $r = db_import_assoc('user', $account['user']); - if ($r===false) { - //echo "
"; var_dump($r, $query, mysql_error()); killme();
-        logger("uimport:insert user : ERROR : ".last_error(), LOGGER_NORMAL);
-        notice(t("User creation error"));
-        return;
-    }
-    $newuid = last_insert_id();
-    //~ $newuid = 1;
-    
+	unset($account['user']['uid']);
+	foreach ($account['user'] as $k => &$v) {
+		$v = str_replace($oldbaseurl, $newbaseurl, $v);
+	}
 
 
-    foreach($account['profile'] as &$profile) {
-        foreach($profile as $k=>&$v) {
-            $v = str_replace($oldbaseurl, $newbaseurl, $v);
-            foreach(array("profile","avatar") as $k)
-                $v = str_replace($newbaseurl."/photo/".$k."/".$olduid.".jpg", $newbaseurl."/photo/".$k."/".$newuid.".jpg", $v);
-        }
-        $profile['uid'] = $newuid;
-        $r = db_import_assoc('profile', $profile);
-        if ($r===false) {
-            logger("uimport:insert profile ".$profile['profile-name']." : ERROR : ".last_error(), LOGGER_NORMAL);
-            info(t("User profile creation error"));
-            import_cleanup($newuid);
-            return;
-        }
-    }
-
-    $errorcount=0;
-    foreach($account['contact'] as &$contact) {
-        if ($contact['uid'] == $olduid && $contact['self'] == '1'){
-            foreach($contact as $k=>&$v) {
-                $v = str_replace($oldbaseurl, $newbaseurl, $v);
-                foreach(array("profile","avatar","micro") as $k)
-                    $v = str_replace($newbaseurl."/photo/".$k."/".$olduid.".jpg", $newbaseurl."/photo/".$k."/".$newuid.".jpg", $v);
-            }
-        }
-         if ($contact['uid'] == $olduid && $contact['self'] == '0') {
-            switch ($contact['network']){
-                case NETWORK_DFRN:
-                    //  send relocate message (below)
-                    break;
-                case NETWORK_ZOT:
-                    // TODO handle zot network
-                    break;
-                case NETWORK_MAIL2:
-                    // TODO ?
-                    break;
-                case NETWORK_FEED:
-                case NETWORK_MAIL:
-                    // Nothing to do
-                    break;
-                default:
-                    // archive other contacts
-                    $contact['archive'] = "1";
-            }
-        }
-        $contact['uid'] = $newuid;
-        $r = db_import_assoc('contact', $contact);
-        if ($r===false) {
-            logger("uimport:insert contact ".$contact['nick'].",".$contact['network']." : ERROR : ".last_error(), LOGGER_NORMAL);
-            $errorcount++;
-        } else {
-            $contact['newid'] = last_insert_id();
-        }
-    }
-    if ($errorcount>0) {
-        notice( sprintf(tt("%d contact not imported", "%d contacts not imported", $errorcount), $errorcount) );
-    }
-
-    foreach($account['group'] as &$group) {
-        $group['uid'] = $newuid;
-        $r = db_import_assoc('group', $group);
-        if ($r===false) {
-            logger("uimport:insert group ".$group['name']." : ERROR : ".last_error(), LOGGER_NORMAL);
-        } else {
-            $group['newid'] = last_insert_id();
-        }
-    }
-
-    foreach($account['group_member'] as &$group_member) {
-        $group_member['uid'] = $newuid;
-        
-        $import = 0;
-        foreach($account['group'] as $group) {
-            if ($group['id'] == $group_member['gid'] && isset($group['newid'])) {
-                $group_member['gid'] = $group['newid'];
-                $import++;
-                break;
-            }
-        }
-        foreach($account['contact'] as $contact) {
-            if ($contact['id'] == $group_member['contact-id'] && isset($contact['newid'])) {
-                $group_member['contact-id'] = $contact['newid'];
-                $import++;
-                break;
-            }
-        }
-        if ($import==2) {
-            $r = db_import_assoc('group_member', $group_member);
-            if ($r===false) {
-                logger("uimport:insert group member ".$group_member['id']." : ERROR : ".last_error(), LOGGER_NORMAL);
-            }
-        }
-    }
+	// import user
+	$r = db_import_assoc('user', $account['user']);
+	if ($r === false) {
+		//echo "
"; var_dump($r, $query, mysql_error()); killme();
+		logger("uimport:insert user : ERROR : " . last_error(), LOGGER_NORMAL);
+		notice(t("User creation error"));
+		return;
+	}
+	$newuid = last_insert_id();
+	//~ $newuid = 1;
 
 
 
-    
-    
-    foreach($account['photo'] as &$photo) {
-        $photo['uid'] = $newuid;
-        $photo['data'] = hex2bin($photo['data']);
-        
-        $p = new Photo($photo['data'], $photo['type']);
-        $r = $p->store(
-            $photo['uid'],
-            $photo['contact-id'], //0
-            $photo['resource-id'],
-            $photo['filename'],
-            $photo['album'],
-            $photo['scale'],
-            $photo['profile'], //1
-            $photo['allow_cid'],
-            $photo['allow_gid'],
-            $photo['deny_cid'],
-            $photo['deny_gid']
-        );
-        
-        if ($r===false) {
-            logger("uimport:insert photo ".$photo['resource-id'].",". $photo['scale']. " : ERROR : ".last_error(), LOGGER_NORMAL);
-        }
-    } 
-    
-    foreach($account['pconfig'] as &$pconfig) {
-        $pconfig['uid'] = $newuid;
-        $r = db_import_assoc('pconfig', $pconfig);
-        if ($r===false) {
-            logger("uimport:insert pconfig ".$pconfig['id']. " : ERROR : ".last_error(), LOGGER_NORMAL);
-        }
-    } 
-    
-    // send relocate messages
-    proc_run('php', 'include/notifier.php', 'relocate' , $newuid);
-    
-    info(t("Done. You can now login with your username and password"));
-    goaway( $a->get_baseurl() ."/login");
-    
-    
+	foreach ($account['profile'] as &$profile) {
+		foreach ($profile as $k => &$v) {
+			$v = str_replace($oldbaseurl, $newbaseurl, $v);
+			foreach (array("profile", "avatar") as $k)
+				$v = str_replace($newbaseurl . "/photo/" . $k . "/" . $olduid . ".jpg", $newbaseurl . "/photo/" . $k . "/" . $newuid . ".jpg", $v);
+		}
+		$profile['uid'] = $newuid;
+		$r = db_import_assoc('profile', $profile);
+		if ($r === false) {
+			logger("uimport:insert profile " . $profile['profile-name'] . " : ERROR : " . last_error(), LOGGER_NORMAL);
+			info(t("User profile creation error"));
+			import_cleanup($newuid);
+			return;
+		}
+	}
+
+	$errorcount = 0;
+	foreach ($account['contact'] as &$contact) {
+		if ($contact['uid'] == $olduid && $contact['self'] == '1') {
+			foreach ($contact as $k => &$v) {
+				$v = str_replace($oldbaseurl, $newbaseurl, $v);
+				foreach (array("profile", "avatar", "micro") as $k)
+					$v = str_replace($newbaseurl . "/photo/" . $k . "/" . $olduid . ".jpg", $newbaseurl . "/photo/" . $k . "/" . $newuid . ".jpg", $v);
+			}
+		}
+		if ($contact['uid'] == $olduid && $contact['self'] == '0') {
+			switch ($contact['network']) {
+				case NETWORK_DFRN:
+					//  send relocate message (below)
+					break;
+				case NETWORK_ZOT:
+					// TODO handle zot network
+					break;
+				case NETWORK_MAIL2:
+					// TODO ?
+					break;
+				case NETWORK_FEED:
+				case NETWORK_MAIL:
+					// Nothing to do
+					break;
+				default:
+					// archive other contacts
+					$contact['archive'] = "1";
+			}
+		}
+		$contact['uid'] = $newuid;
+		$r = db_import_assoc('contact', $contact);
+		if ($r === false) {
+			logger("uimport:insert contact " . $contact['nick'] . "," . $contact['network'] . " : ERROR : " . last_error(), LOGGER_NORMAL);
+			$errorcount++;
+		} else {
+			$contact['newid'] = last_insert_id();
+		}
+	}
+	if ($errorcount > 0) {
+		notice(sprintf(tt("%d contact not imported", "%d contacts not imported", $errorcount), $errorcount));
+	}
+
+	foreach ($account['group'] as &$group) {
+		$group['uid'] = $newuid;
+		$r = db_import_assoc('group', $group);
+		if ($r === false) {
+			logger("uimport:insert group " . $group['name'] . " : ERROR : " . last_error(), LOGGER_NORMAL);
+		} else {
+			$group['newid'] = last_insert_id();
+		}
+	}
+
+	foreach ($account['group_member'] as &$group_member) {
+		$group_member['uid'] = $newuid;
+
+		$import = 0;
+		foreach ($account['group'] as $group) {
+			if ($group['id'] == $group_member['gid'] && isset($group['newid'])) {
+				$group_member['gid'] = $group['newid'];
+				$import++;
+				break;
+			}
+		}
+		foreach ($account['contact'] as $contact) {
+			if ($contact['id'] == $group_member['contact-id'] && isset($contact['newid'])) {
+				$group_member['contact-id'] = $contact['newid'];
+				$import++;
+				break;
+			}
+		}
+		if ($import == 2) {
+			$r = db_import_assoc('group_member', $group_member);
+			if ($r === false) {
+				logger("uimport:insert group member " . $group_member['id'] . " : ERROR : " . last_error(), LOGGER_NORMAL);
+			}
+		}
+	}
+
+
+
+
+
+	foreach ($account['photo'] as &$photo) {
+		$photo['uid'] = $newuid;
+		$photo['data'] = hex2bin($photo['data']);
+
+		$p = new Photo($photo['data'], $photo['type']);
+		$r = $p->store(
+				$photo['uid'], $photo['contact-id'], //0
+				$photo['resource-id'], $photo['filename'], $photo['album'], $photo['scale'], $photo['profile'], //1
+				$photo['allow_cid'], $photo['allow_gid'], $photo['deny_cid'], $photo['deny_gid']
+		);
+
+		if ($r === false) {
+			logger("uimport:insert photo " . $photo['resource-id'] . "," . $photo['scale'] . " : ERROR : " . last_error(), LOGGER_NORMAL);
+		}
+	}
+
+	foreach ($account['pconfig'] as &$pconfig) {
+		$pconfig['uid'] = $newuid;
+		$r = db_import_assoc('pconfig', $pconfig);
+		if ($r === false) {
+			logger("uimport:insert pconfig " . $pconfig['id'] . " : ERROR : " . last_error(), LOGGER_NORMAL);
+		}
+	}
+
+	// send relocate messages
+	proc_run('php', 'include/notifier.php', 'relocate', $newuid);
+
+	info(t("Done. You can now login with your username and password"));
+	goaway($a->get_baseurl() . "/login");
 }
diff --git a/js/main.js b/js/main.js
index 488d5d4c7..a4a1c977c 100644
--- a/js/main.js
+++ b/js/main.js
@@ -188,7 +188,11 @@
 
 				$("img[data-src]", nnm).each(function(i, el){
 					// Add src attribute for images with a data-src attribute
-					$(el).attr('src', $(el).data("src"));
+					// However, don't bother if the data-src attribute is empty, because
+					// an empty "src" tag for an image will cause some browsers
+					// to prefetch the root page of the Friendica hub, which will
+					// unnecessarily load an entire profile/ or network/ page
+					if($(el).data("src") != '') $(el).attr('src', $(el).data("src"));
 				});
 			}
 
@@ -381,6 +385,9 @@
 			}
 			/* autocomplete @nicknames */
 			$(".comment-edit-form  textarea").contact_autocomplete(baseurl+"/acl");
+
+			// setup videos, since VideoJS won't take care of any loaded via AJAX
+			if(typeof videojs != 'undefined') videojs.autoSetup();
 		});
 	}
 
diff --git a/js/main.min.js b/js/main.min.js
index cd127f979..e1cad27fa 100644
--- a/js/main.min.js
+++ b/js/main.min.js
@@ -1 +1 @@
-function openClose(theID){if(document.getElementById(theID).style.display=="block"){document.getElementById(theID).style.display="none"}else{document.getElementById(theID).style.display="block"}}function openMenu(theID){document.getElementById(theID).style.display="block"}function closeMenu(theID){document.getElementById(theID).style.display="none"}var src=null;var prev=null;var livetime=null;var msie=false;var stopped=false;var totStopped=false;var timer=null;var pr=0;var liking=0;var in_progress=false;var langSelect=false;var commentBusy=false;var last_popup_menu=null;var last_popup_button=null;$(function(){$.ajaxSetup({cache:false});msie=$.browser.msie;$(".onoff input").each(function(){val=$(this).val();id=$(this).attr("id");$("#"+id+"_onoff ."+(val==0?"on":"off")).addClass("hidden")});$(".onoff > a").click(function(event){event.preventDefault();var input=$(this).siblings("input");var val=1-input.val();var id=input.attr("id");$("#"+id+"_onoff ."+(val==0?"on":"off")).addClass("hidden");$("#"+id+"_onoff ."+(val==1?"on":"off")).removeClass("hidden");input.val(val)});setupFieldRichtext();function close_last_popup_menu(){if(last_popup_menu){last_popup_menu.hide();last_popup_button.removeClass("selected");last_popup_menu=null;last_popup_button=null}}$("a[rel^=#]").click(function(e){close_last_popup_menu();menu=$($(this).attr("rel"));e.preventDefault();e.stopPropagation();if(menu.attr("popup")=="false")return false;$(this).parent().toggleClass("selected");menu.toggle();if(menu.css("display")=="none"){last_popup_menu=null;last_popup_button=null}else{last_popup_menu=menu;last_popup_button=$(this).parent()}return false});$("html").click(function(){close_last_popup_menu()});$("a.popupbox").colorbox({inline:true,transition:"elastic"});var notifications_tpl=unescape($("#nav-notifications-template[rel=template]").html());var notifications_all=unescape($("
").append($("#nav-notifications-see-all").clone()).html());var notifications_mark=unescape($("
").append($("#nav-notifications-mark-all").clone()).html());var notifications_empty=unescape($("#nav-notifications-menu").html());$("nav").bind("nav-update",function(e,data){var invalid=$(data).find("invalid").text();if(invalid==1){window.location.href=window.location.href}var net=$(data).find("net").text();if(net==0){net="";$("#net-update").removeClass("show")}else{$("#net-update").addClass("show")}$("#net-update").html(net);var home=$(data).find("home").text();if(home==0){home="";$("#home-update").removeClass("show")}else{$("#home-update").addClass("show")}$("#home-update").html(home);var intro=$(data).find("intro").text();if(intro==0){intro="";$("#intro-update").removeClass("show")}else{$("#intro-update").addClass("show")}$("#intro-update").html(intro);var mail=$(data).find("mail").text();if(mail==0){mail="";$("#mail-update").removeClass("show")}else{$("#mail-update").addClass("show")}$("#mail-update").html(mail);var intro=$(data).find("intro").text();if(intro==0){intro="";$("#intro-update-li").removeClass("show")}else{$("#intro-update-li").addClass("show")}$("#intro-update-li").html(intro);var mail=$(data).find("mail").text();if(mail==0){mail="";$("#mail-update-li").removeClass("show")}else{$("#mail-update-li").addClass("show")}$("#mail-update-li").html(mail);var allevents=$(data).find("all-events").text();if(allevents==0){allevents="";$("#allevents-update").removeClass("show")}else{$("#allevents-update").addClass("show")}$("#allevents-update").html(allevents);var alleventstoday=$(data).find("all-events-today").text();if(alleventstoday==0){$("#allevents-update").removeClass("notif-allevents-today")}else{$("#allevents-update").addClass("notif-allevents-today")}var events=$(data).find("events").text();if(events==0){events="";$("#events-update").removeClass("show")}else{$("#events-update").addClass("show")}$("#events-update").html(events);var eventstoday=$(data).find("events-today").text();if(eventstoday==0){$("#events-update").removeClass("notif-events-today")}else{$("#events-update").addClass("notif-events-today")}var birthdays=$(data).find("birthdays").text();if(birthdays==0){birthdays="";$("#birthdays-update").removeClass("show")}else{$("#birthdays-update").addClass("show")}$("#birthdays-update").html(birthdays);var birthdaystoday=$(data).find("birthdays-today").text();if(birthdaystoday==0){$("#birthdays-update").removeClass("notif-birthdays-today")}else{$("#birthdays-update").addClass("notif-birthdays-today")}var eNotif=$(data).find("notif");if(eNotif.children("note").length==0){$("#nav-notifications-menu").html(notifications_empty)}else{nnm=$("#nav-notifications-menu");nnm.html(notifications_all+notifications_mark);eNotif.children("note").each(function(){e=$(this);text=e.text().format(""+e.attr("name")+"");html=notifications_tpl.format(e.attr("href"),e.attr("photo"),text,e.attr("date"),e.attr("seen"));nnm.append(html)});$("img[data-src]",nnm).each(function(i,el){$(el).attr("src",$(el).data("src"))})}notif=eNotif.attr("count");if(notif>0){$("#nav-notifications-linkmenu").addClass("on")}else{$("#nav-notifications-linkmenu").removeClass("on")}if(notif==0){notif="";$("#notify-update").removeClass("show")}else{$("#notify-update").addClass("show")}$("#notify-update").html(notif);var eSysmsg=$(data).find("sysmsgs");eSysmsg.children("notice").each(function(){text=$(this).text();$.jGrowl(text,{sticky:true,theme:"notice"})});eSysmsg.children("info").each(function(){text=$(this).text();$.jGrowl(text,{sticky:false,theme:"info",life:1e4})})});NavUpdate();$(document).keydown(function(event){if(event.keyCode=="8"){var target=event.target||event.srcElement;if(!/input|textarea/i.test(target.nodeName)){return false}}if(event.keyCode=="19"||event.ctrlKey&&event.which=="32"){event.preventDefault();if(stopped==false){stopped=true;if(event.ctrlKey){totStopped=true}$("#pause").html('pause')}else{unpause()}}else{if(!totStopped){unpause()}}})});function NavUpdate(){if(!stopped){var pingCmd="ping"+(localUser!=0?"?f=&uid="+localUser:"");$.get(pingCmd,function(data){$(data).find("result").each(function(){$("nav").trigger("nav-update",this);if($("#live-network").length){src="network";liveUpdate()}if($("#live-profile").length){src="profile";liveUpdate()}if($("#live-community").length){src="community";liveUpdate()}if($("#live-notes").length){src="notes";liveUpdate()}if($("#live-display").length){src="display";liveUpdate()}if($("#live-photos").length){if(liking){liking=0;window.location.href=window.location.href}}})})}timer=setTimeout(NavUpdate,updateInterval)}function liveUpdate(){if(src==null||stopped||!profile_uid){$(".like-rotator").hide();return}if($(".comment-edit-text-full").length||in_progress){if(livetime){clearTimeout(livetime)}livetime=setTimeout(liveUpdate,1e4);return}if(livetime!=null)livetime=null;prev="live-"+src;in_progress=true;var udargs=netargs.length?"/"+netargs:"";var update_url="update_"+src+udargs+"&p="+profile_uid+"&page="+profile_page+"&msie="+(msie?1:0);$.get(update_url,function(data){in_progress=false;$(".toplevel_item",data).each(function(){var ident=$(this).attr("id");if($("#"+ident).length==0&&profile_page==1){$("img",this).each(function(){$(this).attr("src",$(this).attr("dst"))});$("#"+prev).after($(this))}else{var id=$(".hide-comments-total",this).attr("id");if(typeof id!="undefined"){id=id.split("-")[3];var commentsOpen=$("#collapsed-comments-"+id).is(":visible")}$("img",this).each(function(){$(this).attr("src",$(this).attr("dst"))});$("html").height($("html").height());$("#"+ident).replaceWith($(this));if(typeof id!="undefined"){if(commentsOpen)showHideComments(id)}$("html").height("auto")}prev=ident});$(".like-rotator").hide();if(commentBusy){commentBusy=false;$("body").css("cursor","auto")}$(".comment-edit-form textarea").contact_autocomplete(baseurl+"/acl")})}function imgbright(node){$(node).removeClass("drophide").addClass("drop")}function imgdull(node){$(node).removeClass("drop").addClass("drophide")}function dolike(ident,verb){unpause();$("#like-rotator-"+ident.toString()).show();$.get("like/"+ident.toString()+"?verb="+verb,NavUpdate);liking=1}function dosubthread(ident){unpause();$("#like-rotator-"+ident.toString()).show();$.get("subthread/"+ident.toString(),NavUpdate);liking=1}function dostar(ident){ident=ident.toString();$("#like-rotator-"+ident).show();$.get("starred/"+ident,function(data){if(data.match(/1/)){$("#starred-"+ident).addClass("starred");$("#starred-"+ident).removeClass("unstarred");$("#star-"+ident).addClass("hidden");$("#unstar-"+ident).removeClass("hidden")}else{$("#starred-"+ident).addClass("unstarred");$("#starred-"+ident).removeClass("starred");$("#star-"+ident).removeClass("hidden");$("#unstar-"+ident).addClass("hidden")}$("#like-rotator-"+ident).hide()})}function getPosition(e){var cursor={x:0,y:0};if(e.pageX||e.pageY){cursor.x=e.pageX;cursor.y=e.pageY}else{if(e.clientX||e.clientY){cursor.x=e.clientX+(document.documentElement.scrollLeft||document.body.scrollLeft)-document.documentElement.clientLeft;cursor.y=e.clientY+(document.documentElement.scrollTop||document.body.scrollTop)-document.documentElement.clientTop}else{if(e.x||e.y){cursor.x=e.x;cursor.y=e.y}}}return cursor}var lockvisible=false;function lockview(event,id){event=event||window.event;cursor=getPosition(event);if(lockvisible){lockviewhide()}else{lockvisible=true;$.get("lockview/"+id,function(data){$("#panel").html(data);$("#panel").css({left:cursor.x+5,top:cursor.y+5});$("#panel").show()})}}function lockviewhide(){lockvisible=false;$("#panel").hide()}function post_comment(id){unpause();commentBusy=true;$("body").css("cursor","wait");$("#comment-preview-inp-"+id).val("0");$.post("item",$("#comment-edit-form-"+id).serialize(),function(data){if(data.success){$("#comment-edit-wrapper-"+id).hide();$("#comment-edit-text-"+id).val("");var tarea=document.getElementById("comment-edit-text-"+id);if(tarea)commentClose(tarea,id);if(timer)clearTimeout(timer);timer=setTimeout(NavUpdate,10)}if(data.reload){window.location.href=data.reload}},"json");return false}function preview_comment(id){$("#comment-preview-inp-"+id).val("1");$("#comment-edit-preview-"+id).show();$.post("item",$("#comment-edit-form-"+id).serialize(),function(data){if(data.preview){$("#comment-edit-preview-"+id).html(data.preview);$("#comment-edit-preview-"+id+" a").click(function(){return false})}},"json");return true}function showHideComments(id){if($("#collapsed-comments-"+id).is(":visible")){$("#collapsed-comments-"+id).hide();$("#hide-comments-"+id).html(window.showMore)}else{$("#collapsed-comments-"+id).show();$("#hide-comments-"+id).html(window.showFewer)}}function preview_post(){$("#jot-preview").val("1");$("#jot-preview-content").show();tinyMCE.triggerSave();$.post("item",$("#profile-jot-form").serialize(),function(data){if(data.preview){$("#jot-preview-content").html(data.preview);$("#jot-preview-content"+" a").click(function(){return false})}},"json");$("#jot-preview").val("0");return true}function unpause(){totStopped=false;stopped=false;$("#pause").html("")}function bin2hex(s){var v,i,f=0,a=[];s+="";f=s.length;for(i=0;i'+data.desc+'
'+data.version+'
'+data.credits+'
'+theme+'')})} \ No newline at end of file +function openClose(theID){if(document.getElementById(theID).style.display=="block"){document.getElementById(theID).style.display="none"}else{document.getElementById(theID).style.display="block"}}function openMenu(theID){document.getElementById(theID).style.display="block"}function closeMenu(theID){document.getElementById(theID).style.display="none"}var src=null;var prev=null;var livetime=null;var msie=false;var stopped=false;var totStopped=false;var timer=null;var pr=0;var liking=0;var in_progress=false;var langSelect=false;var commentBusy=false;var last_popup_menu=null;var last_popup_button=null;$(function(){$.ajaxSetup({cache:false});msie=$.browser.msie;$(".onoff input").each(function(){val=$(this).val();id=$(this).attr("id");$("#"+id+"_onoff ."+(val==0?"on":"off")).addClass("hidden")});$(".onoff > a").click(function(event){event.preventDefault();var input=$(this).siblings("input");var val=1-input.val();var id=input.attr("id");$("#"+id+"_onoff ."+(val==0?"on":"off")).addClass("hidden");$("#"+id+"_onoff ."+(val==1?"on":"off")).removeClass("hidden");input.val(val)});setupFieldRichtext();function close_last_popup_menu(){if(last_popup_menu){last_popup_menu.hide();last_popup_button.removeClass("selected");last_popup_menu=null;last_popup_button=null}}$("a[rel^=#]").click(function(e){close_last_popup_menu();menu=$($(this).attr("rel"));e.preventDefault();e.stopPropagation();if(menu.attr("popup")=="false")return false;$(this).parent().toggleClass("selected");menu.toggle();if(menu.css("display")=="none"){last_popup_menu=null;last_popup_button=null}else{last_popup_menu=menu;last_popup_button=$(this).parent()}return false});$("html").click(function(){close_last_popup_menu()});$("a.popupbox").colorbox({inline:true,transition:"elastic"});var notifications_tpl=unescape($("#nav-notifications-template[rel=template]").html());var notifications_all=unescape($("
").append($("#nav-notifications-see-all").clone()).html());var notifications_mark=unescape($("
").append($("#nav-notifications-mark-all").clone()).html());var notifications_empty=unescape($("#nav-notifications-menu").html());$("nav").bind("nav-update",function(e,data){var invalid=$(data).find("invalid").text();if(invalid==1){window.location.href=window.location.href}var net=$(data).find("net").text();if(net==0){net="";$("#net-update").removeClass("show")}else{$("#net-update").addClass("show")}$("#net-update").html(net);var home=$(data).find("home").text();if(home==0){home="";$("#home-update").removeClass("show")}else{$("#home-update").addClass("show")}$("#home-update").html(home);var intro=$(data).find("intro").text();if(intro==0){intro="";$("#intro-update").removeClass("show")}else{$("#intro-update").addClass("show")}$("#intro-update").html(intro);var mail=$(data).find("mail").text();if(mail==0){mail="";$("#mail-update").removeClass("show")}else{$("#mail-update").addClass("show")}$("#mail-update").html(mail);var intro=$(data).find("intro").text();if(intro==0){intro="";$("#intro-update-li").removeClass("show")}else{$("#intro-update-li").addClass("show")}$("#intro-update-li").html(intro);var mail=$(data).find("mail").text();if(mail==0){mail="";$("#mail-update-li").removeClass("show")}else{$("#mail-update-li").addClass("show")}$("#mail-update-li").html(mail);var allevents=$(data).find("all-events").text();if(allevents==0){allevents="";$("#allevents-update").removeClass("show")}else{$("#allevents-update").addClass("show")}$("#allevents-update").html(allevents);var alleventstoday=$(data).find("all-events-today").text();if(alleventstoday==0){$("#allevents-update").removeClass("notif-allevents-today")}else{$("#allevents-update").addClass("notif-allevents-today")}var events=$(data).find("events").text();if(events==0){events="";$("#events-update").removeClass("show")}else{$("#events-update").addClass("show")}$("#events-update").html(events);var eventstoday=$(data).find("events-today").text();if(eventstoday==0){$("#events-update").removeClass("notif-events-today")}else{$("#events-update").addClass("notif-events-today")}var birthdays=$(data).find("birthdays").text();if(birthdays==0){birthdays="";$("#birthdays-update").removeClass("show")}else{$("#birthdays-update").addClass("show")}$("#birthdays-update").html(birthdays);var birthdaystoday=$(data).find("birthdays-today").text();if(birthdaystoday==0){$("#birthdays-update").removeClass("notif-birthdays-today")}else{$("#birthdays-update").addClass("notif-birthdays-today")}var eNotif=$(data).find("notif");if(eNotif.children("note").length==0){$("#nav-notifications-menu").html(notifications_empty)}else{nnm=$("#nav-notifications-menu");nnm.html(notifications_all+notifications_mark);eNotif.children("note").each(function(){e=$(this);text=e.text().format(""+e.attr("name")+"");html=notifications_tpl.format(e.attr("href"),e.attr("photo"),text,e.attr("date"),e.attr("seen"));nnm.append(html)});$("img[data-src]",nnm).each(function(i,el){if($(el).data("src")!="")$(el).attr("src",$(el).data("src"))})}notif=eNotif.attr("count");if(notif>0){$("#nav-notifications-linkmenu").addClass("on")}else{$("#nav-notifications-linkmenu").removeClass("on")}if(notif==0){notif="";$("#notify-update").removeClass("show")}else{$("#notify-update").addClass("show")}$("#notify-update").html(notif);var eSysmsg=$(data).find("sysmsgs");eSysmsg.children("notice").each(function(){text=$(this).text();$.jGrowl(text,{sticky:true,theme:"notice"})});eSysmsg.children("info").each(function(){text=$(this).text();$.jGrowl(text,{sticky:false,theme:"info",life:1e4})})});NavUpdate();$(document).keydown(function(event){if(event.keyCode=="8"){var target=event.target||event.srcElement;if(!/input|textarea/i.test(target.nodeName)){return false}}if(event.keyCode=="19"||event.ctrlKey&&event.which=="32"){event.preventDefault();if(stopped==false){stopped=true;if(event.ctrlKey){totStopped=true}$("#pause").html('pause')}else{unpause()}}else{if(!totStopped){unpause()}}})});function NavUpdate(){if(!stopped){var pingCmd="ping"+(localUser!=0?"?f=&uid="+localUser:"");$.get(pingCmd,function(data){$(data).find("result").each(function(){$("nav").trigger("nav-update",this);if($("#live-network").length){src="network";liveUpdate()}if($("#live-profile").length){src="profile";liveUpdate()}if($("#live-community").length){src="community";liveUpdate()}if($("#live-notes").length){src="notes";liveUpdate()}if($("#live-display").length){src="display";liveUpdate()}if($("#live-photos").length){if(liking){liking=0;window.location.href=window.location.href}}})})}timer=setTimeout(NavUpdate,updateInterval)}function liveUpdate(){if(src==null||stopped||!profile_uid){$(".like-rotator").hide();return}if($(".comment-edit-text-full").length||in_progress){if(livetime){clearTimeout(livetime)}livetime=setTimeout(liveUpdate,1e4);return}if(livetime!=null)livetime=null;prev="live-"+src;in_progress=true;var udargs=netargs.length?"/"+netargs:"";var update_url="update_"+src+udargs+"&p="+profile_uid+"&page="+profile_page+"&msie="+(msie?1:0);$.get(update_url,function(data){in_progress=false;$(".toplevel_item",data).each(function(){var ident=$(this).attr("id");if($("#"+ident).length==0&&profile_page==1){$("img",this).each(function(){$(this).attr("src",$(this).attr("dst"))});$("#"+prev).after($(this))}else{var id=$(".hide-comments-total",this).attr("id");if(typeof id!="undefined"){id=id.split("-")[3];var commentsOpen=$("#collapsed-comments-"+id).is(":visible")}$("img",this).each(function(){$(this).attr("src",$(this).attr("dst"))});$("html").height($("html").height());$("#"+ident).replaceWith($(this));if(typeof id!="undefined"){if(commentsOpen)showHideComments(id)}$("html").height("auto")}prev=ident});$(".like-rotator").hide();if(commentBusy){commentBusy=false;$("body").css("cursor","auto")}$(".comment-edit-form textarea").contact_autocomplete(baseurl+"/acl");if(typeof videojs!="undefined")videojs.autoSetup()})}function imgbright(node){$(node).removeClass("drophide").addClass("drop")}function imgdull(node){$(node).removeClass("drop").addClass("drophide")}function dolike(ident,verb){unpause();$("#like-rotator-"+ident.toString()).show();$.get("like/"+ident.toString()+"?verb="+verb,NavUpdate);liking=1}function dosubthread(ident){unpause();$("#like-rotator-"+ident.toString()).show();$.get("subthread/"+ident.toString(),NavUpdate);liking=1}function dostar(ident){ident=ident.toString();$("#like-rotator-"+ident).show();$.get("starred/"+ident,function(data){if(data.match(/1/)){$("#starred-"+ident).addClass("starred");$("#starred-"+ident).removeClass("unstarred");$("#star-"+ident).addClass("hidden");$("#unstar-"+ident).removeClass("hidden")}else{$("#starred-"+ident).addClass("unstarred");$("#starred-"+ident).removeClass("starred");$("#star-"+ident).removeClass("hidden");$("#unstar-"+ident).addClass("hidden")}$("#like-rotator-"+ident).hide()})}function getPosition(e){var cursor={x:0,y:0};if(e.pageX||e.pageY){cursor.x=e.pageX;cursor.y=e.pageY}else{if(e.clientX||e.clientY){cursor.x=e.clientX+(document.documentElement.scrollLeft||document.body.scrollLeft)-document.documentElement.clientLeft;cursor.y=e.clientY+(document.documentElement.scrollTop||document.body.scrollTop)-document.documentElement.clientTop}else{if(e.x||e.y){cursor.x=e.x;cursor.y=e.y}}}return cursor}var lockvisible=false;function lockview(event,id){event=event||window.event;cursor=getPosition(event);if(lockvisible){lockviewhide()}else{lockvisible=true;$.get("lockview/"+id,function(data){$("#panel").html(data);$("#panel").css({left:cursor.x+5,top:cursor.y+5});$("#panel").show()})}}function lockviewhide(){lockvisible=false;$("#panel").hide()}function post_comment(id){unpause();commentBusy=true;$("body").css("cursor","wait");$("#comment-preview-inp-"+id).val("0");$.post("item",$("#comment-edit-form-"+id).serialize(),function(data){if(data.success){$("#comment-edit-wrapper-"+id).hide();$("#comment-edit-text-"+id).val("");var tarea=document.getElementById("comment-edit-text-"+id);if(tarea)commentClose(tarea,id);if(timer)clearTimeout(timer);timer=setTimeout(NavUpdate,10)}if(data.reload){window.location.href=data.reload}},"json");return false}function preview_comment(id){$("#comment-preview-inp-"+id).val("1");$("#comment-edit-preview-"+id).show();$.post("item",$("#comment-edit-form-"+id).serialize(),function(data){if(data.preview){$("#comment-edit-preview-"+id).html(data.preview);$("#comment-edit-preview-"+id+" a").click(function(){return false})}},"json");return true}function showHideComments(id){if($("#collapsed-comments-"+id).is(":visible")){$("#collapsed-comments-"+id).hide();$("#hide-comments-"+id).html(window.showMore)}else{$("#collapsed-comments-"+id).show();$("#hide-comments-"+id).html(window.showFewer)}}function preview_post(){$("#jot-preview").val("1");$("#jot-preview-content").show();tinyMCE.triggerSave();$.post("item",$("#profile-jot-form").serialize(),function(data){if(data.preview){$("#jot-preview-content").html(data.preview);$("#jot-preview-content"+" a").click(function(){return false})}},"json");$("#jot-preview").val("0");return true}function unpause(){totStopped=false;stopped=false;$("#pause").html("")}function bin2hex(s){var v,i,f=0,a=[];s+="";f=s.length;for(i=0;i'+data.desc+'
'+data.version+'
'+data.credits+'
'+theme+'')})} \ No newline at end of file diff --git a/library/OAuth1.php b/library/OAuth1.php index 0db6fabcb..53b905e77 100644 --- a/library/OAuth1.php +++ b/library/OAuth1.php @@ -3,8 +3,10 @@ /* Generic exception class */ -class OAuthException extends Exception { - // pass +if (!class_exists('OAuthException')) { + class OAuthException extends Exception { + // pass + } } class OAuthConsumer { diff --git a/library/video-js/demo.captions.vtt b/library/video-js/demo.captions.vtt new file mode 100644 index 000000000..e598be198 --- /dev/null +++ b/library/video-js/demo.captions.vtt @@ -0,0 +1,41 @@ +WEBVTT + +00:00.700 --> 00:04.110 +Captions describe all relevant audio for the hearing impaired. +[ Heroic music playing for a seagull ] + +00:04.500 --> 00:05.000 +[ Splash!!! ] + +00:05.100 --> 00:06.000 +[ Sploosh!!! ] + +00:08.000 --> 00:09.225 +[ Splash...splash...splash splash splash ] + +00:10.525 --> 00:11.255 +[ Splash, Sploosh again ] + +00:13.500 --> 00:14.984 +Dolphin: eeeEEEEEeeee! + +00:14.984 --> 00:16.984 +Dolphin: Squawk! eeeEEE? + +00:25.000 --> 00:28.284 +[ A whole ton of splashes ] + +00:29.500 --> 00:31.000 +Mine. Mine. Mine. + +00:34.300 --> 00:36.000 +Shark: Chomp + +00:36.800 --> 00:37.900 +Shark: CHOMP!!! + +00:37.861 --> 00:41.193 +EEEEEEOOOOOOOOOOWHALENOISE + +00:42.593 --> 00:45.611 +[ BIG SPLASH ] \ No newline at end of file diff --git a/library/video-js/demo.html b/library/video-js/demo.html new file mode 100644 index 000000000..5698849bf --- /dev/null +++ b/library/video-js/demo.html @@ -0,0 +1,30 @@ + + + + Video.js | HTML5 Video Player + + + + + + + + + + + + + + + + + diff --git a/library/video-js/font/vjs.eot b/library/video-js/font/vjs.eot new file mode 100644 index 000000000..1b8202af8 Binary files /dev/null and b/library/video-js/font/vjs.eot differ diff --git a/library/video-js/font/vjs.svg b/library/video-js/font/vjs.svg new file mode 100644 index 000000000..2059a1f2e --- /dev/null +++ b/library/video-js/font/vjs.svg @@ -0,0 +1,40 @@ + + + + +This is a custom SVG font generated by IcoMoon. + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/library/video-js/font/vjs.ttf b/library/video-js/font/vjs.ttf new file mode 100644 index 000000000..a5ad4685e Binary files /dev/null and b/library/video-js/font/vjs.ttf differ diff --git a/library/video-js/font/vjs.woff b/library/video-js/font/vjs.woff new file mode 100644 index 000000000..375510e04 Binary files /dev/null and b/library/video-js/font/vjs.woff differ diff --git a/library/video-js/video-js.css b/library/video-js/video-js.css new file mode 100644 index 000000000..4d3a1d275 --- /dev/null +++ b/library/video-js/video-js.css @@ -0,0 +1,730 @@ +/* +VideoJS Default Styles (http://videojs.com) +Version GENERATED_AT_BUILD +*/ + +/* +REQUIRED STYLES (be careful overriding) +================================================================================ */ +/* When loading the player, the video tag is replaced with a DIV, + that will hold the video tag or object tag for other playback methods. + The div contains the video playback element (Flash or HTML5) and controls, and sets the width and height of the video. + + ** If you want to add some kind of border/padding (e.g. a frame), or special positioning, use another containing element. + Otherwise you risk messing up control positioning and full window mode. ** +*/ +.video-js { + background-color: #000; + position: relative; + padding: 0; + /* Start with 10px for base font size so other dimensions can be em based and easily calculable. */ + font-size: 10px; + /* Allow poster to be vertially aligned. */ + vertical-align: middle; + /* display: table-cell; */ /*This works in Safari but not Firefox.*/ +} + +/* Playback technology elements expand to the width/height of the containing div. +