mirror of
https://github.com/BookStackApp/BookStack.git
synced 2026-02-14 03:09:39 +03:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e90da18ada | ||
|
|
a08d80e1cc | ||
|
|
b711bc6816 | ||
|
|
247e6dba85 | ||
|
|
2b3d6e4e4a | ||
|
|
6b1980c4f3 | ||
|
|
9ba29770e1 | ||
|
|
3d375fae55 | ||
|
|
c99a50de2c | ||
|
|
1a32b25b5e | ||
|
|
481aa5b5b0 | ||
|
|
c943eb4d0d | ||
|
|
aca6de49b0 | ||
|
|
5fd04fa470 | ||
|
|
87339e4cd0 | ||
|
|
a9eb058dad | ||
|
|
61fad6a665 | ||
|
|
fa4bee2d98 | ||
|
|
ce63260fa6 | ||
|
|
a3557d5bb2 | ||
|
|
9ca22976c3 | ||
|
|
9e2934fe17 | ||
|
|
2259263214 | ||
|
|
762cf5f183 | ||
|
|
07175f2b3e | ||
|
|
6258175922 | ||
|
|
15736777a0 | ||
|
|
0c4ddf16a5 | ||
|
|
74a5e3113e | ||
|
|
df0a982433 | ||
|
|
212f924ffa | ||
|
|
09936566dd | ||
|
|
9469c04eab | ||
|
|
941bb73a68 | ||
|
|
8e652f5d8f | ||
|
|
eec1b21928 | ||
|
|
1baeb7bec9 | ||
|
|
61475ca0a3 | ||
|
|
244c5a3ebb | ||
|
|
39e7ac1c15 | ||
|
|
ab7f5def04 |
12
.github/ISSUE_TEMPLATE.md
vendored
12
.github/ISSUE_TEMPLATE.md
vendored
@@ -4,10 +4,18 @@ Desired Feature:
|
||||
|
||||
### For Bug Reports
|
||||
|
||||
* BookStack Version:
|
||||
* BookStack Version *(Found in settings, Please don't put 'latest')*:
|
||||
* PHP Version:
|
||||
* MySQL Version:
|
||||
|
||||
##### Expected Behavior
|
||||
|
||||
##### Actual Behavior
|
||||
|
||||
|
||||
##### Current Behavior
|
||||
|
||||
|
||||
|
||||
##### Steps to Reproduce
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ class RegenerateSearch extends Command
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Command description';
|
||||
protected $description = 'Re-index all content for searching';
|
||||
|
||||
protected $searchService;
|
||||
|
||||
|
||||
@@ -158,9 +158,9 @@ class PageController extends Controller
|
||||
|
||||
$this->checkOwnablePermission('page-view', $page);
|
||||
|
||||
$pageContent = $this->entityRepo->renderPage($page);
|
||||
$page->html = $this->entityRepo->renderPage($page);
|
||||
$sidebarTree = $this->entityRepo->getBookChildren($page->book);
|
||||
$pageNav = $this->entityRepo->getPageNav($pageContent);
|
||||
$pageNav = $this->entityRepo->getPageNav($page->html);
|
||||
$page->load(['comments.createdBy']);
|
||||
|
||||
Views::add($page);
|
||||
@@ -441,6 +441,7 @@ class PageController extends Controller
|
||||
public function exportPdf($bookSlug, $pageSlug)
|
||||
{
|
||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
||||
$page->html = $this->entityRepo->renderPage($page);
|
||||
$pdfContent = $this->exportService->pageToPdf($page);
|
||||
return response()->make($pdfContent, 200, [
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
@@ -457,6 +458,7 @@ class PageController extends Controller
|
||||
public function exportHtml($bookSlug, $pageSlug)
|
||||
{
|
||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
||||
$page->html = $this->entityRepo->renderPage($page);
|
||||
$containedHtml = $this->exportService->pageToContainedHtml($page);
|
||||
return response()->make($containedHtml, 200, [
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
|
||||
@@ -13,8 +13,8 @@ class Kernel extends HttpKernel
|
||||
*/
|
||||
protected $middleware = [
|
||||
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\BookStack\Http\Middleware\TrimStrings::class,
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -26,6 +26,8 @@ class Kernel extends HttpKernel
|
||||
'web' => [
|
||||
\BookStack\Http\Middleware\EncryptCookies::class,
|
||||
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
|
||||
\Illuminate\Session\Middleware\StartSession::class,
|
||||
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
|
||||
\BookStack\Http\Middleware\VerifyCsrfToken::class,
|
||||
\Illuminate\Routing\Middleware\SubstituteBindings::class,
|
||||
\BookStack\Http\Middleware\Localization::class
|
||||
@@ -42,7 +44,7 @@ class Kernel extends HttpKernel
|
||||
* @var array
|
||||
*/
|
||||
protected $routeMiddleware = [
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'can' => \Illuminate\Auth\Middleware\Authorize::class,
|
||||
'auth' => \BookStack\Http\Middleware\Authenticate::class,
|
||||
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
|
||||
'guest' => \BookStack\Http\Middleware\RedirectIfAuthenticated::class,
|
||||
|
||||
19
app/Http/Middleware/TrimStrings.php
Normal file
19
app/Http/Middleware/TrimStrings.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\TrimStrings as BaseTrimmer;
|
||||
|
||||
class TrimStrings extends BaseTrimmer
|
||||
{
|
||||
/**
|
||||
* The names of the attributes that should not be trimmed.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $except = [
|
||||
'password',
|
||||
'password_confirmation',
|
||||
'password-confirm',
|
||||
];
|
||||
}
|
||||
@@ -16,6 +16,7 @@ class EventServiceProvider extends ServiceProvider
|
||||
protected $listen = [
|
||||
SocialiteWasCalled::class => [
|
||||
'SocialiteProviders\Slack\SlackExtendSocialite@handle',
|
||||
'SocialiteProviders\Azure\AzureExtendSocialite@handle',
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
@@ -716,7 +716,6 @@ class EntityRepo
|
||||
$content = str_replace($matches[0][$index], trim($innerContent), $content);
|
||||
}
|
||||
|
||||
$page->setAttribute('renderedHTML', $content);
|
||||
return $content;
|
||||
}
|
||||
|
||||
|
||||
@@ -382,11 +382,13 @@ class SearchService
|
||||
protected function generateTermArrayFromText($text, $scoreAdjustment = 1)
|
||||
{
|
||||
$tokenMap = []; // {TextToken => OccurrenceCount}
|
||||
$splitText = explode(' ', $text);
|
||||
foreach ($splitText as $token) {
|
||||
if ($token === '') continue;
|
||||
$splitChars = " \n\t.,";
|
||||
$token = strtok($text, $splitChars);
|
||||
|
||||
while ($token !== false) {
|
||||
if (!isset($tokenMap[$token])) $tokenMap[$token] = 0;
|
||||
$tokenMap[$token]++;
|
||||
$token = strtok($splitChars);
|
||||
}
|
||||
|
||||
$terms = [];
|
||||
@@ -479,4 +481,23 @@ class SearchService
|
||||
});
|
||||
}
|
||||
|
||||
protected function filterSortBy(\Illuminate\Database\Eloquent\Builder $query, Entity $model, $input)
|
||||
{
|
||||
$functionName = camel_case('sort_by_' . $input);
|
||||
if (method_exists($this, $functionName)) $this->$functionName($query, $model);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sorting filter options
|
||||
*/
|
||||
|
||||
protected function sortByLastCommented(\Illuminate\Database\Eloquent\Builder $query, Entity $model)
|
||||
{
|
||||
$commentsTable = $this->db->getTablePrefix() . 'comments';
|
||||
$morphClass = str_replace('\\', '\\\\', $model->getMorphClass());
|
||||
$commentQuery = $this->db->raw('(SELECT c1.entity_id, c1.entity_type, c1.created_at as last_commented FROM '.$commentsTable.' c1 LEFT JOIN '.$commentsTable.' c2 ON (c1.entity_id = c2.entity_id AND c1.entity_type = c2.entity_type AND c1.created_at < c2.created_at) WHERE c1.entity_type = \''. $morphClass .'\' AND c2.created_at IS NULL) as comments');
|
||||
|
||||
$query->join($commentQuery, $model->getTable() . '.id', '=', 'comments.entity_id')->orderBy('last_commented', 'desc');
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ class SocialAuthService
|
||||
protected $socialite;
|
||||
protected $socialAccount;
|
||||
|
||||
protected $validSocialDrivers = ['google', 'github', 'facebook', 'slack', 'twitter'];
|
||||
protected $validSocialDrivers = ['google', 'github', 'facebook', 'slack', 'twitter', 'azure'];
|
||||
|
||||
/**
|
||||
* SocialAuthService constructor.
|
||||
@@ -104,7 +104,8 @@ class SocialAuthService
|
||||
// When a user is not logged in and a matching SocialAccount exists,
|
||||
// Simply log the user into the application.
|
||||
if (!$isLoggedIn && $socialAccount !== null) {
|
||||
return $this->logUserIn($socialAccount->user);
|
||||
auth()->login($socialAccount->user);
|
||||
return redirect()->intended('/');
|
||||
}
|
||||
|
||||
// When a user is logged in but the social account does not exist,
|
||||
@@ -137,13 +138,6 @@ class SocialAuthService
|
||||
throw new SocialSignInException($message . '.', '/login');
|
||||
}
|
||||
|
||||
|
||||
private function logUserIn($user)
|
||||
{
|
||||
auth()->login($user);
|
||||
return redirect('/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the social driver is correct and supported.
|
||||
*
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
"gathercontent/htmldiff": "^0.2.1",
|
||||
"barryvdh/laravel-snappy": "^0.3.1",
|
||||
"laravel/browser-kit-testing": "^1.0",
|
||||
"socialiteproviders/slack": "^3.0"
|
||||
"socialiteproviders/slack": "^3.0",
|
||||
"socialiteproviders/microsoft-azure": "^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"fzaninotto/faker": "~1.4",
|
||||
|
||||
41
composer.lock
generated
41
composer.lock
generated
@@ -4,8 +4,8 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "e6d32752d02dae662bedc69fa5856feb",
|
||||
"content-hash": "5f0f4e912f1207e761caf9344f2308a0",
|
||||
"hash": "aa5f3333b909857a179e6aa9c30ab9ab",
|
||||
"content-hash": "dc4c98aa8942f27fde6a9faa440e1a74",
|
||||
"packages": [
|
||||
{
|
||||
"name": "aws/aws-sdk-php",
|
||||
@@ -2073,6 +2073,43 @@
|
||||
"description": "Easily add new or override built-in providers in Laravel Socialite.",
|
||||
"time": "2017-02-07 07:26:42"
|
||||
},
|
||||
{
|
||||
"name": "socialiteproviders/microsoft-azure",
|
||||
"version": "v3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SocialiteProviders/Microsoft-Azure.git",
|
||||
"reference": "d7a703a782eb9f7eae0db803beaa3ddec19ef372"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SocialiteProviders/Microsoft-Azure/zipball/d7a703a782eb9f7eae0db803beaa3ddec19ef372",
|
||||
"reference": "d7a703a782eb9f7eae0db803beaa3ddec19ef372",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.6 || ^7.0",
|
||||
"socialiteproviders/manager": "~3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"SocialiteProviders\\Azure\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Chris Hemmings",
|
||||
"email": "chris@hemmin.gs"
|
||||
}
|
||||
],
|
||||
"description": "Microsoft Azure OAuth2 Provider for Laravel Socialite",
|
||||
"time": "2017-01-25 09:48:29"
|
||||
},
|
||||
{
|
||||
"name": "socialiteproviders/slack",
|
||||
"version": "v3.0.1",
|
||||
|
||||
@@ -58,7 +58,7 @@ return [
|
||||
*/
|
||||
|
||||
'locale' => env('APP_LANG', 'en'),
|
||||
'locales' => ['en', 'de', 'es', 'fr', 'nl', 'pt_BR', 'sk', 'ja', 'pl', 'it'],
|
||||
'locales' => ['en', 'de', 'es', 'es_AR', 'fr', 'nl', 'pt_BR', 'sk', 'ja', 'pl', 'it', 'ru'],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
@@ -72,6 +72,14 @@ return [
|
||||
'name' => 'Twitter',
|
||||
],
|
||||
|
||||
'azure' => [
|
||||
'client_id' => env('AZURE_APP_ID', false),
|
||||
'client_secret' => env('AZURE_APP_SECRET', false),
|
||||
'tenant' => env('AZURE_TENANT', false),
|
||||
'redirect' => env('APP_URL') . '/login/service/azure/callback',
|
||||
'name' => 'Microsoft Azure',
|
||||
],
|
||||
|
||||
'ldap' => [
|
||||
'server' => env('LDAP_SERVER', false),
|
||||
'dn' => env('LDAP_DN', false),
|
||||
|
||||
@@ -25,11 +25,6 @@
|
||||
"yargs": "^7.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"angular": "^1.5.5",
|
||||
"angular-animate": "^1.5.5",
|
||||
"angular-resource": "^1.5.5",
|
||||
"angular-sanitize": "^1.5.5",
|
||||
"angular-ui-sortable": "^0.17.0",
|
||||
"axios": "^0.16.1",
|
||||
"babel-polyfill": "^6.23.0",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
|
||||
4
public/css/export-styles.css
vendored
4
public/css/export-styles.css
vendored
File diff suppressed because one or more lines are too long
4
public/css/styles.css
vendored
4
public/css/styles.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.PluginManager")}),g("2",["3"],function(a){return a("tinymce.util.Tools")}),g("0",["1","2"],function(a,b){return a.add("advlist",function(a){function c(b){return a.$.contains(a.getBody(),b)}function d(a){return a&&/^(OL|UL|DL)$/.test(a.nodeName)&&c(a)}function e(a,c){var d=[];return c&&b.each(c.split(/[ ,]/),function(a){d.push({text:a.replace(/\-/g," ").replace(/\b\w/g,function(a){return a.toUpperCase()}),data:"default"==a?"":a})}),d}function f(c,d){a.undoManager.transact(function(){var e,f=a.dom,g=a.selection;if(e=f.getParent(g.getNode(),"ol,ul"),!e||e.nodeName!=c||d===!1){var h={"list-style-type":d?d:""};a.execCommand("UL"==c?"InsertUnorderedList":"InsertOrderedList",!1,h)}e=f.getParent(g.getNode(),"ol,ul"),e&&b.each(f.select("ol,ul",e).concat([e]),function(a){a.nodeName!==c&&d!==!1&&(a=f.rename(a,c)),f.setStyle(a,"listStyleType",d?d:null),a.removeAttribute("data-mce-style")}),a.focus()})}function g(b){var c=a.dom.getStyle(a.dom.getParent(a.selection.getNode(),"ol,ul"),"listStyleType")||"";b.control.items().each(function(a){a.active(a.settings.data===c)})}var h,i,j=function(a,c){var d=a.settings.plugins?a.settings.plugins:"";return b.inArray(d.split(/[ ,]/),c)!==-1};h=e("OL",a.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman")),i=e("UL",a.getParam("advlist_bullet_styles","default,circle,disc,square"));var k=function(c){return function(){var e=this;a.on("NodeChange",function(a){var f=b.grep(a.parents,d);e.active(f.length>0&&f[0].nodeName===c)})}};j(a,"lists")&&(a.addCommand("ApplyUnorderedListStyle",function(a,b){f("UL",b["list-style-type"])}),a.addCommand("ApplyOrderedListStyle",function(a,b){f("OL",b["list-style-type"])}),a.addButton("numlist",{type:h.length>0?"splitbutton":"button",tooltip:"Numbered list",menu:h,onPostRender:k("OL"),onshow:g,onselect:function(a){f("OL",a.control.settings.data)},onclick:function(){f("OL",!1)}}),a.addButton("bullist",{type:i.length>0?"splitbutton":"button",tooltip:"Bullet list",onPostRender:k("UL"),menu:i,onshow:g,onselect:function(a){f("UL",a.control.settings.data)},onclick:function(){f("UL",!1)}}))}),function(){}}),d("0")()}();
|
||||
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.PluginManager")}),g("2",["3"],function(a){return a("tinymce.util.Tools")}),g("0",["1","2"],function(a,b){return a.add("advlist",function(a){function c(b){return a.$.contains(a.getBody(),b)}function d(a){return a&&/^(OL|UL|DL)$/.test(a.nodeName)&&c(a)}function e(a,c){var d=[];return c&&b.each(c.split(/[ ,]/),function(a){d.push({text:a.replace(/\-/g," ").replace(/\b\w/g,function(a){return a.toUpperCase()}),data:"default"==a?"":a})}),d}function f(b,c){var d="UL"==b?"InsertUnorderedList":"InsertOrderedList";a.execCommand(d,!1,c===!1?null:{"list-style-type":c})}function g(b){var c=a.dom.getStyle(a.dom.getParent(a.selection.getNode(),"ol,ul"),"listStyleType")||"";b.control.items().each(function(a){a.active(a.settings.data===c)})}var h,i,j=function(a,c){var d=a.settings.plugins?a.settings.plugins:"";return b.inArray(d.split(/[ ,]/),c)!==-1};h=e("OL",a.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman")),i=e("UL",a.getParam("advlist_bullet_styles","default,circle,disc,square"));var k=function(c){return function(){var e=this;a.on("NodeChange",function(a){var f=b.grep(a.parents,d);e.active(f.length>0&&f[0].nodeName===c)})}};j(a,"lists")&&(a.addCommand("ApplyUnorderedListStyle",function(a,b){f("UL",b["list-style-type"])}),a.addCommand("ApplyOrderedListStyle",function(a,b){f("OL",b["list-style-type"])}),a.addButton("numlist",{type:h.length>0?"splitbutton":"button",tooltip:"Numbered list",menu:h,onPostRender:k("OL"),onshow:g,onselect:function(a){f("OL",a.control.settings.data)},onclick:function(){a.execCommand("InsertOrderedList")}}),a.addButton("bullist",{type:i.length>0?"splitbutton":"button",tooltip:"Bullet list",onPostRender:k("UL"),menu:i,onshow:g,onselect:function(a){f("UL",a.control.settings.data)},onclick:function(){a.execCommand("InsertUnorderedList")}}))}),function(){}}),d("0")()}();
|
||||
@@ -1 +1 @@
|
||||
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.Env")}),g("2",["3"],function(a){return a("tinymce.PluginManager")}),g("0",["1","2"],function(a,b){return b.add("autolink",function(b){function c(a){f(a,-1,"(",!0)}function d(a){f(a,0,"",!0)}function e(a){f(a,-1,"",!1)}function f(a,b,c){function d(a,b){if(b<0&&(b=0),3==a.nodeType){var c=a.data.length;b>c&&(b=c)}return b}function e(a,b){1!=a.nodeType||a.hasChildNodes()?g.setStart(a,d(a,b)):g.setStartBefore(a)}function f(a,b){1!=a.nodeType||a.hasChildNodes()?g.setEnd(a,d(a,b)):g.setEndAfter(a)}var g,i,j,k,l,m,n,o,p,q;if("A"!=a.selection.getNode().tagName){if(g=a.selection.getRng(!0).cloneRange(),g.startOffset<5){if(o=g.endContainer.previousSibling,!o){if(!g.endContainer.firstChild||!g.endContainer.firstChild.nextSibling)return;o=g.endContainer.firstChild.nextSibling}if(p=o.length,e(o,p),f(o,p),g.endOffset<5)return;i=g.endOffset,k=o}else{if(k=g.endContainer,3!=k.nodeType&&k.firstChild){for(;3!=k.nodeType&&k.firstChild;)k=k.firstChild;3==k.nodeType&&(e(k,0),f(k,k.nodeValue.length))}i=1==g.endOffset?2:g.endOffset-1-b}j=i;do e(k,i>=2?i-2:0),f(k,i>=1?i-1:0),i-=1,q=g.toString();while(" "!=q&&""!==q&&160!=q.charCodeAt(0)&&i-2>=0&&q!=c);g.toString()==c||160==g.toString().charCodeAt(0)?(e(k,i),f(k,j),i+=1):0===g.startOffset?(e(k,0),f(k,j)):(e(k,i),f(k,j)),m=g.toString(),"."==m.charAt(m.length-1)&&f(k,j-1),m=g.toString(),n=m.match(h),n&&("www."==n[1]?n[1]="http://www.":/@$/.test(n[1])&&!/^mailto:/.test(n[1])&&(n[1]="mailto:"+n[1]),l=a.selection.getBookmark(),a.selection.setRng(g),a.execCommand("createlink",!1,n[1]+n[2]),a.settings.default_link_target&&a.dom.setAttrib(a.selection.getNode(),"target",a.settings.default_link_target),a.selection.moveToBookmark(l),a.nodeChanged())}}var g,h=/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i;return b.settings.autolink_pattern&&(h=b.settings.autolink_pattern),b.on("keydown",function(a){if(13==a.keyCode)return e(b)}),a.ie?void b.on("focus",function(){if(!g){g=!0;try{b.execCommand("AutoUrlDetect",!1,!0)}catch(a){}}}):(b.on("keypress",function(a){if(41==a.keyCode)return c(b)}),void b.on("keyup",function(a){if(32==a.keyCode)return d(b)}))}),function(){}}),d("0")()}();
|
||||
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("3",tinymce.util.Tools.resolve),g("1",["3"],function(a){return a("tinymce.Env")}),g("2",["3"],function(a){return a("tinymce.PluginManager")}),g("0",["1","2"],function(a,b){var c=function(a,b){return a===b||" "===a||160===a.charCodeAt(0)};return b.add("autolink",function(b){function d(a){g(a,-1,"(",!0)}function e(a){g(a,0,"",!0)}function f(a){g(a,-1,"",!1)}function g(a,b,d){function e(a,b){if(b<0&&(b=0),3==a.nodeType){var c=a.data.length;b>c&&(b=c)}return b}function f(a,b){1!=a.nodeType||a.hasChildNodes()?h.setStart(a,e(a,b)):h.setStartBefore(a)}function g(a,b){1!=a.nodeType||a.hasChildNodes()?h.setEnd(a,e(a,b)):h.setEndAfter(a)}var h,j,k,l,m,n,o,p,q,r;if("A"!=a.selection.getNode().tagName){if(h=a.selection.getRng(!0).cloneRange(),h.startOffset<5){if(p=h.endContainer.previousSibling,!p){if(!h.endContainer.firstChild||!h.endContainer.firstChild.nextSibling)return;p=h.endContainer.firstChild.nextSibling}if(q=p.length,f(p,q),g(p,q),h.endOffset<5)return;j=h.endOffset,l=p}else{if(l=h.endContainer,3!=l.nodeType&&l.firstChild){for(;3!=l.nodeType&&l.firstChild;)l=l.firstChild;3==l.nodeType&&(f(l,0),g(l,l.nodeValue.length))}j=1==h.endOffset?2:h.endOffset-1-b}k=j;do f(l,j>=2?j-2:0),g(l,j>=1?j-1:0),j-=1,r=h.toString();while(" "!=r&&""!==r&&160!=r.charCodeAt(0)&&j-2>=0&&r!=d);c(h.toString(),d)?(f(l,j),g(l,k),j+=1):0===h.startOffset?(f(l,0),g(l,k)):(f(l,j),g(l,k)),n=h.toString(),"."==n.charAt(n.length-1)&&g(l,k-1),n=h.toString(),o=n.match(i),o&&("www."==o[1]?o[1]="http://www.":/@$/.test(o[1])&&!/^mailto:/.test(o[1])&&(o[1]="mailto:"+o[1]),m=a.selection.getBookmark(),a.selection.setRng(h),a.execCommand("createlink",!1,o[1]+o[2]),a.settings.default_link_target&&a.dom.setAttrib(a.selection.getNode(),"target",a.settings.default_link_target),a.selection.moveToBookmark(m),a.nodeChanged())}}var h,i=/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i;return b.settings.autolink_pattern&&(i=b.settings.autolink_pattern),b.on("keydown",function(a){if(13==a.keyCode)return f(b)}),a.ie?void b.on("focus",function(){if(!h){h=!0;try{b.execCommand("AutoUrlDetect",!1,!0)}catch(a){}}}):(b.on("keypress",function(a){if(41==a.keyCode)return d(b)}),void b.on("keyup",function(a){if(32==a.keyCode)return e(b)}))}),function(){}}),d("0")()}();
|
||||
@@ -1 +1 @@
|
||||
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("6",tinymce.util.Tools.resolve),g("1",["6"],function(a){return a("tinymce.EditorManager")}),g("2",["6"],function(a){return a("tinymce.PluginManager")}),g("3",["6"],function(a){return a("tinymce.util.LocalStorage")}),g("4",["6"],function(a){return a("tinymce.util.Tools")}),h("5",window),g("0",["1","2","3","4","5"],function(a,b,c,d,e){return a._beforeUnloadHandler=function(){var b;return d.each(a.editors,function(a){a.plugins.autosave&&a.plugins.autosave.storeDraft(),!b&&a.isDirty()&&a.getParam("autosave_ask_before_unload",!0)&&(b=a.translate("You have unsaved changes are you sure you want to navigate away?"))}),b},b.add("autosave",function(b){function f(a,b){var c={s:1e3,m:6e4};return a=/^(\d+)([ms]?)$/.exec(""+(a||b)),(a[2]?c[a[2]]:1)*parseInt(a,10)}function g(){var a=parseInt(c.getItem(o+"time"),10)||0;return!((new Date).getTime()-a>q.autosave_retention)||(h(!1),!1)}function h(a){c.removeItem(o+"draft"),c.removeItem(o+"time"),a!==!1&&b.fire("RemoveDraft")}function i(){!n()&&b.isDirty()&&(c.setItem(o+"draft",b.getContent({format:"raw",no_events:!0})),c.setItem(o+"time",(new Date).getTime()),b.fire("StoreDraft"))}function j(){g()&&(b.setContent(c.getItem(o+"draft"),{format:"raw"}),b.fire("RestoreDraft"))}function k(){p||(setInterval(function(){b.removed||i()},q.autosave_interval),p=!0)}function l(){var a=this;a.disabled(!g()),b.on("StoreDraft RestoreDraft RemoveDraft",function(){a.disabled(!g())}),k()}function m(){b.undoManager.beforeChange(),j(),h(),b.undoManager.add()}function n(a){var c=b.settings.forced_root_block;return a=d.trim("undefined"==typeof a?b.getBody().innerHTML:a),""===a||new RegExp("^<"+c+"[^>]*>((\xa0| |[ \t]|<br[^>]*>)+?|)</"+c+">|<br>$","i").test(a)}var o,p,q=b.settings;o=q.autosave_prefix||"tinymce-autosave-{path}{query}-{id}-",o=o.replace(/\{path\}/g,document.location.pathname),o=o.replace(/\{query\}/g,document.location.search),o=o.replace(/\{id\}/g,b.id),q.autosave_interval=f(q.autosave_interval,"30s"),q.autosave_retention=f(q.autosave_retention,"20m"),b.addButton("restoredraft",{title:"Restore last draft",onclick:m,onPostRender:l}),b.addMenuItem("restoredraft",{text:"Restore last draft",onclick:m,onPostRender:l,context:"file"}),b.settings.autosave_restore_when_empty!==!1&&(b.on("init",function(){g()&&n()&&j()}),b.on("saveContent",function(){h()})),e.onbeforeunload=a._beforeUnloadHandler,this.hasDraft=g,this.storeDraft=i,this.restoreDraft=j,this.removeDraft=h,this.isEmpty=n}),function(){}}),d("0")()}();
|
||||
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("6",tinymce.util.Tools.resolve),g("1",["6"],function(a){return a("tinymce.EditorManager")}),g("2",["6"],function(a){return a("tinymce.PluginManager")}),g("3",["6"],function(a){return a("tinymce.util.LocalStorage")}),g("4",["6"],function(a){return a("tinymce.util.Tools")}),h("5",window),g("0",["1","2","3","4","5"],function(a,b,c,d,e){return a._beforeUnloadHandler=function(){var b;return d.each(a.get(),function(a){a.plugins.autosave&&a.plugins.autosave.storeDraft(),!b&&a.isDirty()&&a.getParam("autosave_ask_before_unload",!0)&&(b=a.translate("You have unsaved changes are you sure you want to navigate away?"))}),b},b.add("autosave",function(b){function f(a,b){var c={s:1e3,m:6e4};return a=/^(\d+)([ms]?)$/.exec(""+(a||b)),(a[2]?c[a[2]]:1)*parseInt(a,10)}function g(){var a=parseInt(c.getItem(o+"time"),10)||0;return!((new Date).getTime()-a>q.autosave_retention)||(h(!1),!1)}function h(a){c.removeItem(o+"draft"),c.removeItem(o+"time"),a!==!1&&b.fire("RemoveDraft")}function i(){!n()&&b.isDirty()&&(c.setItem(o+"draft",b.getContent({format:"raw",no_events:!0})),c.setItem(o+"time",(new Date).getTime()),b.fire("StoreDraft"))}function j(){g()&&(b.setContent(c.getItem(o+"draft"),{format:"raw"}),b.fire("RestoreDraft"))}function k(){p||(setInterval(function(){b.removed||i()},q.autosave_interval),p=!0)}function l(){var a=this;a.disabled(!g()),b.on("StoreDraft RestoreDraft RemoveDraft",function(){a.disabled(!g())}),k()}function m(){b.undoManager.beforeChange(),j(),h(),b.undoManager.add()}function n(a){var c=b.settings.forced_root_block;return a=d.trim("undefined"==typeof a?b.getBody().innerHTML:a),""===a||new RegExp("^<"+c+"[^>]*>((\xa0| |[ \t]|<br[^>]*>)+?|)</"+c+">|<br>$","i").test(a)}var o,p,q=b.settings;o=q.autosave_prefix||"tinymce-autosave-{path}{query}-{id}-",o=o.replace(/\{path\}/g,document.location.pathname),o=o.replace(/\{query\}/g,document.location.search),o=o.replace(/\{id\}/g,b.id),q.autosave_interval=f(q.autosave_interval,"30s"),q.autosave_retention=f(q.autosave_retention,"20m"),b.addButton("restoredraft",{title:"Restore last draft",onclick:m,onPostRender:l}),b.addMenuItem("restoredraft",{text:"Restore last draft",onclick:m,onPostRender:l,context:"file"}),b.settings.autosave_restore_when_empty!==!1&&(b.on("init",function(){g()&&n()&&j()}),b.on("saveContent",function(){h()})),e.onbeforeunload=a._beforeUnloadHandler,this.hasDraft=g,this.storeDraft=i,this.restoreDraft=j,this.removeDraft=h,this.isEmpty=n}),function(){}}),d("0")()}();
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("2",tinymce.util.Tools.resolve),g("1",["2"],function(a){return a("tinymce.PluginManager")}),g("0",["1"],function(a){return a.add("nonbreaking",function(a){var b=a.getParam("nonbreaking_force_tab");if(a.addCommand("mceNonBreaking",function(){a.insertContent(a.plugins.visualchars&&a.plugins.visualchars.state?'<span class="mce-nbsp"> </span>':" "),a.dom.setAttrib(a.dom.select("span.mce-nbsp"),"data-mce-bogus","1")}),a.addButton("nonbreaking",{title:"Nonbreaking space",cmd:"mceNonBreaking"}),a.addMenuItem("nonbreaking",{text:"Nonbreaking space",cmd:"mceNonBreaking",context:"insert"}),b){var c=+b>1?+b:3;a.on("keydown",function(b){if(9==b.keyCode){if(b.shiftKey)return;b.preventDefault();for(var d=0;d<c;d++)a.execCommand("mceNonBreaking")}})}}),function(){}}),d("0")()}();
|
||||
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("2",tinymce.util.Tools.resolve),g("1",["2"],function(a){return a("tinymce.PluginManager")}),g("0",["1"],function(a){return a.add("nonbreaking",function(a){var b=a.getParam("nonbreaking_force_tab"),c=function(a,b){for(var c="",d=0;d<b;d++)c+=a;return c},d=function(b){var d=a.plugins.visualchars&&a.plugins.visualchars.state?'<span class="mce-nbsp"> </span>':" ";a.insertContent(c(d,b)),a.dom.setAttrib(a.dom.select("span.mce-nbsp"),"data-mce-bogus","1")};if(a.addCommand("mceNonBreaking",function(){d(1)}),a.addButton("nonbreaking",{title:"Nonbreaking space",cmd:"mceNonBreaking"}),a.addMenuItem("nonbreaking",{text:"Nonbreaking space",cmd:"mceNonBreaking",context:"insert"}),b){var e=+b>1?+b:3;a.on("keydown",function(a){if(9==a.keyCode){if(a.shiftKey)return;a.preventDefault(),d(e)}})}}),function(){}}),d("0")()}();
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("4",tinymce.util.Tools.resolve),g("1",["4"],function(a){return a("tinymce.PluginManager")}),g("2",["4"],function(a){return a("tinymce.Env")}),g("3",["4"],function(a){return a("tinymce.util.Tools")}),g("0",["1","2","3"],function(a,b,c){return a.add("preview",function(a){var d=a.settings,e=!b.ie;a.addCommand("mcePreview",function(){a.windowManager.open({title:"Preview",width:parseInt(a.getParam("plugin_preview_width","650"),10),height:parseInt(a.getParam("plugin_preview_height","500"),10),html:'<iframe src="javascript:\'\'" frameborder="0"'+(e?' sandbox="allow-scripts"':"")+"></iframe>",buttons:{text:"Close",onclick:function(){this.parent().parent().close()}},onPostRender:function(){var b,f="";f+='<base href="'+a.documentBaseURI.getURI()+'">',c.each(a.contentCSS,function(b){f+='<link type="text/css" rel="stylesheet" href="'+a.documentBaseURI.toAbsolute(b)+'">'});var g=d.body_id||"tinymce";g.indexOf("=")!=-1&&(g=a.getParam("body_id","","hash"),g=g[a.id]||g);var h=d.body_class||"";h.indexOf("=")!=-1&&(h=a.getParam("body_class","","hash"),h=h[a.id]||"");var i='<script>document.addEventListener && document.addEventListener("click", function(e) {for (var elm = e.target; elm; elm = elm.parentNode) {if (elm.nodeName === "A") {e.preventDefault();}}}, false);</script> ',j=a.settings.directionality?' dir="'+a.settings.directionality+'"':"";if(b="<!DOCTYPE html><html><head>"+f+'</head><body id="'+g+'" class="mce-content-body '+h+'"'+j+">"+a.getContent()+i+"</body></html>",e)this.getEl("body").firstChild.src="data:text/html;charset=utf-8,"+encodeURIComponent(b);else{var k=this.getEl("body").firstChild.contentWindow.document;k.open(),k.write(b),k.close()}}})}),a.addButton("preview",{title:"Preview",cmd:"mcePreview"}),a.addMenuItem("preview",{text:"Preview",cmd:"mcePreview",context:"view"})}),function(){}}),d("0")()}();
|
||||
!function(){var a={},b=function(b){for(var c=a[b],e=c.deps,f=c.defn,g=e.length,h=new Array(g),i=0;i<g;++i)h[i]=d(e[i]);var j=f.apply(null,h);if(void 0===j)throw"module ["+b+"] returned undefined";c.instance=j},c=function(b,c,d){if("string"!=typeof b)throw"module id must be a string";if(void 0===c)throw"no dependencies for "+b;if(void 0===d)throw"no definition function for "+b;a[b]={deps:c,defn:d,instance:void 0}},d=function(c){var d=a[c];if(void 0===d)throw"module ["+c+"] was undefined";return void 0===d.instance&&b(c),d.instance},e=function(a,b){for(var c=a.length,e=new Array(c),f=0;f<c;++f)e.push(d(a[f]));b.apply(null,b)},f={};f.bolt={module:{api:{define:c,require:e,demand:d}}};var g=c,h=function(a,b){g(a,[],function(){return b})};h("4",tinymce.util.Tools.resolve),g("1",["4"],function(a){return a("tinymce.PluginManager")}),g("2",["4"],function(a){return a("tinymce.Env")}),g("3",["4"],function(a){return a("tinymce.util.Tools")}),g("0",["1","2","3"],function(a,b,c){return a.add("preview",function(a){var d=a.settings,e=!b.ie;a.addCommand("mcePreview",function(){a.windowManager.open({title:"Preview",width:parseInt(a.getParam("plugin_preview_width","650"),10),height:parseInt(a.getParam("plugin_preview_height","500"),10),html:'<iframe src="javascript:\'\'" frameborder="0"'+(e?' sandbox="allow-scripts"':"")+"></iframe>",buttons:{text:"Close",onclick:function(){this.parent().parent().close()}},onPostRender:function(){var b,f="",g=a.dom.encode;f+='<base href="'+g(a.documentBaseURI.getURI())+'">',c.each(a.contentCSS,function(b){f+='<link type="text/css" rel="stylesheet" href="'+g(a.documentBaseURI.toAbsolute(b))+'">'});var h=d.body_id||"tinymce";h.indexOf("=")!=-1&&(h=a.getParam("body_id","","hash"),h=h[a.id]||h);var i=d.body_class||"";i.indexOf("=")!=-1&&(i=a.getParam("body_class","","hash"),i=i[a.id]||"");var j='<script>document.addEventListener && document.addEventListener("click", function(e) {for (var elm = e.target; elm; elm = elm.parentNode) {if (elm.nodeName === "A") {e.preventDefault();}}}, false);</script> ',k=a.settings.directionality?' dir="'+a.settings.directionality+'"':"";if(b="<!DOCTYPE html><html><head>"+f+'</head><body id="'+g(h)+'" class="mce-content-body '+g(i)+'"'+g(k)+">"+a.getContent()+j+"</body></html>",e)this.getEl("body").firstChild.src="data:text/html;charset=utf-8,"+encodeURIComponent(b);else{var l=this.getEl("body").firstChild.contentWindow.document;l.open(),l.write(b),l.close()}}})}),a.addButton("preview",{title:"Preview",cmd:"mcePreview"}),a.addMenuItem("preview",{text:"Preview",cmd:"mcePreview",context:"view"})}),function(){}}),d("0")()}();
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333}.mce-resize-bar-dragging{background-color:blue;opacity:.25;filter:alpha(opacity=25);zoom:1}.mce-content-body p,.mce-content-body div,.mce-content-body h1,.mce-content-body h2,.mce-content-body h3,.mce-content-body h4,.mce-content-body h5,.mce-content-body h6{line-height:1.2em}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2d8ac7}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #7ACAFF}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2d8ac7}.mce-content-body a[data-mce-selected],.mce-content-body code[data-mce-selected]{background:#bfe6ff}.mce-content-body hr{cursor:default}
|
||||
.word-wrap{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333}.mce-resize-bar-dragging{background-color:blue;opacity:.25;filter:alpha(opacity=25);zoom:1}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2d8ac7}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #7ACAFF}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2d8ac7}.mce-content-body a[data-mce-selected],.mce-content-body code[data-mce-selected],.mce-content-body b[data-mce-selected],.mce-content-body i[data-mce-selected],.mce-content-body em[data-mce-selected],.mce-content-body strong[data-mce-selected],.mce-content-body sup[data-mce-selected],.mce-content-body sub[data-mce-selected]{background:#bfe6ff}.mce-content-body hr{cursor:default}.mce-content-body{line-height:1.3}
|
||||
@@ -1 +1 @@
|
||||
body{background-color:#FFFFFF;color:#000000;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px;scrollbar-3dlight-color:#F0F0EE;scrollbar-arrow-color:#676662;scrollbar-base-color:#F0F0EE;scrollbar-darkshadow-color:#DDDDDD;scrollbar-face-color:#E0E0DD;scrollbar-highlight-color:#F0F0EE;scrollbar-shadow-color:#F0F0EE;scrollbar-track-color:#F5F5F5}td,th{font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333}.mce-resize-bar-dragging{background-color:blue;opacity:.25;filter:alpha(opacity=25);zoom:1}.mce-content-body p,.mce-content-body div,.mce-content-body h1,.mce-content-body h2,.mce-content-body h3,.mce-content-body h4,.mce-content-body h5,.mce-content-body h6{line-height:1.2em}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2d8ac7}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #7ACAFF}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2d8ac7}.mce-content-body a[data-mce-selected],.mce-content-body code[data-mce-selected]{background:#bfe6ff}.mce-content-body hr{cursor:default}
|
||||
body{background-color:#FFFFFF;color:#000000;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px;line-height:1.3;scrollbar-3dlight-color:#F0F0EE;scrollbar-arrow-color:#676662;scrollbar-base-color:#F0F0EE;scrollbar-darkshadow-color:#DDDDDD;scrollbar-face-color:#E0E0DD;scrollbar-highlight-color:#F0F0EE;scrollbar-shadow-color:#F0F0EE;scrollbar-track-color:#F5F5F5}td,th{font-family:Verdana,Arial,Helvetica,sans-serif;font-size:14px}.word-wrap{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.mce-content-body .mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:black;font-family:Arial;font-size:11px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;line-height:normal;font-weight:normal;text-align:left;-webkit-tap-highlight-color:transparent;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-object{border:1px dotted #3A3A3A;background:#D5D5D5 url(img/object.gif) no-repeat center}.mce-preview-object{display:inline-block;position:relative;margin:0 2px 0 2px;line-height:0;border:1px solid gray}.mce-preview-object[data-mce-selected="2"] .mce-shim{display:none}.mce-preview-object .mce-shim{position:absolute;top:0;left:0;width:100%;height:100%;background:url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)}figure.align-left{float:left}figure.align-right{float:right}figure.image.align-center{display:table;margin-left:auto;margin-right:auto}figure.image{display:inline-block;border:1px solid gray;margin:0 2px 0 1px;background:#f5f2f0}figure.image img{margin:8px 8px 0 8px}figure.image figcaption{margin:6px 8px 6px 8px;text-align:center}.mce-toc{border:1px solid gray}.mce-toc h2{margin:4px}.mce-toc li{list-style-type:none}.mce-pagebreak{cursor:default;display:block;border:0;width:100%;height:5px;border:1px dashed #666;margin-top:15px;page-break-before:always}@media print{.mce-pagebreak{border:0}}.mce-item-anchor{cursor:default;display:inline-block;-webkit-user-select:all;-webkit-user-modify:read-only;-moz-user-select:all;-moz-user-modify:read-only;user-select:all;user-modify:read-only;width:9px !important;height:9px !important;border:1px dotted #3A3A3A;background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-nbsp,.mce-shy{background:#AAA}.mce-shy::after{content:'-'}.mce-match-marker{background:#AAA;color:#fff}.mce-match-marker-selected{background:#3399ff;color:#fff}.mce-spellchecker-word{border-bottom:2px solid #F00;cursor:default}.mce-spellchecker-grammar{border-bottom:2px solid #008000;cursor:default}.mce-item-table,.mce-item-table td,.mce-item-table th,.mce-item-table caption{border:1px dashed #BBB}td[data-mce-selected],th[data-mce-selected]{background-color:#3399ff !important}.mce-edit-focus{outline:1px dotted #333}.mce-resize-bar-dragging{background-color:blue;opacity:.25;filter:alpha(opacity=25);zoom:1}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2d8ac7}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #7ACAFF}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2d8ac7}.mce-content-body a[data-mce-selected],.mce-content-body code[data-mce-selected],.mce-content-body b[data-mce-selected],.mce-content-body i[data-mce-selected],.mce-content-body em[data-mce-selected],.mce-content-body strong[data-mce-selected],.mce-content-body sup[data-mce-selected],.mce-content-body sub[data-mce-selected]{background:#bfe6ff}.mce-content-body hr{cursor:default}
|
||||
File diff suppressed because one or more lines are too long
32
public/libs/tinymce/tinymce.min.js
vendored
32
public/libs/tinymce/tinymce.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -76,7 +76,6 @@ The BookStack source is provided under the MIT License.
|
||||
These are the great open-source projects used to help build BookStack:
|
||||
|
||||
* [Laravel](http://laravel.com/)
|
||||
* [AngularJS](https://angularjs.org/)
|
||||
* [jQuery](https://jquery.com/)
|
||||
* [TinyMCE](https://www.tinymce.com/)
|
||||
* [CodeMirror](https://codemirror.net)
|
||||
|
||||
1
resources/assets/icons/azure.svg
Normal file
1
resources/assets/icons/azure.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 129 129"><path fill="#f25022" d="M0 0h61.3v61.3H0z"/><path fill="#7fba00" d="M67.7 0H129v61.3H67.7z"/><path fill="#00a4ef" d="M0 67.7h61.3V129H0z"/><path fill="#ffb900" d="M67.7 67.7H129V129H67.7z"/></svg>
|
||||
|
After Width: | Height: | Size: 258 B |
47
resources/assets/js/components/editor-toolbox.js
Normal file
47
resources/assets/js/components/editor-toolbox.js
Normal file
@@ -0,0 +1,47 @@
|
||||
class EditorToolbox {
|
||||
|
||||
constructor(elem) {
|
||||
// Elements
|
||||
this.elem = elem;
|
||||
this.buttons = elem.querySelectorAll('[toolbox-tab-button]');
|
||||
this.contentElements = elem.querySelectorAll('[toolbox-tab-content]');
|
||||
this.toggleButton = elem.querySelector('[toolbox-toggle]');
|
||||
|
||||
// Toolbox toggle button click
|
||||
this.toggleButton.addEventListener('click', this.toggle.bind(this));
|
||||
// Tab button click
|
||||
this.elem.addEventListener('click', event => {
|
||||
let button = event.target.closest('[toolbox-tab-button]');
|
||||
if (button === null) return;
|
||||
let name = button.getAttribute('toolbox-tab-button');
|
||||
this.setActiveTab(name, true);
|
||||
});
|
||||
|
||||
// Set the first tab as active on load
|
||||
this.setActiveTab(this.contentElements[0].getAttribute('toolbox-tab-content'));
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.elem.classList.toggle('open');
|
||||
}
|
||||
|
||||
setActiveTab(tabName, openToolbox = false) {
|
||||
// Set button visibility
|
||||
for (let i = 0, len = this.buttons.length; i < len; i++) {
|
||||
this.buttons[i].classList.remove('active');
|
||||
let bName = this.buttons[i].getAttribute('toolbox-tab-button');
|
||||
if (bName === tabName) this.buttons[i].classList.add('active');
|
||||
}
|
||||
// Set content visibility
|
||||
for (let i = 0, len = this.contentElements.length; i < len; i++) {
|
||||
this.contentElements[i].style.display = 'none';
|
||||
let cName = this.contentElements[i].getAttribute('toolbox-tab-content');
|
||||
if (cName === tabName) this.contentElements[i].style.display = 'block';
|
||||
}
|
||||
|
||||
if (openToolbox) this.elem.classList.add('open');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = EditorToolbox;
|
||||
@@ -11,6 +11,9 @@ let componentMapping = {
|
||||
'sidebar': require('./sidebar'),
|
||||
'page-picker': require('./page-picker'),
|
||||
'page-comments': require('./page-comments'),
|
||||
'wysiwyg-editor': require('./wysiwyg-editor'),
|
||||
'markdown-editor': require('./markdown-editor'),
|
||||
'editor-toolbox': require('./editor-toolbox'),
|
||||
};
|
||||
|
||||
window.components = {};
|
||||
|
||||
293
resources/assets/js/components/markdown-editor.js
Normal file
293
resources/assets/js/components/markdown-editor.js
Normal file
@@ -0,0 +1,293 @@
|
||||
const MarkdownIt = require("markdown-it");
|
||||
const mdTasksLists = require('markdown-it-task-lists');
|
||||
const code = require('../code');
|
||||
|
||||
class MarkdownEditor {
|
||||
|
||||
constructor(elem) {
|
||||
this.elem = elem;
|
||||
this.markdown = new MarkdownIt({html: true});
|
||||
this.markdown.use(mdTasksLists, {label: true});
|
||||
|
||||
this.display = this.elem.querySelector('.markdown-display');
|
||||
this.input = this.elem.querySelector('textarea');
|
||||
this.htmlInput = this.elem.querySelector('input[name=html]');
|
||||
this.cm = code.markdownEditor(this.input);
|
||||
|
||||
this.onMarkdownScroll = this.onMarkdownScroll.bind(this);
|
||||
this.init();
|
||||
}
|
||||
|
||||
init() {
|
||||
|
||||
// Prevent markdown display link click redirect
|
||||
this.display.addEventListener('click', event => {
|
||||
let link = event.target.closest('a');
|
||||
if (link === null) return;
|
||||
|
||||
event.preventDefault();
|
||||
window.open(link.getAttribute('href'));
|
||||
});
|
||||
|
||||
// Button actions
|
||||
this.elem.addEventListener('click', event => {
|
||||
let button = event.target.closest('button[data-action]');
|
||||
if (button === null) return;
|
||||
|
||||
let action = button.getAttribute('data-action');
|
||||
if (action === 'insertImage') this.actionInsertImage();
|
||||
if (action === 'insertLink') this.actionShowLinkSelector();
|
||||
});
|
||||
|
||||
window.$events.listen('editor-markdown-update', value => {
|
||||
this.cm.setValue(value);
|
||||
this.updateAndRender();
|
||||
});
|
||||
|
||||
this.codeMirrorSetup();
|
||||
}
|
||||
|
||||
// Update the input content and render the display.
|
||||
updateAndRender() {
|
||||
let content = this.cm.getValue();
|
||||
this.input.value = content;
|
||||
let html = this.markdown.render(content);
|
||||
window.$events.emit('editor-html-change', html);
|
||||
window.$events.emit('editor-markdown-change', content);
|
||||
this.display.innerHTML = html;
|
||||
this.htmlInput.value = html;
|
||||
}
|
||||
|
||||
onMarkdownScroll(lineCount) {
|
||||
let elems = this.display.children;
|
||||
if (elems.length <= lineCount) return;
|
||||
|
||||
let topElem = (lineCount === -1) ? elems[elems.length-1] : elems[lineCount];
|
||||
// TODO - Replace jQuery
|
||||
$(this.display).animate({
|
||||
scrollTop: topElem.offsetTop
|
||||
}, {queue: false, duration: 200, easing: 'linear'});
|
||||
}
|
||||
|
||||
codeMirrorSetup() {
|
||||
let cm = this.cm;
|
||||
// Custom key commands
|
||||
let metaKey = code.getMetaKey();
|
||||
const extraKeys = {};
|
||||
// Insert Image shortcut
|
||||
extraKeys[`${metaKey}-Alt-I`] = function(cm) {
|
||||
let selectedText = cm.getSelection();
|
||||
let newText = ``;
|
||||
let cursorPos = cm.getCursor('from');
|
||||
cm.replaceSelection(newText);
|
||||
cm.setCursor(cursorPos.line, cursorPos.ch + newText.length -1);
|
||||
};
|
||||
// Save draft
|
||||
extraKeys[`${metaKey}-S`] = cm => {window.$events.emit('editor-save-draft')};
|
||||
// Show link selector
|
||||
extraKeys[`Shift-${metaKey}-K`] = cm => {this.actionShowLinkSelector()};
|
||||
// Insert Link
|
||||
extraKeys[`${metaKey}-K`] = cm => {insertLink()};
|
||||
// FormatShortcuts
|
||||
extraKeys[`${metaKey}-1`] = cm => {replaceLineStart('##');};
|
||||
extraKeys[`${metaKey}-2`] = cm => {replaceLineStart('###');};
|
||||
extraKeys[`${metaKey}-3`] = cm => {replaceLineStart('####');};
|
||||
extraKeys[`${metaKey}-4`] = cm => {replaceLineStart('#####');};
|
||||
extraKeys[`${metaKey}-5`] = cm => {replaceLineStart('');};
|
||||
extraKeys[`${metaKey}-d`] = cm => {replaceLineStart('');};
|
||||
extraKeys[`${metaKey}-6`] = cm => {replaceLineStart('>');};
|
||||
extraKeys[`${metaKey}-q`] = cm => {replaceLineStart('>');};
|
||||
extraKeys[`${metaKey}-7`] = cm => {wrapSelection('\n```\n', '\n```');};
|
||||
extraKeys[`${metaKey}-8`] = cm => {wrapSelection('`', '`');};
|
||||
extraKeys[`Shift-${metaKey}-E`] = cm => {wrapSelection('`', '`');};
|
||||
extraKeys[`${metaKey}-9`] = cm => {wrapSelection('<p class="callout info">', '</p>');};
|
||||
cm.setOption('extraKeys', extraKeys);
|
||||
|
||||
// Update data on content change
|
||||
cm.on('change', (instance, changeObj) => {
|
||||
this.updateAndRender();
|
||||
});
|
||||
|
||||
// Handle scroll to sync display view
|
||||
cm.on('scroll', instance => {
|
||||
// Thanks to http://liuhao.im/english/2015/11/10/the-sync-scroll-of-markdown-editor-in-javascript.html
|
||||
let scroll = instance.getScrollInfo();
|
||||
let atEnd = scroll.top + scroll.clientHeight === scroll.height;
|
||||
if (atEnd) {
|
||||
this.onMarkdownScroll(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
let lineNum = instance.lineAtHeight(scroll.top, 'local');
|
||||
let range = instance.getRange({line: 0, ch: null}, {line: lineNum, ch: null});
|
||||
let parser = new DOMParser();
|
||||
let doc = parser.parseFromString(this.markdown.render(range), 'text/html');
|
||||
let totalLines = doc.documentElement.querySelectorAll('body > *');
|
||||
this.onMarkdownScroll(totalLines.length);
|
||||
});
|
||||
|
||||
// Handle image paste
|
||||
cm.on('paste', (cm, event) => {
|
||||
if (!event.clipboardData || !event.clipboardData.items) return;
|
||||
for (let i = 0; i < event.clipboardData.items.length; i++) {
|
||||
uploadImage(event.clipboardData.items[i].getAsFile());
|
||||
}
|
||||
});
|
||||
|
||||
// Handle images on drag-drop
|
||||
cm.on('drop', (cm, event) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
let cursorPos = cm.coordsChar({left: event.pageX, top: event.pageY});
|
||||
cm.setCursor(cursorPos);
|
||||
if (!event.dataTransfer || !event.dataTransfer.files) return;
|
||||
for (let i = 0; i < event.dataTransfer.files.length; i++) {
|
||||
uploadImage(event.dataTransfer.files[i]);
|
||||
}
|
||||
});
|
||||
|
||||
// Helper to replace editor content
|
||||
function replaceContent(search, replace) {
|
||||
let text = cm.getValue();
|
||||
let cursor = cm.listSelections();
|
||||
cm.setValue(text.replace(search, replace));
|
||||
cm.setSelections(cursor);
|
||||
}
|
||||
|
||||
// Helper to replace the start of the line
|
||||
function replaceLineStart(newStart) {
|
||||
let cursor = cm.getCursor();
|
||||
let lineContent = cm.getLine(cursor.line);
|
||||
let lineLen = lineContent.length;
|
||||
let lineStart = lineContent.split(' ')[0];
|
||||
|
||||
// Remove symbol if already set
|
||||
if (lineStart === newStart) {
|
||||
lineContent = lineContent.replace(`${newStart} `, '');
|
||||
cm.replaceRange(lineContent, {line: cursor.line, ch: 0}, {line: cursor.line, ch: lineLen});
|
||||
cm.setCursor({line: cursor.line, ch: cursor.ch - (newStart.length + 1)});
|
||||
return;
|
||||
}
|
||||
|
||||
let alreadySymbol = /^[#>`]/.test(lineStart);
|
||||
let posDif = 0;
|
||||
if (alreadySymbol) {
|
||||
posDif = newStart.length - lineStart.length;
|
||||
lineContent = lineContent.replace(lineStart, newStart).trim();
|
||||
} else if (newStart !== '') {
|
||||
posDif = newStart.length + 1;
|
||||
lineContent = newStart + ' ' + lineContent;
|
||||
}
|
||||
cm.replaceRange(lineContent, {line: cursor.line, ch: 0}, {line: cursor.line, ch: lineLen});
|
||||
cm.setCursor({line: cursor.line, ch: cursor.ch + posDif});
|
||||
}
|
||||
|
||||
function wrapLine(start, end) {
|
||||
let cursor = cm.getCursor();
|
||||
let lineContent = cm.getLine(cursor.line);
|
||||
let lineLen = lineContent.length;
|
||||
let newLineContent = lineContent;
|
||||
|
||||
if (lineContent.indexOf(start) === 0 && lineContent.slice(-end.length) === end) {
|
||||
newLineContent = lineContent.slice(start.length, lineContent.length - end.length);
|
||||
} else {
|
||||
newLineContent = `${start}${lineContent}${end}`;
|
||||
}
|
||||
|
||||
cm.replaceRange(newLineContent, {line: cursor.line, ch: 0}, {line: cursor.line, ch: lineLen});
|
||||
cm.setCursor({line: cursor.line, ch: cursor.ch + start.length});
|
||||
}
|
||||
|
||||
function wrapSelection(start, end) {
|
||||
let selection = cm.getSelection();
|
||||
if (selection === '') return wrapLine(start, end);
|
||||
|
||||
let newSelection = selection;
|
||||
let frontDiff = 0;
|
||||
let endDiff = 0;
|
||||
|
||||
if (selection.indexOf(start) === 0 && selection.slice(-end.length) === end) {
|
||||
newSelection = selection.slice(start.length, selection.length - end.length);
|
||||
endDiff = -(end.length + start.length);
|
||||
} else {
|
||||
newSelection = `${start}${selection}${end}`;
|
||||
endDiff = start.length + end.length;
|
||||
}
|
||||
|
||||
let selections = cm.listSelections()[0];
|
||||
cm.replaceSelection(newSelection);
|
||||
let headFirst = selections.head.ch <= selections.anchor.ch;
|
||||
selections.head.ch += headFirst ? frontDiff : endDiff;
|
||||
selections.anchor.ch += headFirst ? endDiff : frontDiff;
|
||||
cm.setSelections([selections]);
|
||||
}
|
||||
|
||||
// Handle image upload and add image into markdown content
|
||||
function uploadImage(file) {
|
||||
if (file === null || file.type.indexOf('image') !== 0) return;
|
||||
let ext = 'png';
|
||||
|
||||
if (file.name) {
|
||||
let fileNameMatches = file.name.match(/\.(.+)$/);
|
||||
if (fileNameMatches.length > 1) ext = fileNameMatches[1];
|
||||
}
|
||||
|
||||
// Insert image into markdown
|
||||
let id = "image-" + Math.random().toString(16).slice(2);
|
||||
let placeholderImage = window.baseUrl(`/loading.gif#upload${id}`);
|
||||
let selectedText = cm.getSelection();
|
||||
let placeHolderText = ``;
|
||||
cm.replaceSelection(placeHolderText);
|
||||
|
||||
let remoteFilename = "image-" + Date.now() + "." + ext;
|
||||
let formData = new FormData();
|
||||
formData.append('file', file, remoteFilename);
|
||||
|
||||
window.$http.post('/images/gallery/upload', formData).then(resp => {
|
||||
replaceContent(placeholderImage, resp.data.thumbs.display);
|
||||
}).catch(err => {
|
||||
events.emit('error', trans('errors.image_upload_error'));
|
||||
replaceContent(placeHolderText, selectedText);
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
function insertLink() {
|
||||
let cursorPos = cm.getCursor('from');
|
||||
let selectedText = cm.getSelection() || '';
|
||||
let newText = `[${selectedText}]()`;
|
||||
cm.focus();
|
||||
cm.replaceSelection(newText);
|
||||
let cursorPosDiff = (selectedText === '') ? -3 : -1;
|
||||
cm.setCursor(cursorPos.line, cursorPos.ch + newText.length+cursorPosDiff);
|
||||
}
|
||||
|
||||
this.updateAndRender();
|
||||
}
|
||||
|
||||
actionInsertImage() {
|
||||
let cursorPos = this.cm.getCursor('from');
|
||||
window.ImageManager.show(image => {
|
||||
let selectedText = this.cm.getSelection();
|
||||
let newText = "";
|
||||
this.cm.focus();
|
||||
this.cm.replaceSelection(newText);
|
||||
this.cm.setCursor(cursorPos.line, cursorPos.ch + newText.length);
|
||||
});
|
||||
}
|
||||
|
||||
// Show the popup link selector and insert a link when finished
|
||||
actionShowLinkSelector() {
|
||||
let cursorPos = this.cm.getCursor('from');
|
||||
window.EntitySelectorPopup.show(entity => {
|
||||
let selectedText = this.cm.getSelection() || entity.name;
|
||||
let newText = `[${selectedText}](${entity.link})`;
|
||||
this.cm.focus();
|
||||
this.cm.replaceSelection(newText);
|
||||
this.cm.setCursor(cursorPos.line, cursorPos.ch + newText.length);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = MarkdownEditor ;
|
||||
11
resources/assets/js/components/wysiwyg-editor.js
Normal file
11
resources/assets/js/components/wysiwyg-editor.js
Normal file
@@ -0,0 +1,11 @@
|
||||
class WysiwygEditor {
|
||||
|
||||
constructor(elem) {
|
||||
this.elem = elem;
|
||||
this.options = require("../pages/page-form");
|
||||
tinymce.init(this.options);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = WysiwygEditor;
|
||||
@@ -1,147 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const moment = require('moment');
|
||||
require('moment/locale/en-gb');
|
||||
const editorOptions = require("./pages/page-form");
|
||||
|
||||
moment.locale('en-gb');
|
||||
|
||||
module.exports = function (ngApp, events) {
|
||||
|
||||
|
||||
ngApp.controller('PageEditController', ['$scope', '$http', '$attrs', '$interval', '$timeout', '$sce',
|
||||
function ($scope, $http, $attrs, $interval, $timeout, $sce) {
|
||||
|
||||
$scope.editorOptions = editorOptions();
|
||||
$scope.editContent = '';
|
||||
$scope.draftText = '';
|
||||
let pageId = Number($attrs.pageId);
|
||||
let isEdit = pageId !== 0;
|
||||
let autosaveFrequency = 30; // AutoSave interval in seconds.
|
||||
let isMarkdown = $attrs.editorType === 'markdown';
|
||||
$scope.draftsEnabled = $attrs.draftsEnabled === 'true';
|
||||
$scope.isUpdateDraft = Number($attrs.pageUpdateDraft) === 1;
|
||||
$scope.isNewPageDraft = Number($attrs.pageNewDraft) === 1;
|
||||
|
||||
// Set initial header draft text
|
||||
if ($scope.isUpdateDraft || $scope.isNewPageDraft) {
|
||||
$scope.draftText = trans('entities.pages_editing_draft');
|
||||
} else {
|
||||
$scope.draftText = trans('entities.pages_editing_page');
|
||||
}
|
||||
|
||||
let autoSave = false;
|
||||
|
||||
let currentContent = {
|
||||
title: false,
|
||||
html: false
|
||||
};
|
||||
|
||||
if (isEdit && $scope.draftsEnabled) {
|
||||
setTimeout(() => {
|
||||
startAutoSave();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
// Actions specifically for the markdown editor
|
||||
if (isMarkdown) {
|
||||
$scope.displayContent = '';
|
||||
// Editor change event
|
||||
$scope.editorChange = function (content) {
|
||||
$scope.displayContent = $sce.trustAsHtml(content);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isMarkdown) {
|
||||
$scope.editorChange = function() {};
|
||||
}
|
||||
|
||||
let lastSave = 0;
|
||||
|
||||
/**
|
||||
* Start the AutoSave loop, Checks for content change
|
||||
* before performing the costly AJAX request.
|
||||
*/
|
||||
function startAutoSave() {
|
||||
currentContent.title = $('#name').val();
|
||||
currentContent.html = $scope.editContent;
|
||||
|
||||
autoSave = $interval(() => {
|
||||
// Return if manually saved recently to prevent bombarding the server
|
||||
if (Date.now() - lastSave < (1000*autosaveFrequency)/2) return;
|
||||
let newTitle = $('#name').val();
|
||||
let newHtml = $scope.editContent;
|
||||
|
||||
if (newTitle !== currentContent.title || newHtml !== currentContent.html) {
|
||||
currentContent.html = newHtml;
|
||||
currentContent.title = newTitle;
|
||||
saveDraft();
|
||||
}
|
||||
|
||||
}, 1000 * autosaveFrequency);
|
||||
}
|
||||
|
||||
let draftErroring = false;
|
||||
/**
|
||||
* Save a draft update into the system via an AJAX request.
|
||||
*/
|
||||
function saveDraft() {
|
||||
if (!$scope.draftsEnabled) return;
|
||||
let data = {
|
||||
name: $('#name').val(),
|
||||
html: isMarkdown ? $sce.getTrustedHtml($scope.displayContent) : $scope.editContent
|
||||
};
|
||||
|
||||
if (isMarkdown) data.markdown = $scope.editContent;
|
||||
|
||||
let url = window.baseUrl('/ajax/page/' + pageId + '/save-draft');
|
||||
$http.put(url, data).then(responseData => {
|
||||
draftErroring = false;
|
||||
let updateTime = moment.utc(moment.unix(responseData.data.timestamp)).toDate();
|
||||
$scope.draftText = responseData.data.message + moment(updateTime).format('HH:mm');
|
||||
if (!$scope.isNewPageDraft) $scope.isUpdateDraft = true;
|
||||
showDraftSaveNotification();
|
||||
lastSave = Date.now();
|
||||
}, errorRes => {
|
||||
if (draftErroring) return;
|
||||
events.emit('error', trans('errors.page_draft_autosave_fail'));
|
||||
draftErroring = true;
|
||||
});
|
||||
}
|
||||
|
||||
function showDraftSaveNotification() {
|
||||
$scope.draftUpdated = true;
|
||||
$timeout(() => {
|
||||
$scope.draftUpdated = false;
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
$scope.forceDraftSave = function() {
|
||||
saveDraft();
|
||||
};
|
||||
|
||||
// Listen to save draft events from editor
|
||||
$scope.$on('save-draft', saveDraft);
|
||||
|
||||
/**
|
||||
* Discard the current draft and grab the current page
|
||||
* content from the system via an AJAX request.
|
||||
*/
|
||||
$scope.discardDraft = function () {
|
||||
let url = window.baseUrl('/ajax/page/' + pageId);
|
||||
$http.get(url).then(responseData => {
|
||||
if (autoSave) $interval.cancel(autoSave);
|
||||
$scope.draftText = trans('entities.pages_editing_page');
|
||||
$scope.isUpdateDraft = false;
|
||||
$scope.$broadcast('html-update', responseData.data.html);
|
||||
$scope.$broadcast('markdown-update', responseData.data.markdown || responseData.data.html);
|
||||
$('#name').val(responseData.data.name);
|
||||
$timeout(() => {
|
||||
startAutoSave();
|
||||
}, 1000);
|
||||
events.emit('success', trans('entities.pages_draft_discarded'));
|
||||
});
|
||||
};
|
||||
|
||||
}]);
|
||||
};
|
||||
@@ -1,393 +0,0 @@
|
||||
"use strict";
|
||||
const MarkdownIt = require("markdown-it");
|
||||
const mdTasksLists = require('markdown-it-task-lists');
|
||||
const code = require('./code');
|
||||
|
||||
module.exports = function (ngApp, events) {
|
||||
|
||||
/**
|
||||
* TinyMCE
|
||||
* An angular wrapper around the tinyMCE editor.
|
||||
*/
|
||||
ngApp.directive('tinymce', ['$timeout', function ($timeout) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
tinymce: '=',
|
||||
mceModel: '=',
|
||||
mceChange: '='
|
||||
},
|
||||
link: function (scope, element, attrs) {
|
||||
|
||||
function tinyMceSetup(editor) {
|
||||
editor.on('ExecCommand change input NodeChange ObjectResized', (e) => {
|
||||
let content = editor.getContent();
|
||||
$timeout(() => {
|
||||
scope.mceModel = content;
|
||||
});
|
||||
scope.mceChange(content);
|
||||
});
|
||||
|
||||
editor.on('keydown', (event) => {
|
||||
if (event.keyCode === 83 && (navigator.platform.match("Mac") ? event.metaKey : event.ctrlKey)) {
|
||||
event.preventDefault();
|
||||
scope.$emit('save-draft', event);
|
||||
}
|
||||
});
|
||||
|
||||
editor.on('init', (e) => {
|
||||
scope.mceModel = editor.getContent();
|
||||
});
|
||||
|
||||
scope.$on('html-update', (event, value) => {
|
||||
editor.setContent(value);
|
||||
editor.selection.select(editor.getBody(), true);
|
||||
editor.selection.collapse(false);
|
||||
scope.mceModel = editor.getContent();
|
||||
});
|
||||
}
|
||||
|
||||
scope.tinymce.extraSetups.push(tinyMceSetup);
|
||||
tinymce.init(scope.tinymce);
|
||||
}
|
||||
}
|
||||
}]);
|
||||
|
||||
const md = new MarkdownIt({html: true});
|
||||
md.use(mdTasksLists, {label: true});
|
||||
|
||||
/**
|
||||
* Markdown input
|
||||
* Handles the logic for just the editor input field.
|
||||
*/
|
||||
ngApp.directive('markdownInput', ['$timeout', function ($timeout) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
scope: {
|
||||
mdModel: '=',
|
||||
mdChange: '='
|
||||
},
|
||||
link: function (scope, element, attrs) {
|
||||
|
||||
// Codemirror Setup
|
||||
element = element.find('textarea').first();
|
||||
let cm = code.markdownEditor(element[0]);
|
||||
|
||||
// Custom key commands
|
||||
let metaKey = code.getMetaKey();
|
||||
const extraKeys = {};
|
||||
// Insert Image shortcut
|
||||
extraKeys[`${metaKey}-Alt-I`] = function(cm) {
|
||||
let selectedText = cm.getSelection();
|
||||
let newText = ``;
|
||||
let cursorPos = cm.getCursor('from');
|
||||
cm.replaceSelection(newText);
|
||||
cm.setCursor(cursorPos.line, cursorPos.ch + newText.length -1);
|
||||
};
|
||||
// Save draft
|
||||
extraKeys[`${metaKey}-S`] = function(cm) {scope.$emit('save-draft');};
|
||||
// Show link selector
|
||||
extraKeys[`Shift-${metaKey}-K`] = function(cm) {showLinkSelector()};
|
||||
// Insert Link
|
||||
extraKeys[`${metaKey}-K`] = function(cm) {insertLink()};
|
||||
// FormatShortcuts
|
||||
extraKeys[`${metaKey}-1`] = function(cm) {replaceLineStart('##');};
|
||||
extraKeys[`${metaKey}-2`] = function(cm) {replaceLineStart('###');};
|
||||
extraKeys[`${metaKey}-3`] = function(cm) {replaceLineStart('####');};
|
||||
extraKeys[`${metaKey}-4`] = function(cm) {replaceLineStart('#####');};
|
||||
extraKeys[`${metaKey}-5`] = function(cm) {replaceLineStart('');};
|
||||
extraKeys[`${metaKey}-d`] = function(cm) {replaceLineStart('');};
|
||||
extraKeys[`${metaKey}-6`] = function(cm) {replaceLineStart('>');};
|
||||
extraKeys[`${metaKey}-q`] = function(cm) {replaceLineStart('>');};
|
||||
extraKeys[`${metaKey}-7`] = function(cm) {wrapSelection('\n```\n', '\n```');};
|
||||
extraKeys[`${metaKey}-8`] = function(cm) {wrapSelection('`', '`');};
|
||||
extraKeys[`Shift-${metaKey}-E`] = function(cm) {wrapSelection('`', '`');};
|
||||
extraKeys[`${metaKey}-9`] = function(cm) {wrapSelection('<p class="callout info">', '</p>');};
|
||||
cm.setOption('extraKeys', extraKeys);
|
||||
|
||||
// Update data on content change
|
||||
cm.on('change', (instance, changeObj) => {
|
||||
update(instance);
|
||||
});
|
||||
|
||||
// Handle scroll to sync display view
|
||||
cm.on('scroll', instance => {
|
||||
// Thanks to http://liuhao.im/english/2015/11/10/the-sync-scroll-of-markdown-editor-in-javascript.html
|
||||
let scroll = instance.getScrollInfo();
|
||||
let atEnd = scroll.top + scroll.clientHeight === scroll.height;
|
||||
if (atEnd) {
|
||||
scope.$emit('markdown-scroll', -1);
|
||||
return;
|
||||
}
|
||||
let lineNum = instance.lineAtHeight(scroll.top, 'local');
|
||||
let range = instance.getRange({line: 0, ch: null}, {line: lineNum, ch: null});
|
||||
let parser = new DOMParser();
|
||||
let doc = parser.parseFromString(md.render(range), 'text/html');
|
||||
let totalLines = doc.documentElement.querySelectorAll('body > *');
|
||||
scope.$emit('markdown-scroll', totalLines.length);
|
||||
});
|
||||
|
||||
// Handle image paste
|
||||
cm.on('paste', (cm, event) => {
|
||||
if (!event.clipboardData || !event.clipboardData.items) return;
|
||||
for (let i = 0; i < event.clipboardData.items.length; i++) {
|
||||
uploadImage(event.clipboardData.items[i].getAsFile());
|
||||
}
|
||||
});
|
||||
|
||||
// Handle images on drag-drop
|
||||
cm.on('drop', (cm, event) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
let cursorPos = cm.coordsChar({left: event.pageX, top: event.pageY});
|
||||
cm.setCursor(cursorPos);
|
||||
if (!event.dataTransfer || !event.dataTransfer.files) return;
|
||||
for (let i = 0; i < event.dataTransfer.files.length; i++) {
|
||||
uploadImage(event.dataTransfer.files[i]);
|
||||
}
|
||||
});
|
||||
|
||||
// Helper to replace editor content
|
||||
function replaceContent(search, replace) {
|
||||
let text = cm.getValue();
|
||||
let cursor = cm.listSelections();
|
||||
cm.setValue(text.replace(search, replace));
|
||||
cm.setSelections(cursor);
|
||||
}
|
||||
|
||||
// Helper to replace the start of the line
|
||||
function replaceLineStart(newStart) {
|
||||
let cursor = cm.getCursor();
|
||||
let lineContent = cm.getLine(cursor.line);
|
||||
let lineLen = lineContent.length;
|
||||
let lineStart = lineContent.split(' ')[0];
|
||||
|
||||
// Remove symbol if already set
|
||||
if (lineStart === newStart) {
|
||||
lineContent = lineContent.replace(`${newStart} `, '');
|
||||
cm.replaceRange(lineContent, {line: cursor.line, ch: 0}, {line: cursor.line, ch: lineLen});
|
||||
cm.setCursor({line: cursor.line, ch: cursor.ch - (newStart.length + 1)});
|
||||
return;
|
||||
}
|
||||
|
||||
let alreadySymbol = /^[#>`]/.test(lineStart);
|
||||
let posDif = 0;
|
||||
if (alreadySymbol) {
|
||||
posDif = newStart.length - lineStart.length;
|
||||
lineContent = lineContent.replace(lineStart, newStart).trim();
|
||||
} else if (newStart !== '') {
|
||||
posDif = newStart.length + 1;
|
||||
lineContent = newStart + ' ' + lineContent;
|
||||
}
|
||||
cm.replaceRange(lineContent, {line: cursor.line, ch: 0}, {line: cursor.line, ch: lineLen});
|
||||
cm.setCursor({line: cursor.line, ch: cursor.ch + posDif});
|
||||
}
|
||||
|
||||
function wrapLine(start, end) {
|
||||
let cursor = cm.getCursor();
|
||||
let lineContent = cm.getLine(cursor.line);
|
||||
let lineLen = lineContent.length;
|
||||
let newLineContent = lineContent;
|
||||
|
||||
if (lineContent.indexOf(start) === 0 && lineContent.slice(-end.length) === end) {
|
||||
newLineContent = lineContent.slice(start.length, lineContent.length - end.length);
|
||||
} else {
|
||||
newLineContent = `${start}${lineContent}${end}`;
|
||||
}
|
||||
|
||||
cm.replaceRange(newLineContent, {line: cursor.line, ch: 0}, {line: cursor.line, ch: lineLen});
|
||||
cm.setCursor({line: cursor.line, ch: cursor.ch + start.length});
|
||||
}
|
||||
|
||||
function wrapSelection(start, end) {
|
||||
let selection = cm.getSelection();
|
||||
if (selection === '') return wrapLine(start, end);
|
||||
|
||||
let newSelection = selection;
|
||||
let frontDiff = 0;
|
||||
let endDiff = 0;
|
||||
|
||||
if (selection.indexOf(start) === 0 && selection.slice(-end.length) === end) {
|
||||
newSelection = selection.slice(start.length, selection.length - end.length);
|
||||
endDiff = -(end.length + start.length);
|
||||
} else {
|
||||
newSelection = `${start}${selection}${end}`;
|
||||
endDiff = start.length + end.length;
|
||||
}
|
||||
|
||||
let selections = cm.listSelections()[0];
|
||||
cm.replaceSelection(newSelection);
|
||||
let headFirst = selections.head.ch <= selections.anchor.ch;
|
||||
selections.head.ch += headFirst ? frontDiff : endDiff;
|
||||
selections.anchor.ch += headFirst ? endDiff : frontDiff;
|
||||
cm.setSelections([selections]);
|
||||
}
|
||||
|
||||
// Handle image upload and add image into markdown content
|
||||
function uploadImage(file) {
|
||||
if (file === null || file.type.indexOf('image') !== 0) return;
|
||||
let ext = 'png';
|
||||
|
||||
if (file.name) {
|
||||
let fileNameMatches = file.name.match(/\.(.+)$/);
|
||||
if (fileNameMatches.length > 1) ext = fileNameMatches[1];
|
||||
}
|
||||
|
||||
// Insert image into markdown
|
||||
let id = "image-" + Math.random().toString(16).slice(2);
|
||||
let placeholderImage = window.baseUrl(`/loading.gif#upload${id}`);
|
||||
let selectedText = cm.getSelection();
|
||||
let placeHolderText = ``;
|
||||
cm.replaceSelection(placeHolderText);
|
||||
|
||||
let remoteFilename = "image-" + Date.now() + "." + ext;
|
||||
let formData = new FormData();
|
||||
formData.append('file', file, remoteFilename);
|
||||
|
||||
window.$http.post('/images/gallery/upload', formData).then(resp => {
|
||||
replaceContent(placeholderImage, resp.data.thumbs.display);
|
||||
}).catch(err => {
|
||||
events.emit('error', trans('errors.image_upload_error'));
|
||||
replaceContent(placeHolderText, selectedText);
|
||||
console.log(err);
|
||||
});
|
||||
}
|
||||
|
||||
// Show the popup link selector and insert a link when finished
|
||||
function showLinkSelector() {
|
||||
let cursorPos = cm.getCursor('from');
|
||||
window.EntitySelectorPopup.show(entity => {
|
||||
let selectedText = cm.getSelection() || entity.name;
|
||||
let newText = `[${selectedText}](${entity.link})`;
|
||||
cm.focus();
|
||||
cm.replaceSelection(newText);
|
||||
cm.setCursor(cursorPos.line, cursorPos.ch + newText.length);
|
||||
});
|
||||
}
|
||||
|
||||
function insertLink() {
|
||||
let cursorPos = cm.getCursor('from');
|
||||
let selectedText = cm.getSelection() || '';
|
||||
let newText = `[${selectedText}]()`;
|
||||
cm.focus();
|
||||
cm.replaceSelection(newText);
|
||||
let cursorPosDiff = (selectedText === '') ? -3 : -1;
|
||||
cm.setCursor(cursorPos.line, cursorPos.ch + newText.length+cursorPosDiff);
|
||||
}
|
||||
|
||||
// Show the image manager and handle image insertion
|
||||
function showImageManager() {
|
||||
let cursorPos = cm.getCursor('from');
|
||||
window.ImageManager.show(image => {
|
||||
let selectedText = cm.getSelection();
|
||||
let newText = "";
|
||||
cm.focus();
|
||||
cm.replaceSelection(newText);
|
||||
cm.setCursor(cursorPos.line, cursorPos.ch + newText.length);
|
||||
});
|
||||
}
|
||||
|
||||
// Update the data models and rendered output
|
||||
function update(instance) {
|
||||
let content = instance.getValue();
|
||||
element.val(content);
|
||||
$timeout(() => {
|
||||
scope.mdModel = content;
|
||||
scope.mdChange(md.render(content));
|
||||
});
|
||||
}
|
||||
update(cm);
|
||||
|
||||
// Listen to commands from parent scope
|
||||
scope.$on('md-insert-link', showLinkSelector);
|
||||
scope.$on('md-insert-image', showImageManager);
|
||||
scope.$on('markdown-update', (event, value) => {
|
||||
cm.setValue(value);
|
||||
element.val(value);
|
||||
scope.mdModel = value;
|
||||
scope.mdChange(md.render(value));
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}]);
|
||||
|
||||
/**
|
||||
* Markdown Editor
|
||||
* Handles all functionality of the markdown editor.
|
||||
*/
|
||||
ngApp.directive('markdownEditor', ['$timeout', '$rootScope', function ($timeout, $rootScope) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function (scope, element, attrs) {
|
||||
|
||||
// Editor Elements
|
||||
const $display = element.find('.markdown-display').first();
|
||||
const $insertImage = element.find('button[data-action="insertImage"]');
|
||||
const $insertEntityLink = element.find('button[data-action="insertEntityLink"]');
|
||||
|
||||
// Prevent markdown display link click redirect
|
||||
$display.on('click', 'a', function(event) {
|
||||
event.preventDefault();
|
||||
window.open(this.getAttribute('href'));
|
||||
});
|
||||
|
||||
// Editor UI Actions
|
||||
$insertEntityLink.click(e => {scope.$broadcast('md-insert-link');});
|
||||
$insertImage.click(e => {scope.$broadcast('md-insert-image');});
|
||||
|
||||
// Handle scroll sync event from editor scroll
|
||||
$rootScope.$on('markdown-scroll', (event, lineCount) => {
|
||||
let elems = $display[0].children[0].children;
|
||||
if (elems.length > lineCount) {
|
||||
let topElem = (lineCount === -1) ? elems[elems.length-1] : elems[lineCount];
|
||||
$display.animate({
|
||||
scrollTop: topElem.offsetTop
|
||||
}, {queue: false, duration: 200, easing: 'linear'});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}]);
|
||||
|
||||
/**
|
||||
* Page Editor Toolbox
|
||||
* Controls all functionality for the sliding toolbox
|
||||
* on the page edit view.
|
||||
*/
|
||||
ngApp.directive('toolbox', [function () {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function (scope, elem, attrs) {
|
||||
|
||||
// Get common elements
|
||||
const $buttons = elem.find('[toolbox-tab-button]');
|
||||
const $content = elem.find('[toolbox-tab-content]');
|
||||
const $toggle = elem.find('[toolbox-toggle]');
|
||||
|
||||
// Handle toolbox toggle click
|
||||
$toggle.click((e) => {
|
||||
elem.toggleClass('open');
|
||||
});
|
||||
|
||||
// Set an active tab/content by name
|
||||
function setActive(tabName, openToolbox) {
|
||||
$buttons.removeClass('active');
|
||||
$content.hide();
|
||||
$buttons.filter(`[toolbox-tab-button="${tabName}"]`).addClass('active');
|
||||
$content.filter(`[toolbox-tab-content="${tabName}"]`).show();
|
||||
if (openToolbox) elem.addClass('open');
|
||||
}
|
||||
|
||||
// Set the first tab content active on load
|
||||
setActive($content.first().attr('toolbox-tab-content'), false);
|
||||
|
||||
// Handle tab button click
|
||||
$buttons.click(function (e) {
|
||||
let name = $(this).attr('toolbox-tab-button');
|
||||
setActive(name, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
}]);
|
||||
};
|
||||
@@ -58,16 +58,6 @@ window.$http = axiosInstance;
|
||||
Vue.prototype.$http = axiosInstance;
|
||||
Vue.prototype.$events = window.$events;
|
||||
|
||||
|
||||
// AngularJS - Create application and load components
|
||||
const angular = require("angular");
|
||||
require("angular-resource");
|
||||
require("angular-animate");
|
||||
require("angular-sanitize");
|
||||
require("angular-ui-sortable");
|
||||
|
||||
let ngApp = angular.module('bookStack', ['ngResource', 'ngAnimate', 'ngSanitize', 'ui.sortable']);
|
||||
|
||||
// Translation setup
|
||||
// Creates a global function with name 'trans' to be used in the same way as Laravel's translation system
|
||||
const Translations = require("./translations");
|
||||
@@ -79,11 +69,6 @@ window.trans_choice = translator.getPlural.bind(translator);
|
||||
require("./vues/vues");
|
||||
require("./components");
|
||||
|
||||
// Load in angular specific items
|
||||
const Directives = require('./directives');
|
||||
const Controllers = require('./controllers');
|
||||
Directives(ngApp, window.$events);
|
||||
Controllers(ngApp, window.$events);
|
||||
|
||||
//Global jQuery Config & Extensions
|
||||
|
||||
|
||||
@@ -1,54 +1,55 @@
|
||||
"use strict";
|
||||
|
||||
const Code = require('../code');
|
||||
|
||||
/**
|
||||
* Handle pasting images from clipboard.
|
||||
* @param e - event
|
||||
* @param editor - editor instance
|
||||
* @param {ClipboardEvent} event
|
||||
* @param editor
|
||||
*/
|
||||
function editorPaste(e, editor) {
|
||||
if (!e.clipboardData) return;
|
||||
let items = e.clipboardData.items;
|
||||
if (!items) return;
|
||||
function editorPaste(event, editor) {
|
||||
if (!event.clipboardData || !event.clipboardData.items) return;
|
||||
let items = event.clipboardData.items;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
if (items[i].type.indexOf("image") === -1) return;
|
||||
|
||||
let file = items[i].getAsFile();
|
||||
let formData = new FormData();
|
||||
let ext = 'png';
|
||||
let xhr = new XMLHttpRequest();
|
||||
|
||||
if (file.name) {
|
||||
let fileNameMatches = file.name.match(/\.(.+)$/);
|
||||
if (fileNameMatches) {
|
||||
ext = fileNameMatches[1];
|
||||
}
|
||||
}
|
||||
if (items[i].type.indexOf("image") === -1) continue;
|
||||
event.preventDefault();
|
||||
|
||||
let id = "image-" + Math.random().toString(16).slice(2);
|
||||
let loadingImage = window.baseUrl('/loading.gif');
|
||||
editor.execCommand('mceInsertContent', false, `<img src="${loadingImage}" id="${id}">`);
|
||||
|
||||
let remoteFilename = "image-" + Date.now() + "." + ext;
|
||||
formData.append('file', file, remoteFilename);
|
||||
formData.append('_token', document.querySelector('meta[name="token"]').getAttribute('content'));
|
||||
|
||||
xhr.open('POST', window.baseUrl('/images/gallery/upload'));
|
||||
xhr.onload = function () {
|
||||
if (xhr.status === 200 || xhr.status === 201) {
|
||||
let result = JSON.parse(xhr.responseText);
|
||||
editor.dom.setAttrib(id, 'src', result.thumbs.display);
|
||||
} else {
|
||||
console.log('An error occurred uploading the image', xhr.responseText);
|
||||
let file = items[i].getAsFile();
|
||||
setTimeout(() => {
|
||||
editor.insertContent(`<p><img src="${loadingImage}" id="${id}"></p>`);
|
||||
uploadImageFile(file).then(resp => {
|
||||
editor.dom.setAttrib(id, 'src', resp.thumbs.display);
|
||||
}).catch(err => {
|
||||
editor.dom.remove(id);
|
||||
}
|
||||
};
|
||||
xhr.send(formData);
|
||||
|
||||
window.$events.emit('error', trans('errors.image_upload_error'));
|
||||
console.log(err);
|
||||
});
|
||||
}, 10);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upload an image file to the server
|
||||
* @param {File} file
|
||||
*/
|
||||
function uploadImageFile(file) {
|
||||
if (file === null || file.type.indexOf('image') !== 0) return Promise.reject(`Not an image file`);
|
||||
|
||||
let ext = 'png';
|
||||
if (file.name) {
|
||||
let fileNameMatches = file.name.match(/\.(.+)$/);
|
||||
if (fileNameMatches.length > 1) ext = fileNameMatches[1];
|
||||
}
|
||||
|
||||
let remoteFilename = "image-" + Date.now() + "." + ext;
|
||||
let formData = new FormData();
|
||||
formData.append('file', file, remoteFilename);
|
||||
|
||||
return window.$http.post('/images/gallery/upload', formData).then(resp => (resp.data));
|
||||
}
|
||||
|
||||
function registerEditorShortcuts(editor) {
|
||||
// Headers
|
||||
for (let i = 1; i < 5; i++) {
|
||||
@@ -64,6 +65,12 @@ function registerEditorShortcuts(editor) {
|
||||
editor.shortcuts.add('meta+e', '', ['codeeditor', false, 'pre']);
|
||||
editor.shortcuts.add('meta+8', '', ['FormatBlock', false, 'code']);
|
||||
editor.shortcuts.add('meta+shift+E', '', ['FormatBlock', false, 'code']);
|
||||
|
||||
// Save draft shortcut
|
||||
editor.shortcuts.add('meta+S', '', () => {
|
||||
window.$events.emit('editor-save-draft');
|
||||
});
|
||||
|
||||
// Loop through callout styles
|
||||
editor.shortcuts.add('meta+9', '', function() {
|
||||
let selectedNode = editor.selection.getNode();
|
||||
@@ -82,6 +89,7 @@ function registerEditorShortcuts(editor) {
|
||||
}
|
||||
editor.formatter.apply('p');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -194,191 +202,192 @@ function codePlugin() {
|
||||
|
||||
});
|
||||
}
|
||||
codePlugin();
|
||||
|
||||
function hrPlugin() {
|
||||
window.tinymce.PluginManager.add('customhr', function (editor) {
|
||||
editor.addCommand('InsertHorizontalRule', function () {
|
||||
let hrElem = document.createElement('hr');
|
||||
let cNode = editor.selection.getNode();
|
||||
let parentNode = cNode.parentNode;
|
||||
parentNode.insertBefore(hrElem, cNode);
|
||||
});
|
||||
|
||||
editor.addButton('hr', {
|
||||
icon: 'hr',
|
||||
tooltip: 'Horizontal line',
|
||||
cmd: 'InsertHorizontalRule'
|
||||
});
|
||||
|
||||
editor.addMenuItem('hr', {
|
||||
icon: 'hr',
|
||||
text: 'Horizontal line',
|
||||
cmd: 'InsertHorizontalRule',
|
||||
context: 'insert'
|
||||
});
|
||||
window.tinymce.PluginManager.add('customhr', function (editor) {
|
||||
editor.addCommand('InsertHorizontalRule', function () {
|
||||
let hrElem = document.createElement('hr');
|
||||
let cNode = editor.selection.getNode();
|
||||
let parentNode = cNode.parentNode;
|
||||
parentNode.insertBefore(hrElem, cNode);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = function() {
|
||||
hrPlugin();
|
||||
codePlugin();
|
||||
let settings = {
|
||||
selector: '#html-editor',
|
||||
content_css: [
|
||||
window.baseUrl('/css/styles.css'),
|
||||
window.baseUrl('/libs/material-design-iconic-font/css/material-design-iconic-font.min.css')
|
||||
],
|
||||
branding: false,
|
||||
body_class: 'page-content',
|
||||
browser_spellcheck: true,
|
||||
relative_urls: false,
|
||||
remove_script_host: false,
|
||||
document_base_url: window.baseUrl('/'),
|
||||
statusbar: false,
|
||||
menubar: false,
|
||||
paste_data_images: false,
|
||||
extended_valid_elements: 'pre[*]',
|
||||
automatic_uploads: false,
|
||||
valid_children: "-div[p|h1|h2|h3|h4|h5|h6|blockquote],+div[pre]",
|
||||
plugins: "image table textcolor paste link autolink fullscreen imagetools code customhr autosave lists codeeditor",
|
||||
imagetools_toolbar: 'imageoptions',
|
||||
toolbar: "undo redo | styleselect | bold italic underline strikethrough superscript subscript | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image-insert link hr | removeformat code fullscreen",
|
||||
content_style: "body {padding-left: 15px !important; padding-right: 15px !important; margin:0!important; margin-left:auto!important;margin-right:auto!important;}",
|
||||
style_formats: [
|
||||
{title: "Header Large", format: "h2"},
|
||||
{title: "Header Medium", format: "h3"},
|
||||
{title: "Header Small", format: "h4"},
|
||||
{title: "Header Tiny", format: "h5"},
|
||||
{title: "Paragraph", format: "p", exact: true, classes: ''},
|
||||
{title: "Blockquote", format: "blockquote"},
|
||||
{title: "Code Block", icon: "code", cmd: 'codeeditor', format: 'codeeditor'},
|
||||
{title: "Inline Code", icon: "code", inline: "code"},
|
||||
{title: "Callouts", items: [
|
||||
{title: "Info", format: 'calloutinfo'},
|
||||
{title: "Success", format: 'calloutsuccess'},
|
||||
{title: "Warning", format: 'calloutwarning'},
|
||||
{title: "Danger", format: 'calloutdanger'}
|
||||
]},
|
||||
],
|
||||
style_formats_merge: false,
|
||||
formats: {
|
||||
codeeditor: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div'},
|
||||
alignleft: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-left'},
|
||||
aligncenter: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-center'},
|
||||
alignright: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-right'},
|
||||
calloutsuccess: {block: 'p', exact: true, attributes: {class: 'callout success'}},
|
||||
calloutinfo: {block: 'p', exact: true, attributes: {class: 'callout info'}},
|
||||
calloutwarning: {block: 'p', exact: true, attributes: {class: 'callout warning'}},
|
||||
calloutdanger: {block: 'p', exact: true, attributes: {class: 'callout danger'}}
|
||||
},
|
||||
file_browser_callback: function (field_name, url, type, win) {
|
||||
editor.addButton('hr', {
|
||||
icon: 'hr',
|
||||
tooltip: 'Horizontal line',
|
||||
cmd: 'InsertHorizontalRule'
|
||||
});
|
||||
|
||||
if (type === 'file') {
|
||||
window.EntitySelectorPopup.show(function(entity) {
|
||||
let originalField = win.document.getElementById(field_name);
|
||||
originalField.value = entity.link;
|
||||
$(originalField).closest('.mce-form').find('input').eq(2).val(entity.name);
|
||||
editor.addMenuItem('hr', {
|
||||
icon: 'hr',
|
||||
text: 'Horizontal line',
|
||||
cmd: 'InsertHorizontalRule',
|
||||
context: 'insert'
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
module.exports = {
|
||||
selector: '#html-editor',
|
||||
content_css: [
|
||||
window.baseUrl('/css/styles.css'),
|
||||
window.baseUrl('/libs/material-design-iconic-font/css/material-design-iconic-font.min.css')
|
||||
],
|
||||
branding: false,
|
||||
body_class: 'page-content',
|
||||
browser_spellcheck: true,
|
||||
relative_urls: false,
|
||||
remove_script_host: false,
|
||||
document_base_url: window.baseUrl('/'),
|
||||
statusbar: false,
|
||||
menubar: false,
|
||||
paste_data_images: false,
|
||||
extended_valid_elements: 'pre[*]',
|
||||
automatic_uploads: false,
|
||||
valid_children: "-div[p|h1|h2|h3|h4|h5|h6|blockquote],+div[pre]",
|
||||
plugins: "image table textcolor paste link autolink fullscreen imagetools code customhr autosave lists codeeditor",
|
||||
imagetools_toolbar: 'imageoptions',
|
||||
toolbar: "undo redo | styleselect | bold italic underline strikethrough superscript subscript | forecolor backcolor | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | table image-insert link hr | removeformat code fullscreen",
|
||||
content_style: "body {padding-left: 15px !important; padding-right: 15px !important; margin:0!important; margin-left:auto!important;margin-right:auto!important;}",
|
||||
style_formats: [
|
||||
{title: "Header Large", format: "h2"},
|
||||
{title: "Header Medium", format: "h3"},
|
||||
{title: "Header Small", format: "h4"},
|
||||
{title: "Header Tiny", format: "h5"},
|
||||
{title: "Paragraph", format: "p", exact: true, classes: ''},
|
||||
{title: "Blockquote", format: "blockquote"},
|
||||
{title: "Code Block", icon: "code", cmd: 'codeeditor', format: 'codeeditor'},
|
||||
{title: "Inline Code", icon: "code", inline: "code"},
|
||||
{title: "Callouts", items: [
|
||||
{title: "Info", format: 'calloutinfo'},
|
||||
{title: "Success", format: 'calloutsuccess'},
|
||||
{title: "Warning", format: 'calloutwarning'},
|
||||
{title: "Danger", format: 'calloutdanger'}
|
||||
]},
|
||||
],
|
||||
style_formats_merge: false,
|
||||
formats: {
|
||||
codeeditor: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div'},
|
||||
alignleft: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-left'},
|
||||
aligncenter: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-center'},
|
||||
alignright: {selector: 'p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img', classes: 'align-right'},
|
||||
calloutsuccess: {block: 'p', exact: true, attributes: {class: 'callout success'}},
|
||||
calloutinfo: {block: 'p', exact: true, attributes: {class: 'callout info'}},
|
||||
calloutwarning: {block: 'p', exact: true, attributes: {class: 'callout warning'}},
|
||||
calloutdanger: {block: 'p', exact: true, attributes: {class: 'callout danger'}}
|
||||
},
|
||||
file_browser_callback: function (field_name, url, type, win) {
|
||||
|
||||
if (type === 'file') {
|
||||
window.EntitySelectorPopup.show(function(entity) {
|
||||
let originalField = win.document.getElementById(field_name);
|
||||
originalField.value = entity.link;
|
||||
$(originalField).closest('.mce-form').find('input').eq(2).val(entity.name);
|
||||
});
|
||||
}
|
||||
|
||||
if (type === 'image') {
|
||||
// Show image manager
|
||||
window.ImageManager.show(function (image) {
|
||||
|
||||
// Set popover link input to image url then fire change event
|
||||
// to ensure the new value sticks
|
||||
win.document.getElementById(field_name).value = image.url;
|
||||
if ("createEvent" in document) {
|
||||
let evt = document.createEvent("HTMLEvents");
|
||||
evt.initEvent("change", false, true);
|
||||
win.document.getElementById(field_name).dispatchEvent(evt);
|
||||
} else {
|
||||
win.document.getElementById(field_name).fireEvent("onchange");
|
||||
}
|
||||
|
||||
// Replace the actively selected content with the linked image
|
||||
let html = `<a href="${image.url}" target="_blank">`;
|
||||
html += `<img src="${image.thumbs.display}" alt="${image.name}">`;
|
||||
html += '</a>';
|
||||
win.tinyMCE.activeEditor.execCommand('mceInsertContent', false, html);
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
paste_preprocess: function (plugin, args) {
|
||||
let content = args.content;
|
||||
if (content.indexOf('<img src="file://') !== -1) {
|
||||
args.content = '';
|
||||
}
|
||||
},
|
||||
setup: function (editor) {
|
||||
|
||||
editor.on('init ExecCommand change input NodeChange ObjectResized', editorChange);
|
||||
|
||||
function editorChange() {
|
||||
let content = editor.getContent();
|
||||
window.$events.emit('editor-html-change', content);
|
||||
}
|
||||
|
||||
window.$events.listen('editor-html-update', html => {
|
||||
editor.setContent(html);
|
||||
editor.selection.select(editor.getBody(), true);
|
||||
editor.selection.collapse(false);
|
||||
editorChange(html);
|
||||
});
|
||||
|
||||
registerEditorShortcuts(editor);
|
||||
|
||||
let wrap;
|
||||
|
||||
function hasTextContent(node) {
|
||||
return node && !!( node.textContent || node.innerText );
|
||||
}
|
||||
|
||||
editor.on('dragstart', function () {
|
||||
let node = editor.selection.getNode();
|
||||
|
||||
if (node.nodeName !== 'IMG') return;
|
||||
wrap = editor.dom.getParent(node, '.mceTemp');
|
||||
|
||||
if (!wrap && node.parentNode.nodeName === 'A' && !hasTextContent(node.parentNode)) {
|
||||
wrap = node.parentNode;
|
||||
}
|
||||
});
|
||||
|
||||
editor.on('drop', function (event) {
|
||||
let dom = editor.dom,
|
||||
rng = tinymce.dom.RangeUtils.getCaretRangeFromPoint(event.clientX, event.clientY, editor.getDoc());
|
||||
|
||||
// Don't allow anything to be dropped in a captioned image.
|
||||
if (dom.getParent(rng.startContainer, '.mceTemp')) {
|
||||
event.preventDefault();
|
||||
} else if (wrap) {
|
||||
event.preventDefault();
|
||||
|
||||
editor.undoManager.transact(function () {
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.setNode(wrap);
|
||||
dom.remove(wrap);
|
||||
});
|
||||
}
|
||||
|
||||
if (type === 'image') {
|
||||
// Show image manager
|
||||
wrap = null;
|
||||
});
|
||||
|
||||
// Custom Image picker button
|
||||
editor.addButton('image-insert', {
|
||||
title: 'My title',
|
||||
icon: 'image',
|
||||
tooltip: 'Insert an image',
|
||||
onclick: function () {
|
||||
window.ImageManager.show(function (image) {
|
||||
|
||||
// Set popover link input to image url then fire change event
|
||||
// to ensure the new value sticks
|
||||
win.document.getElementById(field_name).value = image.url;
|
||||
if ("createEvent" in document) {
|
||||
let evt = document.createEvent("HTMLEvents");
|
||||
evt.initEvent("change", false, true);
|
||||
win.document.getElementById(field_name).dispatchEvent(evt);
|
||||
} else {
|
||||
win.document.getElementById(field_name).fireEvent("onchange");
|
||||
}
|
||||
|
||||
// Replace the actively selected content with the linked image
|
||||
let html = `<a href="${image.url}" target="_blank">`;
|
||||
html += `<img src="${image.thumbs.display}" alt="${image.name}">`;
|
||||
html += '</a>';
|
||||
win.tinyMCE.activeEditor.execCommand('mceInsertContent', false, html);
|
||||
editor.execCommand('mceInsertContent', false, html);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
paste_preprocess: function (plugin, args) {
|
||||
let content = args.content;
|
||||
if (content.indexOf('<img src="file://') !== -1) {
|
||||
args.content = '';
|
||||
}
|
||||
},
|
||||
extraSetups: [],
|
||||
setup: function (editor) {
|
||||
|
||||
// Run additional setup actions
|
||||
// Used by the angular side of things
|
||||
for (let i = 0; i < settings.extraSetups.length; i++) {
|
||||
settings.extraSetups[i](editor);
|
||||
}
|
||||
|
||||
registerEditorShortcuts(editor);
|
||||
|
||||
let wrap;
|
||||
|
||||
function hasTextContent(node) {
|
||||
return node && !!( node.textContent || node.innerText );
|
||||
}
|
||||
|
||||
editor.on('dragstart', function () {
|
||||
let node = editor.selection.getNode();
|
||||
|
||||
if (node.nodeName !== 'IMG') return;
|
||||
wrap = editor.dom.getParent(node, '.mceTemp');
|
||||
|
||||
if (!wrap && node.parentNode.nodeName === 'A' && !hasTextContent(node.parentNode)) {
|
||||
wrap = node.parentNode;
|
||||
}
|
||||
});
|
||||
|
||||
editor.on('drop', function (event) {
|
||||
let dom = editor.dom,
|
||||
rng = tinymce.dom.RangeUtils.getCaretRangeFromPoint(event.clientX, event.clientY, editor.getDoc());
|
||||
|
||||
// Don't allow anything to be dropped in a captioned image.
|
||||
if (dom.getParent(rng.startContainer, '.mceTemp')) {
|
||||
event.preventDefault();
|
||||
} else if (wrap) {
|
||||
event.preventDefault();
|
||||
|
||||
editor.undoManager.transact(function () {
|
||||
editor.selection.setRng(rng);
|
||||
editor.selection.setNode(wrap);
|
||||
dom.remove(wrap);
|
||||
});
|
||||
}
|
||||
|
||||
wrap = null;
|
||||
});
|
||||
|
||||
// Custom Image picker button
|
||||
editor.addButton('image-insert', {
|
||||
title: 'My title',
|
||||
icon: 'image',
|
||||
tooltip: 'Insert an image',
|
||||
onclick: function () {
|
||||
window.ImageManager.show(function (image) {
|
||||
let html = `<a href="${image.url}" target="_blank">`;
|
||||
html += `<img src="${image.thumbs.display}" alt="${image.name}">`;
|
||||
html += '</a>';
|
||||
editor.execCommand('mceInsertContent', false, html);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Paste image-uploads
|
||||
editor.on('paste', function(event) {
|
||||
editorPaste(event, editor);
|
||||
});
|
||||
}
|
||||
};
|
||||
return settings;
|
||||
// Paste image-uploads
|
||||
editor.on('paste', event => { editorPaste(event, editor) });
|
||||
}
|
||||
};
|
||||
149
resources/assets/js/vues/page-editor.js
Normal file
149
resources/assets/js/vues/page-editor.js
Normal file
@@ -0,0 +1,149 @@
|
||||
const moment = require('moment');
|
||||
require('moment/locale/en-gb');
|
||||
moment.locale('en-gb');
|
||||
|
||||
let autoSaveFrequency = 30;
|
||||
|
||||
let autoSave = false;
|
||||
let draftErroring = false;
|
||||
|
||||
let currentContent = {
|
||||
title: false,
|
||||
html: false
|
||||
};
|
||||
|
||||
let lastSave = 0;
|
||||
|
||||
function mounted() {
|
||||
let elem = this.$el;
|
||||
this.draftsEnabled = elem.getAttribute('drafts-enabled') === 'true';
|
||||
this.editorType = elem.getAttribute('editor-type');
|
||||
this.pageId= Number(elem.getAttribute('page-id'));
|
||||
this.isNewDraft = Number(elem.getAttribute('page-new-draft')) === 1;
|
||||
this.isUpdateDraft = Number(elem.getAttribute('page-update-draft')) === 1;
|
||||
|
||||
if (this.pageId !== 0 && this.draftsEnabled) {
|
||||
window.setTimeout(() => {
|
||||
this.startAutoSave();
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
if (this.isUpdateDraft || this.isNewDraft) {
|
||||
this.draftText = trans('entities.pages_editing_draft');
|
||||
} else {
|
||||
this.draftText = trans('entities.pages_editing_page');
|
||||
}
|
||||
|
||||
// Listen to save draft events from editor
|
||||
window.$events.listen('editor-save-draft', this.saveDraft);
|
||||
|
||||
// Listen to content changes from the editor
|
||||
window.$events.listen('editor-html-change', html => {
|
||||
this.editorHTML = html;
|
||||
});
|
||||
window.$events.listen('editor-markdown-change', markdown => {
|
||||
this.editorMarkdown = markdown;
|
||||
});
|
||||
}
|
||||
|
||||
let data = {
|
||||
draftsEnabled: false,
|
||||
editorType: 'wysiwyg',
|
||||
pagedId: 0,
|
||||
isNewDraft: false,
|
||||
isUpdateDraft: false,
|
||||
|
||||
draftText: '',
|
||||
draftUpdated : false,
|
||||
changeSummary: '',
|
||||
|
||||
editorHTML: '',
|
||||
editorMarkdown: '',
|
||||
};
|
||||
|
||||
let methods = {
|
||||
|
||||
startAutoSave() {
|
||||
currentContent.title = document.getElementById('name').value.trim();
|
||||
currentContent.html = this.editorHTML;
|
||||
|
||||
autoSave = window.setInterval(() => {
|
||||
// Return if manually saved recently to prevent bombarding the server
|
||||
if (Date.now() - lastSave < (1000 * autoSaveFrequency)/2) return;
|
||||
let newTitle = document.getElementById('name').value.trim();
|
||||
let newHtml = this.editorHTML;
|
||||
|
||||
if (newTitle !== currentContent.title || newHtml !== currentContent.html) {
|
||||
currentContent.html = newHtml;
|
||||
currentContent.title = newTitle;
|
||||
this.saveDraft();
|
||||
}
|
||||
|
||||
}, 1000 * autoSaveFrequency);
|
||||
},
|
||||
|
||||
saveDraft() {
|
||||
if (!this.draftsEnabled) return;
|
||||
|
||||
let data = {
|
||||
name: document.getElementById('name').value.trim(),
|
||||
html: this.editorHTML
|
||||
};
|
||||
|
||||
if (this.editorType === 'markdown') data.markdown = this.editorMarkdown;
|
||||
|
||||
let url = window.baseUrl(`/ajax/page/${this.pageId}/save-draft`);
|
||||
window.$http.put(url, data).then(response => {
|
||||
draftErroring = false;
|
||||
let updateTime = moment.utc(moment.unix(response.data.timestamp)).toDate();
|
||||
if (!this.isNewDraft) this.isUpdateDraft = true;
|
||||
this.draftNotifyChange(response.data.message + moment(updateTime).format('HH:mm'));
|
||||
lastSave = Date.now();
|
||||
}, errorRes => {
|
||||
if (draftErroring) return;
|
||||
window.$events('error', trans('errors.page_draft_autosave_fail'));
|
||||
draftErroring = true;
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
draftNotifyChange(text) {
|
||||
this.draftText = text;
|
||||
this.draftUpdated = true;
|
||||
window.setTimeout(() => {
|
||||
this.draftUpdated = false;
|
||||
}, 2000);
|
||||
},
|
||||
|
||||
discardDraft() {
|
||||
let url = window.baseUrl(`/ajax/page/${this.pageId}`);
|
||||
window.$http.get(url).then(response => {
|
||||
if (autoSave) window.clearInterval(autoSave);
|
||||
|
||||
this.draftText = trans('entities.pages_editing_page');
|
||||
this.isUpdateDraft = false;
|
||||
window.$events.emit('editor-html-update', response.data.html);
|
||||
window.$events.emit('editor-markdown-update', response.data.markdown || response.data.html);
|
||||
|
||||
document.getElementById('name').value = response.data.name;
|
||||
window.setTimeout(() => {
|
||||
this.startAutoSave();
|
||||
}, 1000);
|
||||
window.$events.emit('success', trans('entities.pages_draft_discarded'));
|
||||
});
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
let computed = {
|
||||
changeSummaryShort() {
|
||||
let len = this.changeSummary.length;
|
||||
if (len === 0) return trans('entities.pages_edit_set_changelog');
|
||||
if (len <= 16) return this.changeSummary;
|
||||
return this.changeSummary.slice(0, 16) + '...';
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
mounted, data, methods, computed,
|
||||
};
|
||||
@@ -11,6 +11,7 @@ let vueMapping = {
|
||||
'image-manager': require('./image-manager'),
|
||||
'tag-manager': require('./tag-manager'),
|
||||
'attachment-manager': require('./attachment-manager'),
|
||||
'page-editor': require('./page-editor'),
|
||||
};
|
||||
|
||||
window.vues = {};
|
||||
|
||||
@@ -195,10 +195,13 @@
|
||||
font-weight: 400;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
h3 a {
|
||||
line-height: 1;
|
||||
}
|
||||
.body, p.empty-text {
|
||||
padding: $-m;
|
||||
}
|
||||
a {
|
||||
a, p {
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
@@ -370,6 +370,7 @@ span.CodeMirror-selectedtext { background: none; }
|
||||
.cm-s-base16-light span.cm-keyword { color: #ac4142; }
|
||||
.cm-s-base16-light span.cm-string { color: #e09c3c; }
|
||||
|
||||
.cm-s-base16-light span.cm-builtin { color: #4c7f9e; }
|
||||
.cm-s-base16-light span.cm-variable { color: #90a959; }
|
||||
.cm-s-base16-light span.cm-variable-2 { color: #6a9fb5; }
|
||||
.cm-s-base16-light span.cm-def { color: #d28445; }
|
||||
|
||||
@@ -120,13 +120,15 @@ return [
|
||||
'en' => 'English',
|
||||
'de' => 'Deutsch',
|
||||
'es' => 'Español',
|
||||
'es_AR' => 'Español Argentina',
|
||||
'fr' => 'Français',
|
||||
'nl' => 'Nederlands',
|
||||
'pt_BR' => 'Português do Brasil',
|
||||
'sk' => 'Slovensky',
|
||||
'ja' => '日本語',
|
||||
'pl' => 'Polski',
|
||||
'it' => 'Italian'
|
||||
'it' => 'Italian',
|
||||
'ru' => 'Русский'
|
||||
]
|
||||
///////////////////////////////////
|
||||
];
|
||||
|
||||
42
resources/lang/es_AR/activities.php
Normal file
42
resources/lang/es_AR/activities.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/**
|
||||
* Activity text strings.
|
||||
* Is used for all the text within activity logs & notifications.
|
||||
*/
|
||||
|
||||
// Pages
|
||||
'page_create' => 'página creada',
|
||||
'page_create_notification' => 'Página creada exitosamente',
|
||||
'page_update' => 'página actualizada',
|
||||
'page_update_notification' => 'Página actualizada exitosamente',
|
||||
'page_delete' => 'página borrada',
|
||||
'page_delete_notification' => 'Página borrada exitosamente',
|
||||
'page_restore' => 'página restaurada',
|
||||
'page_restore_notification' => 'Página restaurada exitosamente',
|
||||
'page_move' => 'página movida',
|
||||
|
||||
// Chapters
|
||||
'chapter_create' => 'capítulo creado',
|
||||
'chapter_create_notification' => 'Capítulo creado exitosamente',
|
||||
'chapter_update' => 'capítulo actualizado',
|
||||
'chapter_update_notification' => 'Capítulo actualizado exitosamente',
|
||||
'chapter_delete' => 'capítulo borrado',
|
||||
'chapter_delete_notification' => 'Capítulo borrado exitosamente',
|
||||
'chapter_move' => 'capítulo movido',
|
||||
|
||||
// Books
|
||||
'book_create' => 'libro creado',
|
||||
'book_create_notification' => 'Libro creado exitosamente',
|
||||
'book_update' => 'libro actualizado',
|
||||
'book_update_notification' => 'Libro actualizado exitosamente',
|
||||
'book_delete' => 'libro borrado',
|
||||
'book_delete_notification' => 'Libro borrado exitosamente',
|
||||
'book_sort' => 'libro ordenado',
|
||||
'book_sort_notification' => 'Libro reordenado exitosamente',
|
||||
|
||||
// Other
|
||||
'commented_on' => 'comentado',
|
||||
];
|
||||
76
resources/lang/es_AR/auth.php
Normal file
76
resources/lang/es_AR/auth.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
return [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used during authentication for various
|
||||
| messages that we need to display to the user. You are free to modify
|
||||
| these language lines according to your application's requirements.
|
||||
|
|
||||
*/
|
||||
'failed' => 'Las credenciales no concuerdan con nuestros registros.',
|
||||
'throttle' => 'Demasiados intentos fallidos de conexión. Por favor intente nuevamente en :seconds segundos.',
|
||||
|
||||
/**
|
||||
* Login & Register
|
||||
*/
|
||||
'sign_up' => 'Registrarse',
|
||||
'log_in' => 'Acceder',
|
||||
'log_in_with' => 'Acceder con :socialDriver',
|
||||
'sign_up_with' => 'Registrarse con :socialDriver',
|
||||
'logout' => 'Logout',
|
||||
|
||||
'name' => 'Nombre',
|
||||
'username' => 'Nombre de usuario',
|
||||
'email' => 'Correo electrónico',
|
||||
'password' => 'Contraseña',
|
||||
'password_confirm' => 'Confirmar contraseña',
|
||||
'password_hint' => 'Debe contener al menos 5 caracteres',
|
||||
'forgot_password' => '¿Olvidó la contraseña?',
|
||||
'remember_me' => 'Recordarme',
|
||||
'ldap_email_hint' => 'Por favor introduzca un correo electrónico para utilizar con esta cuenta.',
|
||||
'create_account' => 'Crear una cuenta',
|
||||
'social_login' => 'Acceso con cuenta Social',
|
||||
'social_registration' => 'Registro con cuenta Social',
|
||||
'social_registration_text' => 'Registrar y entrar utilizando otro servicio.',
|
||||
|
||||
'register_thanks' => '¡Gracias por registrarse!',
|
||||
'register_confirm' => 'Por favor verifique su correo electrónico y presione en el botón de confirmación enviado para acceder a :appName.',
|
||||
'registrations_disabled' => 'Los registros están deshabilitados actualmente',
|
||||
'registration_email_domain_invalid' => 'Este dominio de correo electrónico no tiene acceso a esta aplicación',
|
||||
'register_success' => '¡Gracias por registrarse! Ahora se encuentra registrado y ha accedido a la aplicación.',
|
||||
|
||||
|
||||
/**
|
||||
* Password Reset
|
||||
*/
|
||||
'reset_password' => 'Restablecer la contraseña',
|
||||
'reset_password_send_instructions' => 'Introduzca su correo electrónico a continuación y se le enviará un correo electrónico con un enlace para la restauración',
|
||||
'reset_password_send_button' => 'Enviar enlace de restauración',
|
||||
'reset_password_sent_success' => 'Se envió un enlace para restablecer la contraseña a :email.',
|
||||
'reset_password_success' => 'Su contraseña se restableció con éxito.',
|
||||
|
||||
'email_reset_subject' => 'Restauración de la contraseña de para la aplicación :appName',
|
||||
'email_reset_text' => 'Ud. esta recibiendo este correo electrónico debido a que recibimos una solicitud de restauración de la contraseña de su cuenta.',
|
||||
'email_reset_not_requested' => 'Si ud. no solicitó un cambio de contraseña, no se requiere ninguna acción.',
|
||||
|
||||
|
||||
/**
|
||||
* Email Confirmation
|
||||
*/
|
||||
'email_confirm_subject' => 'Confirme su correo electrónico en :appName',
|
||||
'email_confirm_greeting' => '¡Gracias por unirse a :appName!',
|
||||
'email_confirm_text' => 'Por favor confirme su dirección de correo electrónico presionando en el siguiente botón:',
|
||||
'email_confirm_action' => 'Confirmar correo electrónico',
|
||||
'email_confirm_send_error' => 'Se pidió confirmación de correo electrónico pero el sistema no pudo enviar el correo electrónico. Contacte al administrador para asegurarse que el correo electrónico está configurado correctamente.',
|
||||
'email_confirm_success' => '¡Su correo electrónico hasido confirmado!',
|
||||
'email_confirm_resent' => 'Correo electrónico de confirmación reenviado, Por favor verifique su bandeja de entrada.',
|
||||
|
||||
'email_not_confirmed' => 'Dirección de correo electrónico no confirmada',
|
||||
'email_not_confirmed_text' => 'Su cuenta de correo electrónico todavía no ha sido confirmada.',
|
||||
'email_not_confirmed_click_link' => 'Por favor verifique el correo electrónico con el enlace de confirmación que fue enviado luego de registrarse.',
|
||||
'email_not_confirmed_resend' => 'Si no puede encontrar el correo electrónico, puede solicitar el renvío del correo electrónico de confirmación rellenando el formulario a continuación.',
|
||||
'email_not_confirmed_resend_button' => 'Reenviar correo electrónico de confirmación',
|
||||
];
|
||||
61
resources/lang/es_AR/common.php
Normal file
61
resources/lang/es_AR/common.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
return [
|
||||
|
||||
/**
|
||||
* Buttons
|
||||
*/
|
||||
'cancel' => 'Cancelar',
|
||||
'confirm' => 'Confirmar',
|
||||
'back' => 'Atrás',
|
||||
'save' => 'Guardar',
|
||||
'continue' => 'Continuar',
|
||||
'select' => 'Seleccionar',
|
||||
'more' => 'Más',
|
||||
|
||||
/**
|
||||
* Form Labels
|
||||
*/
|
||||
'name' => 'Nombre',
|
||||
'description' => 'Descripción',
|
||||
'role' => 'Rol',
|
||||
|
||||
/**
|
||||
* Actions
|
||||
*/
|
||||
'actions' => 'Acciones',
|
||||
'view' => 'Ver',
|
||||
'create' => 'Crear',
|
||||
'update' => 'Actualizar',
|
||||
'edit' => 'Editar',
|
||||
'sort' => 'Ordenar',
|
||||
'move' => 'Mover',
|
||||
'reply' => 'Responder',
|
||||
'delete' => 'Borrar',
|
||||
'search' => 'Buscar',
|
||||
'search_clear' => 'Limpiar búsqueda',
|
||||
'reset' => 'Restablecer',
|
||||
'remove' => 'Remover',
|
||||
'add' => 'Agregar',
|
||||
|
||||
/**
|
||||
* Misc
|
||||
*/
|
||||
'deleted_user' => 'Usuario borrado',
|
||||
'no_activity' => 'Ninguna actividad para mostrar',
|
||||
'no_items' => 'No hay items disponibles',
|
||||
'back_to_top' => 'Volver arriba',
|
||||
'toggle_details' => 'Alternar detalles',
|
||||
'details' => 'Detalles',
|
||||
|
||||
/**
|
||||
* Header
|
||||
*/
|
||||
'view_profile' => 'Ver Perfil',
|
||||
'edit_profile' => 'Editar Perfil',
|
||||
|
||||
/**
|
||||
* Email Content
|
||||
*/
|
||||
'email_action_help' => 'Si está teniendo problemas haga click en el botón ":actionText", copie y pegue la siguiente URL en su navegador web:',
|
||||
'email_rights' => 'Todos los derechos reservados',
|
||||
];
|
||||
32
resources/lang/es_AR/components.php
Normal file
32
resources/lang/es_AR/components.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
return [
|
||||
|
||||
/**
|
||||
* Image Manager
|
||||
*/
|
||||
'image_select' => 'Seleccionar Imagen',
|
||||
'image_all' => 'Todo',
|
||||
'image_all_title' => 'Ver todas las imágenes',
|
||||
'image_book_title' => 'Ver las imágenes subidas a este libro',
|
||||
'image_page_title' => 'Ver las imágenes subidas a esta página',
|
||||
'image_search_hint' => 'Buscar por nombre de imagen',
|
||||
'image_uploaded' => 'Subido el :uploadedDate',
|
||||
'image_load_more' => 'Cargar más',
|
||||
'image_image_name' => 'Nombre de imagen',
|
||||
'image_delete_confirm' => 'Esta imagen esta siendo utilizada en las páginas a continuación, haga click de nuevo para confirmar que quiere borrar esta imagen.',
|
||||
'image_select_image' => 'Seleccionar Imagen',
|
||||
'image_dropzone' => 'Arrastre las imágenes o hacer click aquí para Subir',
|
||||
'images_deleted' => 'Imágenes borradas',
|
||||
'image_preview' => 'Preview de la imagen',
|
||||
'image_upload_success' => 'Imagen subida éxitosamente',
|
||||
'image_update_success' => 'Detalles de la imagen actualizados exitosamente',
|
||||
'image_delete_success' => 'Imagen borrada exitosamente',
|
||||
|
||||
/**
|
||||
* Code editor
|
||||
*/
|
||||
'code_editor' => 'Editar Código',
|
||||
'code_language' => 'Lenguaje del Código',
|
||||
'code_content' => 'Contenido del Código',
|
||||
'code_save' => 'Guardar Código',
|
||||
];
|
||||
260
resources/lang/es_AR/entities.php
Normal file
260
resources/lang/es_AR/entities.php
Normal file
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
return [
|
||||
|
||||
/**
|
||||
* Shared
|
||||
*/
|
||||
'recently_created' => 'Recientemente creado',
|
||||
'recently_created_pages' => 'Páginas recientemente creadas',
|
||||
'recently_updated_pages' => 'Páginas recientemente actualizadas',
|
||||
'recently_created_chapters' => 'Capítulos recientemente creados',
|
||||
'recently_created_books' => 'Libros recientemente creados',
|
||||
'recently_update' => 'Recientemente actualizado',
|
||||
'recently_viewed' => 'Recientemente visto',
|
||||
'recent_activity' => 'Actividad reciente',
|
||||
'create_now' => 'Crear uno ahora',
|
||||
'revisions' => 'Revisiones',
|
||||
'meta_created' => 'Creado el :timeLength',
|
||||
'meta_created_name' => 'Creado el :timeLength por :user',
|
||||
'meta_updated' => 'Actualizado el :timeLength',
|
||||
'meta_updated_name' => 'Actualizado el :timeLength por :user',
|
||||
'x_pages' => ':count Páginas',
|
||||
'entity_select' => 'Seleccione entidad',
|
||||
'images' => 'Imágenes',
|
||||
'my_recent_drafts' => 'Mis borradores recientes',
|
||||
'my_recently_viewed' => 'Mis visualizaciones recientes',
|
||||
'no_pages_viewed' => 'Ud. no ha visto ninguna página',
|
||||
'no_pages_recently_created' => 'Ninguna página ha sido creada recientemente',
|
||||
'no_pages_recently_updated' => 'Ninguna página ha sido actualizada recientemente',
|
||||
'export' => 'Export',
|
||||
'export_html' => 'Contained Web File',
|
||||
'export_pdf' => 'PDF File',
|
||||
'export_text' => 'Plain Text File',
|
||||
|
||||
/**
|
||||
* Permissions and restrictions
|
||||
*/
|
||||
'permissions' => 'Permisos',
|
||||
'permissions_intro' => 'una vez habilitado, Estos permisos tendrán prioridad por encima de cualquier permiso establecido.',
|
||||
'permissions_enable' => 'Habilitar permisos custom',
|
||||
'permissions_save' => 'Guardar permisos',
|
||||
|
||||
/**
|
||||
* Search
|
||||
*/
|
||||
'search_results' => 'Buscar resultados',
|
||||
'search_total_results_found' => ':count resultados encontrados|:count total de resultados encontrados',
|
||||
'search_clear' => 'Limpiar resultados',
|
||||
'search_no_pages' => 'Ninguna página encontrada para la búsqueda',
|
||||
'search_for_term' => 'Busqueda por :term',
|
||||
'search_more' => 'Más resultados',
|
||||
'search_filters' => 'Filtros de búsqueda',
|
||||
'search_content_type' => 'Tipo de contenido',
|
||||
'search_exact_matches' => 'Coincidencias exactas',
|
||||
'search_tags' => 'Búsquedas de etiquetas',
|
||||
'search_viewed_by_me' => 'Vistos por mí',
|
||||
'search_not_viewed_by_me' => 'No vistos por mí',
|
||||
'search_permissions_set' => 'Permisos establecidos',
|
||||
'search_created_by_me' => 'Creado por mí',
|
||||
'search_updated_by_me' => 'Actualizado por mí',
|
||||
'search_updated_before' => 'Actualizado antes de',
|
||||
'search_updated_after' => 'Actualizado después de',
|
||||
'search_created_before' => 'Creado antes de',
|
||||
'search_created_after' => 'Creado después de',
|
||||
'search_set_date' => 'Esablecer fecha',
|
||||
'search_update' => 'Actualizar búsqueda',
|
||||
|
||||
/**
|
||||
* Books
|
||||
*/
|
||||
'book' => 'Libro',
|
||||
'books' => 'Libros',
|
||||
'x_books' => ':count Libro|:count Libros',
|
||||
'books_empty' => 'No hay libros creados',
|
||||
'books_popular' => 'Libros populares',
|
||||
'books_recent' => 'Libros recientes',
|
||||
'books_new' => 'Libros nuevos',
|
||||
'books_popular_empty' => 'Los libros más populares aparecerán aquí.',
|
||||
'books_new_empty' => 'Los libros creados más recientemente aparecerán aquí.',
|
||||
'books_create' => 'Crear nuevo libro',
|
||||
'books_delete' => 'Borrar libro',
|
||||
'books_delete_named' => 'Borrar libro :bookName',
|
||||
'books_delete_explain' => 'Esto borrará el libro con el nombre \':bookName\', Todas las páginas y capítulos serán removidos.',
|
||||
'books_delete_confirmation' => '¿Está seguro de que desea borrar este libro?',
|
||||
'books_edit' => 'Editar Libro',
|
||||
'books_edit_named' => 'Editar Libro :bookName',
|
||||
'books_form_book_name' => 'Nombre de libro',
|
||||
'books_save' => 'Guardar libro',
|
||||
'books_permissions' => 'permisos de libro',
|
||||
'books_permissions_updated' => 'Permisos de libro actualizados',
|
||||
'books_empty_contents' => 'Ninguna página o capítulo ha sido creada para este libro.',
|
||||
'books_empty_create_page' => 'Crear una nueva página',
|
||||
'books_empty_or' => 'ó',
|
||||
'books_empty_sort_current_book' => 'Organizar el libro actual',
|
||||
'books_empty_add_chapter' => 'Agregar un capítulo',
|
||||
'books_permissions_active' => 'Permisos de libro activados',
|
||||
'books_search_this' => 'Buscar en este libro',
|
||||
'books_navigation' => 'Navegación de libro',
|
||||
'books_sort' => 'Organizar contenido de libro',
|
||||
'books_sort_named' => 'Organizar libro :bookName',
|
||||
'books_sort_show_other' => 'Mostrar otros libros',
|
||||
'books_sort_save' => 'Guardar nuevo orden',
|
||||
|
||||
/**
|
||||
* Chapters
|
||||
*/
|
||||
'chapter' => 'Capítulo',
|
||||
'chapters' => 'Capítulos',
|
||||
'x_chapters' => ':count Capítulo|:count Capítulos',
|
||||
'chapters_popular' => 'Capítulos populares',
|
||||
'chapters_new' => 'Nuevo capítulo',
|
||||
'chapters_create' => 'Crear nuevo capítulo',
|
||||
'chapters_delete' => 'Borrar capítulo',
|
||||
'chapters_delete_named' => 'Borrar capítulo :chapterName',
|
||||
'chapters_delete_explain' => 'Esto borrará el capítulo con el nombre \':chapterName\', todas las páginas serán removidas y agregadas directamente al libro padre.',
|
||||
'chapters_delete_confirm' => '¿Está seguro de borrar este capítulo?',
|
||||
'chapters_edit' => 'Editar capítulo',
|
||||
'chapters_edit_named' => 'Editar capítulo :chapterName',
|
||||
'chapters_save' => 'Guardar capítulo',
|
||||
'chapters_move' => 'Mover capítulo',
|
||||
'chapters_move_named' => 'Mover Capítulo :chapterName',
|
||||
'chapter_move_success' => 'Capítulo movido a :bookName',
|
||||
'chapters_permissions' => 'Permisos de capítulo',
|
||||
'chapters_empty' => 'No existen páginas en este capítulo.',
|
||||
'chapters_permissions_active' => 'Permisos de capítulo activado',
|
||||
'chapters_permissions_success' => 'Permisos de capítulo actualizados',
|
||||
'chapters_search_this' => 'Buscar en este capítulo',
|
||||
|
||||
/**
|
||||
* Pages
|
||||
*/
|
||||
'page' => 'Página',
|
||||
'pages' => 'Páginas',
|
||||
'x_pages' => ':count Página|:count Páginas',
|
||||
'pages_popular' => 'Páginas populares',
|
||||
'pages_new' => 'Nueva página',
|
||||
'pages_attachments' => 'Adjuntos',
|
||||
'pages_navigation' => 'Navegación de página',
|
||||
'pages_delete' => 'Borrar página',
|
||||
'pages_delete_named' => 'Borrar página :pageName',
|
||||
'pages_delete_draft_named' => 'Borrar borrador de página :pageName',
|
||||
'pages_delete_draft' => 'Borrar borrador de página',
|
||||
'pages_delete_success' => 'Página borrada',
|
||||
'pages_delete_draft_success' => 'Borrador de página borrado',
|
||||
'pages_delete_confirm' => '¿Está seguro de borrar esta página?',
|
||||
'pages_delete_draft_confirm' => 'Está seguro de que desea borrar este borrador de página?',
|
||||
'pages_editing_named' => 'Editando página :pageName',
|
||||
'pages_edit_toggle_header' => 'Alternar cabecera',
|
||||
'pages_edit_save_draft' => 'Guardar borrador',
|
||||
'pages_edit_draft' => 'Editar borrador de página',
|
||||
'pages_editing_draft' => 'Editando borrador',
|
||||
'pages_editing_page' => 'Editando página',
|
||||
'pages_edit_draft_save_at' => 'Borrador guardado el ',
|
||||
'pages_edit_delete_draft' => 'Borrar borrador',
|
||||
'pages_edit_discard_draft' => 'Descartar borrador',
|
||||
'pages_edit_set_changelog' => 'Establecer cambios de registro',
|
||||
'pages_edit_enter_changelog_desc' => 'Introduzca una breve descripción de los cambios que ha realizado',
|
||||
'pages_edit_enter_changelog' => 'Entrar en cambio de registro',
|
||||
'pages_save' => 'Guardar página',
|
||||
'pages_title' => 'Título de página',
|
||||
'pages_name' => 'Nombre de página',
|
||||
'pages_md_editor' => 'Editor',
|
||||
'pages_md_preview' => 'Previsualizar',
|
||||
'pages_md_insert_image' => 'Insertar Imagen',
|
||||
'pages_md_insert_link' => 'Insertar link de entidad',
|
||||
'pages_not_in_chapter' => 'La página no esá en el capítulo',
|
||||
'pages_move' => 'Mover página',
|
||||
'pages_move_success' => 'Página movida a ":parentName"',
|
||||
'pages_permissions' => 'Permisos de página',
|
||||
'pages_permissions_success' => 'Permisos de página actualizados',
|
||||
'pages_revision' => 'Revisión',
|
||||
'pages_revisions' => 'Revisiones de página',
|
||||
'pages_revisions_named' => 'Revisiones de página para :pageName',
|
||||
'pages_revision_named' => 'Revisión de ágina para :pageName',
|
||||
'pages_revisions_created_by' => 'Creado por',
|
||||
'pages_revisions_date' => 'Fecha de revisión',
|
||||
'pages_revisions_number' => '#',
|
||||
'pages_revisions_changelog' => 'Registro de cambios',
|
||||
'pages_revisions_changes' => 'Cambios',
|
||||
'pages_revisions_current' => 'Versión actual',
|
||||
'pages_revisions_preview' => 'Previsualizar',
|
||||
'pages_revisions_restore' => 'Restaurar',
|
||||
'pages_revisions_none' => 'Esta página no tiene revisiones',
|
||||
'pages_copy_link' => 'Copiar enlace',
|
||||
'pages_permissions_active' => 'Permisos de página activos',
|
||||
'pages_initial_revision' => 'Publicación inicial',
|
||||
'pages_initial_name' => 'Página nueva',
|
||||
'pages_editing_draft_notification' => 'Usted está actualmente editando un borrador que fue guardado por última vez el :timeDiff.',
|
||||
'pages_draft_edited_notification' => 'Esta página ha sido actualizada desde aquel momento. Se recomienda que cancele este borrador.',
|
||||
'pages_draft_edit_active' => [
|
||||
'start_a' => ':count usuarios han comenzado a editar esta página',
|
||||
'start_b' => ':userName ha comenzado a editar esta página',
|
||||
'time_a' => 'desde que las página fue actualizada',
|
||||
'time_b' => 'en los últimos :minCount minutos',
|
||||
'message' => ':start :time. Ten cuidado de no sobreescribir los cambios del otro usuario',
|
||||
],
|
||||
'pages_draft_discarded' => 'Borrador descartado, el editor ha sido actualizado con el contenido de la página actual',
|
||||
|
||||
/**
|
||||
* Editor sidebar
|
||||
*/
|
||||
'page_tags' => 'Etiquetas de página',
|
||||
'tag' => 'Etiqueta',
|
||||
'tags' => 'Etiquetas',
|
||||
'tag_value' => 'Valor de la etiqueta (Opcional)',
|
||||
'tags_explain' => "Agregar algunas etiquetas para mejorar la categorización de su contenido. \n Se puede asignar un valor a una etiqueta para una organizacón con mayor detalle.",
|
||||
'tags_add' => 'Agregar otra etiqueta',
|
||||
'attachments' => 'Adjuntos',
|
||||
'attachments_explain' => 'Subir archivos o agregar enlaces para mostrar en la página. Estos son visibles en la barra lateral de la página.',
|
||||
'attachments_explain_instant_save' => 'Los cambios se guardan de manera instantánea.',
|
||||
'attachments_items' => 'Elementos adjuntados',
|
||||
'attachments_upload' => 'Archivo adjuntado',
|
||||
'attachments_link' => 'Adjuntar enlace',
|
||||
'attachments_set_link' => 'Establecer enlace',
|
||||
'attachments_delete_confirm' => 'Presione en borrar nuevamente para confirmar que quiere borrar este elemento adjunto.',
|
||||
'attachments_dropzone' => 'Arrastre archivos aquí o presione aquí para adjuntar un archivo',
|
||||
'attachments_no_files' => 'No se adjuntó ningún archivo',
|
||||
'attachments_explain_link' => 'Usted puede agregar un enlace o si lo prefiere puede agregar un archivo. Esto puede ser un enlace a otra página o un enlace a un archivo en la nube.',
|
||||
'attachments_link_name' => 'Nombre del enlace',
|
||||
'attachment_link' => 'Enlace adjunto',
|
||||
'attachments_link_url' => 'Enlace a archivo',
|
||||
'attachments_link_url_hint' => 'URL del sitio o archivo',
|
||||
'attach' => 'Adjuntar',
|
||||
'attachments_edit_file' => 'Editar archivo',
|
||||
'attachments_edit_file_name' => 'Nombre del archivo',
|
||||
'attachments_edit_drop_upload' => 'Arrastre los archivos o presione aquí para subir o sobreescribir',
|
||||
'attachments_order_updated' => 'Orden de adjuntos actualizado',
|
||||
'attachments_updated_success' => 'Detalles de adjuntos actualizados',
|
||||
'attachments_deleted' => 'Adjunto borrado',
|
||||
'attachments_file_uploaded' => 'Archivo subido exitosamente',
|
||||
'attachments_file_updated' => 'Archivo actualizado exitosamente',
|
||||
'attachments_link_attached' => 'Enlace agregado exitosamente a la página',
|
||||
|
||||
/**
|
||||
* Profile View
|
||||
*/
|
||||
'profile_user_for_x' => 'Usuario para :time',
|
||||
'profile_created_content' => 'Contenido creado',
|
||||
'profile_not_created_pages' => ':userName no ha creado ninguna página',
|
||||
'profile_not_created_chapters' => ':userName no ha creado ningún capítulo',
|
||||
'profile_not_created_books' => ':userName no ha creado ningún libro',
|
||||
|
||||
/**
|
||||
* Comments
|
||||
*/
|
||||
'comment' => 'Comentario',
|
||||
'comments' => 'Comentarios',
|
||||
'comment_placeholder' => 'DEjar un comentario aquí',
|
||||
'comment_count' => '{0} Sin Comentarios|{1} 1 Comentario|[2,*] :count Comentarios',
|
||||
'comment_save' => 'Guardar comentario',
|
||||
'comment_saving' => 'Guardando comentario...',
|
||||
'comment_deleting' => 'Borrando comentario...',
|
||||
'comment_new' => 'Nuevo comentario',
|
||||
'comment_created' => 'comentado :createDiff',
|
||||
'comment_updated' => 'Actualizado :updateDiff por :username',
|
||||
'comment_deleted_success' => 'Comentario borrado',
|
||||
'comment_created_success' => 'Comentario agregado',
|
||||
'comment_updated_success' => 'Comentario actualizado',
|
||||
'comment_delete_confirm' => '¿Está seguro que quiere borrar este comentario?',
|
||||
'comment_in_reply_to' => 'En respuesta a :commentId',
|
||||
];
|
||||
77
resources/lang/es_AR/errors.php
Normal file
77
resources/lang/es_AR/errors.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/**
|
||||
* Error text strings.
|
||||
*/
|
||||
|
||||
// Permissions
|
||||
'permission' => 'Ud. no tiene permisos para visualizar la página solicitada.',
|
||||
'permissionJson' => 'Ud. no tiene permisos para ejecutar la acción solicitada.',
|
||||
|
||||
// Auth
|
||||
'error_user_exists_different_creds' => 'Un usuario con el email :email ya existe pero con credenciales diferentes.',
|
||||
'email_already_confirmed' => 'El email ya ha sido confirmado, Intente loguearse en la aplicación.',
|
||||
'email_confirmation_invalid' => 'Este token de confirmación no e válido o ya ha sido usado,Intente registrar uno nuevamente.',
|
||||
'email_confirmation_expired' => 'El token de confirmación ha expirado, Un nuevo email de confirmacón ha sido enviado.',
|
||||
'ldap_fail_anonymous' => 'El acceso con LDAP ha fallado usando binding anónimo',
|
||||
'ldap_fail_authed' => 'El acceso LDAP usando el dn & password detallados',
|
||||
'ldap_extension_not_installed' => 'La extensión LDAP PHP no se encuentra instalada',
|
||||
'ldap_cannot_connect' => 'No se puede conectar con el servidor ldap, la conexión inicial ha fallado',
|
||||
'social_no_action_defined' => 'Acción no definida',
|
||||
'social_account_in_use' => 'la cuenta :socialAccount ya se encuentra en uso, intente loguearse a través de la opcón :socialAccount .',
|
||||
'social_account_email_in_use' => 'El email :email ya se encuentra en uso. Si ud. ya dispone de una cuenta puede loguearse a través de su cuenta :socialAccount desde la configuración de perfil.',
|
||||
'social_account_existing' => 'La cuenta :socialAccount ya se encuentra asignada a su perfil.',
|
||||
'social_account_already_used_existing' => 'La cuenta :socialAccount ya se encuentra usada por otro usuario.',
|
||||
'social_account_not_used' => 'La cuenta :socialAccount no está asociada a ningún usuario. Por favor adjuntela a su configuración de perfil. ',
|
||||
'social_account_register_instructions' => 'Si no dispone de una cuenta, puede registrar una cuenta usando la opción de :socialAccount .',
|
||||
'social_driver_not_found' => 'Driver social no encontrado',
|
||||
'social_driver_not_configured' => 'Su configuración :socialAccount no es correcta.',
|
||||
|
||||
// System
|
||||
'path_not_writable' => 'La ruta :filePath no pudo ser cargada. Asegurese de que es escribible por el servidor.',
|
||||
'cannot_get_image_from_url' => 'No se puede obtener la imagen desde :url',
|
||||
'cannot_create_thumbs' => 'El servidor no puede crear la imagen miniatura. Por favor chequee que tiene la extensión GD instalada.',
|
||||
'server_upload_limit' => 'El servidor no permite la subida de ficheros de este tamañ. Por favor intente con un fichero de menor tamañ.',
|
||||
'image_upload_error' => 'Ha ocurrido un error al subir la imagen',
|
||||
|
||||
// Attachments
|
||||
'attachment_page_mismatch' => 'Página no coincidente durante la subida del adjunto ',
|
||||
|
||||
// Pages
|
||||
'page_draft_autosave_fail' => 'Fallo al guardar borrador. Asegurese de que tiene conexión a Internet antes de guardar este borrador',
|
||||
|
||||
// Entities
|
||||
'entity_not_found' => 'Entidad no encontrada',
|
||||
'book_not_found' => 'Libro no encontrado',
|
||||
'page_not_found' => 'Página no encontrada',
|
||||
'chapter_not_found' => 'Capítulo no encontrado',
|
||||
'selected_book_not_found' => 'El libro seleccionado no fue encontrado',
|
||||
'selected_book_chapter_not_found' => 'El libro o capítulo seleccionado no fue encontrado',
|
||||
'guests_cannot_save_drafts' => 'Los invitados no pueden guardar los borradores',
|
||||
|
||||
// Users
|
||||
'users_cannot_delete_only_admin' => 'No se puede borrar el único administrador',
|
||||
'users_cannot_delete_guest' => 'No se puede borrar el usuario invitado',
|
||||
|
||||
// Roles
|
||||
'role_cannot_be_edited' => 'Este rol no puede ser editado',
|
||||
'role_system_cannot_be_deleted' => 'Este rol es un rol de sistema y no puede ser borrado',
|
||||
'role_registration_default_cannot_delete' => 'Este rol no puede ser borrado mientras sea el rol por defecto de registro',
|
||||
|
||||
// Comments
|
||||
'comment_list' => 'Se produjo un error al obtener los comentarios.',
|
||||
'cannot_add_comment_to_draft' => 'No puede gregar comentarios a un borrador.',
|
||||
'comment_add' => 'Se produjo un error al agregar o actualizar el comentario.',
|
||||
'comment_delete' => 'Se produjo un error al borrar el comentario.',
|
||||
'empty_comment' => 'No se puede agregar un comentario vacío.',
|
||||
|
||||
// Error pages
|
||||
'404_page_not_found' => 'Página no encontrada',
|
||||
'sorry_page_not_found' => 'Lo sentimos, la página que intenta acceder no pudo ser encontrada.',
|
||||
'return_home' => 'Volver al home',
|
||||
'error_occurred' => 'Ha ocurrido un error',
|
||||
'app_down' => 'La aplicación :appName se encuentra caída en este momento',
|
||||
'back_soon' => 'Volverá a estar operativa en corto tiempo.',
|
||||
];
|
||||
19
resources/lang/es_AR/pagination.php
Normal file
19
resources/lang/es_AR/pagination.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Pagination Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used by the paginator library to build
|
||||
| the simple pagination links. You are free to change them to anything
|
||||
| you want to customize your views to better match your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'previous' => '« Anterior',
|
||||
'next' => 'Siguiente »',
|
||||
|
||||
];
|
||||
22
resources/lang/es_AR/passwords.php
Normal file
22
resources/lang/es_AR/passwords.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reminder Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are the default lines which match reasons
|
||||
| that are given by the password broker for a password update attempt
|
||||
| has failed, such as for an invalid token or invalid new password.
|
||||
|
|
||||
*/
|
||||
|
||||
'password' => 'La contraseña debe ser como mínimo de seis caracteres y coincidir con la confirmación.',
|
||||
'user' => "No podemos encontrar un usuario con esta dirección de correo electrónico.",
|
||||
'token' => 'Este token de restablecimiento de contraseña no es válido.',
|
||||
'sent' => '¡Hemos enviado a su cuenta de correo electrónico un enlace para restaurar su contraseña!',
|
||||
'reset' => '¡Su contraseña fue restaurada!',
|
||||
|
||||
];
|
||||
115
resources/lang/es_AR/settings.php
Normal file
115
resources/lang/es_AR/settings.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/**
|
||||
* Settings text strings
|
||||
* Contains all text strings used in the general settings sections of BookStack
|
||||
* including users and roles.
|
||||
*/
|
||||
|
||||
'settings' => 'Ajustes',
|
||||
'settings_save' => 'Guardar ajustes',
|
||||
'settings_save_success' => 'Ajustes guardados',
|
||||
|
||||
/**
|
||||
* App settings
|
||||
*/
|
||||
|
||||
'app_settings' => 'Ajustes de Aplicación',
|
||||
'app_name' => 'Nombre de aplicación',
|
||||
'app_name_desc' => 'Este nombre se muestra en la cabecera y en cualquier correo electrónico de la aplicación',
|
||||
'app_name_header' => '¿Mostrar el nombre de la aplicación en la cabecera?',
|
||||
'app_public_viewing' => '¿Permitir vista pública?',
|
||||
'app_secure_images' => '¿Habilitar mayor seguridad para subir imágenes?',
|
||||
'app_secure_images_desc' => 'Por razones de rendimiento, todas las imágenes son públicas. Esta opción agrega una cadena larga difícil de adivinar, asegúrese que los índices de directorios no están habilitados para prevenir el acceso fácil a las imágenes.',
|
||||
'app_editor' => 'Editor de página',
|
||||
'app_editor_desc' => 'Seleccione cuál editor será usado por todos los usuarios para editar páginas.',
|
||||
'app_custom_html' => 'Contenido de cabecera HTML personalizable',
|
||||
'app_custom_html_desc' => 'Cualquier contenido agregado aquí será agregado al final de la sección <head> de cada página. Esto es útil para sobreescribir estilos o agregar código para analíticas.',
|
||||
'app_logo' => 'Logo de la aplicación',
|
||||
'app_logo_desc' => 'Esta imagen debería ser de 43px en altura. <br>Las imágenes grandes seán escaladas.',
|
||||
'app_primary_color' => 'Color primario de la aplicación',
|
||||
'app_primary_color_desc' => 'Esto debería ser un valor hexadecimal. <br>Deje el valor vacío para reiniciar al valor por defecto.',
|
||||
'app_homepage' => 'Página de inicio de la Aplicación',
|
||||
'app_homepage_desc' => 'Seleccione una página de inicio para mostrar en lugar de la vista por defecto. Se ignoran los permisos de página para las páginas seleccionadas.',
|
||||
'app_homepage_default' => 'Página de inicio por defecto seleccionadad',
|
||||
|
||||
/**
|
||||
* Registration settings
|
||||
*/
|
||||
|
||||
'reg_settings' => 'Ajustes de registro',
|
||||
'reg_allow' => '¿Permitir registro?',
|
||||
'reg_default_role' => 'Rol de usuario por defecto despúes del registro',
|
||||
'reg_confirm_email' => '¿Requerir correo electrónico de confirmación?',
|
||||
'reg_confirm_email_desc' => 'Si se utiliza la restricción por dominio, entonces se requerirá la confirmación por correo electrónico y se ignorará el valor a continuación.',
|
||||
'reg_confirm_restrict_domain' => 'Restringir registro al dominio',
|
||||
'reg_confirm_restrict_domain_desc' => 'Introduzca una lista separada por comas de los correos electrónicos del dominio a los que les gustaría restringir el registro por dominio. A los usuarios les será enviado un correo elctrónico para confirmar la dirección antes de que se le permita interactuar con la aplicación. <br> Note que a los usuarios se les permitirá cambiar sus direcciones de correo electrónico luego de un registro éxioso.',
|
||||
'reg_confirm_restrict_domain_placeholder' => 'Ninguna restricción establecida',
|
||||
|
||||
/**
|
||||
* Role settings
|
||||
*/
|
||||
|
||||
'roles' => 'Roles',
|
||||
'role_user_roles' => 'Roles de usuario',
|
||||
'role_create' => 'Crear nuevo rol',
|
||||
'role_create_success' => 'Rol creado satisfactoriamente',
|
||||
'role_delete' => 'Borrar rol',
|
||||
'role_delete_confirm' => 'Se borrará el rol con nombre \':roleName\'.',
|
||||
'role_delete_users_assigned' => 'Este rol tiene :userCount usuarios asignados. Si ud. quisiera migrar los usuarios de este rol, seleccione un nuevo rol a continuación.',
|
||||
'role_delete_no_migration' => "No migrar usuarios",
|
||||
'role_delete_sure' => '¿Está seguro que desea borrar este rol?',
|
||||
'role_delete_success' => 'Rol borrado satisfactoriamente',
|
||||
'role_edit' => 'Editar rol',
|
||||
'role_details' => 'Detalles de rol',
|
||||
'role_name' => 'Nombre de rol',
|
||||
'role_desc' => 'Descripción corta de rol',
|
||||
'role_system' => 'Permisos de sistema',
|
||||
'role_manage_users' => 'Gestionar usuarios',
|
||||
'role_manage_roles' => 'Gestionar roles y permisos de roles',
|
||||
'role_manage_entity_permissions' => 'Gestionar todos los permisos de libros, capítulos y páginas',
|
||||
'role_manage_own_entity_permissions' => 'Gestionar permisos en libros propios, capítulos y páginas',
|
||||
'role_manage_settings' => 'Gestionar ajustes de activos',
|
||||
'role_asset' => 'Permisos de activos',
|
||||
'role_asset_desc' => 'Estos permisos controlan el acceso por defecto a los activos del sistema. Permisos a Libros, Capítulos y Páginas sobreescribiran estos permisos.',
|
||||
'role_all' => 'Todo',
|
||||
'role_own' => 'Propio',
|
||||
'role_controlled_by_asset' => 'Controlado por el activo al que ha sido subido',
|
||||
'role_save' => 'Guardar rol',
|
||||
'role_update_success' => 'Rol actualizado exitosamente',
|
||||
'role_users' => 'Usuarios en este rol',
|
||||
'role_users_none' => 'No hay usuarios asignados a este rol',
|
||||
|
||||
/**
|
||||
* Users
|
||||
*/
|
||||
|
||||
'users' => 'Usuarios',
|
||||
'user_profile' => 'Perfil de usuario',
|
||||
'users_add_new' => 'Agregar nuevo usuario',
|
||||
'users_search' => 'Buscar usuarios',
|
||||
'users_role' => 'Roles de usuario',
|
||||
'users_external_auth_id' => 'ID externo de autenticación',
|
||||
'users_password_warning' => 'Solo rellene a continuación si desea cambiar su password:',
|
||||
'users_system_public' => 'Este usuario representa cualquier usuario invitado que visita la aplicación. No puede utilizarse para hacer login sino que es asignado automáticamente.',
|
||||
'users_delete' => 'Borrar usuario',
|
||||
'users_delete_named' => 'Borrar usuario :userName',
|
||||
'users_delete_warning' => 'Se borrará completamente el usuario con el nombre \':userName\' del sistema.',
|
||||
'users_delete_confirm' => '¿Está seguro que desea borrar este usuario?',
|
||||
'users_delete_success' => 'Usuarios removidos exitosamente',
|
||||
'users_edit' => 'Editar Usuario',
|
||||
'users_edit_profile' => 'Editar perfil',
|
||||
'users_edit_success' => 'Usuario actualizado',
|
||||
'users_avatar' => 'Avatar del usuario',
|
||||
'users_avatar_desc' => 'Esta imagen debe ser de aproximadamente 256px por lado.',
|
||||
'users_preferred_language' => 'Lenguaje preferido',
|
||||
'users_social_accounts' => 'Cuentas sociales',
|
||||
'users_social_accounts_info' => 'Aquí puede conectar sus otras cuentas para un acceso rápido y más fácil. Desconectando una cuenta aquí no revoca accesos ya autorizados. Revoque el acceso desde los ajustes de perfil en la cuenta social conectada.',
|
||||
'users_social_connect' => 'Conectar cuenta',
|
||||
'users_social_disconnect' => 'Desconectar cuenta',
|
||||
'users_social_connected' => 'La cuenta :socialAccount ha sido exitosamente añadida a su perfil.',
|
||||
'users_social_disconnected' => 'La cuenta :socialAccount ha sido desconectada exitosamente de su perfil.',
|
||||
|
||||
];
|
||||
108
resources/lang/es_AR/validation.php
Normal file
108
resources/lang/es_AR/validation.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines contain the default error messages used by
|
||||
| the validator class. Some of these rules have multiple versions such
|
||||
| as the size rules. Feel free to tweak each of these messages here.
|
||||
|
|
||||
*/
|
||||
|
||||
'accepted' => 'El :attribute debe ser aceptado.',
|
||||
'active_url' => 'El :attribute no es una URl válida.',
|
||||
'after' => 'El :attribute debe ser una fecha posterior :date.',
|
||||
'alpha' => 'El :attribute solo puede contener letras.',
|
||||
'alpha_dash' => 'El :attribute solo puede contener letras, números y guiones.',
|
||||
'alpha_num' => 'El :attribute solo puede contener letras y número.',
|
||||
'array' => 'El :attribute debe de ser un array.',
|
||||
'before' => 'El :attribute debe ser una fecha anterior a :date.',
|
||||
'between' => [
|
||||
'numeric' => 'El :attribute debe estar entre :min y :max.',
|
||||
'file' => 'El :attribute debe estar entre :min y :max kilobytes.',
|
||||
'string' => 'El :attribute debe estar entre :min y :max carácteres.',
|
||||
'array' => 'El :attribute debe estar entre :min y :max items.',
|
||||
],
|
||||
'boolean' => 'El campo :attribute debe ser true o false.',
|
||||
'confirmed' => 'La confirmación de :attribute no concuerda.',
|
||||
'date' => 'El :attribute no es una fecha válida.',
|
||||
'date_format' => 'El :attribute no coincide con el formato :format.',
|
||||
'different' => ':attribute y :other deben ser diferentes.',
|
||||
'digits' => ':attribute debe ser de :digits dígitos.',
|
||||
'digits_between' => ':attribute debe ser un valor entre :min y :max dígios.',
|
||||
'email' => ':attribute debe ser una dirección álida.',
|
||||
'filled' => 'El campo :attribute es requerido.',
|
||||
'exists' => 'El :attribute seleccionado es inválido.',
|
||||
'image' => 'El :attribute debe ser una imagen.',
|
||||
'in' => 'El selected :attribute es inválio.',
|
||||
'integer' => 'El :attribute debe ser un entero.',
|
||||
'ip' => 'El :attribute debe ser una dirección IP álida.',
|
||||
'max' => [
|
||||
'numeric' => ':attribute no puede ser mayor que :max.',
|
||||
'file' => ':attribute no puede ser mayor que :max kilobytes.',
|
||||
'string' => ':attribute no puede ser mayor que :max carácteres.',
|
||||
'array' => ':attribute no puede contener más de :max items.',
|
||||
],
|
||||
'mimes' => ':attribute debe ser un fichero de tipo: :values.',
|
||||
'min' => [
|
||||
'numeric' => ':attribute debe ser al menos de :min.',
|
||||
'file' => ':attribute debe ser al menos :min kilobytes.',
|
||||
'string' => ':attribute debe ser al menos :min caracteres.',
|
||||
'array' => ':attribute debe tener como mínimo :min items.',
|
||||
],
|
||||
'not_in' => ':attribute seleccionado es inválio.',
|
||||
'numeric' => ':attribute debe ser numérico.',
|
||||
'regex' => ':attribute con formato inválido',
|
||||
'required' => ':attribute es requerido.',
|
||||
'required_if' => ':attribute es requerido cuando :other vale :value.',
|
||||
'required_with' => 'El campo :attribute es requerido cuando se encuentre entre los valores :values.',
|
||||
'required_with_all' => 'El campo :attribute es requerido cuando los valores sean :values.',
|
||||
'required_without' => ':attribute es requerido cuando no se encuentre entre los valores :values.',
|
||||
'required_without_all' => ':attribute es requerido cuando ninguno de los valores :values están presentes.',
|
||||
'same' => ':attribute y :other deben coincidir.',
|
||||
'size' => [
|
||||
'numeric' => ':attribute debe ser :size.',
|
||||
'file' => ':attribute debe ser :size kilobytes.',
|
||||
'string' => ':attribute debe ser :size caracteres.',
|
||||
'array' => ':attribute debe contener :size items.',
|
||||
],
|
||||
'string' => 'El atributo :attribute debe ser una cadena.',
|
||||
'timezone' => 'El atributo :attribute debe ser una zona válida.',
|
||||
'unique' => 'El atributo :attribute ya ha sido tomado.',
|
||||
'url' => 'El atributo :attribute tiene un formato inválid.',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify custom validation messages for attributes using the
|
||||
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||
| specify a specific custom language line for a given attribute rule.
|
||||
|
|
||||
*/
|
||||
|
||||
'custom' => [
|
||||
'password-confirm' => [
|
||||
'required_with' => 'Confirmación de Password requerida',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Attributes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used to swap attribute place-holders
|
||||
| with something more reader friendly such as E-Mail Address instead
|
||||
| of "email". This simply helps us make messages a little cleaner.
|
||||
|
|
||||
*/
|
||||
|
||||
'attributes' => [],
|
||||
|
||||
];
|
||||
@@ -37,4 +37,6 @@ return [
|
||||
'book_sort' => 'ha ordinato il libro',
|
||||
'book_sort_notification' => 'Libro Riordinato Correttamente',
|
||||
|
||||
// Other
|
||||
'commented_on' => 'ha commentato in',
|
||||
];
|
||||
|
||||
@@ -29,6 +29,7 @@ return [
|
||||
'edit' => 'Modifica',
|
||||
'sort' => 'Ordina',
|
||||
'move' => 'Muovi',
|
||||
'reply' => 'Rispondi',
|
||||
'delete' => 'Elimina',
|
||||
'search' => 'Cerca',
|
||||
'search_clear' => 'Pulisci Ricerca',
|
||||
|
||||
@@ -19,7 +19,6 @@ return [
|
||||
'meta_created_name' => 'Creato :timeLength da :user',
|
||||
'meta_updated' => 'Aggiornato :timeLength',
|
||||
'meta_updated_name' => 'Aggiornato :timeLength da :user',
|
||||
'x_pages' => ':count Pagine',
|
||||
'entity_select' => 'Selezione Entità',
|
||||
'images' => 'Immagini',
|
||||
'my_recent_drafts' => 'Bozze Recenti',
|
||||
@@ -70,6 +69,7 @@ return [
|
||||
*/
|
||||
'book' => 'Libro',
|
||||
'books' => 'Libri',
|
||||
'x_books' => ':count Libro|:count Libri',
|
||||
'books_empty' => 'Nessun libro è stato creato',
|
||||
'books_popular' => 'Libri Popolari',
|
||||
'books_recent' => 'Libri Recenti',
|
||||
@@ -105,6 +105,7 @@ return [
|
||||
*/
|
||||
'chapter' => 'Capitolo',
|
||||
'chapters' => 'Capitoli',
|
||||
'x_chapters' => ':count Capitolo|:count Capitoli',
|
||||
'chapters_popular' => 'Capitoli Popolari',
|
||||
'chapters_new' => 'Nuovo Capitolo',
|
||||
'chapters_create' => 'Crea un nuovo capitolo',
|
||||
@@ -129,20 +130,21 @@ return [
|
||||
*/
|
||||
'page' => 'Pagina',
|
||||
'pages' => 'Pagine',
|
||||
'x_pages' => ':count Pagina|:count Pagine',
|
||||
'pages_popular' => 'Pagine Popolari',
|
||||
'pages_new' => 'Nuova Pagina',
|
||||
'pages_attachments' => 'Allegati',
|
||||
'pages_navigation' => 'Page Navigation',
|
||||
'pages_navigation' => 'Navigazione Pagine',
|
||||
'pages_delete' => 'Elimina Pagina',
|
||||
'pages_delete_named' => 'Elimina la pagina :pageName',
|
||||
'pages_delete_draft_named' => 'Delete Draft Page :pageName',
|
||||
'pages_delete_draft_named' => 'Elimina bozza della pagina :pageName',
|
||||
'pages_delete_draft' => 'Elimina Bozza Pagina',
|
||||
'pages_delete_success' => 'Pagina eliminata',
|
||||
'pages_delete_draft_success' => 'Bozza di una pagina eliminata',
|
||||
'pages_delete_confirm' => 'Sei sicuro di voler eliminare questa pagina?',
|
||||
'pages_delete_draft_confirm' => 'Sei sicuro di voler eliminare la bozza di questa pagina?',
|
||||
'pages_editing_named' => 'Modifica :pageName',
|
||||
'pages_edit_toggle_header' => 'Toggle header',
|
||||
'pages_edit_toggle_header' => 'Mostra/Nascondi header',
|
||||
'pages_edit_save_draft' => 'Salva Bozza',
|
||||
'pages_edit_draft' => 'Modifica Bozza della pagina',
|
||||
'pages_editing_draft' => 'Modifica Bozza',
|
||||
@@ -164,7 +166,7 @@ return [
|
||||
'pages_move' => 'Muovi Pagina',
|
||||
'pages_move_success' => 'Pagina mossa in ":parentName"',
|
||||
'pages_permissions' => 'Permessi Pagina',
|
||||
'pages_permissions_success' => 'Page permissions updated',
|
||||
'pages_permissions_success' => 'Permessi pagina aggiornati',
|
||||
'pages_revision' => 'Versione',
|
||||
'pages_revisions' => 'Versioni Pagina',
|
||||
'pages_revisions_named' => 'Versioni della pagina :pageName',
|
||||
@@ -242,10 +244,17 @@ return [
|
||||
*/
|
||||
'comment' => 'Commento',
|
||||
'comments' => 'Commenti',
|
||||
'comment_count' => '1 Commento|:count Commenti',
|
||||
'comment_placeholder' => 'Scrivi un commento',
|
||||
'comment_count' => '{0} Nessun Commento|{1} 1 Commento|[2,*] :count Commenti',
|
||||
'comment_save' => 'Salva Commento',
|
||||
'comment_saving' => 'Salvataggio commento...',
|
||||
'comment_deleting' => 'Eliminazione commento...',
|
||||
'comment_new' => 'Nuovo Commento',
|
||||
'comment_created' => 'ha commentato :createDiff',
|
||||
'comment_updated' => 'Aggiornato :updateDiff da :username',
|
||||
'comment_deleted_success' => 'Commento eliminato',
|
||||
'comment_created_success' => 'Commento aggiunto',
|
||||
'comment_updated_success' => 'Commento aggiornato',
|
||||
'comment_delete_confirm' => 'Questo rimuoverà il contenuto del commento?',
|
||||
'comment_delete_confirm' => 'Sei sicuro di voler elminare questo commento?',
|
||||
'comment_in_reply_to' => 'In risposta a :commentId',
|
||||
];
|
||||
@@ -37,4 +37,6 @@ return [
|
||||
'book_sort' => 'sorteerde boek',
|
||||
'book_sort_notification' => 'Boek Succesvol Gesorteerd',
|
||||
|
||||
// Other
|
||||
'commented_on' => 'reactie op',
|
||||
];
|
||||
|
||||
@@ -10,6 +10,7 @@ return [
|
||||
'save' => 'Opslaan',
|
||||
'continue' => 'Doorgaan',
|
||||
'select' => 'Kies',
|
||||
'more' => 'Meer',
|
||||
|
||||
/**
|
||||
* Form Labels
|
||||
@@ -33,7 +34,7 @@ return [
|
||||
'search_clear' => 'Zoekopdracht wissen',
|
||||
'reset' => 'Reset',
|
||||
'remove' => 'Verwijderen',
|
||||
|
||||
'add' => 'Toevoegen',
|
||||
|
||||
/**
|
||||
* Misc
|
||||
|
||||
@@ -20,5 +20,12 @@ return [
|
||||
'image_preview' => 'Afbeelding Voorbeeld',
|
||||
'image_upload_success' => 'Afbeelding succesvol geüpload',
|
||||
'image_update_success' => 'Afbeeldingsdetails succesvol verwijderd',
|
||||
'image_delete_success' => 'Afbeelding succesvol verwijderd'
|
||||
];
|
||||
'image_delete_success' => 'Afbeelding succesvol verwijderd',
|
||||
/**
|
||||
* Code editor
|
||||
*/
|
||||
'code_editor' => 'Code invoegen',
|
||||
'code_language' => 'Code taal',
|
||||
'code_content' => 'Code',
|
||||
'code_save' => 'Sla code op',
|
||||
];
|
||||
|
||||
@@ -14,6 +14,7 @@ return [
|
||||
'recent_activity' => 'Recente Activiteit',
|
||||
'create_now' => 'Maak er zelf één',
|
||||
'revisions' => 'Revisies',
|
||||
'meta_revision' => 'Revisie #:revisionCount',
|
||||
'meta_created' => 'Aangemaakt :timeLength',
|
||||
'meta_created_name' => 'Aangemaakt: :timeLength door :user',
|
||||
'meta_updated' => ':timeLength Aangepast',
|
||||
@@ -43,18 +44,37 @@ return [
|
||||
* Search
|
||||
*/
|
||||
'search_results' => 'Zoekresultaten',
|
||||
'search_total_results_found' => ':count resultaten gevonden|:count resultaten gevonden',
|
||||
'search_clear' => 'Zoekopdracht wissen',
|
||||
'search_no_pages' => 'Er zijn geen pagina\'s gevonden',
|
||||
'search_for_term' => 'Zoeken op :term',
|
||||
'search_more' => 'Meer resultaten',
|
||||
'search_filters' => 'Zoek filters',
|
||||
'search_content_type' => 'Content Type',
|
||||
'search_exact_matches' => 'Exacte Matches',
|
||||
'search_tags' => 'Zoek tags',
|
||||
'search_viewed_by_me' => 'Bekeken door mij',
|
||||
'search_not_viewed_by_me' => 'Niet bekeken door mij',
|
||||
'search_permissions_set' => 'Permissies gezet',
|
||||
'search_created_by_me' => 'Door mij gemaakt',
|
||||
'search_updated_by_me' => 'Door mij geupdate',
|
||||
'search_updated_before' => 'Geupdate voor',
|
||||
'search_updated_after' => 'Geupdate na',
|
||||
'search_created_before' => 'Gecreeerd voor',
|
||||
'search_created_after' => 'Gecreeerd na',
|
||||
'search_set_date' => 'Zet datum',
|
||||
'search_update' => 'Update zoekresultaten',
|
||||
|
||||
/**
|
||||
* Books
|
||||
*/
|
||||
'book' => 'Boek',
|
||||
'books' => 'Boeken',
|
||||
'x_books' => ':count Boek|:count Boeken',
|
||||
'books_empty' => 'Er zijn geen boeken aangemaakt',
|
||||
'books_popular' => 'Populaire Boeken',
|
||||
'books_recent' => 'Recente Boeken',
|
||||
'books_new' => 'Nieuwe Boeken',
|
||||
'books_popular_empty' => 'De meest populaire boeken worden hier weergegeven.',
|
||||
'books_create' => 'Nieuw Boek Aanmaken',
|
||||
'books_delete' => 'Boek Verwijderen',
|
||||
@@ -85,6 +105,7 @@ return [
|
||||
*/
|
||||
'chapter' => 'Hoofdstuk',
|
||||
'chapters' => 'Hoofdstukken',
|
||||
'x_chapters' => ':count Hoofdstuk|:count Hoofdstukken',
|
||||
'chapters_popular' => 'Populaire Hoofdstukken',
|
||||
'chapters_new' => 'Nieuw Hoofdstuk',
|
||||
'chapters_create' => 'Hoofdstuk Toevoegen',
|
||||
@@ -103,12 +124,14 @@ return [
|
||||
'chapters_empty' => 'Er zijn geen pagina\'s in dit hoofdstuk aangemaakt.',
|
||||
'chapters_permissions_active' => 'Hoofdstuk Permissies Actief',
|
||||
'chapters_permissions_success' => 'Hoofdstuk Permissies Bijgewerkt',
|
||||
'chapters_search_this' => 'Doorzoek dit hoofdstuk',
|
||||
|
||||
/**
|
||||
* Pages
|
||||
*/
|
||||
'page' => 'Pagina',
|
||||
'pages' => 'Pagina\'s',
|
||||
'x_pages' => ':count Pagina|:count Pagina\'s',
|
||||
'pages_popular' => 'Populaire Pagina\'s',
|
||||
'pages_new' => 'Nieuwe Pagina',
|
||||
'pages_attachments' => 'Bijlages',
|
||||
@@ -122,7 +145,7 @@ return [
|
||||
'pages_delete_confirm' => 'Weet je zeker dat je deze pagina wilt verwijderen?',
|
||||
'pages_delete_draft_confirm' => 'Weet je zeker dat je dit concept wilt verwijderen?',
|
||||
'pages_editing_named' => 'Pagina :pageName Bewerken',
|
||||
'pages_edit_toggle_header' => 'Toggle header',
|
||||
'pages_edit_toggle_header' => 'Wissel header',
|
||||
'pages_edit_save_draft' => 'Concept opslaan',
|
||||
'pages_edit_draft' => 'Paginaconcept Bewerken',
|
||||
'pages_editing_draft' => 'Concept Bewerken',
|
||||
@@ -132,12 +155,12 @@ return [
|
||||
'pages_edit_discard_draft' => 'Concept Verwijderen',
|
||||
'pages_edit_set_changelog' => 'Changelog',
|
||||
'pages_edit_enter_changelog_desc' => 'Geef een korte omschrijving van de wijzingen die je gemaakt hebt.',
|
||||
'pages_edit_enter_changelog' => 'Enter Changelog',
|
||||
'pages_edit_enter_changelog' => 'Zie logboek',
|
||||
'pages_save' => 'Pagina Opslaan',
|
||||
'pages_title' => 'Pagina Titel',
|
||||
'pages_name' => 'Pagina Naam',
|
||||
'pages_md_editor' => 'Bewerker',
|
||||
'pages_md_preview' => 'Preview',
|
||||
'pages_md_preview' => 'Voorbeeld',
|
||||
'pages_md_insert_image' => 'Afbeelding Invoegen',
|
||||
'pages_md_insert_link' => 'Entity Link Invoegen',
|
||||
'pages_not_in_chapter' => 'Deze pagina staat niet in een hoofdstuk',
|
||||
@@ -145,11 +168,13 @@ return [
|
||||
'pages_move_success' => 'Pagina verplaatst naar ":parentName"',
|
||||
'pages_permissions' => 'Pagina Permissies',
|
||||
'pages_permissions_success' => 'Pagina Permissies bijgwerkt',
|
||||
'pages_revision' => 'Revisie',
|
||||
'pages_revisions' => 'Pagina Revisies',
|
||||
'pages_revisions_named' => 'Pagina Revisies voor :pageName',
|
||||
'pages_revision_named' => 'Pagina Revisie voor :pageName',
|
||||
'pages_revisions_created_by' => 'Aangemaakt door',
|
||||
'pages_revisions_date' => 'Revisiedatum',
|
||||
'pages_revisions_number' => '#',
|
||||
'pages_revisions_changelog' => 'Changelog',
|
||||
'pages_revisions_changes' => 'Wijzigingen',
|
||||
'pages_revisions_current' => 'Huidige Versie',
|
||||
@@ -218,8 +243,19 @@ return [
|
||||
/**
|
||||
* Comments
|
||||
*/
|
||||
'comment' => 'Commentaar',
|
||||
'comments' => 'Commentaren',
|
||||
'comment_placeholder' => 'Vul hier uw reacties in',
|
||||
'comment_save' => 'Opslaan opslaan',
|
||||
];
|
||||
'comment' => 'Reactie',
|
||||
'comments' => 'Reacties',
|
||||
'comment_placeholder' => 'Laat hier een reactie achter',
|
||||
'comment_count' => '{0} Geen reacties|{1} 1 Reactie|[2,*] :count Reacties',
|
||||
'comment_save' => 'Sla reactie op',
|
||||
'comment_saving' => 'Opslaan van reactie...',
|
||||
'comment_deleting' => 'Verwijderen van reactie...',
|
||||
'comment_new' => 'Nieuwe reactie',
|
||||
'comment_created' => 'reactie gegeven :createDiff',
|
||||
'comment_updated' => 'Update :updateDiff door :username',
|
||||
'comment_deleted_success' => 'Reactie verwijderd',
|
||||
'comment_created_success' => 'Reactie toegevoegd',
|
||||
'comment_updated_success' => 'Reactie bijgewerkt',
|
||||
'comment_delete_confirm' => 'Zeker reactie verwijderen?',
|
||||
'comment_in_reply_to' => 'Antwoord op :commentId',
|
||||
];
|
||||
|
||||
@@ -60,6 +60,12 @@ return [
|
||||
'role_system_cannot_be_deleted' => 'Dit is een systeemrol en kan niet verwijderd worden',
|
||||
'role_registration_default_cannot_delete' => 'Deze rol kan niet verwijerd worden zolang dit de standaardrol na registratie is.',
|
||||
|
||||
// Comments
|
||||
'comment_list' => 'Er is een fout opgetreden tijdens het ophalen van de reacties.',
|
||||
'cannot_add_comment_to_draft' => 'U kunt geen reacties toevoegen aan een concept.',
|
||||
'comment_add' => 'Er is een fout opgetreden tijdens het toevoegen van de reactie.',
|
||||
'comment_delete' => 'Er is een fout opgetreden tijdens het verwijderen van de reactie.',
|
||||
'empty_comment' => 'Kan geen lege reactie toevoegen.',
|
||||
// Error pages
|
||||
'404_page_not_found' => 'Pagina Niet Gevonden',
|
||||
'sorry_page_not_found' => 'Sorry, de pagina die je zocht is niet beschikbaar.',
|
||||
@@ -67,11 +73,4 @@ return [
|
||||
'error_occurred' => 'Er Ging Iets Fout',
|
||||
'app_down' => ':appName is nu niet beschikbaar',
|
||||
'back_soon' => 'Komt snel weer online.',
|
||||
|
||||
// Comments
|
||||
'comment_list' => 'Er is een fout opgetreden tijdens het ophalen van de reacties.',
|
||||
'cannot_add_comment_to_draft' => 'U kunt geen reacties toevoegen aan een ontwerp.',
|
||||
'comment_add' => 'Er is een fout opgetreden tijdens het toevoegen van de reactie.',
|
||||
'comment_delete' => 'Er is een fout opgetreden tijdens het verwijderen van de reactie.',
|
||||
'empty_comment' => 'Kan geen lege reactie toevoegen.',
|
||||
];
|
||||
42
resources/lang/ru/activities.php
Normal file
42
resources/lang/ru/activities.php
Normal file
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/**
|
||||
* Activity text strings.
|
||||
* Is used for all the text within activity logs & notifications.
|
||||
*/
|
||||
|
||||
// Pages
|
||||
'page_create' => 'создал страницу',
|
||||
'page_create_notification' => 'Страница успешно создана',
|
||||
'page_update' => 'обновил страницу',
|
||||
'page_update_notification' => 'Станица успешно обновлена',
|
||||
'page_delete' => 'удалил страницу',
|
||||
'page_delete_notification' => 'Старница успешно удалена',
|
||||
'page_restore' => 'восстановил страницу',
|
||||
'page_restore_notification' => 'Страница успешно восстановлена',
|
||||
'page_move' => 'переместил страницу',
|
||||
|
||||
// Chapters
|
||||
'chapter_create' => 'создал главу',
|
||||
'chapter_create_notification' => 'глава успешно создана',
|
||||
'chapter_update' => 'обновил главу',
|
||||
'chapter_update_notification' => 'Глава успешно обновленна',
|
||||
'chapter_delete' => 'удалил главу',
|
||||
'chapter_delete_notification' => 'Глава успешно удалено',
|
||||
'chapter_move' => 'переместил главу',
|
||||
|
||||
// Books
|
||||
'book_create' => 'создал книгу',
|
||||
'book_create_notification' => 'Книга успешно создана',
|
||||
'book_update' => 'обновил книгу',
|
||||
'book_update_notification' => 'Книга успешно обновлена',
|
||||
'book_delete' => 'удалил книгу',
|
||||
'book_delete_notification' => 'Книга успешно удалена',
|
||||
'book_sort' => 'отсортировал книгу',
|
||||
'book_sort_notification' => 'Книга успешно отсортирована',
|
||||
|
||||
// Other
|
||||
'commented_on' => 'прокомментировал',
|
||||
];
|
||||
76
resources/lang/ru/auth.php
Normal file
76
resources/lang/ru/auth.php
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
return [
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Authentication Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used during authentication for various
|
||||
| messages that we need to display to the user. You are free to modify
|
||||
| these language lines according to your application's requirements.
|
||||
|
|
||||
*/
|
||||
'failed' => 'Учётная запись не найдена.',
|
||||
'throttle' => 'Слишком много попыток входа. Пожалуйста, попробуйте позже через :seconds секунд.',
|
||||
|
||||
/**
|
||||
* Login & Register
|
||||
*/
|
||||
'sign_up' => 'Регистрация',
|
||||
'log_in' => 'Вход',
|
||||
'log_in_with' => 'Вход с :socialDriver',
|
||||
'sign_up_with' => 'Регистрация с :socialDriver',
|
||||
'logout' => 'Выход',
|
||||
|
||||
'name' => 'Имя',
|
||||
'username' => 'Логин',
|
||||
'email' => 'Е-мэйл',
|
||||
'password' => 'Пароль',
|
||||
'password_confirm' => 'Подтверждение пароля',
|
||||
'password_hint' => 'Должен быть больше 5 символов',
|
||||
'forgot_password' => 'Забыли пароль?',
|
||||
'remember_me' => 'Запомнить меня',
|
||||
'ldap_email_hint' => 'Введите email адрес для данной учётной записи.',
|
||||
'create_account' => 'Создать аккаунт',
|
||||
'social_login' => 'Вход через Соцсеть',
|
||||
'social_registration' => 'Регистрация через Соцсеть',
|
||||
'social_registration_text' => 'Регистрация и вход через другой сервис.',
|
||||
|
||||
'register_thanks' => 'Благодарим за регистрацию!',
|
||||
'register_confirm' => 'Проверьте свою электронную почту и нажмите кнопку подтверждения для доступа к :appName.',
|
||||
'registrations_disabled' => 'Регистрация отключена',
|
||||
'registration_email_domain_invalid' => 'Данный домен электрронной почты не доступен для регистрации',
|
||||
'register_success' => 'Спасибо за регистрацию! Регистрация и вход в систему выполнены.',
|
||||
|
||||
|
||||
/**
|
||||
* Password Reset
|
||||
*/
|
||||
'reset_password' => 'Сброс пароля',
|
||||
'reset_password_send_instructions' => 'Введите свой адрес электронной почты ниже, и вам будет отправлено электронное письмо с ссылкой для сброса пароля.',
|
||||
'reset_password_send_button' => 'Отправить ссылку для сброса',
|
||||
'reset_password_sent_success' => 'Ссылка для сброса была отправлена на :email.',
|
||||
'reset_password_success' => 'Ваш пароль был успешно сброшен.',
|
||||
|
||||
'email_reset_subject' => 'Сбросить ваш :appName пароль',
|
||||
'email_reset_text' => 'Вы получили это электронное письмо, потому что мы получили запрос на сброс пароля для вашей учетной записи.',
|
||||
'email_reset_not_requested' => 'Если вы не запрашивали сброса пароля, то никаких дополнительных действий не требуется.',
|
||||
|
||||
|
||||
/**
|
||||
* Email Confirmation
|
||||
*/
|
||||
'email_confirm_subject' => 'Подтвердите ваш почтовый адрес на :appName',
|
||||
'email_confirm_greeting' => 'Благодарим за участие :appName!',
|
||||
'email_confirm_text' => 'Пожалуйста, подтвердите ваш почтовый адрес кликнув на кнопку ниже:',
|
||||
'email_confirm_action' => 'Подтвердить е-мэйл',
|
||||
'email_confirm_send_error' => 'Требуется подтверждение электронной почты, но система не может отправить электронное письмо. Свяжитесь с администратором, чтобы убедиться, что адрес электронной почты настроен правильно.',
|
||||
'email_confirm_success' => 'Ваш е-мэйл был подтверждён!',
|
||||
'email_confirm_resent' => 'Письмо с подтверждение выслано снова. Пожалуйста, проверьте ваш почтовый ящик.',
|
||||
|
||||
'email_not_confirmed' => 'Е-мэйл не подтверждён',
|
||||
'email_not_confirmed_text' => 'Ваш email адрес всё ещё не подтверждён.',
|
||||
'email_not_confirmed_click_link' => 'Пожалуйста, нажмите на ссылку в письме, которое было отправлено при регистрации.',
|
||||
'email_not_confirmed_resend' => 'Если вы не можете найти электронное письмо, вы можете снова отправить письмо с подтверждением по форме ниже.',
|
||||
'email_not_confirmed_resend_button' => 'Переотправить письмо с подтверждёнием',
|
||||
];
|
||||
61
resources/lang/ru/common.php
Normal file
61
resources/lang/ru/common.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
return [
|
||||
|
||||
/**
|
||||
* Buttons
|
||||
*/
|
||||
'cancel' => 'Отмена',
|
||||
'confirm' => 'Применить',
|
||||
'back' => 'Назад',
|
||||
'save' => 'Сохранить',
|
||||
'continue' => 'Продолжить',
|
||||
'select' => 'Выбрать',
|
||||
'more' => 'Ещё',
|
||||
|
||||
/**
|
||||
* Form Labels
|
||||
*/
|
||||
'name' => 'Имя',
|
||||
'description' => 'Описание',
|
||||
'role' => 'Роль',
|
||||
|
||||
/**
|
||||
* Actions
|
||||
*/
|
||||
'actions' => 'Действия',
|
||||
'view' => 'Просмотр',
|
||||
'create' => 'Создание',
|
||||
'update' => 'Обновление',
|
||||
'edit' => 'Редактировать',
|
||||
'sort' => 'Сортировать',
|
||||
'move' => 'Переместить',
|
||||
'reply' => 'Ответить',
|
||||
'delete' => 'Удалить',
|
||||
'search' => 'Поиск',
|
||||
'search_clear' => 'Очистить поиск',
|
||||
'reset' => 'Сбросить',
|
||||
'remove' => 'Удалить',
|
||||
'add' => 'Добавить',
|
||||
|
||||
/**
|
||||
* Misc
|
||||
*/
|
||||
'deleted_user' => 'Удалённый пользователь',
|
||||
'no_activity' => 'Нет действий для просмотра',
|
||||
'no_items' => 'Нет доступных элементов',
|
||||
'back_to_top' => 'Вернуться наверх',
|
||||
'toggle_details' => 'Подробности',
|
||||
'details' => 'Детали',
|
||||
|
||||
/**
|
||||
* Header
|
||||
*/
|
||||
'view_profile' => 'Просмотреть профиль',
|
||||
'edit_profile' => 'Редактировать профиль',
|
||||
|
||||
/**
|
||||
* Email Content
|
||||
*/
|
||||
'email_action_help' => 'Если у вас возникли проблемы с нажатием кнопки ":actionText", то скопируйте и вставьте указанный URL-адрес в свой веб-браузер:',
|
||||
'email_rights' => 'Все прова зарезервированы',
|
||||
];
|
||||
25
resources/lang/ru/components.php
Normal file
25
resources/lang/ru/components.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
return [
|
||||
|
||||
/**
|
||||
* Image Manager
|
||||
*/
|
||||
'image_select' => 'Выбрать изображение',
|
||||
'image_all' => 'Все',
|
||||
'image_all_title' => 'Простмотр всех изображений',
|
||||
'image_book_title' => 'Просмотр всех изображений загруженных в эту книгу',
|
||||
'image_page_title' => 'Просмотр всех изображений загруженных на эту страницу',
|
||||
'image_search_hint' => 'Поиск по имени изображения',
|
||||
'image_uploaded' => 'Загруженно :uploadedDate',
|
||||
'image_load_more' => 'Загрузить ещё',
|
||||
'image_image_name' => 'Имя изображения',
|
||||
'image_delete_confirm' => 'Это изображение используется на странице ниже. Снова кликните удалить для подтверждения того что вы хотите удалить.',
|
||||
'image_select_image' => 'Выбрать изображение',
|
||||
'image_dropzone' => 'Перетащите изображение или кликните для загрузки',
|
||||
'images_deleted' => 'Изображения удалены',
|
||||
'image_preview' => 'Предосмотр изображения',
|
||||
'image_upload_success' => 'Изображение загружено успешно',
|
||||
'image_update_success' => 'Детали изображения успешно обновлены',
|
||||
'image_delete_success' => 'Изображение успешно удалено',
|
||||
|
||||
];
|
||||
260
resources/lang/ru/entities.php
Normal file
260
resources/lang/ru/entities.php
Normal file
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
return [
|
||||
|
||||
/**
|
||||
* Shared
|
||||
*/
|
||||
'recently_created' => 'Недавно созданные',
|
||||
'recently_created_pages' => 'Недавно созданные страницы',
|
||||
'recently_updated_pages' => 'Недавно обновлённые страницы',
|
||||
'recently_created_chapters' => 'Недавно созданные главы',
|
||||
'recently_created_books' => 'Недавно созданные книги',
|
||||
'recently_update' => 'Недавно обновленные',
|
||||
'recently_viewed' => 'Недавно просмотренные',
|
||||
'recent_activity' => 'Недавние действия',
|
||||
'create_now' => 'Создать сейчас',
|
||||
'revisions' => 'Версия',
|
||||
'meta_revision' => 'Версия #:revisionCount',
|
||||
'meta_created' => 'Создано :timeLength',
|
||||
'meta_created_name' => 'Создано :timeLength пользователем :user',
|
||||
'meta_updated' => 'Обновлено :timeLength',
|
||||
'meta_updated_name' => 'Обновлено :timeLength пользователем :user',
|
||||
'entity_select' => 'Выбор объекта',
|
||||
'images' => 'Изображения',
|
||||
'my_recent_drafts' => 'Мои последние черновики',
|
||||
'my_recently_viewed' => 'Мои недавние просмотры',
|
||||
'no_pages_viewed' => 'Вы не просматривали ни одной страницы',
|
||||
'no_pages_recently_created' => 'Недавно не были созданы страницы',
|
||||
'no_pages_recently_updated' => 'Недавно не обновлялись страницы',
|
||||
'export' => 'Экспорт',
|
||||
'export_html' => 'Веб файл',
|
||||
'export_pdf' => 'PDF файл',
|
||||
'export_text' => 'Текстовый файл',
|
||||
|
||||
/**
|
||||
* Permissions and restrictions
|
||||
*/
|
||||
'permissions' => 'Разрешения',
|
||||
'permissions_intro' => 'После включения эти разрешения будут иметь приоритет над любыми установленными полномочиями.',
|
||||
'permissions_enable' => 'Включение пользовательских разрешений',
|
||||
'permissions_save' => 'Сохранить разрешения',
|
||||
|
||||
/**
|
||||
* Search
|
||||
*/
|
||||
'search_results' => 'Результаты поиска',
|
||||
'search_total_results_found' => ':count результатов найдено|:count всего результатов найдено',
|
||||
'search_clear' => 'Очистить поиск',
|
||||
'search_no_pages' => 'Нет страниц, соответствующих этому поиску.',
|
||||
'search_for_term' => 'Искать :term',
|
||||
'search_more' => 'Ещё результаты',
|
||||
'search_filters' => 'Фильтры поиска',
|
||||
'search_content_type' => 'Тип содержимого',
|
||||
'search_exact_matches' => 'Точные соответствия',
|
||||
'search_tags' => 'Поиск по тэгам',
|
||||
'search_viewed_by_me' => 'Просмотрено мной',
|
||||
'search_not_viewed_by_me' => 'Не просматривалось мной',
|
||||
'search_permissions_set' => 'Набор разрешений',
|
||||
'search_created_by_me' => 'Создано мной',
|
||||
'search_updated_by_me' => 'Обновлено мной',
|
||||
'search_updated_before' => 'Обновлено до',
|
||||
'search_updated_after' => 'Обновлено после',
|
||||
'search_created_before' => 'Создано до',
|
||||
'search_created_after' => 'Создано после',
|
||||
'search_set_date' => 'Установить дату',
|
||||
'search_update' => 'Обновить поиск',
|
||||
|
||||
/**
|
||||
* Books
|
||||
*/
|
||||
'book' => 'Книга',
|
||||
'books' => 'Книги',
|
||||
'x_books' => ':count книг|:count Книг',
|
||||
'books_empty' => 'Нет созданных книг',
|
||||
'books_popular' => 'Популярные книги',
|
||||
'books_recent' => 'Недавние книги',
|
||||
'books_new' => 'Новые книги',
|
||||
'books_popular_empty' => 'Здесь появятся самые популярные книги.',
|
||||
'books_new_empty' => 'Здесь появятся самые последние созданные книги.',
|
||||
'books_create' => 'Создать новую книгу',
|
||||
'books_delete' => 'Удалить книгу',
|
||||
'books_delete_named' => 'Удалить книгу :bookName',
|
||||
'books_delete_explain' => 'Это удалит книги с именем \':bookName\'. Все разделы и страницы будут удалены.',
|
||||
'books_delete_confirmation' => 'Вы действительно хотите удалить эту книгу?',
|
||||
'books_edit' => 'Редактировать книгу',
|
||||
'books_edit_named' => 'Редактировать книгу :bookName',
|
||||
'books_form_book_name' => 'Имя книги',
|
||||
'books_save' => 'Сохранить книгу',
|
||||
'books_permissions' => 'Разрешения на книгу',
|
||||
'books_permissions_updated' => 'Разрешения на книгу обновлены',
|
||||
'books_empty_contents' => 'Для этой книги нет страниц или разделов.',
|
||||
'books_empty_create_page' => 'Создать новую страницу',
|
||||
'books_empty_or' => 'или',
|
||||
'books_empty_sort_current_book' => 'Сортировка текущей книги',
|
||||
'books_empty_add_chapter' => 'Добавить главу',
|
||||
'books_permissions_active' => 'действующие разрешения на книгу',
|
||||
'books_search_this' => 'Поиск в этой книге',
|
||||
'books_navigation' => 'Навигация по книге',
|
||||
'books_sort' => 'Сортировка содержимого книги',
|
||||
'books_sort_named' => 'Сортировка книги :bookName',
|
||||
'books_sort_show_other' => 'Показать другие книги',
|
||||
'books_sort_save' => 'Сохранить новый порядок',
|
||||
|
||||
/**
|
||||
* Chapters
|
||||
*/
|
||||
'chapter' => 'Глава',
|
||||
'chapters' => 'Главы',
|
||||
'x_chapters' => ':count глава|:count Главы',
|
||||
'chapters_popular' => 'Популярные главы',
|
||||
'chapters_new' => 'Новая глава',
|
||||
'chapters_create' => 'Создать новую главу',
|
||||
'chapters_delete' => 'Удалить главу',
|
||||
'chapters_delete_named' => 'Удалить главу :chapterName',
|
||||
'chapters_delete_explain' => 'Это удалит главу с именем \':chapterName\'. Все страницы главы будут удалены и перемещены напрямую в книгу.',
|
||||
'chapters_delete_confirm' => 'Вы действительно хотите удалить эту главу?',
|
||||
'chapters_edit' => 'Редактировать главу',
|
||||
'chapters_edit_named' => 'редактировать главу :chapterName',
|
||||
'chapters_save' => 'Сохранить главу',
|
||||
'chapters_move' => 'Переместить главу',
|
||||
'chapters_move_named' => 'Переместить главу :chapterName',
|
||||
'chapter_move_success' => 'Глава перемещена в :bookName',
|
||||
'chapters_permissions' => 'Разрешения главы',
|
||||
'chapters_empty' => 'В этой главе нет страниц.',
|
||||
'chapters_permissions_active' => 'Действующие разрешения главы',
|
||||
'chapters_permissions_success' => 'Разрешения главы обновлены',
|
||||
'chapters_search_this' => 'Искать в этой главе',
|
||||
|
||||
/**
|
||||
* Pages
|
||||
*/
|
||||
'page' => 'Страница',
|
||||
'pages' => 'Страницы',
|
||||
'x_pages' => ':count страниц|:count страниц',
|
||||
'pages_popular' => 'Популярные страницы',
|
||||
'pages_new' => 'Новая страница',
|
||||
'pages_attachments' => 'Вложения',
|
||||
'pages_navigation' => 'Навигация на странице',
|
||||
'pages_delete' => 'Удалить устраницу',
|
||||
'pages_delete_named' => 'Удалить страницу :pageName',
|
||||
'pages_delete_draft_named' => 'Удалить черновик :pageName',
|
||||
'pages_delete_draft' => 'Удалить черновик',
|
||||
'pages_delete_success' => 'Страница удалена',
|
||||
'pages_delete_draft_success' => 'Черновик удалён',
|
||||
'pages_delete_confirm' => 'Вы действительно хотите удалить эту страницу?',
|
||||
'pages_delete_draft_confirm' => 'Вы действительно хотите удалить этот черновик?',
|
||||
'pages_editing_named' => 'Редактирование страницы :pageName',
|
||||
'pages_edit_toggle_header' => 'Переключение заголовка',
|
||||
'pages_edit_save_draft' => 'Сохранить черновик',
|
||||
'pages_edit_draft' => 'Редактировать черновик',
|
||||
'pages_editing_draft' => 'Редактирование черновика',
|
||||
'pages_editing_page' => 'Редактирование страницы',
|
||||
'pages_edit_draft_save_at' => 'Черновик сохранить в ',
|
||||
'pages_edit_delete_draft' => 'Удалить черновик',
|
||||
'pages_edit_discard_draft' => 'отменить черновик',
|
||||
'pages_edit_set_changelog' => 'Задать список изменений',
|
||||
'pages_edit_enter_changelog_desc' => 'Введите краткое описание изменений, которые вы сделали',
|
||||
'pages_edit_enter_changelog' => 'Введите список изменений',
|
||||
'pages_save' => 'Сохранить страницу',
|
||||
'pages_title' => 'Заголовок страницы',
|
||||
'pages_name' => 'Имя страницы',
|
||||
'pages_md_editor' => 'Редактор',
|
||||
'pages_md_preview' => 'Просмотр',
|
||||
'pages_md_insert_image' => 'Вставить изображение',
|
||||
'pages_md_insert_link' => 'Вставить ссылку на объект',
|
||||
'pages_not_in_chapter' => 'Страница не находится в главе',
|
||||
'pages_move' => 'Переместить страницу',
|
||||
'pages_move_success' => 'Страница перемещена в ":parentName"',
|
||||
'pages_permissions' => 'Разрешения страницы',
|
||||
'pages_permissions_success' => 'PРазрешения страницы обновлены',
|
||||
'pages_revision' => 'Версия',
|
||||
'pages_revisions' => 'Версия страницы',
|
||||
'pages_revisions_named' => 'Версии страницы для :pageName',
|
||||
'pages_revision_named' => 'Версия страницы для :pageName',
|
||||
'pages_revisions_created_by' => 'Создана',
|
||||
'pages_revisions_date' => 'Дата версии',
|
||||
'pages_revisions_number' => '#',
|
||||
'pages_revisions_changelog' => 'Список изменений',
|
||||
'pages_revisions_changes' => 'Изменения',
|
||||
'pages_revisions_current' => 'Текущая версия',
|
||||
'pages_revisions_preview' => 'Просмотр',
|
||||
'pages_revisions_restore' => 'Восстановить',
|
||||
'pages_revisions_none' => 'У этой страницы нет других версий',
|
||||
'pages_copy_link' => 'Копировать ссылку',
|
||||
'pages_permissions_active' => 'Действующие разрешения на страницу',
|
||||
'pages_initial_revision' => 'Первоначальное издание',
|
||||
'pages_initial_name' => 'Новая страница',
|
||||
'pages_editing_draft_notification' => 'Вы в настоящее время редактируете черновик, который был сохранен :timeDiff.',
|
||||
'pages_draft_edited_notification' => 'Эта страница была обновлена до этого момента. Рекомендуется отменить этот черновик',
|
||||
'pages_draft_edit_active' => [
|
||||
'start_a' => ':count пользователей начали редактирование этой страницы',
|
||||
'start_b' => ':userName начал редактирование этой страницы',
|
||||
'time_a' => 'поскольку последние страницы были обновлены',
|
||||
'time_b' => 'за последние :minCount минут',
|
||||
'message' => ':start :time. Будьте осторожны, чтобы не перезаписывать друг друга!',
|
||||
],
|
||||
'pages_draft_discarded' => 'Черновик сброшен, редактор обновлен текущим содержимым страницы',
|
||||
|
||||
/**
|
||||
* Editor sidebar
|
||||
*/
|
||||
'page_tags' => 'Теги страницы',
|
||||
'tag' => 'Тэг',
|
||||
'tags' => '',
|
||||
'tag_value' => 'Значение тэга (опционально)',
|
||||
'tags_explain' => "Добавьте теги, чтобы лучше классифицировать ваш контент. \n Вы можете присвоить значение тегу для более глубокой организации.",
|
||||
'tags_add' => 'Добавить тэг',
|
||||
'attachments' => 'Вложение',
|
||||
'attachments_explain' => 'Загрузите несколько файлов или добавьте ссылку для отображения на своей странице. Они видны на боковой панели страницы.',
|
||||
'attachments_explain_instant_save' => 'Изменения здесь сохраняются мгновенно.',
|
||||
'attachments_items' => 'Прикрепленные элементы',
|
||||
'attachments_upload' => 'Загрузить файл',
|
||||
'attachments_link' => 'Присоединить ссылку',
|
||||
'attachments_set_link' => 'Установить ссылку',
|
||||
'attachments_delete_confirm' => 'Нажмите «Удалить» еще раз, чтобы подтвердить, что вы хотите удалить этот файл.',
|
||||
'attachments_dropzone' => 'Перетащите файл сюда или нажмите здесь, чтобы загрузить файл',
|
||||
'attachments_no_files' => 'Файлы не загружены',
|
||||
'attachments_explain_link' => 'Вы можете присоединить ссылку, если вы предпочитаете не загружать файл. Это может быть ссылка на другую страницу или ссылку на файл в облаке',
|
||||
'attachments_link_name' => 'Имя ссылки',
|
||||
'attachment_link' => 'Ссылка на вложение',
|
||||
'attachments_link_url' => 'Ссылка на файл',
|
||||
'attachments_link_url_hint' => 'URL-адрес сайта или файла',
|
||||
'attach' => 'Прикрепить',
|
||||
'attachments_edit_file' => 'Редактировать файл',
|
||||
'attachments_edit_file_name' => 'Имя файла',
|
||||
'attachments_edit_drop_upload' => 'перетащите файлы или нажмите здесь, чтобы загрузить и перезаписать',
|
||||
'attachments_order_updated' => 'Прикрепленный файл обновлен',
|
||||
'attachments_updated_success' => 'Attachment details updated',
|
||||
'attachments_deleted' => 'Приложение удалено',
|
||||
'attachments_file_uploaded' => 'Файл успешно загружен',
|
||||
'attachments_file_updated' => 'Файл успешно обновлен',
|
||||
'attachments_link_attached' => 'Ссылка успешно присоединена к странице',
|
||||
|
||||
/**
|
||||
* Profile View
|
||||
*/
|
||||
'profile_user_for_x' => 'пользователь уже :time',
|
||||
'profile_created_content' => 'Созданный контент',
|
||||
'profile_not_created_pages' => ':userName не создавал страниц',
|
||||
'profile_not_created_chapters' => ':userName не создавал глав',
|
||||
'profile_not_created_books' => ':userName не создавал ни одной книги',
|
||||
|
||||
/**
|
||||
* Comments
|
||||
*/
|
||||
'comment' => 'Комментарий',
|
||||
'comments' => 'Комментарии',
|
||||
'comment_placeholder' => 'Оставить комментарий здесь',
|
||||
'comment_count' => '{0} Нет комментариев|{1} 1 комментарий|[2,*] :count комментария',
|
||||
'comment_save' => 'Сохранить комментарий',
|
||||
'comment_saving' => 'Сохраниение комментария...',
|
||||
'comment_deleting' => 'Удаление комментария...',
|
||||
'comment_new' => 'Новый комментарий',
|
||||
'comment_created' => 'прокомментировал :createDiff',
|
||||
'comment_updated' => 'Обновлён :updateDiff пользователем :username',
|
||||
'comment_deleted_success' => 'Комментарий удалён',
|
||||
'comment_created_success' => 'Комментарий добавлён',
|
||||
'comment_updated_success' => 'Комментарий обновлён',
|
||||
'comment_delete_confirm' => 'Вы уверенны, что хотите удалить этот комментарий?',
|
||||
'comment_in_reply_to' => 'В ответ на :commentId',
|
||||
];
|
||||
77
resources/lang/ru/errors.php
Normal file
77
resources/lang/ru/errors.php
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/**
|
||||
* Error text strings.
|
||||
*/
|
||||
|
||||
// Permissions
|
||||
'permission' => 'У вас нет доступа к запрашиваемой странице.',
|
||||
'permissionJson' => 'У вас нет разрешения для запрашиваемого действия.',
|
||||
|
||||
// Auth
|
||||
'error_user_exists_different_creds' => 'Пользователь с электронной почтой: :email уже существует, но с другими учетными данными.',
|
||||
'email_already_confirmed' => 'Электронная почта уже подтверждена, попробуйте войти в систему.',
|
||||
'email_confirmation_invalid' => 'Этот токен подтверждения недействителен или уже используется. Повторите попытку регистрации.',
|
||||
'email_confirmation_expired' => 'Идентификатор подтверждения истек. Отправлено новое письмо с подтверждением.',
|
||||
'ldap_fail_anonymous' => 'Недопустимый доступ LDAP с использованием анонимной привязки',
|
||||
'ldap_fail_authed' => 'Не удалось получить доступ к LDAP, используя данные dn & password',
|
||||
'ldap_extension_not_installed' => 'LDAP расширения для PHP не установлено',
|
||||
'ldap_cannot_connect' => 'Не удается подключиться к серверу ldap, Не удалось выполнить начальное соединение',
|
||||
'social_no_action_defined' => 'Действие не определено',
|
||||
'social_account_in_use' => 'Этот :socialAccount аккаунт уже исопльзуется, Попробуйте войти с параматрами :socialAccount.',
|
||||
'social_account_email_in_use' => 'Электронный ящик :email уже используется. Если у вас уже есть учетная запись, вы можете подключить свою учетную запись :socialAccount из настроек своего профиля.',
|
||||
'social_account_existing' => 'Этот :socialAccount уже привязан к вашему профилю.',
|
||||
'social_account_already_used_existing' => 'Этот :socialAccount уже используется другим пользователем.',
|
||||
'social_account_not_used' => 'Эта :socialAccount учетная запись не связана ни с какими пользователями. Прикрепите его в настройках вашего профиля.',
|
||||
'social_account_register_instructions' => 'Если у вас еще нет учетной записи, вы можете зарегистрироваться, используя параметр :socialAccount.',
|
||||
'social_driver_not_found' => 'Драйдер для Соцсети не найден',
|
||||
'social_driver_not_configured' => 'Настройки вашего :socialAccount сконфигурированы неправильно.',
|
||||
|
||||
// System
|
||||
'path_not_writable' => 'Невозможно загрузить файл по пути :filePath . Убедитесь что сервер доступен для записи.',
|
||||
'cannot_get_image_from_url' => 'Не удается получить изображение из :url',
|
||||
'cannot_create_thumbs' => 'Сервер не может создавать эскизы. Убедитесь, что у вас установлено расширение GD PHP.',
|
||||
'server_upload_limit' => 'Сервер не разрешает загрузку такого размера. Попробуйте уменьшить размер файла.',
|
||||
'image_upload_error' => 'Произошла ошибка при загрузке изображения.',
|
||||
|
||||
// Attachments
|
||||
'attachment_page_mismatch' => 'Несоответствие страницы во время обновления вложения',
|
||||
|
||||
// Pages
|
||||
'page_draft_autosave_fail' => 'Не удалось сохранить черновик. Перед сохранением этой страницы убедитесь, что у вас есть подключение к Интернету.',
|
||||
|
||||
// Entities
|
||||
'entity_not_found' => 'Объект не найден',
|
||||
'book_not_found' => 'Книга не найдена',
|
||||
'page_not_found' => 'Страница не найдена',
|
||||
'chapter_not_found' => 'Глава не найдена',
|
||||
'selected_book_not_found' => 'Выбранная книга не найдена',
|
||||
'selected_book_chapter_not_found' => 'Выбранная книга или глава не найдена',
|
||||
'guests_cannot_save_drafts' => 'Гости не могут сохранить черновики',
|
||||
|
||||
// Users
|
||||
'users_cannot_delete_only_admin' => 'Вы не можете удалить единственного администратора',
|
||||
'users_cannot_delete_guest' => 'Вы не можете удалить гостевого пользователя',
|
||||
|
||||
// Roles
|
||||
'role_cannot_be_edited' => 'Невозможно отредактировать данную роль',
|
||||
'role_system_cannot_be_deleted' => 'Эта роль является системной и не может быть удалена',
|
||||
'role_registration_default_cannot_delete' => 'Эта роль не может быть удалена, так как она устанолена в качестве роли регистрации по-умолчанию',
|
||||
|
||||
// Comments
|
||||
'comment_list' => 'При получении комментариев произошла ошибка.',
|
||||
'cannot_add_comment_to_draft' => 'Вы не можете добавлять комментарии к черновику.',
|
||||
'comment_add' => 'При добавлении / обновлении комментария произошла ошибка.',
|
||||
'comment_delete' => 'При удалении комментария произошла ошибка.',
|
||||
'empty_comment' => 'Нельзя добавить пустой комментарий.',
|
||||
|
||||
// Error pages
|
||||
'404_page_not_found' => 'Старница не найдена',
|
||||
'sorry_page_not_found' => 'Извините, страница, которую вы искали, не найдена.',
|
||||
'return_home' => 'вернуться на главную страницу',
|
||||
'error_occurred' => 'Произошла ошибка',
|
||||
'app_down' => ':appName в данный момент не достпуно',
|
||||
'back_soon' => 'Скоро восстановится.',
|
||||
];
|
||||
19
resources/lang/ru/pagination.php
Normal file
19
resources/lang/ru/pagination.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Pagination Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used by the paginator library to build
|
||||
| the simple pagination links. You are free to change them to anything
|
||||
| you want to customize your views to better match your application.
|
||||
|
|
||||
*/
|
||||
|
||||
'previous' => '« Предыдущая',
|
||||
'next' => 'Следующая »',
|
||||
|
||||
];
|
||||
22
resources/lang/ru/passwords.php
Normal file
22
resources/lang/ru/passwords.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Password Reminder Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are the default lines which match reasons
|
||||
| that are given by the password broker for a password update attempt
|
||||
| has failed, such as for an invalid token or invalid new password.
|
||||
|
|
||||
*/
|
||||
|
||||
'password' => 'Пароль должен содержать не менее шести символов для применения.',
|
||||
'user' => "Невозможно найти пользователя с указанным e-mail адресом.",
|
||||
'token' => 'Этот токен для сброса пароля недействителен.',
|
||||
'sent' => 'Ссылка для сброса пароля была отправлена на электронную почту!',
|
||||
'reset' => 'Ваш пароль был сброшен!',
|
||||
|
||||
];
|
||||
116
resources/lang/ru/settings.php
Executable file
116
resources/lang/ru/settings.php
Executable file
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/**
|
||||
* Settings text strings
|
||||
* Contains all text strings used in the general settings sections of BookStack
|
||||
* including users and roles.
|
||||
*/
|
||||
|
||||
'settings' => 'Настройки',
|
||||
'settings_save' => 'Сохранить настройки',
|
||||
'settings_save_success' => 'Настройки сохранены',
|
||||
|
||||
/**
|
||||
* App settings
|
||||
*/
|
||||
|
||||
'app_settings' => 'Настройки приложения',
|
||||
'app_name' => 'Имя приложения',
|
||||
'app_name_desc' => 'Это имя отображается в заголовке и в любых письмах.',
|
||||
'app_name_header' => 'Показать имя приложения в заголовке?',
|
||||
'app_public_viewing' => 'Разрешить публичный просмотр?',
|
||||
'app_secure_images' => 'Включить загрузку изображений с более высокой безопасностью?',
|
||||
'app_secure_images_desc' => 'По соображениям производительности все изображения являются общедоступными. Этот параметр добавляет случайную, труднодоступную строку перед образами изображений. Убедитесь, что индексация каталогов не включена, чтобы предотвратить к ним легкий доступ.',
|
||||
'app_editor' => 'Редактор страницы',
|
||||
'app_editor_desc' => 'Выберите, какой редактор будет использоваться всеми пользователями для редактирования страниц.',
|
||||
'app_custom_html' => 'Пользовательский контент заголовка HTML',
|
||||
'app_custom_html_desc' => 'Любой контент, добавленный здесь, будет вставлен в нижнюю часть раздела <head> каждой страницы. Это удобно для переопределения стилей или добавления кода аналитики.',
|
||||
'app_logo' => 'Лого приложения',
|
||||
'app_logo_desc' => 'Это изображение должно быть 43px в высоту. <br>Большее изображение будет уменьшено.',
|
||||
'app_primary_color' => 'Главный цвет приложения',
|
||||
'app_primary_color_desc' => 'Это должно быть указано в hex. <br>Оставьте пустым чтобы использовать цвет по-умолчанию.',
|
||||
'app_homepage' => 'Домашняя страница приложения',
|
||||
'app_homepage_desc' => 'Выберите страницу, которая будет отображаться на главной странице вместо стандартной. Права на страницы игнорируются для выбранных страниц.',
|
||||
'app_homepage_default' => 'Выбрана домашняя страница по-умолчанию',
|
||||
|
||||
/**
|
||||
* Registration
|
||||
*/
|
||||
|
||||
'reg_settings' => 'Настройки регистрации',
|
||||
'reg_allow' => 'Открыть регистрацию?',
|
||||
'reg_default_role' => 'Роль пользователя по-умолчанию после регистрации',
|
||||
'reg_confirm_email' => 'Требуется подтверждение по электронной почте?',
|
||||
'reg_confirm_email_desc' => 'Если используется ограничение домена, тогда потребуется подтверждение по электронной почте и этот пункт будет проигнорирован.',
|
||||
'reg_confirm_restrict_domain' => 'Ограничить регистрацию по домену',
|
||||
'reg_confirm_restrict_domain_desc' => 'EВведите список доменов электронной почты, разделенных запятыми, на которые вы хотели бы ограничить регистрацию. Пользователям будет отправлено электронное письмо, чтобы подтвердить их адрес, прежде чем им разрешат взаимодействовать с приложением. <br> Обратите внимание, что пользователи смогут изменять свои адреса электронной почты после успешной регистрации.',
|
||||
'reg_confirm_restrict_domain_placeholder' => 'Нет ограничений',
|
||||
|
||||
/**
|
||||
* Role settings
|
||||
*/
|
||||
|
||||
'roles' => 'Роли',
|
||||
'role_user_roles' => 'Роли пользователя',
|
||||
'role_create' => 'Создать новую роль',
|
||||
'role_create_success' => 'Роль упешно создана',
|
||||
'role_delete' => 'Удалить роль',
|
||||
'role_delete_confirm' => 'Это удалит роль с именем \':roleName\'.',
|
||||
'role_delete_users_assigned' => 'Эта роль имеет :userCount пользователей привязанных к ней. Если вы хотите перенести пользователей из этой роли, выберите новую роль ниже.',
|
||||
'role_delete_no_migration' => "Не мигрировать пользователей",
|
||||
'role_delete_sure' => 'Вы уверены что хотите удалить данную роль?',
|
||||
'role_delete_success' => 'Роль успешно удалена',
|
||||
'role_edit' => 'Редактировать роль',
|
||||
'role_details' => 'Детали роли',
|
||||
'role_name' => 'Имя роли',
|
||||
'role_desc' => 'Короткое описание роли',
|
||||
'role_system' => 'Системные разрешения',
|
||||
'role_manage_users' => 'Управление пользователями',
|
||||
'role_manage_roles' => 'Управление ролями и правами на роли',
|
||||
'role_manage_entity_permissions' => 'Управление правами на все книги, главы и страницы',
|
||||
'role_manage_own_entity_permissions' => 'Управление разрешениями для собственных книг, разделов и страниц',
|
||||
'role_manage_settings' => 'Управление настройками приложения',
|
||||
'role_asset' => 'Разрешение для активации',
|
||||
'role_asset_desc' => 'Эти разрешения контролируют доступ по-умолчанию к параметрам внутри системы. Разрешения на книги, главы и страницы перезапишут эти разрешения.',
|
||||
'role_all' => 'Все',
|
||||
'role_own' => 'Владелец',
|
||||
'role_controlled_by_asset' => 'Регилируемые активацией они загружаются в',
|
||||
'role_save' => 'Сохранить роль',
|
||||
'role_update_success' => 'Роль успешно обновлена',
|
||||
'role_users' => 'Пользователи с данной ролью',
|
||||
'role_users_none' => 'Нет пользователей с данной ролью',
|
||||
|
||||
/**
|
||||
* Users
|
||||
*/
|
||||
|
||||
'users' => 'Пользователи',
|
||||
'user_profile' => 'Профиль пользователя',
|
||||
'users_add_new' => 'Добавить нового пользователя',
|
||||
'users_search' => 'Поиск пользователей',
|
||||
'users_role' => 'Роли пользователя',
|
||||
'users_external_auth_id' => 'Внешний ID аутентификации',
|
||||
'users_password_warning' => 'Введите ниже свой пароль новый пароль для его изменения:',
|
||||
'users_system_public' => 'Этот пользователь представляет любых гостевых пользователей, которые посещают ваше приложение. Он не может использоваться для входа в систему и назначается автоматически.',
|
||||
'users_delete' => 'Удалить пользователя',
|
||||
'users_delete_named' => 'Удалить пользователя :userName',
|
||||
'users_delete_warning' => 'Это полностью удалит этого пользователя с именем \':userName\' из системы.',
|
||||
'users_delete_confirm' => 'Вы уверены что хотите удалить этого пользователя?',
|
||||
'users_delete_success' => 'Пользователи успешно удалены',
|
||||
'users_edit' => 'Редактировать польщователя',
|
||||
'users_edit_profile' => 'Редактировать профиль',
|
||||
'users_edit_success' => 'Пользователь успешно обновлён',
|
||||
'users_avatar' => 'Аватар пользователя',
|
||||
'users_avatar_desc' => 'Это изображение должно быть размером около 256 пикселей.',
|
||||
'users_preferred_language' => 'Предпочитаемый язык',
|
||||
'users_social_accounts' => 'Аккаунты Соцсетей',
|
||||
'users_social_accounts_info' => 'Здесь вы можете подключить другие учетные записи для более быстрого и легкого входа в систему. Отключение учетной записи здесь не разрешено. Отменить доступ к настройкам вашего профиля в подключенном социальном аккаунте.',
|
||||
'users_social_connect' => 'Подключить аккаунт',
|
||||
'users_social_disconnect' => 'Отключить аккаунт',
|
||||
'users_social_connected' => ':socialAccount аккаунт упешно подключён к вашему профилю.',
|
||||
'users_social_disconnected' => ':socialAccount аккаунт успешно отключён от вашего профиля.',
|
||||
|
||||
|
||||
];
|
||||
108
resources/lang/ru/validation.php
Normal file
108
resources/lang/ru/validation.php
Normal file
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines contain the default error messages used by
|
||||
| the validator class. Some of these rules have multiple versions such
|
||||
| as the size rules. Feel free to tweak each of these messages here.
|
||||
|
|
||||
*/
|
||||
|
||||
'accepted' => ':attribute должен быть принят.',
|
||||
'active_url' => ':attribute не является валидным URL.',
|
||||
'after' => ':attribute дата должна быть позже :date.',
|
||||
'alpha' => ':attribute может содержать только буквы.',
|
||||
'alpha_dash' => ':attribute может содержать только буквы, цифры и тире.',
|
||||
'alpha_num' => ':attribute должен содержать только буквы и цифры.',
|
||||
'array' => ':attribute должен быть массивом.',
|
||||
'before' => ':attribute дата должна быть до :date.',
|
||||
'between' => [
|
||||
'numeric' => ':attribute должен быть между :min и :max.',
|
||||
'file' => ':attribute должен быть между :min и :max килобайт.',
|
||||
'string' => 'длина :attribute должена быть между :min и :max символами.',
|
||||
'array' => ':attribute должен содержать не менее :min и не более:max элементов.',
|
||||
],
|
||||
'boolean' => ':attribute поле может быть только true или false.',
|
||||
'confirmed' => ':attribute подтверждение не совпадает.',
|
||||
'date' => ':attribute не корректные данные.',
|
||||
'date_format' => ':attribute не соответствует формату :format.',
|
||||
'different' => ':attribute и :other должны быть различны.',
|
||||
'digits' => ':attribute должен быть из :digits цифр.',
|
||||
'digits_between' => ':attribute должен иметь от :min до :max цифр.',
|
||||
'email' => ':attribute must be a valid email address.',
|
||||
'filled' => ':attribute поле необходимо.',
|
||||
'exists' => 'выделенный :attribute невалиден.',
|
||||
'image' => ':attribute must be an image.',
|
||||
'in' => 'выделенный :attribute невалиден.',
|
||||
'integer' => ':attribute должно быть целое число.',
|
||||
'ip' => ':attribute должен быть валидный IP адрес.',
|
||||
'max' => [
|
||||
'numeric' => ':attribute не может быть больше чем :max.',
|
||||
'file' => ':attribute не может быть больше чем :max килобайт.',
|
||||
'string' => ':attribute не может быть больше чем :max символов.',
|
||||
'array' => ':attribute не может содержать больше чем :max элементов.',
|
||||
],
|
||||
'mimes' => ':attribute должен быть файлом с типом: :values.',
|
||||
'min' => [
|
||||
'numeric' => ':attribute должен быть хотя бы :min.',
|
||||
'file' => ':attribute должен быть минимум :min килобайт.',
|
||||
'string' => ':attribute должен быть минимум :min символов.',
|
||||
'array' => ':attribute должен содержать хотя бы :min элементов.',
|
||||
],
|
||||
'not_in' => 'Выбранный :attribute некорректен.',
|
||||
'numeric' => ':attribute должен быть числом.',
|
||||
'regex' => ':attribute неправильный формат.',
|
||||
'required' => ':attribute обязательное поле.',
|
||||
'required_if' => ':attribute обязательное поле когда :other со значением :value.',
|
||||
'required_with' => ':attribute обязательное поле когда :values установлено.',
|
||||
'required_with_all' => ':attribute обязательное поле когда :values установлены.',
|
||||
'required_without' => ':attribute обязательное поле когда :values не установлены.',
|
||||
'required_without_all' => ':attribute обязательное поле когда ни одно из :values не установлены.',
|
||||
'same' => ':attribute и :other должны совпадать.',
|
||||
'size' => [
|
||||
'numeric' => ':attribute должен быть :size.',
|
||||
'file' => ':attribute должен быть :size килобайт.',
|
||||
'string' => ':attribute должен быть :size символов.',
|
||||
'array' => ':attribute должен содержать :size элементов.',
|
||||
],
|
||||
'string' => ':attribute должен быть строкой.',
|
||||
'timezone' => ':attribute должен быть валидной временной зоной.',
|
||||
'unique' => ':attribute уже есть.',
|
||||
'url' => ':attribute имеет неправильный формат.',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Language Lines
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may specify custom validation messages for attributes using the
|
||||
| convention "attribute.rule" to name the lines. This makes it quick to
|
||||
| specify a specific custom language line for a given attribute rule.
|
||||
|
|
||||
*/
|
||||
|
||||
'custom' => [
|
||||
'password-confirm' => [
|
||||
'required_with' => 'Требуется подтверждение пароля',
|
||||
],
|
||||
],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Custom Validation Attributes
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| The following language lines are used to swap attribute place-holders
|
||||
| with something more reader friendly such as E-Mail Address instead
|
||||
| of "email". This simply helps us make messages a little cleaner.
|
||||
|
|
||||
*/
|
||||
|
||||
'attributes' => [],
|
||||
|
||||
];
|
||||
@@ -1,7 +1,7 @@
|
||||
@extends('base')
|
||||
|
||||
@section('head')
|
||||
<script src="{{ baseUrl('/libs/tinymce/tinymce.min.js?ver=4.6.3') }}"></script>
|
||||
<script src="{{ baseUrl('/libs/tinymce/tinymce.min.js?ver=4.6.6') }}"></script>
|
||||
@stop
|
||||
|
||||
@section('body-class', 'flexbox')
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
<div toolbox class="floating-toolbox">
|
||||
<div editor-toolbox class="floating-toolbox">
|
||||
|
||||
<div class="tabs primary-background-light">
|
||||
<span toolbox-toggle><i class="zmdi zmdi-caret-left-circle"></i></span>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
<div class="page-editor flex-fill flex" ng-controller="PageEditController" drafts-enabled="{{ $draftsEnabled ? 'true' : 'false' }}" editor-type="{{ setting('app-editor') }}" page-id="{{ $model->id or 0 }}" page-new-draft="{{ $model->draft or 0 }}" page-update-draft="{{ $model->isDraft or 0 }}">
|
||||
<div class="page-editor flex-fill flex" id="page-editor" drafts-enabled="{{ $draftsEnabled ? 'true' : 'false' }}" editor-type="{{ setting('app-editor') }}" page-id="{{ $model->id or 0 }}" page-new-draft="{{ $model->draft or 0 }}" page-update-draft="{{ $model->isDraft or 0 }}">
|
||||
|
||||
{{ csrf_field() }}
|
||||
|
||||
@@ -15,30 +15,30 @@
|
||||
</div>
|
||||
<div class="col-sm-4 faded text-center">
|
||||
|
||||
<div ng-show="draftsEnabled" dropdown class="dropdown-container draft-display">
|
||||
<a dropdown-toggle class="text-primary text-button"><span class="faded-text" ng-bind="draftText"></span> <i class="zmdi zmdi-more-vert"></i></a>
|
||||
<i class="zmdi zmdi-check-circle text-pos draft-notification" ng-class="{visible: draftUpdated}"></i>
|
||||
<div v-show="draftsEnabled" dropdown class="dropdown-container draft-display">
|
||||
<a dropdown-toggle class="text-primary text-button"><span class="faded-text" v-text="draftText"></span> <i class="zmdi zmdi-more-vert"></i></a>
|
||||
<i class="zmdi zmdi-check-circle text-pos draft-notification" :class="{visible: draftUpdated}"></i>
|
||||
<ul>
|
||||
<li>
|
||||
<a ng-click="forceDraftSave()" class="text-pos"><i class="zmdi zmdi-save"></i>{{ trans('entities.pages_edit_save_draft') }}</a>
|
||||
<a @click="saveDraft()" class="text-pos"><i class="zmdi zmdi-save"></i>{{ trans('entities.pages_edit_save_draft') }}</a>
|
||||
</li>
|
||||
<li ng-if="isNewPageDraft">
|
||||
<li v-if="isNewDraft">
|
||||
<a href="{{ $model->getUrl('/delete') }}" class="text-neg"><i class="zmdi zmdi-delete"></i>{{ trans('entities.pages_edit_delete_draft') }}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a type="button" ng-if="isUpdateDraft" ng-click="discardDraft()" class="text-neg"><i class="zmdi zmdi-close-circle"></i>{{ trans('entities.pages_edit_discard_draft') }}</a>
|
||||
<li v-if="isUpdateDraft">
|
||||
<a type="button" @click="discardDraft" class="text-neg"><i class="zmdi zmdi-close-circle"></i>{{ trans('entities.pages_edit_discard_draft') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-4 faded">
|
||||
<div class="action-buttons" ng-cloak>
|
||||
<div class="action-buttons" v-cloak>
|
||||
<div dropdown class="dropdown-container">
|
||||
<a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-edit"></i> <span ng-bind="(changeSummary | limitTo:16) + (changeSummary.length>16?'...':'') || '{{ trans('entities.pages_edit_set_changelog') }}'"></span></a>
|
||||
<a dropdown-toggle class="text-primary text-button"><i class="zmdi zmdi-edit"></i> <span v-text="changeSummaryShort"></span></a>
|
||||
<ul class="wide">
|
||||
<li class="padded">
|
||||
<p class="text-muted">{{ trans('entities.pages_edit_enter_changelog_desc') }}</p>
|
||||
<input name="summary" id="summary-input" type="text" placeholder="{{ trans('entities.pages_edit_enter_changelog') }}" ng-model="changeSummary" />
|
||||
<input name="summary" id="summary-input" type="text" placeholder="{{ trans('entities.pages_edit_enter_changelog') }}" v-model="changeSummary" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -62,9 +62,9 @@
|
||||
|
||||
{{--WYSIWYG Editor--}}
|
||||
@if(setting('app-editor') === 'wysiwyg')
|
||||
<div tinymce="editorOptions" mce-change="editorChange" mce-model="editContent" class="flex-fill flex">
|
||||
<div wysiwyg-editor class="flex-fill flex">
|
||||
<textarea id="html-editor" name="html" rows="5" ng-non-bindable
|
||||
@if($errors->has('html')) class="neg" @endif>@if(isset($model) || old('html')){{htmlspecialchars( old('html') ? old('html') : $model->html)}}@endif</textarea>
|
||||
@if($errors->has('html')) class="neg" @endif>@if(isset($model) || old('html')){{htmlspecialchars( old('html') ? old('html') : $model->html)}}@endif</textarea>
|
||||
</div>
|
||||
|
||||
@if($errors->has('html'))
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
{{--Markdown Editor--}}
|
||||
@if(setting('app-editor') === 'markdown')
|
||||
<div id="markdown-editor" markdown-editor class="flex-fill flex code-fill">
|
||||
<div ng-non-bindable id="markdown-editor" markdown-editor class="flex-fill flex code-fill">
|
||||
|
||||
<div class="markdown-editor-wrap">
|
||||
<div class="editor-toolbar">
|
||||
@@ -82,12 +82,12 @@
|
||||
<div class="float right buttons">
|
||||
<button class="text-button" type="button" data-action="insertImage"><i class="zmdi zmdi-image"></i>{{ trans('entities.pages_md_insert_image') }}</button>
|
||||
|
|
||||
<button class="text-button" type="button" data-action="insertEntityLink"><i class="zmdi zmdi-link"></i>{{ trans('entities.pages_md_insert_link') }}</button>
|
||||
<button class="text-button" type="button" data-action="insertLink"><i class="zmdi zmdi-link"></i>{{ trans('entities.pages_md_insert_link') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div markdown-input md-change="editorChange" md-model="editContent" class="flex flex-fill">
|
||||
<textarea ng-non-bindable id="markdown-editor-input" name="markdown" rows="5"
|
||||
<div markdown-input class="flex flex-fill">
|
||||
<textarea id="markdown-editor-input" name="markdown" rows="5"
|
||||
@if($errors->has('markdown')) class="neg" @endif>@if(isset($model) || old('markdown')){{htmlspecialchars( old('markdown') ? old('markdown') : ($model->markdown === '' ? $model->html : $model->markdown))}}@endif</textarea>
|
||||
</div>
|
||||
|
||||
@@ -98,13 +98,14 @@
|
||||
<div class="">{{ trans('entities.pages_md_preview') }}</div>
|
||||
</div>
|
||||
<div class="markdown-display">
|
||||
<div class="page-content" ng-bind-html="displayContent"></div>
|
||||
<div class="page-content"></div>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="html"/>
|
||||
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="html" ng-value="displayContent">
|
||||
|
||||
|
||||
@if($errors->has('markdown'))
|
||||
<div class="text-neg text-small">{{ $errors->first('markdown') }}</div>
|
||||
|
||||
@@ -123,14 +123,15 @@
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@include('partials/book-tree', ['book' => $book, 'sidebarTree' => $sidebarTree])
|
||||
|
||||
<div class="card">
|
||||
<h3><i class="zmdi zmdi-info-outline"></i> {{ trans('common.details') }}</h3>
|
||||
<div class="body">
|
||||
@include('partials.entity-meta', ['entity' => $page])
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('partials/book-tree', ['book' => $book, 'sidebarTree' => $sidebarTree])
|
||||
|
||||
@stop
|
||||
|
||||
@section('body')
|
||||
|
||||
@@ -35,6 +35,21 @@ class PageContentTest extends TestCase
|
||||
$pageContent->assertSee('Well This is a second block of content');
|
||||
}
|
||||
|
||||
public function test_saving_page_with_includes()
|
||||
{
|
||||
$page = Page::first();
|
||||
$secondPage = Page::all()->get(2);
|
||||
$this->asEditor();
|
||||
$page->html = "<p>{{@$secondPage->id}}</p>";
|
||||
|
||||
$resp = $this->put($page->getUrl(), ['name' => $page->name, 'html' => $page->html, 'summary' => '']);
|
||||
|
||||
$resp->assertStatus(302);
|
||||
|
||||
$page = Page::find($page->id);
|
||||
$this->assertContains("{{@$secondPage->id}}", $page->html);
|
||||
}
|
||||
|
||||
public function test_page_revision_views_viewable()
|
||||
{
|
||||
$this->asEditor();
|
||||
|
||||
Reference in New Issue
Block a user