Merge remote-tracking branch 'upstream/2023.03-rc' into remove-tab

This commit is contained in:
Michael 2023-03-20 04:16:52 +00:00
commit b7288b2bfd
23 changed files with 777 additions and 166 deletions

View file

@ -29,6 +29,7 @@
"asika/simple-console": "^1.0",
"bacon/bacon-qr-code": "^2.0.0",
"divineomega/password_exposed": "^2.8",
"enyo/dropzone": "^5.9",
"ezyang/htmlpurifier": "^4.7",
"friendica/json-ld": "^1.0",
"geekwright/po": "^2.0",

38
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "5af9ac9003f4653f3aa1860dd5a4d821",
"content-hash": "c9e005c79c8556215c30a66c470659eb",
"packages": [
{
"name": "asika/simple-console",
@ -550,6 +550,42 @@
"description": "This PHP package provides a `password_exposed` helper function, that uses the haveibeenpwned.com API to check if a password has been exposed in a data breach.",
"time": "2019-01-25T12:00:28+00:00"
},
{
"name": "enyo/dropzone",
"version": "v5.9.3",
"source": {
"type": "git",
"url": "https://github.com/dropzone/dropzone-packagist.git",
"reference": "286b2dc1f1195bd12169e4c9d5f91cfbe46e245f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dropzone/dropzone-packagist/zipball/286b2dc1f1195bd12169e4c9d5f91cfbe46e245f",
"reference": "286b2dc1f1195bd12169e4c9d5f91cfbe46e245f",
"shasum": ""
},
"type": "library",
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Matias Meno",
"email": "m@tias.me",
"homepage": "http://www.yesmeno.com"
}
],
"description": "Handles drag and drop of files for you.",
"homepage": "http://www.dropzonejs.com",
"keywords": [
"drag and drop",
"dragndrop",
"file upload",
"upload"
],
"time": "2021-09-21T17:03:36+00:00"
},
{
"name": "ezyang/htmlpurifier",
"version": "v4.14.0",

View file

@ -1139,7 +1139,7 @@ function photos_content(App $a)
'$preview' => DI::l10n()->t('Preview'),
'$loading' => DI::l10n()->t('Loading...'),
'$qcomment' => $qcomment,
'$rand_num' => Crypto::randomDigits(12)
'$rand_num' => Crypto::randomDigits(12),
]);
}
}
@ -1194,7 +1194,7 @@ function photos_content(App $a)
'$submit' => DI::l10n()->t('Submit'),
'$preview' => DI::l10n()->t('Preview'),
'$qcomment' => $qcomment,
'$rand_num' => Crypto::randomDigits(12)
'$rand_num' => Crypto::randomDigits(12),
]);
}
@ -1268,7 +1268,7 @@ function photos_content(App $a)
'$submit' => DI::l10n()->t('Submit'),
'$preview' => DI::l10n()->t('Preview'),
'$qcomment' => $qcomment,
'$rand_num' => Crypto::randomDigits(12)
'$rand_num' => Crypto::randomDigits(12),
]);
}
}

View file

@ -253,11 +253,14 @@ class Page implements ArrayAccess
'$touch_icon' => $touch_icon,
'$block_public' => intval($config->get('system', 'block_public')),
'$stylesheets' => $this->stylesheets,
'$likeError' => $l10n->t('Like not successfull'),
'$dislikeError' => $l10n->t('Dislike not successfull'),
'$announceError' => $l10n->t('Sharing not successfull'),
'$srvError' => $l10n->t('Backend error'),
'$netError' => $l10n->t('Network error'),
'$likeError' => $l10n->t('Like not successfull'),
'$dislikeError' => $l10n->t('Dislike not successfull'),
'$announceError' => $l10n->t('Sharing not successfull'),
'$srvError' => $l10n->t('Backend error'),
'$netError' => $l10n->t('Network error'),
// Dropzone
'$max_imagesize' => round(\Friendica\Util\Strings::getBytesFromShorthand($config->get('system', 'maximagesize')) / 1000000, 1),
]) . $this->page['htmlhead'];
}

View file

@ -1475,8 +1475,8 @@ class BBCode
$text = preg_replace("/\[list=((?-i)I)\](.*?)\[\/list\]/ism", '</p><ul class="listupperroman" style="list-style-type: upper-roman;">$2</ul><p>', $text);
$text = preg_replace("/\[list=((?-i)a)\](.*?)\[\/list\]/ism", '</p><ul class="listloweralpha" style="list-style-type: lower-alpha;">$2</ul><p>', $text);
$text = preg_replace("/\[list=((?-i)A)\](.*?)\[\/list\]/ism", '</p><ul class="listupperalpha" style="list-style-type: upper-alpha;">$2</ul><p>', $text);
$text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '</p><ul class="listbullet" style="list-style-type: circle;">$1</ul><p>', $text);
$text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '</p><ul class="listdecimal" style="list-style-type: decimal;">$1</ul><p>', $text);
$text = preg_replace("/\[ul\](.*?)\[\/ul\]/ism", '</p><ul>$1</ul><p>', $text);
$text = preg_replace("/\[ol\](.*?)\[\/ol\]/ism", '</p><ol>$1</ol><p>', $text);
$text = preg_replace("/\[li\](.*?)\[\/li\]/ism", '<li>$1</li>', $text);
}

View file

@ -281,9 +281,9 @@ class HTML
self::tagToBBCode($doc, 'div', [], "\r", "\r");
self::tagToBBCode($doc, 'p', [], "\n", "\n");
self::tagToBBCode($doc, 'ul', [], "[list]", "[/list]");
self::tagToBBCode($doc, 'ol', [], "[list=1]", "[/list]");
self::tagToBBCode($doc, 'li', [], "[*]", "");
self::tagToBBCode($doc, 'ul', [], "[ul]", "\n[/ul]");
self::tagToBBCode($doc, 'ol', [], "[ol]", "\n[/ol]");
self::tagToBBCode($doc, 'li', [], "\n[*]", "");
self::tagToBBCode($doc, 'hr', [], "[hr]", "");
@ -349,33 +349,6 @@ class HTML
$message = str_replace("\n\n\n", "\n\n", $message);
} while ($oldmessage != $message);
do {
$oldmessage = $message;
$message = str_replace(
[
"[/size]\n\n",
"\n[hr]",
"[hr]\n",
"\n[list",
"[/list]\n",
"\n[/",
"[list]\n",
"[list=1]\n",
"\n[*]"],
[
"[/size]\n",
"[hr]",
"[hr]",
"[list",
"[/list]",
"[/",
"[list]",
"[list=1]",
"[*]"],
$message
);
} while ($message != $oldmessage);
$message = str_replace(
['[b][b]', '[/b][/b]', '[i][i]', '[/i][/i]'],
['[b]', '[/b]', '[i]', '[/i]'],

View file

@ -55,19 +55,17 @@ class Session
* @param LoggerInterface $logger
* @param Profiler $profiler
* @param array $server
* @return IHandleSessions
*/
public function createSession(App\Mode $mode, App\BaseURL $baseURL, IManageConfigValues $config, Database $dba, Cache $cacheFactory, LoggerInterface $logger, Profiler $profiler, array $server = []): IHandleSessions
public function create(App\Mode $mode, App\BaseURL $baseURL, IManageConfigValues $config, Database $dba, Cache $cacheFactory, LoggerInterface $logger, Profiler $profiler, array $server = []): IHandleSessions
{
$profiler->startRecording('session');
$session = null;
$session_handler = $config->get('system', 'session_handler', self::HANDLER_DEFAULT);
try {
if ($mode->isInstall() || $mode->isBackend()) {
$session = new Type\Memory();
} else {
$session_handler = $config->get('system', 'session_handler', self::HANDLER_DEFAULT);
$handler = null;
switch ($session_handler) {
case self::HANDLER_DATABASE:
$handler = new Handler\Database($dba, $logger, $server);
@ -82,10 +80,15 @@ class Session
$handler = new Handler\Cache($cache, $logger);
}
break;
default:
$handler = null;
}
$session = new Type\Native($baseURL, $handler);
}
} catch (\Throwable $e) {
$logger->notice('Unable to create session', ['mode' => $mode, 'session_handler' => $session_handler, 'exception' => $e]);
$session = new Type\Memory();
} finally {
$profiler->stopRecording();
return $session;

View file

@ -589,7 +589,7 @@ class Item
public static function isValid(array $item): bool
{
// When there is no content then we don't post it
if (($item['body'] . $item['title'] == '') && empty($item['quote-uri-id']) && (empty($item['uri-id']) || !Post\Media::existsByURIId($item['uri-id']))) {
if (($item['body'] . $item['title'] == '') && empty($item['quote-uri-id']) && empty($item['attachments']) && (empty($item['uri-id']) || !Post\Media::existsByURIId($item['uri-id']))) {
Logger::notice('No body, no title.');
return false;
}

View file

@ -334,7 +334,7 @@ class Profile
if (!$local_user_is_self) {
if (!$visitor_is_authenticated) {
// Remote follow is only available for local profiles
if (!empty($profile['nickname']) && strpos($profile_url, DI::baseUrl()) === 0) {
if (!empty($profile['nickname']) && strpos($profile_url, (string)DI::baseUrl()) === 0) {
$follow_link = 'profile/' . $profile['nickname'] . '/remote_follow';
}
} else {

View file

@ -25,7 +25,7 @@ use Friendica\App;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Database\Database;
use Friendica\Core\System;
use Friendica\Model\Attach;
use Friendica\Model\User;
use Friendica\Module\Response;
@ -42,9 +42,6 @@ use Psr\Log\LoggerInterface;
*/
class Upload extends \Friendica\BaseModule
{
/** @var Database */
private $database;
/** @var IHandleUserSessions */
private $userSession;
@ -57,31 +54,32 @@ class Upload extends \Friendica\BaseModule
/** @var bool */
private $isJson;
public function __construct(SystemMessages $systemMessages, IManageConfigValues $config, IHandleUserSessions $userSession, Database $database, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
/** @var App\Page */
private $page;
public function __construct(App\Page $page, SystemMessages $systemMessages, IManageConfigValues $config, IHandleUserSessions $userSession, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->database = $database;
$this->userSession = $userSession;
$this->config = $config;
$this->systemMessages = $systemMessages;
$this->page = $page;
}
protected function post(array $request = [])
{
if ($this->isJson = !empty($request['response']) && $request['response'] == 'json') {
$this->response->setType(Response::TYPE_JSON, 'application/json');
}
$this->isJson = !empty($request['response']) && $request['response'] == 'json';
$owner = User::getOwnerDataById($this->userSession->getLocalUserId());
if (!$owner) {
$this->logger->warning('Owner not found.', ['uid' => $this->userSession->getLocalUserId()]);
return $this->return(401, $this->t('Invalid request.'));
$this->return(401, $this->t('Invalid request.'));
}
if (empty($_FILES['userfile'])) {
$this->logger->warning('No file uploaded (empty userfile)');
return $this->return(401, $this->t('Invalid request.'), true);
$this->return(401, $this->t('Invalid request.'), true);
}
$tempFileName = $_FILES['userfile']['tmp_name'];
@ -98,14 +96,14 @@ class Upload extends \Friendica\BaseModule
@unlink($tempFileName);
$msg = $this->t('Sorry, maybe your upload is bigger than the PHP configuration allows') . '<br />' . $this->t('Or - did you try to upload an empty file?');
$this->logger->warning($msg, ['fileSize' => $fileSize]);
return $this->return(401, $msg, true);
$this->return(401, $msg, true);
}
if ($maxFileSize && $fileSize > $maxFileSize) {
@unlink($tempFileName);
$msg = $this->t('File exceeds size limit of %s', Strings::formatBytes($maxFileSize));
$this->logger->warning($msg, ['fileSize' => $fileSize]);
return $this->return(401, $msg);
$this->return(401, $msg);
}
$newid = Attach::storeFile($tempFileName, $owner['uid'], $fileName, '<' . $owner['id'] . '>');
@ -115,16 +113,16 @@ class Upload extends \Friendica\BaseModule
if ($newid === false) {
$msg = $this->t('File upload failed.');
$this->logger->warning($msg);
return $this->return(500, $msg);
$this->return(500, $msg);
}
if ($this->isJson) {
$content = json_encode(['ok' => true, 'id' => $newid], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
$content = $newid;
} else {
$content = "\n\n" . '[attachment]' . $newid . '[/attachment]' . "\n";
}
return $this->response->addContent($content);
$this->return(200, $content);
}
/**
@ -136,16 +134,23 @@ class Upload extends \Friendica\BaseModule
*/
private function return(int $httpCode, string $message, bool $systemMessage = false): void
{
$this->response->setStatus($httpCode, $message);
if ($this->isJson) {
$this->response->addContent(json_encode(['error' => $message], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
$message = $httpCode >= 400 ? ['error' => $message] : ['ok' => true, 'id' => $message];
$this->response->setType(Response::TYPE_JSON, 'application/json');
$this->response->addContent(json_encode($message, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT));
} else {
if ($systemMessage) {
$this->systemMessages->addNotice($message);
}
if ($httpCode >= 400) {
$this->response->setStatus($httpCode, $message);
}
$this->response->addContent($message);
}
$this->page->exit($this->response->generate());
System::exit();
}
}

View file

@ -25,10 +25,9 @@ use Friendica\App;
use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n;
use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Database\Database;
use Friendica\Core\System;
use Friendica\Model\Photo;
use Friendica\Model\User;
use Friendica\Module\BaseApi;
use Friendica\Module\Response;
use Friendica\Navigation\SystemMessages;
use Friendica\Network\HTTPException\InternalServerErrorException;
@ -45,9 +44,6 @@ use Psr\Log\LoggerInterface;
*/
class Upload extends \Friendica\BaseModule
{
/** @var Database */
private $database;
/** @var IHandleUserSessions */
private $userSession;
@ -60,14 +56,17 @@ class Upload extends \Friendica\BaseModule
/** @var bool */
private $isJson = false;
public function __construct(IManageConfigValues $config, SystemMessages $systemMessages, IHandleUserSessions $userSession, Database $database, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
/** @var App\Page */
private $page;
public function __construct(App\Page $page, IManageConfigValues $config, SystemMessages $systemMessages, IHandleUserSessions $userSession, L10n $l10n, App\BaseURL $baseUrl, App\Arguments $args, LoggerInterface $logger, Profiler $profiler, Response $response, array $server, array $parameters = [])
{
parent::__construct($l10n, $baseUrl, $args, $logger, $profiler, $response, $server, $parameters);
$this->database = $database;
$this->userSession = $userSession;
$this->systemMessages = $systemMessages;
$this->config = $config;
$this->page = $page;
}
protected function post(array $request = [])
@ -80,12 +79,12 @@ class Upload extends \Friendica\BaseModule
if (!$owner) {
$this->logger->warning('Owner not found.', ['uid' => $this->userSession->getLocalUserId()]);
return $this->return(401, $this->t('Invalid request.'));
$this->return(401, $this->t('Invalid request.'));
}
if (empty($_FILES['userfile']) && empty($_FILES['media'])) {
$this->logger->warning('Empty "userfile" and "media" field');
return $this->return(401, $this->t('Invalid request.'));
$this->return(401, $this->t('Invalid request.'));
}
$src = '';
@ -134,7 +133,7 @@ class Upload extends \Friendica\BaseModule
if ($src == '') {
$this->logger->warning('File source (temporary file) cannot be determined', ['$_FILES' => $_FILES]);
return $this->return(401, $this->t('Invalid request.'), true);
$this->return(401, $this->t('Invalid request.'), true);
}
$filetype = Images::getMimeTypeBySource($src, $filename, $filetype);
@ -152,7 +151,7 @@ class Upload extends \Friendica\BaseModule
if (!$image->isValid()) {
@unlink($src);
$this->logger->warning($this->t('Unable to process image.'), ['imagedata[]' => gettype($imagedata), 'filetype' => $filetype]);
return $this->return(401, $this->t('Unable to process image.'));
$this->return(401, $this->t('Unable to process image.'));
}
$image->orient($src);
@ -185,7 +184,7 @@ class Upload extends \Friendica\BaseModule
if ($filesize > $maximagesize) {
@unlink($src);
$this->logger->notice('Image size is too big', ['size' => $filesize, 'max' => $maximagesize]);
return $this->return(401, $this->t('Image exceeds size limit of %s', Strings::formatBytes($maximagesize)));
$this->return(401, $this->t('Image exceeds size limit of %s', Strings::formatBytes($maximagesize)));
}
}
@ -203,7 +202,7 @@ class Upload extends \Friendica\BaseModule
$result = Photo::store($image, $owner['uid'], 0, $resource_id, $filename, $album, 0, Photo::DEFAULT, $allow_cid);
if (!$result) {
$this->logger->warning('Photo::store() failed', ['result' => $result]);
return $this->return(401, $this->t('Image upload failed.'));
$this->return(401, $this->t('Image upload failed.'));
}
if ($width > 640 || $height > 640) {
@ -223,7 +222,7 @@ class Upload extends \Friendica\BaseModule
}
$this->logger->info('upload done');
return $this->return(200, "\n\n" . '[url=' . $this->baseUrl . '/photos/' . $owner['nickname'] . '/image/' . $resource_id . '][img]' . $this->baseUrl . "/photo/$resource_id-$smallest." . $image->getExt() . "[/img][/url]\n\n");
$this->return(200, "\n\n" . '[url=' . $this->baseUrl . '/photos/' . $owner['nickname'] . '/image/' . $resource_id . '][img]' . $this->baseUrl . "/photo/$resource_id-$smallest." . $image->getExt() . "[/img][/url]\n\n");
}
/**
@ -250,5 +249,8 @@ class Upload extends \Friendica\BaseModule
$this->response->addContent($message);
}
$this->page->exit($this->response->generate());
System::exit();
}
}

View file

@ -237,7 +237,7 @@ return [
IHandleSessions::class => [
'instanceOf' => \Friendica\Core\Session\Factory\Session::class,
'call' => [
['createSession', [$_SERVER], Dice::CHAIN_CALL],
['create', [$_SERVER], Dice::CHAIN_CALL],
['start', [], Dice::CHAIN_CALL],
],
],

View file

@ -158,21 +158,21 @@ class BBCodeTest extends FixtureTest
{
return [
'bug-7271-condensed-space' => [
'expectedHtml' => '<ul class="listdecimal" style="list-style-type:decimal;"><li> <a href="http://example.com/" target="_blank" rel="noopener noreferrer">http://example.com/</a></li></ul>',
'expectedHtml' => '<ol><li> <a href="http://example.com/" target="_blank" rel="noopener noreferrer">http://example.com/</a></li></ol>',
'text' => '[ol][*] http://example.com/[/ol]',
],
'bug-7271-condensed-nospace' => [
'expectedHtml' => '<ul class="listdecimal" style="list-style-type:decimal;"><li><a href="http://example.com/" target="_blank" rel="noopener noreferrer">http://example.com/</a></li></ul>',
'expectedHtml' => '<ol><li><a href="http://example.com/" target="_blank" rel="noopener noreferrer">http://example.com/</a></li></ol>',
'text' => '[ol][*]http://example.com/[/ol]',
],
'bug-7271-indented-space' => [
'expectedHtml' => '<ul class="listbullet" style="list-style-type:circle;"><li> <a href="http://example.com/" target="_blank" rel="noopener noreferrer">http://example.com/</a></li></ul>',
'expectedHtml' => '<ul><li> <a href="http://example.com/" target="_blank" rel="noopener noreferrer">http://example.com/</a></li></ul>',
'text' => '[ul]
[*] http://example.com/
[/ul]',
],
'bug-7271-indented-nospace' => [
'expectedHtml' => '<ul class="listbullet" style="list-style-type:circle;"><li><a href="http://example.com/" target="_blank" rel="noopener noreferrer">http://example.com/</a></li></ul>',
'expectedHtml' => '<ul><li><a href="http://example.com/" target="_blank" rel="noopener noreferrer">http://example.com/</a></li></ul>',
'text' => '[ul]
[*]http://example.com/
[/ul]',
@ -259,13 +259,21 @@ Karl Marx - Die ursprüngliche Akkumulation
'text' => '[emoji=https://fedi.underscore.world/emoji/custom/custom/heart_nb.png]:heart_nb:[/emoji]',
],
'task-12900-multiple-paragraphs' => [
'expectedHTML' => '<h1>Header</h1><ul class="listbullet" style="list-style-type:circle;"><li>One</li><li>Two</li></ul><p>This is a paragraph<br>with a line feed.</p><p>Second Chapter</p>',
'expectedHTML' => '<h1>Header</h1><ul><li>One</li><li>Two</li></ul><p>This is a paragraph<br>with a line feed.</p><p>Second Chapter</p>',
'text' => "[h1]Header[/h1][ul][*]One[*]Two[/ul]\n\nThis is a paragraph\nwith a line feed.\n\nSecond Chapter",
],
'task-12900-header-with-paragraphs' => [
'expectedHTML' => '<h1>Header</h1><p>Some Chapter</p>',
'text' => '[h1]Header[/h1]Some Chapter',
]
],
'bug-12842-ul-newlines' => [
'expectedHTML' => '<p>This is:</p><ul><li>some<br></li><li>amazing<br></li><li>list</li></ul>',
'text' => "This is:\r\n[ul]\r\n[*]some\r\n[*]amazing\r\n[*]list\r\n[/ul]",
],
'bug-12842-ol-newlines' => [
'expectedHTML' => '<p>This is:</p><ol><li>some<br></li><li>amazing<br></li><li>list</li></ol>',
'text' => "This is:\r\n[ol]\r\n[*]some\r\n[*]amazing\r\n[*]list\r\n[/ol]",
],
];
}
@ -282,8 +290,9 @@ Karl Marx - Die ursprüngliche Akkumulation
*
* @throws InternalServerErrorException
*/
public function testConvert(string $expectedHtml, string $text, $try_oembed = false, int $simpleHtml = 0, bool $forPlaintext = false)
public function testConvert(string $expectedHtml, string $text, bool $try_oembed = true, int $simpleHtml = BBCode::INTERNAL, bool $forPlaintext = false)
{
// This assumes system.remove_multiplicated_lines = false
$actual = BBCode::convert($text, $try_oembed, $simpleHtml, $forPlaintext);
self::assertEquals($expectedHtml, $actual);

View file

@ -88,6 +88,24 @@ its surprisingly good",
'expectedBBCode' => '[url=https://dev-friendica.mrpetovan.com/profile/hypolite]@hypolite[/url] 0',
'html' => '<p><span class="h-card"><a href="https://dev-friendica.mrpetovan.com/profile/hypolite" class="u-url mention">@<span>hypolite</span></a></span> 0</p>',
],
'bug-12842-ul-new-lines' => [
'expectedBBCode' => 'This is:
[ul]
[*]some
[*]amazing
[*]list
[/ul]',
'html'=> '<p>This is:</p><ul><li>some</li><li>amazing</li><li>list</li></ul>',
],
'bug-12842-ol-new-lines' => [
'expectedBBCode' => 'This is:
[ol]
[*]some
[*]amazing
[*]list
[/ol]',
'html'=> '<p>This is:</p><ol><li>some</li><li>amazing</li><li>list</li></ol>',
],
];
}
@ -627,13 +645,13 @@ its surprisingly good",
e.preventDefault();
// console.log('[id=\"' + this.getAttribute('href') + '\"]');
// console.log(document.getElementById('[id=\"' + this.getAttribute('href') + '\"]'));
document.querySelector('[ez-toc-data-id=\"' + decodeURI(this.getAttribute('href')) + '\"]').scrollIntoView({
behavior: 'smooth'
});
});
});
};
};
document.addEventListener('DOMContentLoaded', ezTocScrollScriptJS, false);</script> <script type='text/javascript' src='https://blog.austria-insiderinfo.com/wp-includes/js/jquery/jquery.min.js?ver=3.6.1' id='jquery-core-js'></script> <link rel=\"https://api.w.org/\" href=\"https://blog.austria-insiderinfo.com/wp-json/\" /><link rel=\"alternate\" type=\"application/json\" href=\"https://blog.austria-insiderinfo.com/wp-json/wp/v2/posts/17543\" /><link rel=\"EditURI\" type=\"application/rsd+xml\" title=\"RSD\" href=\"https://blog.austria-insiderinfo.com/xmlrpc.php?rsd\" /><link rel='shortlink' href='https://blog.austria-insiderinfo.com/?p=17543' /><link rel=\"icon\" href=\"https://blog.austria-insiderinfo.com/wp-content/uploads/2016/11/cropped-fav_icon-2-32x32.png\" sizes=\"32x32\" /><link rel=\"icon\" href=\"https://blog.austria-insiderinfo.com/wp-content/uploads/2016/11/cropped-fav_icon-2-192x192.png\" sizes=\"192x192\" /><link rel=\"apple-touch-icon\" href=\"https://blog.austria-insiderinfo.com/wp-content/uploads/2016/11/cropped-fav_icon-2-180x180.png\" /><meta name=\"msapplication-TileImage\" content=\"https://blog.austria-insiderinfo.com/wp-content/uploads/2016/11/cropped-fav_icon-2-270x270.png\" /> <script type=\"text/javascript\">var doc = document.documentElement;
\t\t\tdoc.setAttribute( 'data-useragent', navigator.userAgent );</script> <script type=\"text/javascript\">(function(c,l,a,r,i,t,y){
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
@ -658,7 +676,7 @@ Du kannst Kommentare auch <a href=\"https://blog.austria-insiderinfo.com/comment
<div class=\"row\">
<div class=\"col-12\">
<div class=\"_brlbs-flex-center\">
<span role=\"heading\" aria-level=\"3\" class=\"_brlbs-h3\" id=\"CookieBoxTextHeadline\">Cookie Einstellungen</span>
</div>
@ -685,7 +703,7 @@ Externe Medien<br />
>
Externe Medien </li>
</ul>
<p class=\"_brlbs-accept\">
<a
href=\"#\"
@ -708,7 +726,7 @@ Externe Medien<br />
>
Nur essenzielle Cookies akzeptieren </a>
</p>
<p class=\"_brlbs-manage\">
<a
href=\"#\"
@ -736,7 +754,7 @@ Externe Medien<br />
href=\"https://blog.austria-insiderinfo.com/rechtshinweis/\"
>
Datenschutzerklärung </a>
<span class=\"_brlbs-separator\"></span>
<a
tabindex=\"0\"
@ -760,7 +778,7 @@ Externe Medien<br />
<div class=\"row no-gutters\">
<div class=\"col-12\">
<div class=\"row no-gutters align-items-top\">
<div class=\"col-12\">
<span role=\"heading\" aria-level=\"3\" class=\"_brlbs-h3\">Datenschutzeinstellungen</span>
@ -778,7 +796,7 @@ Externe Medien<br />
data-cookie-accept-all
>
Alle Cookies akzeptieren </a>
<a
href=\"#\"
id=\"CookiePrefSave\"
@ -853,7 +871,7 @@ Externe Medien<br />
data-cookie-accordion-parent=\"essential\"
>
<table>
<tr>
<th>Name</th>
<td>
@ -871,21 +889,21 @@ Externe Medien<br />
<th>Zweck</th>
<td>Speichert die Einstellungen der Besucher, die in der Cookie Box von Borlabs Cookie ausgewählt wurden.</td>
</tr>
<tr>
<th>Cookie Name</th>
<td>borlabs-cookie</td>
</tr>
<tr>
<th>Cookie Laufzeit</th>
<td>1 Jahr</td>
</tr>
</table>
<table>
<tr>
<th>Name</th>
<td>
@ -905,7 +923,7 @@ Externe Medien<br />
Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezogenen Daten erfasst.</td>
</tr>
<tr>
<th>Datenschutzerklärung</th>
<td class=\"_brlbs-pp-url\">
@ -917,24 +935,24 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
https://www.vgwort.de/hilfsseiten/datenschutz.html </a>
</td>
</tr>
<tr>
<th>Host(s)</th>
<td>*.vgwort.de</td>
</tr>
<tr>
<th>Cookie Name</th>
<td>srp</td>
</tr>
<tr>
<th>Cookie Laufzeit</th>
<td>Sitzung</td>
</tr>
</table>
<table>
<tr>
<th>Name</th>
<td>
@ -952,7 +970,7 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
<th>Zweck</th>
<td>Content Delivery Netzwerk und DNS Verwaltung</td>
</tr>
<tr>
<th>Datenschutzerklärung</th>
<td class=\"_brlbs-pp-url\">
@ -964,24 +982,24 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
https://www.cloudflare.com/privacypolicy/ </a>
</td>
</tr>
<tr>
<th>Host(s)</th>
<td>www.cloudflare.com</td>
</tr>
<tr>
<th>Cookie Name</th>
<td>__cfduid</td>
</tr>
<tr>
<th>Cookie Laufzeit</th>
<td>1 Jahr</td>
</tr>
</table>
<table>
<tr>
<th>Name</th>
<td>
@ -999,7 +1017,7 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
<th>Zweck</th>
<td>Wird für den Austria Insiderinfo WebShop verwendet, um zum Beispiel den Inhalt des Warenkorbes zu sichern oder um die Versandkosten abhängig von deinem Standort berechnen zu können.</td>
</tr>
<tr>
<th>Datenschutzerklärung</th>
<td class=\"_brlbs-pp-url\">
@ -1011,17 +1029,17 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
https://blog.austria-insiderinfo.com/rechtshinweis/#Shop_der_Austria_Insiderinfo </a>
</td>
</tr>
<tr>
<th>Host(s)</th>
<td>blog.austria-insiderinfo.com</td>
</tr>
<tr>
<th>Cookie Name</th>
<td>tk_ai</td>
</tr>
<tr>
<th>Cookie Laufzeit</th>
<td>Sitzung</td>
@ -1104,7 +1122,7 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
</label>
</td>
</tr>
<tr>
<th>Name</th>
<td>
@ -1122,7 +1140,7 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
<th>Zweck</th>
<td>Cookie von Matomo für Website-Analysen. Erzeugt statistische Daten darüber, wie der Besucher die Website nutzt.</td>
</tr>
<tr>
<th>Datenschutzerklärung</th>
<td class=\"_brlbs-pp-url\">
@ -1134,17 +1152,17 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
https://blog.austria-insiderinfo.com/rechtshinweis/ </a>
</td>
</tr>
<tr>
<th>Host(s)</th>
<td>analytics.austria-insiderinfo.com</td>
</tr>
<tr>
<th>Cookie Name</th>
<td>_pk_*.*</td>
</tr>
<tr>
<th>Cookie Laufzeit</th>
<td>13 Monate</td>
@ -1227,7 +1245,7 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
</label>
</td>
</tr>
<tr>
<th>Name</th>
<td>
@ -1245,7 +1263,7 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
<th>Zweck</th>
<td>Wird verwendet, um OpenStreetMap-Inhalte zu entsperren.</td>
</tr>
<tr>
<th>Datenschutzerklärung</th>
<td class=\"_brlbs-pp-url\">
@ -1257,17 +1275,17 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
https://wiki.osmfoundation.org/wiki/Privacy_Policy </a>
</td>
</tr>
<tr>
<th>Host(s)</th>
<td>.openstreetmap.org</td>
</tr>
<tr>
<th>Cookie Name</th>
<td>_osm_location, _osm_session, _osm_totp_token, _osm_welcome, _pk_id., _pk_ref., _pk_ses., qos_token</td>
</tr>
<tr>
<th>Cookie Laufzeit</th>
<td>1-10 Jahre</td>
@ -1298,7 +1316,7 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
</label>
</td>
</tr>
<tr>
<th>Name</th>
<td>
@ -1316,7 +1334,7 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
<th>Zweck</th>
<td>Wird verwendet, um Twitter-Inhalte zu entsperren.</td>
</tr>
<tr>
<th>Datenschutzerklärung</th>
<td class=\"_brlbs-pp-url\">
@ -1328,17 +1346,17 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
https://twitter.com/privacy </a>
</td>
</tr>
<tr>
<th>Host(s)</th>
<td>.twimg.com, .twitter.com</td>
</tr>
<tr>
<th>Cookie Name</th>
<td>__widgetsettings, local_storage_support_test</td>
</tr>
<tr>
<th>Cookie Laufzeit</th>
<td>Unbegrenzt</td>
@ -1369,7 +1387,7 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
</label>
</td>
</tr>
<tr>
<th>Name</th>
<td>
@ -1387,7 +1405,7 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
<th>Zweck</th>
<td>Wird verwendet, um YouTube-Inhalte zu entsperren.</td>
</tr>
<tr>
<th>Datenschutzerklärung</th>
<td class=\"_brlbs-pp-url\">
@ -1399,17 +1417,17 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
https://policies.google.com/privacy </a>
</td>
</tr>
<tr>
<th>Host(s)</th>
<td>google.com</td>
</tr>
<tr>
<th>Cookie Name</th>
<td>NID</td>
</tr>
<tr>
<th>Cookie Laufzeit</th>
<td>6 Monate</td>
@ -1426,9 +1444,9 @@ Deine IP-Adresse wird nur anonymisiert verarbeitet, es werden keine personenbezo
<p class=\"_brlbs-legal flex-fill\">
<a href=\"https://blog.austria-insiderinfo.com/rechtshinweis/\">
Datenschutzerklärung </a>
<span class=\"_brlbs-separator\"></span>
<a href=\"https://blog.austria-insiderinfo.com/impressum/\">
Impressum </a>
</p>
@ -1461,7 +1479,7 @@ BorlabsCookieInitCheck();});</script> <script type=\"application/ld+json\">{\"@c
<!--
Performance optimized by W3 Total Cache. Learn more: https://www.boldgrid.com/w3-total-cache/
Seiten-Caching mit disk: enhanced
Seiten-Caching mit disk: enhanced
Served from: blog.austria-insiderinfo.com @ 2023-01-07 10:50:10 by W3 Total Cache
-->",

View file

@ -80,6 +80,6 @@ class DBKeyValueStorageTest extends KeyValueStorageTest
$updateAtAfter = $entry['updated_at'];
self::assertLessThanOrEqual($updateAt, $updateAtAfter);
self::assertGreaterThanOrEqual($updateAt, $updateAtAfter);
}
}

View file

@ -0,0 +1,63 @@
var DzFactory = function () {
this.createDropzone = function(dropSelector, textareaElementId) {
return new Dropzone(dropSelector, {
paramName: 'userfile', // The name that will be used to transfer the file
maxFilesize: max_imagesize, // MB
url: '/media/photo/upload?album=',
acceptedFiles: 'image/*',
clickable: true,
accept: function(file, done) {
done();
},
init: function() {
this.on('success', function(file, serverResponse) {
const targetTextarea = document.getElementById(textareaElementId);
if (targetTextarea.setRangeText) {
//if setRangeText function is supported by current browser
targetTextarea.setRangeText(' ' + $.trim(serverResponse) + ' ');
} else {
targetTextarea.focus();
document.execCommand('insertText', false /*no UI*/, '\n' + $.trim(serverResponse) + '\n');
}
});
this.on('complete', function(file) {
const dz = this;
// Remove just uploaded file from dropzone, makes interface more clear.
// Image can be seen in posting-preview
// We need preview to get optical feedback about upload-progress.
// you see success, when the bb-code link for image is inserted
setTimeout(function(){
dz.removeFile(file);
},5000);
});
},
paste: function(event){
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
items.forEach((item) => {
if (item.kind === 'file') {
// adds the file to your dropzone instance
dz.addFile(item.getAsFile());
}
})
},
});
};
this.copyPaste = function(event, dz) {
const items = (event.clipboardData || event.originalEvent.clipboardData).items;
items.forEach((item) => {
if (item.kind === 'file') {
// adds the file to your dropzone instance
dz.addFile(item.getAsFile());
}
})
};
this.setupDropzone = function(dropSelector, textareaElementId) {
var dropzone = this.createDropzone(dropSelector, textareaElementId);
$(dropSelector).on('paste', function(event) {
dzFactory.copyPaste(event, dropzone);
})
};
}

View file

@ -1,11 +1,11 @@
<div class="generic-page-wrapper">
<h2>{{$l10n.compose_title}}</h2>
{{if $l10n.always_open_compose}}
{{if $l10n.always_open_compose}}
<p>{{$l10n.always_open_compose nofilter}}</p>
{{/if}}
<div id="profile-jot-wrapper">
<form class="comment-edit-form" data-item-id="{{$id}}" id="comment-edit-form-{{$id}}" action="compose/{{$type}}" method="post">
{{*<!--<input type="hidden" name="return" value="{{$return_path}}" />-->*}}
{{*<!--<input type="hidden" name="return" value="{{$return_path}}" />-->*}}
<input type="hidden" name="post_id_random" value="{{$rand_num}}" />
<input type="hidden" name="post_type" value="{{$posttype}}" />
<input type="hidden" name="wall" value="{{$wall}}" />
@ -13,11 +13,11 @@
<div id="jot-title-wrap">
<input type="text" name="title" id="jot-title" class="jothidden jotforms form-control" placeholder="{{$l10n.placeholdertitle}}" title="{{$l10n.placeholdertitle}}" value="{{$title}}" tabindex="1" dir="auto" />
</div>
{{if $l10n.placeholdercategory}}
{{if $l10n.placeholdercategory}}
<div id="jot-category-wrap">
<input name="category" id="jot-category" class="jothidden jotforms form-control" type="text" placeholder="{{$l10n.placeholdercategory}}" title="{{$l10n.placeholdercategory}}" value="{{$category}}" tabindex="2" dir="auto" />
</div>
{{/if}}
{{/if}}
<p class="comment-edit-bb-{{$id}} comment-icon-list">
<span>
@ -46,21 +46,22 @@
</button>
</span>
</p>
<p>
<textarea id="comment-edit-text-{{$id}}" class="comment-edit-text form-control text-autosize" name="body" placeholder="{{$l10n.default}}" rows="7" tabindex="3" dir="auto" dir="auto">{{$body}}</textarea>
</p>
<div id="dropzone-{{$id}}" class="dropzone" style="overflow:scroll">
<p>
<textarea id="comment-edit-text-{{$id}}" class="comment-edit-text form-control text-autosize" name="body" placeholder="{{$l10n.default}}" rows="7" tabindex="3" dir="auto" dir="auto">{{$body}}</textarea>
</p>
</div>
<p class="comment-edit-submit-wrapper">
{{if $type == 'post'}}
<span role="presentation" class="form-inline">
<input type="text" name="location" class="form-control" id="jot-location" value="{{$location}}" placeholder="{{$l10n.location_set}}"/>
<button type="button" class="btn btn-sm template-icon" id="profile-location"
data-title-set="{{$l10n.location_set}}"
data-title-disabled="{{$l10n.location_disabled}}"
data-title-unavailable="{{$l10n.location_unavailable}}"
data-title-clear="{{$l10n.location_clear}}"
title="{{$l10n.location_set}}"
tabindex="6">
data-title-set="{{$l10n.location_set}}"
data-title-disabled="{{$l10n.location_disabled}}"
data-title-unavailable="{{$l10n.location_unavailable}}"
data-title-clear="{{$l10n.location_clear}}"
title="{{$l10n.location_set}}"
tabindex="6">
<i class="fa fa-map-marker" aria-hidden="true"></i>
</button>
</span>
@ -94,3 +95,6 @@
</form>
</div>
</div>
<script>
dzFactory.setupDropzone('#dropzone-{{$id}}', 'comment-edit-text-{{$id}}');
</script>

View file

@ -0,0 +1,467 @@
@-webkit-keyframes passing-through {
0% {
opacity: 0;
-webkit-transform: translateY(40px);
-moz-transform: translateY(40px);
-ms-transform: translateY(40px);
-o-transform: translateY(40px);
transform: translateY(40px);
}
30%, 70% {
opacity: 1;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px);
}
100% {
opacity: 0;
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
transform: translateY(-40px);
}
}
@-moz-keyframes passing-through {
0% {
opacity: 0;
-webkit-transform: translateY(40px);
-moz-transform: translateY(40px);
-ms-transform: translateY(40px);
-o-transform: translateY(40px);
transform: translateY(40px);
}
30%, 70% {
opacity: 1;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px);
}
100% {
opacity: 0;
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
transform: translateY(-40px);
}
}
@keyframes passing-through {
0% {
opacity: 0;
-webkit-transform: translateY(40px);
-moz-transform: translateY(40px);
-ms-transform: translateY(40px);
-o-transform: translateY(40px);
transform: translateY(40px);
}
30%, 70% {
opacity: 1;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px);
}
100% {
opacity: 0;
-webkit-transform: translateY(-40px);
-moz-transform: translateY(-40px);
-ms-transform: translateY(-40px);
-o-transform: translateY(-40px);
transform: translateY(-40px);
}
}
@-webkit-keyframes slide-in {
0% {
opacity: 0;
-webkit-transform: translateY(40px);
-moz-transform: translateY(40px);
-ms-transform: translateY(40px);
-o-transform: translateY(40px);
transform: translateY(40px);
}
30% {
opacity: 1;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px);
}
}
@-moz-keyframes slide-in {
0% {
opacity: 0;
-webkit-transform: translateY(40px);
-moz-transform: translateY(40px);
-ms-transform: translateY(40px);
-o-transform: translateY(40px);
transform: translateY(40px);
}
30% {
opacity: 1;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px);
}
}
@keyframes slide-in {
0% {
opacity: 0;
-webkit-transform: translateY(40px);
-moz-transform: translateY(40px);
-ms-transform: translateY(40px);
-o-transform: translateY(40px);
transform: translateY(40px);
}
30% {
opacity: 1;
-webkit-transform: translateY(0px);
-moz-transform: translateY(0px);
-ms-transform: translateY(0px);
-o-transform: translateY(0px);
transform: translateY(0px);
}
}
@-webkit-keyframes pulse {
0% {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
10% {
-webkit-transform: scale(1.1);
-moz-transform: scale(1.1);
-ms-transform: scale(1.1);
-o-transform: scale(1.1);
transform: scale(1.1);
}
20% {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
}
@-moz-keyframes pulse {
0% {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
10% {
-webkit-transform: scale(1.1);
-moz-transform: scale(1.1);
-ms-transform: scale(1.1);
-o-transform: scale(1.1);
transform: scale(1.1);
}
20% {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
}
@keyframes pulse {
0% {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
10% {
-webkit-transform: scale(1.1);
-moz-transform: scale(1.1);
-ms-transform: scale(1.1);
-o-transform: scale(1.1);
transform: scale(1.1);
}
20% {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
}
}
.dropzone, .dropzone * {
box-sizing: border-box;
}
.dropzone {
min-height: 150px;
border: 1px solid rgba(0, 0, 0, 0.3);
background: white;
padding: 2px 2px;
}
.dropzone.dz-clickable {
cursor: pointer;
}
.dropzone.dz-clickable * {
cursor: default;
}
.dropzone.dz-clickable .dz-message, .dropzone.dz-clickable .dz-message * {
cursor: pointer;
}
.dropzone.dz-started .dz-message {
display: none;
}
.dropzone.dz-drag-hover {
border-style: solid;
}
.dropzone.dz-drag-hover .dz-message {
opacity: 0.5;
}
.dropzone .dz-message {
text-align: center;
}
.dropzone .dz-message .dz-button {
background: none;
color: inherit;
border: none;
padding: 0;
font: inherit;
cursor: pointer;
outline: inherit;
}
.dropzone .dz-preview {
position: relative;
display: inline-block;
vertical-align: top;
margin: 16px;
min-height: 100px;
}
.dropzone .dz-preview:hover {
z-index: 1000;
}
.dropzone .dz-preview:hover .dz-details {
opacity: 1;
}
.dropzone .dz-preview.dz-file-preview .dz-image {
border-radius: 20px;
background: #999;
background: linear-gradient(to bottom, #eee, #ddd);
}
.dropzone .dz-preview.dz-file-preview .dz-details {
opacity: 1;
}
.dropzone .dz-preview.dz-image-preview {
background: white;
}
.dropzone .dz-preview.dz-image-preview .dz-details {
-webkit-transition: opacity 0.2s linear;
-moz-transition: opacity 0.2s linear;
-ms-transition: opacity 0.2s linear;
-o-transition: opacity 0.2s linear;
transition: opacity 0.2s linear;
}
.dropzone .dz-preview .dz-remove {
font-size: 14px;
text-align: center;
display: block;
cursor: pointer;
border: none;
}
.dropzone .dz-preview .dz-remove:hover {
text-decoration: underline;
}
.dropzone .dz-preview:hover .dz-details {
opacity: 1;
}
.dropzone .dz-preview .dz-details {
z-index: 20;
position: absolute;
top: 0;
left: 0;
opacity: 0;
font-size: 13px;
min-width: 100%;
max-width: 100%;
padding: 2em 1em;
text-align: center;
color: rgba(0, 0, 0, 0.9);
line-height: 150%;
}
.dropzone .dz-preview .dz-details .dz-size {
margin-bottom: 1em;
font-size: 16px;
}
.dropzone .dz-preview .dz-details .dz-filename {
white-space: nowrap;
}
.dropzone .dz-preview .dz-details .dz-filename:hover span {
border: 1px solid rgba(200, 200, 200, 0.8);
background-color: rgba(255, 255, 255, 0.8);
}
.dropzone .dz-preview .dz-details .dz-filename:not(:hover) {
overflow: hidden;
text-overflow: ellipsis;
}
.dropzone .dz-preview .dz-details .dz-filename:not(:hover) span {
border: 1px solid transparent;
}
.dropzone .dz-preview .dz-details .dz-filename span, .dropzone .dz-preview .dz-details .dz-size span {
background-color: rgba(255, 255, 255, 0.4);
padding: 0 0.4em;
border-radius: 3px;
}
.dropzone .dz-preview:hover .dz-image img {
-webkit-transform: scale(1.05, 1.05);
-moz-transform: scale(1.05, 1.05);
-ms-transform: scale(1.05, 1.05);
-o-transform: scale(1.05, 1.05);
transform: scale(1.05, 1.05);
-webkit-filter: blur(8px);
filter: blur(8px);
}
.dropzone .dz-preview .dz-image {
border-radius: 20px;
overflow: hidden;
width: 120px;
height: 120px;
position: relative;
display: block;
z-index: 10;
}
.dropzone .dz-preview .dz-image img {
display: block;
}
.dropzone .dz-preview.dz-success .dz-success-mark {
-webkit-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
-moz-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
-ms-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
-o-animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
animation: passing-through 3s cubic-bezier(0.77, 0, 0.175, 1);
}
.dropzone .dz-preview.dz-error .dz-error-mark {
opacity: 1;
-webkit-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
-moz-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
-ms-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
-o-animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
animation: slide-in 3s cubic-bezier(0.77, 0, 0.175, 1);
}
.dropzone .dz-preview .dz-success-mark, .dropzone .dz-preview .dz-error-mark {
pointer-events: none;
opacity: 0;
z-index: 500;
position: absolute;
display: block;
top: 50%;
left: 50%;
margin-left: -27px;
margin-top: -27px;
}
.dropzone .dz-preview .dz-success-mark svg, .dropzone .dz-preview .dz-error-mark svg {
display: block;
width: 54px;
height: 54px;
}
.dropzone .dz-preview.dz-processing .dz-progress {
opacity: 1;
-webkit-transition: all 0.2s linear;
-moz-transition: all 0.2s linear;
-ms-transition: all 0.2s linear;
-o-transition: all 0.2s linear;
transition: all 0.2s linear;
}
.dropzone .dz-preview.dz-complete .dz-progress {
opacity: 0;
-webkit-transition: opacity 0.4s ease-in;
-moz-transition: opacity 0.4s ease-in;
-ms-transition: opacity 0.4s ease-in;
-o-transition: opacity 0.4s ease-in;
transition: opacity 0.4s ease-in;
}
.dropzone .dz-preview:not(.dz-processing) .dz-progress {
-webkit-animation: pulse 6s ease infinite;
-moz-animation: pulse 6s ease infinite;
-ms-animation: pulse 6s ease infinite;
-o-animation: pulse 6s ease infinite;
animation: pulse 6s ease infinite;
}
.dropzone .dz-preview .dz-progress {
opacity: 1;
z-index: 1000;
pointer-events: none;
position: absolute;
height: 16px;
left: 50%;
top: 50%;
margin-top: -8px;
width: 80px;
margin-left: -40px;
background: rgba(255, 255, 255, 0.9);
-webkit-transform: scale(1);
border-radius: 8px;
overflow: hidden;
}
.dropzone .dz-preview .dz-progress .dz-upload {
background: #333;
background: linear-gradient(to bottom, #666, #444);
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 0;
-webkit-transition: width 300ms ease-in-out;
-moz-transition: width 300ms ease-in-out;
-ms-transition: width 300ms ease-in-out;
-o-transition: width 300ms ease-in-out;
transition: width 300ms ease-in-out;
}
.dropzone .dz-preview.dz-error .dz-error-message {
display: block;
}
.dropzone .dz-preview.dz-error:hover .dz-error-message {
opacity: 1;
pointer-events: auto;
}
.dropzone .dz-preview .dz-error-message {
pointer-events: none;
z-index: 1000;
position: absolute;
display: block;
display: none;
opacity: 0;
-webkit-transition: opacity 0.3s ease;
-moz-transition: opacity 0.3s ease;
-ms-transition: opacity 0.3s ease;
-o-transition: opacity 0.3s ease;
transition: opacity 0.3s ease;
border-radius: 8px;
font-size: 13px;
top: 130px;
left: -10px;
width: 140px;
background: #be2626;
background: linear-gradient(to bottom, #be2626, #a92222);
padding: 0.5em 1.2em;
color: white;
}
.dropzone .dz-preview .dz-error-message:after {
content: "";
position: absolute;
top: -6px;
left: 64px;
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-bottom: 6px solid #be2626;
}

File diff suppressed because one or more lines are too long

View file

@ -291,6 +291,10 @@ function editpost(url) {
$("#profile-jot-form #jot-category-wrap").hide();
}
// To make dropzone fileupload work on editing a comment, we need to
// attach a new dropzone to modal
dzFactory.setupDropzone('#jot-text-wrap', 'profile-jot-text');
modal.show();
$("#jot-popup").show();
linkPreview = $("#profile-jot-text").linkPreview();

View file

@ -37,12 +37,14 @@
<i class="fa fa-quote-left"></i>
</button>
</span>
</p>
<p>
<textarea id="comment-edit-text-{{$id}}" class="comment-edit-text-empty form-control text-autosize" name="body" placeholder="{{$comment}}" rows="3" data-default="{{$default}}" dir="auto">{{$default}}</textarea>
</p>
{{if $qcomment}}
<p>
</p>
<div id="dropzone-{{$id}}" class="dropzone" style="overflow:scroll">
<p>
<textarea id="comment-edit-text-{{$id}}" class="dropzone comment-edit-text-empty form-control text-autosize" name="body" placeholder="{{$comment}}" rows="3" data-default="{{$default}}" dir="auto">{{$default}}</textarea>
</p>
</div>
{{if $qcomment}}
<p>
<select id="qcomment-select-{{$id}}" name="qcomment-{{$id}}" class="qcomment" onchange="qCommentInsert(this,{{$id}});">
<option value=""></option>
{{foreach $qcomment as $qc}}
@ -51,7 +53,6 @@
</select>
</p>
{{/if}}
<p class="comment-edit-submit-wrapper">
{{if $preview}}
<button type="button" class="btn btn-default comment-edit-preview" onclick="preview_comment({{$id}});" id="comment-edit-preview-link-{{$id}}"><i class="fa fa-eye"></i> {{$preview}}</button>
@ -64,3 +65,15 @@
<div id="comment-edit-preview-{{$id}}" class="comment-edit-preview" style="display:none;"></div>
</div>
<script>
$('[id=comment-fake-text-{{$id}}]').on('focus', function() {
dzFactory.setupDropzone('#dropzone-{{$id}}', 'comment-edit-text-{{$id}}');
$('[id=comment-fake-text-{{$id}}]').prop('focus', null).off('focus');
$('[id=comment-{{$id}}]').prop('click', null).off('click');
});
$('[id=comment-{{$id}}]').on('click', function() {
dzFactory.setupDropzone('#dropzone-{{$id}}', 'comment-edit-text-{{$id}}');
$('[id=comment-fake-text-{{$id}}]').prop('focus', null).off('focus');
$('[id=comment-{{$id}}]').prop('click', null).off('click');
});
</script>

View file

@ -55,6 +55,8 @@
media="screen" />
<link rel="stylesheet" href="view/theme/frio/css/font-awesome.custom.css?v={{$smarty.const.FRIENDICA_VERSION}}"
type="text/css" media="screen" />
<link rel="stylesheet" href="view/theme/frio/css/dropzone.min.frio.css?v={{$smarty.const.FRIENDICA_VERSION}}"
type="text/css" media="screen" />
{{foreach $stylesheets as $stylesheetUrl => $media}}
<link rel="stylesheet" href="{{$stylesheetUrl}}" type="text/css" media="{{$media}}" />
@ -137,6 +139,9 @@
<script type="text/javascript" src="view/theme/frio/js/hovercard.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
{{/if}}
<script type="text/javascript" src="view/theme/frio/js/textedit.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
<script type="text/javascript" src="vendor/enyo/dropzone/dist/min/dropzone.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
<script type="text/javascript" src="view/js/dropzone-factory.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
<script type="text/javascript"> max_imagesize = {{$max_imagesize}}; var dzFactory = new DzFactory(); Dropzone.autoDiscover = false; </script>
{{* Include the strings which are needed for some js functions (e.g. translation)
They are loaded into the html <head> so that js functions can use them *}}

View file

@ -99,7 +99,7 @@
{{/if}}
{{* The jot text field in which the post text is inserted *}}
<div id="jot-text-wrap">
<div id="jot-text-wrap" class="dropzone" style="overflow:scroll">
<textarea rows="2" cols="64" class="profile-jot-text form-control text-autosize" id="profile-jot-text" name="body" placeholder="{{$share}}" onFocus="jotTextOpenUI(this);" onBlur="jotTextCloseUI(this);" style="min-width:100%; max-width:100%;" dir="auto">{{if $content}}{{$content nofilter}}{{/if}}</textarea>
</div>
@ -152,6 +152,7 @@
<div id="jot-fbrowser-wrapper" class="minimize" aria-labelledby="jot-browser-link" role="tabpanel" aria-hidden="true"></div>
</form>
<div id="dz-preview-jot" class="dropzone-preview"></div>
{{if $content}}<script type="text/javascript">initEditor();</script>{{/if}}
</div>
@ -162,9 +163,9 @@
{{* The jot modal - We use a own modal for the jot and not the standard modal
from the page template. This is because the special structure of the jot
(e.g.jot navigation tabs in the modal titel area).
The in the frio theme the jot will loaded regulary and is hidden by default.)
Then in the frio theme the jot will loaded regulary and is hidden by default.)
The js function jotShow() loads the jot into the modal. With this structure we
can load different content into the jot moadl (e.g. the item edit jot)
can load different content into the jot modal (e.g. the item edit jot)
*}}
<div id="jot-modal" class="modal fade" role="dialog">
<div class="modal-dialog">
@ -172,9 +173,12 @@ can load different content into the jot moadl (e.g. the item edit jot)
</div>
</div>
<script type="text/javascript">
$('iframe').load(function() {
this.style.height = this.contentWindow.document.body.offsetHeight + 'px';
});
</script>
<script>
dzFactory.setupDropzone('#jot-text-wrap', 'profile-jot-text');
</script>