mirror of
https://github.com/BookStackApp/BookStack.git
synced 2026-02-14 11:19:37 +03:00
Compare commits
148 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf74f53ca7 | ||
|
|
9d67efb4a4 | ||
|
|
43122f86e8 | ||
|
|
935337862c | ||
|
|
dd671524f8 | ||
|
|
1cac3d43d3 | ||
|
|
9243c635f2 | ||
|
|
93f820d9da | ||
|
|
b62afcad1f | ||
|
|
7b32aa163f | ||
|
|
eebfd8904e | ||
|
|
0d84a0b976 | ||
|
|
88ac636c00 | ||
|
|
9dc26a8c52 | ||
|
|
6543020fd2 | ||
|
|
be4f3d62cd | ||
|
|
da58c41ab6 | ||
|
|
10d08e641c | ||
|
|
3a39b9f440 | ||
|
|
27f7aab375 | ||
|
|
337da0c467 | ||
|
|
c4e4cebf14 | ||
|
|
3f58800ed1 | ||
|
|
0931ff38e9 | ||
|
|
07bc0612c0 | ||
|
|
6dec485b45 | ||
|
|
a441faf65c | ||
|
|
50ee1462ad | ||
|
|
1cb6ae39c8 | ||
|
|
c667c6e235 | ||
|
|
e3e484e561 | ||
|
|
73fa18a128 | ||
|
|
5c2e3f4e56 | ||
|
|
c47b578599 | ||
|
|
e60d11ee04 | ||
|
|
7ad8314bd7 | ||
|
|
131fcae4c7 | ||
|
|
c8d893fac7 | ||
|
|
b59e5942c8 | ||
|
|
8ff969dd17 | ||
|
|
6eead437d8 | ||
|
|
0b6f83837b | ||
|
|
81eb642f75 | ||
|
|
47b08888ba | ||
|
|
32e34f10ff | ||
|
|
f455b317ec | ||
|
|
08b967607f | ||
|
|
90883bb22b | ||
|
|
0c8b6b7324 | ||
|
|
81d3bdc168 | ||
|
|
54ca4487fa | ||
|
|
25da4d9a8b | ||
|
|
f0add69b61 | ||
|
|
714c7bbd3a | ||
|
|
e0b479efef | ||
|
|
9d09c4c7b0 | ||
|
|
b89411c108 | ||
|
|
c472b82ee3 | ||
|
|
f56b3560c4 | ||
|
|
d2f5313f92 | ||
|
|
572e75b783 | ||
|
|
02dfe11ce6 | ||
|
|
83d06beb70 | ||
|
|
d2a9b312e9 | ||
|
|
b224a2c8a0 | ||
|
|
fe6dfcedf9 | ||
|
|
a8cfc059c8 | ||
|
|
1614b2bab0 | ||
|
|
01260d95f3 | ||
|
|
d69ba6b47a | ||
|
|
098128aafb | ||
|
|
92c9837157 | ||
|
|
18e5f86ffa | ||
|
|
c860645a5a | ||
|
|
fcb93dc7c8 | ||
|
|
fcdb39e428 | ||
|
|
1b3e1863f4 | ||
|
|
fbc2175789 | ||
|
|
8099c431bb | ||
|
|
efbfe0f7af | ||
|
|
66402b474c | ||
|
|
c3986cedfc | ||
|
|
b5a2d3c1c4 | ||
|
|
a6862362c1 | ||
|
|
7d4ec0d633 | ||
|
|
85544c04a9 | ||
|
|
0a8ff6ffad | ||
|
|
04274078c4 | ||
|
|
aac9fbf236 | ||
|
|
08e290f3ea | ||
|
|
86602854ac | ||
|
|
f47f0e05d6 | ||
|
|
4bdec0d214 | ||
|
|
6a7d7e7c2b | ||
|
|
c83a51f7e2 | ||
|
|
b922c8029e | ||
|
|
653761e67d | ||
|
|
d59ff132ab | ||
|
|
e6e740b2a1 | ||
|
|
af6f4e6c8c | ||
|
|
69a0f8d502 | ||
|
|
6d35fb5237 | ||
|
|
6eb63a1e03 | ||
|
|
8774f1a320 | ||
|
|
6ca8ccd330 | ||
|
|
df88ffa159 | ||
|
|
dcbb8ad960 | ||
|
|
0f2ffa9545 | ||
|
|
6bae16f7e9 | ||
|
|
f5ca7ab1c8 | ||
|
|
7dd11decb8 | ||
|
|
79d0f707e6 | ||
|
|
369dc02e78 | ||
|
|
9d2e65b73d | ||
|
|
f421d83627 | ||
|
|
be2ca9d4bb | ||
|
|
17bca662a7 | ||
|
|
1776204870 | ||
|
|
985e214d94 | ||
|
|
2bcc159fd6 | ||
|
|
fb7c12438d | ||
|
|
b2cd363539 | ||
|
|
f668bee88b | ||
|
|
642f2760cc | ||
|
|
37aa8b05f8 | ||
|
|
d640cc1eee | ||
|
|
c2d6e98985 | ||
|
|
84b4fe6176 | ||
|
|
decdf5714b | ||
|
|
9da600caf9 | ||
|
|
45aee2a1c1 | ||
|
|
f5df5ac7d5 | ||
|
|
fb29f4119d | ||
|
|
93795b6eda | ||
|
|
f7b808a9e6 | ||
|
|
4948b443b6 | ||
|
|
448068e318 | ||
|
|
7d81a95156 | ||
|
|
a9bf2ed398 | ||
|
|
771f781e7f | ||
|
|
78be8535f7 | ||
|
|
6c4c1ccb58 | ||
|
|
562225a77b | ||
|
|
b936e1f403 | ||
|
|
b3cc3130f0 | ||
|
|
0363fc4ea1 | ||
|
|
134a96fa32 | ||
|
|
56f444a8a7 |
2
.browserslistrc
Normal file
2
.browserslistrc
Normal file
@@ -0,0 +1,2 @@
|
||||
>0.25%
|
||||
not op_mini all
|
||||
@@ -56,6 +56,8 @@ TWITCH_APP_SECRET=false
|
||||
GITLAB_APP_ID=false
|
||||
GITLAB_APP_SECRET=false
|
||||
GITLAB_BASE_URI=false
|
||||
DISCORD_APP_ID=false
|
||||
DISCORD_APP_SECRET=false
|
||||
|
||||
# External services such as Gravatar and Draw.IO
|
||||
DISABLE_EXTERNAL_SERVICES=false
|
||||
@@ -67,6 +69,13 @@ LDAP_DN=false
|
||||
LDAP_PASS=false
|
||||
LDAP_USER_FILTER=false
|
||||
LDAP_VERSION=false
|
||||
# Do you want to sync LDAP groups to BookStack roles for a user
|
||||
LDAP_USER_TO_GROUPS=false
|
||||
# What is the LDAP attribute for group memberships
|
||||
LDAP_GROUP_ATTRIBUTE="memberOf"
|
||||
# Would you like to remove users from roles on BookStack if they do not match on LDAP
|
||||
# If false, the ldap groups-roles sync will only add users to roles
|
||||
LDAP_REMOVE_FROM_GROUPS=false
|
||||
|
||||
# Mail settings
|
||||
MAIL_DRIVER=smtp
|
||||
|
||||
21
.github/ISSUE_TEMPLATE.md
vendored
21
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,21 +0,0 @@
|
||||
### For Feature Requests
|
||||
|
||||
Desired Feature:
|
||||
|
||||
### For Bug Reports
|
||||
|
||||
* BookStack Version *(Found in settings, Please don't put 'latest')*:
|
||||
* PHP Version:
|
||||
* MySQL Version:
|
||||
|
||||
##### Expected Behavior
|
||||
|
||||
|
||||
|
||||
##### Current Behavior
|
||||
|
||||
|
||||
|
||||
##### Steps to Reproduce
|
||||
|
||||
|
||||
29
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
29
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**Steps To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Your Configuration (please complete the following information):**
|
||||
- Exact BookStack Version (Found in settings):
|
||||
- PHP Version:
|
||||
- Hosting Method (Nginx/Apache/Docker):
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
14
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
**Describe the feature you'd like**
|
||||
A clear description of the feature you'd like implemented in BookStack.
|
||||
|
||||
**Describe the benefits this feature would bring to BookStack users**
|
||||
Explain the measurable benefits this feature would achieve.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
17
app/Book.php
17
app/Book.php
@@ -48,14 +48,6 @@ class Book extends Entity
|
||||
{
|
||||
return $this->belongsTo(Image::class, 'image_id');
|
||||
}
|
||||
/*
|
||||
* Get the edit url for this book.
|
||||
* @return string
|
||||
*/
|
||||
public function getEditUrl()
|
||||
{
|
||||
return $this->getUrl() . '/edit';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all pages within this book.
|
||||
@@ -75,6 +67,15 @@ class Book extends Entity
|
||||
return $this->hasMany(Chapter::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the shelves this book is contained within.
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function shelves()
|
||||
{
|
||||
return $this->belongsToMany(Bookshelf::class, 'bookshelves_books', 'book_id', 'bookshelf_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an excerpt of this book's description to the specified length or less.
|
||||
* @param int $length
|
||||
|
||||
83
app/Bookshelf.php
Normal file
83
app/Bookshelf.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php namespace BookStack;
|
||||
|
||||
class Bookshelf extends Entity
|
||||
{
|
||||
protected $table = 'bookshelves';
|
||||
|
||||
public $searchFactor = 3;
|
||||
|
||||
protected $fillable = ['name', 'description', 'image_id'];
|
||||
|
||||
/**
|
||||
* Get the books in this shelf.
|
||||
* Should not be used directly since does not take into account permissions.
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
*/
|
||||
public function books()
|
||||
{
|
||||
return $this->belongsToMany(Book::class, 'bookshelves_books', 'bookshelf_id', 'book_id')->orderBy('order', 'asc');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the url for this bookshelf.
|
||||
* @param string|bool $path
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl($path = false)
|
||||
{
|
||||
if ($path !== false) {
|
||||
return baseUrl('/shelves/' . urlencode($this->slug) . '/' . trim($path, '/'));
|
||||
}
|
||||
return baseUrl('/shelves/' . urlencode($this->slug));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns BookShelf cover image, if cover does not exists return default cover image.
|
||||
* @param int $width - Width of the image
|
||||
* @param int $height - Height of the image
|
||||
* @return string
|
||||
*/
|
||||
public function getBookCover($width = 440, $height = 250)
|
||||
{
|
||||
$default = baseUrl('/book_default_cover.png');
|
||||
if (!$this->image_id) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
try {
|
||||
$cover = $this->cover ? baseUrl($this->cover->getThumb($width, $height, false)) : $default;
|
||||
} catch (\Exception $err) {
|
||||
$cover = $default;
|
||||
}
|
||||
return $cover;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the cover image of the book
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function cover()
|
||||
{
|
||||
return $this->belongsTo(Image::class, 'image_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an excerpt of this book's description to the specified length or less.
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
public function getExcerpt($length = 100)
|
||||
{
|
||||
$description = $this->description;
|
||||
return strlen($description) > $length ? substr($description, 0, $length-3) . '...' : $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a generalised, common raw query that can be 'unioned' across entities.
|
||||
* @return string
|
||||
*/
|
||||
public function entityRawQuery()
|
||||
{
|
||||
return "'BookStack\\\\BookShelf' as entity_type, id, id as entity_id, slug, name, {$this->textField} as text,'' as html, '0' as book_id, '0' as priority, '0' as chapter_id, '0' as draft, created_by, updated_by, updated_at, created_at";
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,9 @@ class CleanupImages extends Command
|
||||
|
||||
protected function showDeletedImages($paths)
|
||||
{
|
||||
if ($this->getOutput()->getVerbosity() <= OutputInterface::VERBOSITY_NORMAL) return;
|
||||
if ($this->getOutput()->getVerbosity() <= OutputInterface::VERBOSITY_NORMAL) {
|
||||
return;
|
||||
}
|
||||
if (count($paths) > 0) {
|
||||
$this->line('Images to delete:');
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ class Entity extends Ownable
|
||||
*/
|
||||
public static function getEntityInstance($type)
|
||||
{
|
||||
$types = ['Page', 'Book', 'Chapter'];
|
||||
$types = ['Page', 'Book', 'Chapter', 'Bookshelf'];
|
||||
$className = str_replace([' ', '-', '_'], '', ucwords($type));
|
||||
if (!in_array($className, $types)) {
|
||||
return null;
|
||||
@@ -168,10 +168,10 @@ class Entity extends Ownable
|
||||
*/
|
||||
public function getShortName($length = 25)
|
||||
{
|
||||
if (strlen($this->name) <= $length) {
|
||||
if (mb_strlen($this->name) <= $length) {
|
||||
return $this->name;
|
||||
}
|
||||
return substr($this->name, 0, $length - 3) . '...';
|
||||
return mb_substr($this->name, 0, $length - 3) . '...';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
6
app/Exceptions/SocialSignInAccountNotUsed.php
Normal file
6
app/Exceptions/SocialSignInAccountNotUsed.php
Normal file
@@ -0,0 +1,6 @@
|
||||
<?php namespace BookStack\Exceptions;
|
||||
|
||||
class SocialSignInAccountNotUsed extends SocialSignInException
|
||||
{
|
||||
|
||||
}
|
||||
@@ -201,10 +201,7 @@ class AttachmentController extends Controller
|
||||
}
|
||||
|
||||
$attachmentContents = $this->attachmentService->getAttachmentFromStorage($attachment);
|
||||
return response($attachmentContents, 200, [
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
'Content-Disposition' => 'attachment; filename="'. $attachment->getFileName() .'"'
|
||||
]);
|
||||
return $this->downloadResponse($attachmentContents, $attachment->getFileName());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace BookStack\Http\Controllers\Auth;
|
||||
use BookStack\Exceptions\AuthException;
|
||||
use BookStack\Http\Controllers\Controller;
|
||||
use BookStack\Repos\UserRepo;
|
||||
use BookStack\Services\LdapService;
|
||||
use BookStack\Services\SocialAuthService;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
@@ -36,18 +37,21 @@ class LoginController extends Controller
|
||||
protected $redirectAfterLogout = '/login';
|
||||
|
||||
protected $socialAuthService;
|
||||
protected $ldapService;
|
||||
protected $userRepo;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @param SocialAuthService $socialAuthService
|
||||
* @param LdapService $ldapService
|
||||
* @param UserRepo $userRepo
|
||||
*/
|
||||
public function __construct(SocialAuthService $socialAuthService, UserRepo $userRepo)
|
||||
public function __construct(SocialAuthService $socialAuthService, LdapService $ldapService, UserRepo $userRepo)
|
||||
{
|
||||
$this->middleware('guest', ['only' => ['getLogin', 'postLogin']]);
|
||||
$this->socialAuthService = $socialAuthService;
|
||||
$this->ldapService = $ldapService;
|
||||
$this->userRepo = $userRepo;
|
||||
$this->redirectPath = baseUrl('/');
|
||||
$this->redirectAfterLogout = baseUrl('/login');
|
||||
@@ -66,6 +70,7 @@ class LoginController extends Controller
|
||||
* @param Authenticatable $user
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @throws AuthException
|
||||
* @throws \BookStack\Exceptions\LdapException
|
||||
*/
|
||||
protected function authenticated(Request $request, Authenticatable $user)
|
||||
{
|
||||
@@ -96,6 +101,11 @@ class LoginController extends Controller
|
||||
auth()->login($user);
|
||||
}
|
||||
|
||||
// Sync LDAP groups if required
|
||||
if ($this->ldapService->shouldSyncGroups()) {
|
||||
$this->ldapService->syncGroups($user, $request->get($this->username()));
|
||||
}
|
||||
|
||||
$path = session()->pull('url.intended', '/');
|
||||
$path = baseUrl($path, true);
|
||||
return redirect($path);
|
||||
@@ -125,6 +135,7 @@ class LoginController extends Controller
|
||||
* Redirect to the relevant social site.
|
||||
* @param $socialDriver
|
||||
* @return \Symfony\Component\HttpFoundation\RedirectResponse
|
||||
* @throws \BookStack\Exceptions\SocialDriverNotConfigured
|
||||
*/
|
||||
public function getSocialLogin($socialDriver)
|
||||
{
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace BookStack\Http\Controllers\Auth;
|
||||
|
||||
use BookStack\Exceptions\ConfirmationEmailException;
|
||||
use BookStack\Exceptions\SocialSignInAccountNotUsed;
|
||||
use BookStack\Exceptions\SocialSignInException;
|
||||
use BookStack\Exceptions\UserRegistrationException;
|
||||
use BookStack\Repos\UserRepo;
|
||||
@@ -16,6 +16,7 @@ use Illuminate\Http\Response;
|
||||
use Validator;
|
||||
use BookStack\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\RegistersUsers;
|
||||
use Laravel\Socialite\Contracts\User as SocialUser;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
@@ -133,25 +134,28 @@ class RegisterController extends Controller
|
||||
* The registrations flow for all users.
|
||||
* @param array $userData
|
||||
* @param bool|false|SocialAccount $socialAccount
|
||||
* @param bool $emailVerified
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
* @throws UserRegistrationException
|
||||
*/
|
||||
protected function registerUser(array $userData, $socialAccount = false)
|
||||
protected function registerUser(array $userData, $socialAccount = false, $emailVerified = false)
|
||||
{
|
||||
if (setting('registration-restrict')) {
|
||||
$restrictedEmailDomains = explode(',', str_replace(' ', '', setting('registration-restrict')));
|
||||
$registrationRestrict = setting('registration-restrict');
|
||||
|
||||
if ($registrationRestrict) {
|
||||
$restrictedEmailDomains = explode(',', str_replace(' ', '', $registrationRestrict));
|
||||
$userEmailDomain = $domain = substr(strrchr($userData['email'], "@"), 1);
|
||||
if (!in_array($userEmailDomain, $restrictedEmailDomains)) {
|
||||
throw new UserRegistrationException(trans('auth.registration_email_domain_invalid'), '/register');
|
||||
}
|
||||
}
|
||||
|
||||
$newUser = $this->userRepo->registerNew($userData);
|
||||
$newUser = $this->userRepo->registerNew($userData, $emailVerified);
|
||||
if ($socialAccount) {
|
||||
$newUser->socialAccounts()->save($socialAccount);
|
||||
}
|
||||
|
||||
if (setting('registration-confirmation') || setting('registration-restrict')) {
|
||||
if ((setting('registration-confirmation') || $registrationRestrict) && !$emailVerified) {
|
||||
$newUser->save();
|
||||
|
||||
try {
|
||||
@@ -250,7 +254,6 @@ class RegisterController extends Controller
|
||||
* @throws SocialSignInException
|
||||
* @throws UserRegistrationException
|
||||
* @throws \BookStack\Exceptions\SocialDriverNotConfigured
|
||||
* @throws ConfirmationEmailException
|
||||
*/
|
||||
public function socialCallback($socialDriver, Request $request)
|
||||
{
|
||||
@@ -267,12 +270,24 @@ class RegisterController extends Controller
|
||||
}
|
||||
|
||||
$action = session()->pull('social-callback');
|
||||
|
||||
// Attempt login or fall-back to register if allowed.
|
||||
$socialUser = $this->socialAuthService->getSocialUser($socialDriver);
|
||||
if ($action == 'login') {
|
||||
return $this->socialAuthService->handleLoginCallback($socialDriver);
|
||||
try {
|
||||
return $this->socialAuthService->handleLoginCallback($socialDriver, $socialUser);
|
||||
} catch (SocialSignInAccountNotUsed $exception) {
|
||||
if ($this->socialAuthService->driverAutoRegisterEnabled($socialDriver)) {
|
||||
return $this->socialRegisterCallback($socialDriver, $socialUser);
|
||||
}
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
|
||||
if ($action == 'register') {
|
||||
return $this->socialRegisterCallback($socialDriver);
|
||||
return $this->socialRegisterCallback($socialDriver, $socialUser);
|
||||
}
|
||||
|
||||
return redirect()->back();
|
||||
}
|
||||
|
||||
@@ -288,15 +303,16 @@ class RegisterController extends Controller
|
||||
|
||||
/**
|
||||
* Register a new user after a registration callback.
|
||||
* @param $socialDriver
|
||||
* @param string $socialDriver
|
||||
* @param SocialUser $socialUser
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
* @throws UserRegistrationException
|
||||
* @throws \BookStack\Exceptions\SocialDriverNotConfigured
|
||||
*/
|
||||
protected function socialRegisterCallback($socialDriver)
|
||||
protected function socialRegisterCallback(string $socialDriver, SocialUser $socialUser)
|
||||
{
|
||||
$socialUser = $this->socialAuthService->handleRegistrationCallback($socialDriver);
|
||||
$socialUser = $this->socialAuthService->handleRegistrationCallback($socialDriver, $socialUser);
|
||||
$socialAccount = $this->socialAuthService->fillSocialAccount($socialDriver, $socialUser);
|
||||
$emailVerified = $this->socialAuthService->driverAutoConfirmEmailEnabled($socialDriver);
|
||||
|
||||
// Create an array of the user data to create a new user instance
|
||||
$userData = [
|
||||
@@ -304,6 +320,6 @@ class RegisterController extends Controller
|
||||
'email' => $socialUser->getEmail(),
|
||||
'password' => str_random(30)
|
||||
];
|
||||
return $this->registerUser($userData, $socialAccount);
|
||||
return $this->registerUser($userData, $socialAccount, $emailVerified);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,10 +299,7 @@ class BookController extends Controller
|
||||
{
|
||||
$book = $this->entityRepo->getBySlug('book', $bookSlug);
|
||||
$pdfContent = $this->exportService->bookToPdf($book);
|
||||
return response()->make($pdfContent, 200, [
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
'Content-Disposition' => 'attachment; filename="' . $bookSlug . '.pdf'
|
||||
]);
|
||||
return $this->downloadResponse($pdfContent, $bookSlug . '.pdf');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,10 +311,7 @@ class BookController extends Controller
|
||||
{
|
||||
$book = $this->entityRepo->getBySlug('book', $bookSlug);
|
||||
$htmlContent = $this->exportService->bookToContainedHtml($book);
|
||||
return response()->make($htmlContent, 200, [
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
'Content-Disposition' => 'attachment; filename="' . $bookSlug . '.html'
|
||||
]);
|
||||
return $this->downloadResponse($htmlContent, $bookSlug . '.html');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -328,10 +322,7 @@ class BookController extends Controller
|
||||
public function exportPlainText($bookSlug)
|
||||
{
|
||||
$book = $this->entityRepo->getBySlug('book', $bookSlug);
|
||||
$htmlContent = $this->exportService->bookToPlainText($book);
|
||||
return response()->make($htmlContent, 200, [
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
'Content-Disposition' => 'attachment; filename="' . $bookSlug . '.txt'
|
||||
]);
|
||||
$textContent = $this->exportService->bookToPlainText($book);
|
||||
return $this->downloadResponse($textContent, $bookSlug . '.txt');
|
||||
}
|
||||
}
|
||||
|
||||
243
app/Http/Controllers/BookshelfController.php
Normal file
243
app/Http/Controllers/BookshelfController.php
Normal file
@@ -0,0 +1,243 @@
|
||||
<?php namespace BookStack\Http\Controllers;
|
||||
|
||||
use Activity;
|
||||
use BookStack\Book;
|
||||
use BookStack\Bookshelf;
|
||||
use BookStack\Repos\EntityRepo;
|
||||
use BookStack\Repos\UserRepo;
|
||||
use BookStack\Services\ExportService;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Views;
|
||||
|
||||
class BookshelfController extends Controller
|
||||
{
|
||||
|
||||
protected $entityRepo;
|
||||
protected $userRepo;
|
||||
protected $exportService;
|
||||
|
||||
/**
|
||||
* BookController constructor.
|
||||
* @param EntityRepo $entityRepo
|
||||
* @param UserRepo $userRepo
|
||||
* @param ExportService $exportService
|
||||
*/
|
||||
public function __construct(EntityRepo $entityRepo, UserRepo $userRepo, ExportService $exportService)
|
||||
{
|
||||
$this->entityRepo = $entityRepo;
|
||||
$this->userRepo = $userRepo;
|
||||
$this->exportService = $exportService;
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the book.
|
||||
* @return Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$shelves = $this->entityRepo->getAllPaginated('bookshelf', 18);
|
||||
$recents = $this->signedIn ? $this->entityRepo->getRecentlyViewed('bookshelf', 4, 0) : false;
|
||||
$popular = $this->entityRepo->getPopular('bookshelf', 4, 0);
|
||||
$new = $this->entityRepo->getRecentlyCreated('bookshelf', 4, 0);
|
||||
$shelvesViewType = setting()->getUser($this->currentUser, 'bookshelves_view_type', config('app.views.bookshelves', 'grid'));
|
||||
|
||||
$this->setPageTitle(trans('entities.shelves'));
|
||||
return view('shelves/index', [
|
||||
'shelves' => $shelves,
|
||||
'recents' => $recents,
|
||||
'popular' => $popular,
|
||||
'new' => $new,
|
||||
'shelvesViewType' => $shelvesViewType
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new bookshelf.
|
||||
* @return Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$this->checkPermission('bookshelf-create-all');
|
||||
$books = $this->entityRepo->getAll('book', false, 'update');
|
||||
$this->setPageTitle(trans('entities.shelves_create'));
|
||||
return view('shelves/create', ['books' => $books]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created bookshelf in storage.
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$this->checkPermission('bookshelf-create-all');
|
||||
$this->validate($request, [
|
||||
'name' => 'required|string|max:255',
|
||||
'description' => 'string|max:1000',
|
||||
]);
|
||||
|
||||
$bookshelf = $this->entityRepo->createFromInput('bookshelf', $request->all());
|
||||
$this->entityRepo->updateShelfBooks($bookshelf, $request->get('books', ''));
|
||||
Activity::add($bookshelf, 'bookshelf_create');
|
||||
|
||||
return redirect($bookshelf->getUrl());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Display the specified bookshelf.
|
||||
* @param String $slug
|
||||
* @return Response
|
||||
* @throws \BookStack\Exceptions\NotFoundException
|
||||
*/
|
||||
public function show(string $slug)
|
||||
{
|
||||
$bookshelf = $this->entityRepo->getBySlug('bookshelf', $slug); /** @var $bookshelf Bookshelf */
|
||||
$this->checkOwnablePermission('book-view', $bookshelf);
|
||||
|
||||
$books = $this->entityRepo->getBookshelfChildren($bookshelf);
|
||||
Views::add($bookshelf);
|
||||
|
||||
$this->setPageTitle($bookshelf->getShortName());
|
||||
return view('shelves/show', [
|
||||
'shelf' => $bookshelf,
|
||||
'books' => $books,
|
||||
'activity' => Activity::entityActivity($bookshelf, 20, 0)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified bookshelf.
|
||||
* @param $slug
|
||||
* @return Response
|
||||
* @throws \BookStack\Exceptions\NotFoundException
|
||||
*/
|
||||
public function edit(string $slug)
|
||||
{
|
||||
$bookshelf = $this->entityRepo->getBySlug('bookshelf', $slug); /** @var $bookshelf Bookshelf */
|
||||
$this->checkOwnablePermission('bookshelf-update', $bookshelf);
|
||||
|
||||
$shelfBooks = $this->entityRepo->getBookshelfChildren($bookshelf);
|
||||
$shelfBookIds = $shelfBooks->pluck('id');
|
||||
$books = $this->entityRepo->getAll('book', false, 'update');
|
||||
$books = $books->filter(function ($book) use ($shelfBookIds) {
|
||||
return !$shelfBookIds->contains($book->id);
|
||||
});
|
||||
|
||||
$this->setPageTitle(trans('entities.shelves_edit_named', ['name' => $bookshelf->getShortName()]));
|
||||
return view('shelves/edit', [
|
||||
'shelf' => $bookshelf,
|
||||
'books' => $books,
|
||||
'shelfBooks' => $shelfBooks,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the specified bookshelf in storage.
|
||||
* @param Request $request
|
||||
* @param string $slug
|
||||
* @return Response
|
||||
* @throws \BookStack\Exceptions\NotFoundException
|
||||
*/
|
||||
public function update(Request $request, string $slug)
|
||||
{
|
||||
$shelf = $this->entityRepo->getBySlug('bookshelf', $slug); /** @var $bookshelf Bookshelf */
|
||||
$this->checkOwnablePermission('bookshelf-update', $shelf);
|
||||
$this->validate($request, [
|
||||
'name' => 'required|string|max:255',
|
||||
'description' => 'string|max:1000',
|
||||
]);
|
||||
|
||||
$shelf = $this->entityRepo->updateFromInput('bookshelf', $shelf, $request->all());
|
||||
$this->entityRepo->updateShelfBooks($shelf, $request->get('books', ''));
|
||||
Activity::add($shelf, 'bookshelf_update');
|
||||
|
||||
return redirect($shelf->getUrl());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shows the page to confirm deletion
|
||||
* @param $slug
|
||||
* @return \Illuminate\View\View
|
||||
* @throws \BookStack\Exceptions\NotFoundException
|
||||
*/
|
||||
public function showDelete(string $slug)
|
||||
{
|
||||
$bookshelf = $this->entityRepo->getBySlug('bookshelf', $slug); /** @var $bookshelf Bookshelf */
|
||||
$this->checkOwnablePermission('bookshelf-delete', $bookshelf);
|
||||
|
||||
$this->setPageTitle(trans('entities.shelves_delete_named', ['name' => $bookshelf->getShortName()]));
|
||||
return view('shelves/delete', ['shelf' => $bookshelf]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified bookshelf from storage.
|
||||
* @param string $slug
|
||||
* @return Response
|
||||
* @throws \BookStack\Exceptions\NotFoundException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function destroy(string $slug)
|
||||
{
|
||||
$bookshelf = $this->entityRepo->getBySlug('bookshelf', $slug); /** @var $bookshelf Bookshelf */
|
||||
$this->checkOwnablePermission('bookshelf-delete', $bookshelf);
|
||||
Activity::addMessage('bookshelf_delete', 0, $bookshelf->name);
|
||||
$this->entityRepo->destroyBookshelf($bookshelf);
|
||||
return redirect('/shelves');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the Restrictions view.
|
||||
* @param $slug
|
||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||
* @throws \BookStack\Exceptions\NotFoundException
|
||||
*/
|
||||
public function showRestrict(string $slug)
|
||||
{
|
||||
$bookshelf = $this->entityRepo->getBySlug('bookshelf', $slug);
|
||||
$this->checkOwnablePermission('restrictions-manage', $bookshelf);
|
||||
|
||||
$roles = $this->userRepo->getRestrictableRoles();
|
||||
return view('shelves.restrictions', [
|
||||
'shelf' => $bookshelf,
|
||||
'roles' => $roles
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the restrictions for this bookshelf.
|
||||
* @param $slug
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
* @throws \BookStack\Exceptions\NotFoundException
|
||||
*/
|
||||
public function restrict(string $slug, Request $request)
|
||||
{
|
||||
$bookshelf = $this->entityRepo->getBySlug('bookshelf', $slug);
|
||||
$this->checkOwnablePermission('restrictions-manage', $bookshelf);
|
||||
|
||||
$this->entityRepo->updateEntityPermissionsFromRequest($request, $bookshelf);
|
||||
session()->flash('success', trans('entities.shelves_permissions_updated'));
|
||||
return redirect($bookshelf->getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the permissions of a bookshelf to the child books.
|
||||
* @param string $slug
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
* @throws \BookStack\Exceptions\NotFoundException
|
||||
*/
|
||||
public function copyPermissions(string $slug)
|
||||
{
|
||||
$bookshelf = $this->entityRepo->getBySlug('bookshelf', $slug);
|
||||
$this->checkOwnablePermission('restrictions-manage', $bookshelf);
|
||||
|
||||
$updateCount = $this->entityRepo->copyBookshelfPermissions($bookshelf);
|
||||
session()->flash('success', trans('entities.shelves_copy_permission_success', ['count' => $updateCount]));
|
||||
return redirect($bookshelf->getUrl());
|
||||
}
|
||||
}
|
||||
@@ -250,10 +250,7 @@ class ChapterController extends Controller
|
||||
{
|
||||
$chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
|
||||
$pdfContent = $this->exportService->chapterToPdf($chapter);
|
||||
return response()->make($pdfContent, 200, [
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
'Content-Disposition' => 'attachment; filename="' . $chapterSlug . '.pdf'
|
||||
]);
|
||||
return $this->downloadResponse($pdfContent, $chapterSlug . '.pdf');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -266,10 +263,7 @@ class ChapterController extends Controller
|
||||
{
|
||||
$chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
|
||||
$containedHtml = $this->exportService->chapterToContainedHtml($chapter);
|
||||
return response()->make($containedHtml, 200, [
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
'Content-Disposition' => 'attachment; filename="' . $chapterSlug . '.html'
|
||||
]);
|
||||
return $this->downloadResponse($containedHtml, $chapterSlug . '.html');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,10 +275,7 @@ class ChapterController extends Controller
|
||||
public function exportPlainText($bookSlug, $chapterSlug)
|
||||
{
|
||||
$chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
|
||||
$containedHtml = $this->exportService->chapterToPlainText($chapter);
|
||||
return response()->make($containedHtml, 200, [
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
'Content-Disposition' => 'attachment; filename="' . $chapterSlug . '.txt'
|
||||
]);
|
||||
$chapterText = $this->exportService->chapterToPlainText($chapter);
|
||||
return $this->downloadResponse($chapterText, $chapterSlug . '.txt');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,6 @@ abstract class Controller extends BaseController
|
||||
|
||||
/**
|
||||
* Create the response for when a request fails validation.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param array $errors
|
||||
* @return \Symfony\Component\HttpFoundation\Response
|
||||
@@ -151,4 +150,18 @@ abstract class Controller extends BaseController
|
||||
->withInput($request->input())
|
||||
->withErrors($errors, $this->errorBag());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a response that forces a download in the browser.
|
||||
* @param string $content
|
||||
* @param string $fileName
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
protected function downloadResponse(string $content, string $fileName)
|
||||
{
|
||||
return response()->make($content, 200, [
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
'Content-Disposition' => 'attachment; filename="' . $fileName . '"'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,42 +33,42 @@ class HomeController extends Controller
|
||||
$recents = $this->signedIn ? Views::getUserRecentlyViewed(12*$recentFactor, 0) : $this->entityRepo->getRecentlyCreated('book', 12*$recentFactor);
|
||||
$recentlyUpdatedPages = $this->entityRepo->getRecentlyUpdated('page', 12);
|
||||
|
||||
|
||||
$customHomepage = false;
|
||||
$books = false;
|
||||
$booksViewType = false;
|
||||
|
||||
// Check book homepage
|
||||
$bookHomepageSetting = setting('app-book-homepage');
|
||||
if ($bookHomepageSetting) {
|
||||
$books = $this->entityRepo->getAllPaginated('book', 18);
|
||||
$booksViewType = setting()->getUser($this->currentUser, 'books_view_type', config('app.views.books', 'list'));
|
||||
} else {
|
||||
// Check custom homepage
|
||||
$homepageSetting = setting('app-homepage');
|
||||
if ($homepageSetting) {
|
||||
$id = intval(explode(':', $homepageSetting)[0]);
|
||||
$customHomepage = $this->entityRepo->getById('page', $id, false, true);
|
||||
$this->entityRepo->renderPage($customHomepage, true);
|
||||
}
|
||||
$homepageOptions = ['default', 'books', 'bookshelves', 'page'];
|
||||
$homepageOption = setting('app-homepage-type', 'default');
|
||||
if (!in_array($homepageOption, $homepageOptions)) {
|
||||
$homepageOption = 'default';
|
||||
}
|
||||
|
||||
$view = 'home';
|
||||
if ($bookHomepageSetting) {
|
||||
$view = 'home-book';
|
||||
} else if ($customHomepage) {
|
||||
$view = 'home-custom';
|
||||
}
|
||||
|
||||
return view('common/' . $view, [
|
||||
$commonData = [
|
||||
'activity' => $activity,
|
||||
'recents' => $recents,
|
||||
'recentlyUpdatedPages' => $recentlyUpdatedPages,
|
||||
'draftPages' => $draftPages,
|
||||
'customHomepage' => $customHomepage,
|
||||
'books' => $books,
|
||||
'booksViewType' => $booksViewType
|
||||
]);
|
||||
];
|
||||
|
||||
if ($homepageOption === 'bookshelves') {
|
||||
$shelves = $this->entityRepo->getAllPaginated('bookshelf', 18);
|
||||
$shelvesViewType = setting()->getUser($this->currentUser, 'bookshelves_view_type', config('app.views.bookshelves', 'grid'));
|
||||
$data = array_merge($commonData, ['shelves' => $shelves, 'shelvesViewType' => $shelvesViewType]);
|
||||
return view('common.home-shelves', $data);
|
||||
}
|
||||
|
||||
if ($homepageOption === 'books') {
|
||||
$books = $this->entityRepo->getAllPaginated('book', 18);
|
||||
$booksViewType = setting()->getUser($this->currentUser, 'books_view_type', config('app.views.books', 'list'));
|
||||
$data = array_merge($commonData, ['books' => $books, 'booksViewType' => $booksViewType]);
|
||||
return view('common.home-book', $data);
|
||||
}
|
||||
|
||||
if ($homepageOption === 'page') {
|
||||
$homepageSetting = setting('app-homepage', '0:');
|
||||
$id = intval(explode(':', $homepageSetting)[0]);
|
||||
$customHomepage = $this->entityRepo->getById('page', $id, false, true);
|
||||
$this->entityRepo->renderPage($customHomepage, true);
|
||||
return view('common.home-custom', array_merge($commonData, ['customHomepage' => $customHomepage]));
|
||||
}
|
||||
|
||||
return view('common.home', $commonData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,6 @@ use BookStack\Exceptions\NotFoundException;
|
||||
use BookStack\Repos\EntityRepo;
|
||||
use BookStack\Repos\UserRepo;
|
||||
use BookStack\Services\ExportService;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use Views;
|
||||
@@ -38,11 +37,18 @@ class PageController extends Controller
|
||||
* @param string $chapterSlug
|
||||
* @return Response
|
||||
* @internal param bool $pageSlug
|
||||
* @throws NotFoundException
|
||||
*/
|
||||
public function create($bookSlug, $chapterSlug = null)
|
||||
{
|
||||
$book = $this->entityRepo->getBySlug('book', $bookSlug);
|
||||
$chapter = $chapterSlug ? $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug) : null;
|
||||
if ($chapterSlug !== null) {
|
||||
$chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
|
||||
$book = $chapter->book;
|
||||
} else {
|
||||
$chapter = null;
|
||||
$book = $this->entityRepo->getBySlug('book', $bookSlug);
|
||||
}
|
||||
|
||||
$parent = $chapter ? $chapter : $book;
|
||||
$this->checkOwnablePermission('page-create', $parent);
|
||||
|
||||
@@ -52,7 +58,7 @@ class PageController extends Controller
|
||||
return redirect($draft->getUrl());
|
||||
}
|
||||
|
||||
// Otherwise show edit view
|
||||
// Otherwise show the edit view if they're a guest
|
||||
$this->setPageTitle(trans('entities.pages_new'));
|
||||
return view('pages/guest-create', ['parent' => $parent]);
|
||||
}
|
||||
@@ -71,8 +77,14 @@ class PageController extends Controller
|
||||
'name' => 'required|string|max:255'
|
||||
]);
|
||||
|
||||
$book = $this->entityRepo->getBySlug('book', $bookSlug);
|
||||
$chapter = $chapterSlug ? $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug) : null;
|
||||
if ($chapterSlug !== null) {
|
||||
$chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
|
||||
$book = $chapter->book;
|
||||
} else {
|
||||
$chapter = null;
|
||||
$book = $this->entityRepo->getBySlug('book', $bookSlug);
|
||||
}
|
||||
|
||||
$parent = $chapter ? $chapter : $book;
|
||||
$this->checkOwnablePermission('page-create', $parent);
|
||||
|
||||
@@ -93,7 +105,7 @@ class PageController extends Controller
|
||||
public function editDraft($bookSlug, $pageId)
|
||||
{
|
||||
$draft = $this->entityRepo->getById('page', $pageId, true);
|
||||
$this->checkOwnablePermission('page-create', $draft->book);
|
||||
$this->checkOwnablePermission('page-create', $draft->parent);
|
||||
$this->setPageTitle(trans('entities.pages_edit_draft'));
|
||||
|
||||
$draftsEnabled = $this->signedIn;
|
||||
@@ -119,12 +131,10 @@ class PageController extends Controller
|
||||
]);
|
||||
|
||||
$input = $request->all();
|
||||
$book = $this->entityRepo->getBySlug('book', $bookSlug);
|
||||
|
||||
$draftPage = $this->entityRepo->getById('page', $pageId, true);
|
||||
$book = $draftPage->book;
|
||||
|
||||
$chapterId = intval($draftPage->chapter_id);
|
||||
$parent = $chapterId !== 0 ? $this->entityRepo->getById('chapter', $chapterId) : $book;
|
||||
$parent = $draftPage->parent;
|
||||
$this->checkOwnablePermission('page-create', $parent);
|
||||
|
||||
if ($parent->isA('chapter')) {
|
||||
@@ -444,6 +454,40 @@ class PageController extends Controller
|
||||
return redirect($page->getUrl());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Deletes a revision using the id of the specified revision.
|
||||
* @param string $bookSlug
|
||||
* @param string $pageSlug
|
||||
* @param int $revId
|
||||
* @throws NotFoundException
|
||||
* @throws BadRequestException
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
*/
|
||||
public function destroyRevision($bookSlug, $pageSlug, $revId)
|
||||
{
|
||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
||||
$this->checkOwnablePermission('page-delete', $page);
|
||||
|
||||
$revision = $page->revisions()->where('id', '=', $revId)->first();
|
||||
if ($revision === null) {
|
||||
throw new NotFoundException("Revision #{$revId} not found");
|
||||
}
|
||||
|
||||
// Get the current revision for the page
|
||||
$currentRevision = $page->getCurrentRevision();
|
||||
|
||||
// Check if its the latest revision, cannot delete latest revision.
|
||||
if (intval($currentRevision->id) === intval($revId)) {
|
||||
session()->flash('error', trans('entities.revision_cannot_delete_latest'));
|
||||
return response()->view('pages/revisions', ['page' => $page, 'book' => $page->book, 'current' => $page], 400);
|
||||
}
|
||||
|
||||
$revision->delete();
|
||||
session()->flash('success', trans('entities.revision_delete_success'));
|
||||
return view('pages/revisions', ['page' => $page, 'book' => $page->book, 'current' => $page]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Exports a page to a PDF.
|
||||
* https://github.com/barryvdh/laravel-dompdf
|
||||
@@ -456,10 +500,7 @@ class PageController extends Controller
|
||||
$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',
|
||||
'Content-Disposition' => 'attachment; filename="' . $pageSlug . '.pdf'
|
||||
]);
|
||||
return $this->downloadResponse($pdfContent, $pageSlug . '.pdf');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -473,10 +514,7 @@ class PageController extends Controller
|
||||
$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',
|
||||
'Content-Disposition' => 'attachment; filename="' . $pageSlug . '.html'
|
||||
]);
|
||||
return $this->downloadResponse($containedHtml, $pageSlug . '.html');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -488,11 +526,8 @@ class PageController extends Controller
|
||||
public function exportPlainText($bookSlug, $pageSlug)
|
||||
{
|
||||
$page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
|
||||
$containedHtml = $this->exportService->pageToPlainText($page);
|
||||
return response()->make($containedHtml, 200, [
|
||||
'Content-Type' => 'application/octet-stream',
|
||||
'Content-Disposition' => 'attachment; filename="' . $pageSlug . '.txt'
|
||||
]);
|
||||
$pageText = $this->exportService->pageToPlainText($page);
|
||||
return $this->downloadResponse($pageText, $pageSlug . '.txt');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -78,6 +78,7 @@ class PermissionController extends Controller
|
||||
* @param $id
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
* @throws PermissionsException
|
||||
*/
|
||||
public function updateRole($id, Request $request)
|
||||
{
|
||||
|
||||
@@ -252,7 +252,7 @@ class UserController extends Controller
|
||||
return $this->currentUser->id == $id;
|
||||
});
|
||||
|
||||
$viewType = $request->get('book_view_type');
|
||||
$viewType = $request->get('view_type');
|
||||
if (!in_array($viewType, ['grid', 'list'])) {
|
||||
$viewType = 'list';
|
||||
}
|
||||
@@ -262,4 +262,27 @@ class UserController extends Controller
|
||||
|
||||
return redirect()->back(302, [], "/settings/users/$id");
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the user's preferred shelf-list display setting.
|
||||
* @param $id
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function switchShelfView($id, Request $request)
|
||||
{
|
||||
$this->checkPermissionOr('users-manage', function () use ($id) {
|
||||
return $this->currentUser->id == $id;
|
||||
});
|
||||
|
||||
$viewType = $request->get('view_type');
|
||||
if (!in_array($viewType, ['grid', 'list'])) {
|
||||
$viewType = 'list';
|
||||
}
|
||||
|
||||
$user = $this->user->findOrFail($id);
|
||||
setting()->putUser($user, 'bookshelves_view_type', $viewType);
|
||||
|
||||
return redirect()->back(302, [], "/settings/users/$id");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,13 @@
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class Localization
|
||||
{
|
||||
|
||||
protected $rtlLocales = ['ar'];
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
@@ -15,21 +19,38 @@ class Localization
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
$defaultLang = config('app.locale');
|
||||
if (user()->isDefault()) {
|
||||
$locale = $defaultLang;
|
||||
$availableLocales = config('app.locales');
|
||||
foreach ($request->getLanguages() as $lang) {
|
||||
if (!in_array($lang, $availableLocales)) {
|
||||
continue;
|
||||
}
|
||||
$locale = $lang;
|
||||
break;
|
||||
}
|
||||
|
||||
if (user()->isDefault() && config('app.auto_detect_locale')) {
|
||||
$locale = $this->autoDetectLocale($request, $defaultLang);
|
||||
} else {
|
||||
$locale = setting()->getUser(user(), 'language', $defaultLang);
|
||||
}
|
||||
|
||||
// Set text direction
|
||||
if (in_array($locale, $this->rtlLocales)) {
|
||||
config()->set('app.rtl', true);
|
||||
}
|
||||
|
||||
app()->setLocale($locale);
|
||||
Carbon::setLocale($locale);
|
||||
return $next($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Autodetect the visitors locale by matching locales in their headers
|
||||
* against the locales supported by BookStack.
|
||||
* @param Request $request
|
||||
* @param string $default
|
||||
* @return string
|
||||
*/
|
||||
protected function autoDetectLocale(Request $request, string $default)
|
||||
{
|
||||
$availableLocales = config('app.locales');
|
||||
foreach ($request->getLanguages() as $lang) {
|
||||
if (in_array($lang, $availableLocales)) {
|
||||
return $lang;
|
||||
}
|
||||
}
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,5 +19,4 @@ class Image extends Ownable
|
||||
{
|
||||
return Images::getThumbnail($this, $width, $height, $keepRatio);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
18
app/Page.php
18
app/Page.php
@@ -28,6 +28,15 @@ class Page extends Entity
|
||||
return $this->belongsTo(Book::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent item
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function parent()
|
||||
{
|
||||
return $this->chapter_id ? $this->chapter() : $this->book();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the chapter that this page is in, If applicable.
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
@@ -103,4 +112,13 @@ class Page extends Entity
|
||||
$htmlQuery = $withContent ? 'html' : "'' as html";
|
||||
return "'BookStack\\\\Page' as entity_type, id, id as entity_id, slug, name, {$this->textField} as text, {$htmlQuery}, book_id, priority, chapter_id, draft, created_by, updated_by, updated_at, created_at";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current revision for the page if existing
|
||||
* @return \BookStack\PageRevision|null
|
||||
*/
|
||||
public function getCurrentRevision()
|
||||
{
|
||||
return $this->revisions()->first();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ class EventServiceProvider extends ServiceProvider
|
||||
'SocialiteProviders\Okta\OktaExtendSocialite@handle',
|
||||
'SocialiteProviders\GitLab\GitLabExtendSocialite@handle',
|
||||
'SocialiteProviders\Twitch\TwitchExtendSocialite@handle',
|
||||
'SocialiteProviders\Discord\DiscordExtendSocialite@handle',
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php namespace BookStack\Repos;
|
||||
|
||||
use BookStack\Book;
|
||||
use BookStack\Bookshelf;
|
||||
use BookStack\Chapter;
|
||||
use BookStack\Entity;
|
||||
use BookStack\Exceptions\NotFoundException;
|
||||
@@ -18,6 +19,10 @@ use Illuminate\Support\Collection;
|
||||
|
||||
class EntityRepo
|
||||
{
|
||||
/**
|
||||
* @var Bookshelf
|
||||
*/
|
||||
public $bookshelf;
|
||||
|
||||
/**
|
||||
* @var Book $book
|
||||
@@ -67,6 +72,7 @@ class EntityRepo
|
||||
|
||||
/**
|
||||
* EntityRepo constructor.
|
||||
* @param Bookshelf $bookshelf
|
||||
* @param Book $book
|
||||
* @param Chapter $chapter
|
||||
* @param Page $page
|
||||
@@ -77,6 +83,7 @@ class EntityRepo
|
||||
* @param SearchService $searchService
|
||||
*/
|
||||
public function __construct(
|
||||
Bookshelf $bookshelf,
|
||||
Book $book,
|
||||
Chapter $chapter,
|
||||
Page $page,
|
||||
@@ -86,11 +93,13 @@ class EntityRepo
|
||||
TagRepo $tagRepo,
|
||||
SearchService $searchService
|
||||
) {
|
||||
$this->bookshelf = $bookshelf;
|
||||
$this->book = $book;
|
||||
$this->chapter = $chapter;
|
||||
$this->page = $page;
|
||||
$this->pageRevision = $pageRevision;
|
||||
$this->entities = [
|
||||
'bookshelf' => $this->bookshelf,
|
||||
'page' => $this->page,
|
||||
'chapter' => $this->chapter,
|
||||
'book' => $this->book
|
||||
@@ -331,6 +340,17 @@ class EntityRepo
|
||||
->skip($count * $page)->take($count)->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the child items for a chapter sorted by priority but
|
||||
* with draft items floated to the top.
|
||||
* @param Bookshelf $bookshelf
|
||||
* @return \Illuminate\Database\Eloquent\Collection|static[]
|
||||
*/
|
||||
public function getBookshelfChildren(Bookshelf $bookshelf)
|
||||
{
|
||||
return $this->permissionService->enforceEntityRestrictions('book', $bookshelf->books())->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all child objects of a book.
|
||||
* Returns a sorted collection of Pages and Chapters.
|
||||
@@ -533,6 +553,28 @@ class EntityRepo
|
||||
return $entityModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync the books assigned to a shelf from a comma-separated list
|
||||
* of book IDs.
|
||||
* @param Bookshelf $shelf
|
||||
* @param string $books
|
||||
*/
|
||||
public function updateShelfBooks(Bookshelf $shelf, string $books)
|
||||
{
|
||||
$ids = explode(',', $books);
|
||||
|
||||
// Check books exist and match ordering
|
||||
$bookIds = $this->entityQuery('book')->whereIn('id', $ids)->get(['id'])->pluck('id');
|
||||
$syncData = [];
|
||||
foreach ($ids as $index => $id) {
|
||||
if ($bookIds->contains($id)) {
|
||||
$syncData[$id] = ['order' => $index];
|
||||
}
|
||||
}
|
||||
|
||||
$shelf->books()->sync($syncData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the book that an entity belongs to.
|
||||
* @param string $type
|
||||
@@ -704,10 +746,13 @@ class EntityRepo
|
||||
$revision->revision_number = $page->revision_count;
|
||||
$revision->save();
|
||||
|
||||
// Clear old revisions
|
||||
if ($this->pageRevision->where('page_id', '=', $page->id)->count() > 50) {
|
||||
$this->pageRevision->where('page_id', '=', $page->id)
|
||||
->orderBy('created_at', 'desc')->skip(50)->take(5)->delete();
|
||||
$revisionLimit = config('app.revision_limit');
|
||||
if ($revisionLimit !== false) {
|
||||
$revisionsToDelete = $this->pageRevision->where('page_id', '=', $page->id)
|
||||
->orderBy('created_at', 'desc')->skip(intval($revisionLimit))->take(10)->get(['id']);
|
||||
if ($revisionsToDelete->count() > 0) {
|
||||
$this->pageRevision->whereIn('id', $revisionsToDelete->pluck('id'))->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return $revision;
|
||||
@@ -1154,9 +1199,22 @@ class EntityRepo
|
||||
$this->permissionService->buildJointPermissionsForEntity($book);
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a bookshelf instance
|
||||
* @param Bookshelf $shelf
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function destroyBookshelf(Bookshelf $shelf)
|
||||
{
|
||||
$this->destroyEntityCommonRelations($shelf);
|
||||
$shelf->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy the provided book and all its child entities.
|
||||
* @param Book $book
|
||||
* @throws NotifyException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function destroyBook(Book $book)
|
||||
{
|
||||
@@ -1166,17 +1224,14 @@ class EntityRepo
|
||||
foreach ($book->chapters as $chapter) {
|
||||
$this->destroyChapter($chapter);
|
||||
}
|
||||
\Activity::removeEntity($book);
|
||||
$book->views()->delete();
|
||||
$book->permissions()->delete();
|
||||
$this->permissionService->deleteJointPermissionsForEntity($book);
|
||||
$this->searchService->deleteEntityTerms($book);
|
||||
$this->destroyEntityCommonRelations($book);
|
||||
$book->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy a chapter and its relations.
|
||||
* @param Chapter $chapter
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function destroyChapter(Chapter $chapter)
|
||||
{
|
||||
@@ -1186,11 +1241,7 @@ class EntityRepo
|
||||
$page->save();
|
||||
}
|
||||
}
|
||||
\Activity::removeEntity($chapter);
|
||||
$chapter->views()->delete();
|
||||
$chapter->permissions()->delete();
|
||||
$this->permissionService->deleteJointPermissionsForEntity($chapter);
|
||||
$this->searchService->deleteEntityTerms($chapter);
|
||||
$this->destroyEntityCommonRelations($chapter);
|
||||
$chapter->delete();
|
||||
}
|
||||
|
||||
@@ -1198,23 +1249,18 @@ class EntityRepo
|
||||
* Destroy a given page along with its dependencies.
|
||||
* @param Page $page
|
||||
* @throws NotifyException
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function destroyPage(Page $page)
|
||||
{
|
||||
\Activity::removeEntity($page);
|
||||
$page->views()->delete();
|
||||
$page->tags()->delete();
|
||||
$page->revisions()->delete();
|
||||
$page->permissions()->delete();
|
||||
$this->permissionService->deleteJointPermissionsForEntity($page);
|
||||
$this->searchService->deleteEntityTerms($page);
|
||||
|
||||
// Check if set as custom homepage
|
||||
$customHome = setting('app-homepage', '0:');
|
||||
if (intval($page->id) === intval(explode(':', $customHome)[0])) {
|
||||
throw new NotifyException(trans('errors.page_custom_home_deletion'), $page->getUrl());
|
||||
}
|
||||
|
||||
$this->destroyEntityCommonRelations($page);
|
||||
|
||||
// Delete Attached Files
|
||||
$attachmentService = app(AttachmentService::class);
|
||||
foreach ($page->attachments as $attachment) {
|
||||
@@ -1223,4 +1269,48 @@ class EntityRepo
|
||||
|
||||
$page->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy or handle the common relations connected to an entity.
|
||||
* @param Entity $entity
|
||||
* @throws \Throwable
|
||||
*/
|
||||
protected function destroyEntityCommonRelations(Entity $entity)
|
||||
{
|
||||
\Activity::removeEntity($entity);
|
||||
$entity->views()->delete();
|
||||
$entity->permissions()->delete();
|
||||
$entity->tags()->delete();
|
||||
$entity->comments()->delete();
|
||||
$this->permissionService->deleteJointPermissionsForEntity($entity);
|
||||
$this->searchService->deleteEntityTerms($entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the permissions of a bookshelf to all child books.
|
||||
* Returns the number of books that had permissions updated.
|
||||
* @param Bookshelf $bookshelf
|
||||
* @return int
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function copyBookshelfPermissions(Bookshelf $bookshelf)
|
||||
{
|
||||
$shelfPermissions = $bookshelf->permissions()->get(['role_id', 'action'])->toArray();
|
||||
$shelfBooks = $bookshelf->books()->get();
|
||||
$updatedBookCount = 0;
|
||||
|
||||
foreach ($shelfBooks as $book) {
|
||||
if (!userCan('restrictions-manage', $book)) {
|
||||
continue;
|
||||
}
|
||||
$book->permissions()->delete();
|
||||
$book->restricted = $bookshelf->restricted;
|
||||
$book->permissions()->createMany($shelfPermissions);
|
||||
$book->save();
|
||||
$this->permissionService->buildJointPermissionsForEntity($book);
|
||||
$updatedBookCount++;
|
||||
}
|
||||
|
||||
return $updatedBookCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ class PermissionsRepo
|
||||
|
||||
/**
|
||||
* Updates an existing role.
|
||||
* Ensure Admin role always has all permissions.
|
||||
* Ensure Admin role always have core permissions.
|
||||
* @param $roleId
|
||||
* @param $roleData
|
||||
* @throws PermissionsException
|
||||
@@ -90,13 +90,18 @@ class PermissionsRepo
|
||||
$role = $this->role->findOrFail($roleId);
|
||||
|
||||
$permissions = isset($roleData['permissions']) ? array_keys($roleData['permissions']) : [];
|
||||
$this->assignRolePermissions($role, $permissions);
|
||||
|
||||
if ($role->system_name === 'admin') {
|
||||
$permissions = $this->permission->all()->pluck('id')->toArray();
|
||||
$role->permissions()->sync($permissions);
|
||||
$permissions = array_merge($permissions, [
|
||||
'users-manage',
|
||||
'user-roles-manage',
|
||||
'restrictions-manage-all',
|
||||
'restrictions-manage-own',
|
||||
'settings-manage',
|
||||
]);
|
||||
}
|
||||
|
||||
$this->assignRolePermissions($role, $permissions);
|
||||
|
||||
$role->fill($roleData);
|
||||
$role->save();
|
||||
$this->permissionService->buildJointPermissionForRole($role);
|
||||
|
||||
@@ -76,14 +76,15 @@ class UserRepo
|
||||
return $query->paginate($count);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Creates a new user and attaches a role to them.
|
||||
* @param array $data
|
||||
* @param boolean $verifyEmail
|
||||
* @return User
|
||||
*/
|
||||
public function registerNew(array $data)
|
||||
public function registerNew(array $data, $verifyEmail = false)
|
||||
{
|
||||
$user = $this->create($data);
|
||||
$user = $this->create($data, $verifyEmail);
|
||||
$this->attachDefaultRole($user);
|
||||
|
||||
// Get avatar from gravatar and save
|
||||
@@ -94,15 +95,14 @@ class UserRepo
|
||||
|
||||
/**
|
||||
* Give a user the default role. Used when creating a new user.
|
||||
* @param $user
|
||||
* @param User $user
|
||||
*/
|
||||
public function attachDefaultRole($user)
|
||||
public function attachDefaultRole(User $user)
|
||||
{
|
||||
$roleId = setting('registration-role');
|
||||
if ($roleId === false) {
|
||||
$roleId = $this->role->first()->id;
|
||||
if ($roleId !== false && $user->roles()->where('id', '=', $roleId)->count() === 0) {
|
||||
$user->attachRoleId($roleId);
|
||||
}
|
||||
$user->attachRoleId($roleId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -141,15 +141,17 @@ class UserRepo
|
||||
/**
|
||||
* Create a new basic instance of user.
|
||||
* @param array $data
|
||||
* @param boolean $verifyEmail
|
||||
* @return User
|
||||
*/
|
||||
public function create(array $data)
|
||||
public function create(array $data, $verifyEmail = false)
|
||||
{
|
||||
|
||||
return $this->user->forceCreate([
|
||||
'name' => $data['name'],
|
||||
'email' => $data['email'],
|
||||
'password' => bcrypt($data['password']),
|
||||
'email_confirmed' => false
|
||||
'email_confirmed' => $verifyEmail
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
class Role extends Model
|
||||
{
|
||||
|
||||
protected $fillable = ['display_name', 'description'];
|
||||
protected $fillable = ['display_name', 'description', 'external_auth_id'];
|
||||
|
||||
/**
|
||||
* The roles that belong to the role.
|
||||
|
||||
@@ -316,25 +316,25 @@ class ImageService extends UploadService
|
||||
$deletedPaths = [];
|
||||
|
||||
$this->image->newQuery()->whereIn('type', $types)
|
||||
->chunk(1000, function($images) use ($types, $checkRevisions, &$deletedPaths, $dryRun) {
|
||||
foreach ($images as $image) {
|
||||
$searchQuery = '%' . basename($image->path) . '%';
|
||||
$inPage = DB::table('pages')
|
||||
->chunk(1000, function ($images) use ($types, $checkRevisions, &$deletedPaths, $dryRun) {
|
||||
foreach ($images as $image) {
|
||||
$searchQuery = '%' . basename($image->path) . '%';
|
||||
$inPage = DB::table('pages')
|
||||
->where('html', 'like', $searchQuery)->count() > 0;
|
||||
$inRevision = false;
|
||||
if ($checkRevisions) {
|
||||
$inRevision = DB::table('page_revisions')
|
||||
$inRevision = false;
|
||||
if ($checkRevisions) {
|
||||
$inRevision = DB::table('page_revisions')
|
||||
->where('html', 'like', $searchQuery)->count() > 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$inPage && !$inRevision) {
|
||||
$deletedPaths[] = $image->path;
|
||||
if (!$dryRun) {
|
||||
$this->destroy($image);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!$inPage && !$inRevision) {
|
||||
$deletedPaths[] = $image->path;
|
||||
if (!$dryRun) {
|
||||
$this->destroy($image);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return $deletedPaths;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
<?php namespace BookStack\Services;
|
||||
|
||||
use BookStack\Exceptions\LdapException;
|
||||
use BookStack\Repos\UserRepo;
|
||||
use BookStack\Role;
|
||||
use BookStack\User;
|
||||
use Illuminate\Contracts\Auth\Authenticatable;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
/**
|
||||
* Class LdapService
|
||||
@@ -14,15 +18,55 @@ class LdapService
|
||||
protected $ldap;
|
||||
protected $ldapConnection;
|
||||
protected $config;
|
||||
protected $userRepo;
|
||||
protected $enabled;
|
||||
|
||||
/**
|
||||
* LdapService constructor.
|
||||
* @param Ldap $ldap
|
||||
* @param UserRepo $userRepo
|
||||
*/
|
||||
public function __construct(Ldap $ldap)
|
||||
public function __construct(Ldap $ldap, UserRepo $userRepo)
|
||||
{
|
||||
$this->ldap = $ldap;
|
||||
$this->config = config('services.ldap');
|
||||
$this->userRepo = $userRepo;
|
||||
$this->enabled = config('auth.method') === 'ldap';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if groups should be synced.
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldSyncGroups()
|
||||
{
|
||||
return $this->enabled && $this->config['user_to_groups'] !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for attributes for a specific user on the ldap
|
||||
* @param string $userName
|
||||
* @param array $attributes
|
||||
* @return null|array
|
||||
* @throws LdapException
|
||||
*/
|
||||
private function getUserWithAttributes($userName, $attributes)
|
||||
{
|
||||
$ldapConnection = $this->getConnection();
|
||||
$this->bindSystemUser($ldapConnection);
|
||||
|
||||
// Find user
|
||||
$userFilter = $this->buildFilter($this->config['user_filter'], ['user' => $userName]);
|
||||
$baseDn = $this->config['base_dn'];
|
||||
|
||||
$followReferrals = $this->config['follow_referrals'] ? 1 : 0;
|
||||
$this->ldap->setOption($ldapConnection, LDAP_OPT_REFERRALS, $followReferrals);
|
||||
$users = $this->ldap->searchAndGetEntries($ldapConnection, $baseDn, $userFilter, $attributes);
|
||||
if ($users['count'] === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $users[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,21 +78,13 @@ class LdapService
|
||||
*/
|
||||
public function getUserDetails($userName)
|
||||
{
|
||||
$ldapConnection = $this->getConnection();
|
||||
$this->bindSystemUser($ldapConnection);
|
||||
|
||||
// Find user
|
||||
$userFilter = $this->buildFilter($this->config['user_filter'], ['user' => $userName]);
|
||||
$baseDn = $this->config['base_dn'];
|
||||
$emailAttr = $this->config['email_attribute'];
|
||||
$followReferrals = $this->config['follow_referrals'] ? 1 : 0;
|
||||
$this->ldap->setOption($ldapConnection, LDAP_OPT_REFERRALS, $followReferrals);
|
||||
$users = $this->ldap->searchAndGetEntries($ldapConnection, $baseDn, $userFilter, ['cn', 'uid', 'dn', $emailAttr]);
|
||||
if ($users['count'] === 0) {
|
||||
$user = $this->getUserWithAttributes($userName, ['cn', 'uid', 'dn', $emailAttr]);
|
||||
|
||||
if ($user === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$user = $users[0];
|
||||
return [
|
||||
'uid' => (isset($user['uid'])) ? $user['uid'][0] : $user['dn'],
|
||||
'name' => $user['cn'][0],
|
||||
@@ -162,4 +198,172 @@ class LdapService
|
||||
}
|
||||
return strtr($filterString, $newAttrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the groups a user is a part of on ldap
|
||||
* @param string $userName
|
||||
* @return array
|
||||
* @throws LdapException
|
||||
*/
|
||||
public function getUserGroups($userName)
|
||||
{
|
||||
$groupsAttr = $this->config['group_attribute'];
|
||||
$user = $this->getUserWithAttributes($userName, [$groupsAttr]);
|
||||
|
||||
if ($user === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$userGroups = $this->groupFilter($user);
|
||||
$userGroups = $this->getGroupsRecursive($userGroups, []);
|
||||
return $userGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent groups of an array of groups
|
||||
* @param array $groupsArray
|
||||
* @param array $checked
|
||||
* @return array
|
||||
* @throws LdapException
|
||||
*/
|
||||
private function getGroupsRecursive($groupsArray, $checked)
|
||||
{
|
||||
$groups_to_add = [];
|
||||
foreach ($groupsArray as $groupName) {
|
||||
if (in_array($groupName, $checked)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$groupsToAdd = $this->getGroupGroups($groupName);
|
||||
$groups_to_add = array_merge($groups_to_add, $groupsToAdd);
|
||||
$checked[] = $groupName;
|
||||
}
|
||||
$groupsArray = array_unique(array_merge($groupsArray, $groups_to_add), SORT_REGULAR);
|
||||
|
||||
if (!empty($groups_to_add)) {
|
||||
return $this->getGroupsRecursive($groupsArray, $checked);
|
||||
} else {
|
||||
return $groupsArray;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the parent groups of a single group
|
||||
* @param string $groupName
|
||||
* @return array
|
||||
* @throws LdapException
|
||||
*/
|
||||
private function getGroupGroups($groupName)
|
||||
{
|
||||
$ldapConnection = $this->getConnection();
|
||||
$this->bindSystemUser($ldapConnection);
|
||||
|
||||
$followReferrals = $this->config['follow_referrals'] ? 1 : 0;
|
||||
$this->ldap->setOption($ldapConnection, LDAP_OPT_REFERRALS, $followReferrals);
|
||||
|
||||
$baseDn = $this->config['base_dn'];
|
||||
$groupsAttr = strtolower($this->config['group_attribute']);
|
||||
|
||||
$groups = $this->ldap->searchAndGetEntries($ldapConnection, $baseDn, 'CN='.$groupName, [$groupsAttr]);
|
||||
if ($groups['count'] === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$groupGroups = $this->groupFilter($groups[0]);
|
||||
return $groupGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out LDAP CN and DN language in a ldap search return
|
||||
* Gets the base CN (common name) of the string
|
||||
* @param string $ldapSearchReturn
|
||||
* @return array
|
||||
*/
|
||||
protected function groupFilter($ldapSearchReturn)
|
||||
{
|
||||
$groupsAttr = strtolower($this->config['group_attribute']);
|
||||
$ldapGroups = [];
|
||||
$count = 0;
|
||||
if (isset($ldapSearchReturn[$groupsAttr]['count'])) {
|
||||
$count = (int) $ldapSearchReturn[$groupsAttr]['count'];
|
||||
}
|
||||
for ($i=0; $i<$count; $i++) {
|
||||
$dnComponents = ldap_explode_dn($ldapSearchReturn[$groupsAttr][$i], 1);
|
||||
if (!in_array($dnComponents[0], $ldapGroups)) {
|
||||
$ldapGroups[] = $dnComponents[0];
|
||||
}
|
||||
}
|
||||
return $ldapGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync the LDAP groups to the user roles for the current user
|
||||
* @param \BookStack\User $user
|
||||
* @param string $username
|
||||
* @throws LdapException
|
||||
*/
|
||||
public function syncGroups(User $user, string $username)
|
||||
{
|
||||
$userLdapGroups = $this->getUserGroups($username);
|
||||
|
||||
// Get the ids for the roles from the names
|
||||
$ldapGroupsAsRoles = $this->matchLdapGroupsToSystemsRoles($userLdapGroups);
|
||||
|
||||
// Sync groups
|
||||
if ($this->config['remove_from_groups']) {
|
||||
$user->roles()->sync($ldapGroupsAsRoles);
|
||||
$this->userRepo->attachDefaultRole($user);
|
||||
} else {
|
||||
$user->roles()->syncWithoutDetaching($ldapGroupsAsRoles);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Match an array of group names from LDAP to BookStack system roles.
|
||||
* Formats LDAP group names to be lower-case and hyphenated.
|
||||
* @param array $groupNames
|
||||
* @return \Illuminate\Support\Collection
|
||||
*/
|
||||
protected function matchLdapGroupsToSystemsRoles(array $groupNames)
|
||||
{
|
||||
foreach ($groupNames as $i => $groupName) {
|
||||
$groupNames[$i] = str_replace(' ', '-', trim(strtolower($groupName)));
|
||||
}
|
||||
|
||||
$roles = Role::query()->where(function (Builder $query) use ($groupNames) {
|
||||
$query->whereIn('name', $groupNames);
|
||||
foreach ($groupNames as $groupName) {
|
||||
$query->orWhere('external_auth_id', 'LIKE', '%' . $groupName . '%');
|
||||
}
|
||||
})->get();
|
||||
|
||||
$matchedRoles = $roles->filter(function (Role $role) use ($groupNames) {
|
||||
return $this->roleMatchesGroupNames($role, $groupNames);
|
||||
});
|
||||
|
||||
return $matchedRoles->pluck('id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a role against an array of group names to see if it matches.
|
||||
* Checked against role 'external_auth_id' if set otherwise the name of the role.
|
||||
* @param Role $role
|
||||
* @param array $groupNames
|
||||
* @return bool
|
||||
*/
|
||||
protected function roleMatchesGroupNames(Role $role, array $groupNames)
|
||||
{
|
||||
if ($role->external_auth_id) {
|
||||
$externalAuthIds = explode(',', strtolower($role->external_auth_id));
|
||||
foreach ($externalAuthIds as $externalAuthId) {
|
||||
if (in_array(trim($externalAuthId), $groupNames)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
$roleName = str_replace(' ', '-', trim(strtolower($role->display_name)));
|
||||
return in_array($roleName, $groupNames);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php namespace BookStack\Services;
|
||||
|
||||
use BookStack\Book;
|
||||
use BookStack\Bookshelf;
|
||||
use BookStack\Chapter;
|
||||
use BookStack\Entity;
|
||||
use BookStack\EntityPermission;
|
||||
@@ -25,6 +26,7 @@ class PermissionService
|
||||
public $book;
|
||||
public $chapter;
|
||||
public $page;
|
||||
public $bookshelf;
|
||||
|
||||
protected $db;
|
||||
|
||||
@@ -38,22 +40,31 @@ class PermissionService
|
||||
* PermissionService constructor.
|
||||
* @param JointPermission $jointPermission
|
||||
* @param EntityPermission $entityPermission
|
||||
* @param Role $role
|
||||
* @param Connection $db
|
||||
* @param Bookshelf $bookshelf
|
||||
* @param Book $book
|
||||
* @param Chapter $chapter
|
||||
* @param Page $page
|
||||
* @param Role $role
|
||||
*/
|
||||
public function __construct(JointPermission $jointPermission, EntityPermission $entityPermission, Connection $db, Book $book, Chapter $chapter, Page $page, Role $role)
|
||||
{
|
||||
public function __construct(
|
||||
JointPermission $jointPermission,
|
||||
EntityPermission $entityPermission,
|
||||
Role $role,
|
||||
Connection $db,
|
||||
Bookshelf $bookshelf,
|
||||
Book $book,
|
||||
Chapter $chapter,
|
||||
Page $page
|
||||
) {
|
||||
$this->db = $db;
|
||||
$this->jointPermission = $jointPermission;
|
||||
$this->entityPermission = $entityPermission;
|
||||
$this->role = $role;
|
||||
$this->bookshelf = $bookshelf;
|
||||
$this->book = $book;
|
||||
$this->chapter = $chapter;
|
||||
$this->page = $page;
|
||||
// TODO - Update so admin still goes through filters
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,6 +170,12 @@ class PermissionService
|
||||
$this->bookFetchQuery()->chunk(5, function ($books) use ($roles) {
|
||||
$this->buildJointPermissionsForBooks($books, $roles);
|
||||
});
|
||||
|
||||
// Chunk through all bookshelves
|
||||
$this->bookshelf->newQuery()->select(['id', 'restricted', 'created_by'])
|
||||
->chunk(50, function ($shelves) use ($roles) {
|
||||
$this->buildJointPermissionsForShelves($shelves, $roles);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,6 +191,20 @@ class PermissionService
|
||||
}]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Collection $shelves
|
||||
* @param array $roles
|
||||
* @param bool $deleteOld
|
||||
* @throws \Throwable
|
||||
*/
|
||||
protected function buildJointPermissionsForShelves($shelves, $roles, $deleteOld = false)
|
||||
{
|
||||
if ($deleteOld) {
|
||||
$this->deleteManyJointPermissionsForEntities($shelves->all());
|
||||
}
|
||||
$this->createManyJointPermissions($shelves, $roles);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build joint permissions for an array of books
|
||||
* @param Collection $books
|
||||
@@ -204,6 +235,7 @@ class PermissionService
|
||||
/**
|
||||
* Rebuild the entity jointPermissions for a particular entity.
|
||||
* @param Entity $entity
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function buildJointPermissionsForEntity(Entity $entity)
|
||||
{
|
||||
@@ -214,7 +246,9 @@ class PermissionService
|
||||
return;
|
||||
}
|
||||
|
||||
$entities[] = $entity->book;
|
||||
if ($entity->book) {
|
||||
$entities[] = $entity->book;
|
||||
}
|
||||
|
||||
if ($entity->isA('page') && $entity->chapter_id) {
|
||||
$entities[] = $entity->chapter;
|
||||
@@ -226,13 +260,13 @@ class PermissionService
|
||||
}
|
||||
}
|
||||
|
||||
$this->deleteManyJointPermissionsForEntities($entities);
|
||||
$this->buildJointPermissionsForEntities(collect($entities));
|
||||
}
|
||||
|
||||
/**
|
||||
* Rebuild the entity jointPermissions for a collection of entities.
|
||||
* @param Collection $entities
|
||||
* @throws \Throwable
|
||||
*/
|
||||
public function buildJointPermissionsForEntities(Collection $entities)
|
||||
{
|
||||
@@ -254,6 +288,12 @@ class PermissionService
|
||||
$this->bookFetchQuery()->chunk(20, function ($books) use ($roles) {
|
||||
$this->buildJointPermissionsForBooks($books, $roles);
|
||||
});
|
||||
|
||||
// Chunk through all bookshelves
|
||||
$this->bookshelf->newQuery()->select(['id', 'restricted', 'created_by'])
|
||||
->chunk(50, function ($shelves) use ($roles) {
|
||||
$this->buildJointPermissionsForShelves($shelves, $roles);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -412,7 +452,7 @@ class PermissionService
|
||||
return $this->createJointPermissionDataArray($entity, $role, $action, $hasAccess, $hasAccess);
|
||||
}
|
||||
|
||||
if ($entity->isA('book')) {
|
||||
if ($entity->isA('book') || $entity->isA('bookshelf')) {
|
||||
return $this->createJointPermissionDataArray($entity, $role, $action, $roleHasPermission, $roleHasPermissionOwn);
|
||||
}
|
||||
|
||||
@@ -484,11 +524,6 @@ class PermissionService
|
||||
*/
|
||||
public function checkOwnableUserAccess(Ownable $ownable, $permission)
|
||||
{
|
||||
if ($this->isAdmin()) {
|
||||
$this->clean();
|
||||
return true;
|
||||
}
|
||||
|
||||
$explodedPermission = explode('-', $permission);
|
||||
|
||||
$baseQuery = $ownable->where('id', '=', $ownable->id);
|
||||
@@ -581,17 +616,16 @@ class PermissionService
|
||||
$query = $this->db->query()->select('*')->from($this->db->raw("({$pageSelect->toSql()} UNION {$chapterSelect->toSql()}) AS U"))
|
||||
->mergeBindings($pageSelect)->mergeBindings($chapterSelect);
|
||||
|
||||
if (!$this->isAdmin()) {
|
||||
$whereQuery = $this->db->table('joint_permissions as jp')->selectRaw('COUNT(*)')
|
||||
->whereRaw('jp.entity_id=U.id')->whereRaw('jp.entity_type=U.entity_type')
|
||||
->where('jp.action', '=', 'view')->whereIn('jp.role_id', $this->getRoles())
|
||||
->where(function ($query) {
|
||||
$query->where('jp.has_permission', '=', 1)->orWhere(function ($query) {
|
||||
$query->where('jp.has_permission_own', '=', 1)->where('jp.created_by', '=', $this->currentUser()->id);
|
||||
});
|
||||
// Add joint permission filter
|
||||
$whereQuery = $this->db->table('joint_permissions as jp')->selectRaw('COUNT(*)')
|
||||
->whereRaw('jp.entity_id=U.id')->whereRaw('jp.entity_type=U.entity_type')
|
||||
->where('jp.action', '=', 'view')->whereIn('jp.role_id', $this->getRoles())
|
||||
->where(function ($query) {
|
||||
$query->where('jp.has_permission', '=', 1)->orWhere(function ($query) {
|
||||
$query->where('jp.has_permission_own', '=', 1)->where('jp.created_by', '=', $this->currentUser()->id);
|
||||
});
|
||||
$query->whereRaw("({$whereQuery->toSql()}) > 0")->mergeBindings($whereQuery);
|
||||
}
|
||||
});
|
||||
$query->whereRaw("({$whereQuery->toSql()}) > 0")->mergeBindings($whereQuery);
|
||||
|
||||
$query->orderBy('draft', 'desc')->orderBy('priority', 'asc');
|
||||
$this->clean();
|
||||
@@ -619,11 +653,6 @@ class PermissionService
|
||||
});
|
||||
}
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
$this->clean();
|
||||
return $query;
|
||||
}
|
||||
|
||||
$this->currentAction = $action;
|
||||
return $this->entityRestrictionQuery($query);
|
||||
}
|
||||
@@ -639,10 +668,6 @@ class PermissionService
|
||||
*/
|
||||
public function filterRestrictedEntityRelations($query, $tableName, $entityIdColumn, $entityTypeColumn, $action = 'view')
|
||||
{
|
||||
if ($this->isAdmin()) {
|
||||
$this->clean();
|
||||
return $query;
|
||||
}
|
||||
|
||||
$this->currentAction = $action;
|
||||
$tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn, 'entityTypeColumn' => $entityTypeColumn];
|
||||
@@ -675,11 +700,6 @@ class PermissionService
|
||||
*/
|
||||
public function filterRelatedPages($query, $tableName, $entityIdColumn)
|
||||
{
|
||||
if ($this->isAdmin()) {
|
||||
$this->clean();
|
||||
return $query;
|
||||
}
|
||||
|
||||
$this->currentAction = 'view';
|
||||
$tableDetails = ['tableName' => $tableName, 'entityIdColumn' => $entityIdColumn];
|
||||
|
||||
@@ -704,19 +724,6 @@ class PermissionService
|
||||
return $q;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current user is an admin.
|
||||
* @return bool
|
||||
*/
|
||||
private function isAdmin()
|
||||
{
|
||||
if ($this->isAdminUser === null) {
|
||||
$this->isAdminUser = ($this->currentUser()->id !== null) ? $this->currentUser()->hasSystemRole('admin') : false;
|
||||
}
|
||||
|
||||
return $this->isAdminUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current user
|
||||
* @return User
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php namespace BookStack\Services;
|
||||
|
||||
use BookStack\Book;
|
||||
use BookStack\Bookshelf;
|
||||
use BookStack\Chapter;
|
||||
use BookStack\Entity;
|
||||
use BookStack\Page;
|
||||
@@ -13,11 +14,16 @@ use Illuminate\Support\Collection;
|
||||
class SearchService
|
||||
{
|
||||
protected $searchTerm;
|
||||
protected $bookshelf;
|
||||
protected $book;
|
||||
protected $chapter;
|
||||
protected $page;
|
||||
protected $db;
|
||||
protected $permissionService;
|
||||
|
||||
/**
|
||||
* @var Entity[]
|
||||
*/
|
||||
protected $entities;
|
||||
|
||||
/**
|
||||
@@ -29,20 +35,23 @@ class SearchService
|
||||
/**
|
||||
* SearchService constructor.
|
||||
* @param SearchTerm $searchTerm
|
||||
* @param Bookshelf $bookshelf
|
||||
* @param Book $book
|
||||
* @param Chapter $chapter
|
||||
* @param Page $page
|
||||
* @param Connection $db
|
||||
* @param PermissionService $permissionService
|
||||
*/
|
||||
public function __construct(SearchTerm $searchTerm, Book $book, Chapter $chapter, Page $page, Connection $db, PermissionService $permissionService)
|
||||
public function __construct(SearchTerm $searchTerm, Bookshelf $bookshelf, Book $book, Chapter $chapter, Page $page, Connection $db, PermissionService $permissionService)
|
||||
{
|
||||
$this->searchTerm = $searchTerm;
|
||||
$this->bookshelf = $bookshelf;
|
||||
$this->book = $book;
|
||||
$this->chapter = $chapter;
|
||||
$this->page = $page;
|
||||
$this->db = $db;
|
||||
$this->entities = [
|
||||
'bookshelf' => $this->bookshelf,
|
||||
'page' => $this->page,
|
||||
'chapter' => $this->chapter,
|
||||
'book' => $this->book
|
||||
@@ -65,6 +74,7 @@ class SearchService
|
||||
* @param string $entityType
|
||||
* @param int $page
|
||||
* @param int $count - Count of each entity to search, Total returned could can be larger and not guaranteed.
|
||||
* @param string $action
|
||||
* @return array[int, Collection];
|
||||
*/
|
||||
public function searchEntities($searchString, $entityType = 'all', $page = 1, $count = 20, $action = 'view')
|
||||
@@ -370,20 +380,12 @@ class SearchService
|
||||
{
|
||||
$this->searchTerm->truncate();
|
||||
|
||||
// Chunk through all books
|
||||
$this->book->chunk(1000, function ($books) {
|
||||
$this->indexEntities($books);
|
||||
});
|
||||
|
||||
// Chunk through all chapters
|
||||
$this->chapter->chunk(1000, function ($chapters) {
|
||||
$this->indexEntities($chapters);
|
||||
});
|
||||
|
||||
// Chunk through all pages
|
||||
$this->page->chunk(1000, function ($pages) {
|
||||
$this->indexEntities($pages);
|
||||
});
|
||||
foreach ($this->entities as $entityModel) {
|
||||
$selectFields = ['id', 'name', $entityModel->textField];
|
||||
$entityModel->newQuery()->select($selectFields)->chunk(1000, function ($entities) {
|
||||
$this->indexEntities($entities);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
<?php namespace BookStack\Services;
|
||||
|
||||
use BookStack\Http\Requests\Request;
|
||||
use GuzzleHttp\Exception\ClientException;
|
||||
use BookStack\Exceptions\SocialSignInAccountNotUsed;
|
||||
use Laravel\Socialite\Contracts\Factory as Socialite;
|
||||
use BookStack\Exceptions\SocialDriverNotConfigured;
|
||||
use BookStack\Exceptions\SocialSignInException;
|
||||
use BookStack\Exceptions\UserRegistrationException;
|
||||
use BookStack\Repos\UserRepo;
|
||||
use BookStack\SocialAccount;
|
||||
use Laravel\Socialite\Contracts\User as SocialUser;
|
||||
|
||||
class SocialAuthService
|
||||
{
|
||||
@@ -16,7 +15,7 @@ class SocialAuthService
|
||||
protected $socialite;
|
||||
protected $socialAccount;
|
||||
|
||||
protected $validSocialDrivers = ['google', 'github', 'facebook', 'slack', 'twitter', 'azure', 'okta', 'gitlab', 'twitch'];
|
||||
protected $validSocialDrivers = ['google', 'github', 'facebook', 'slack', 'twitter', 'azure', 'okta', 'gitlab', 'twitch', 'discord'];
|
||||
|
||||
/**
|
||||
* SocialAuthService constructor.
|
||||
@@ -58,18 +57,13 @@ class SocialAuthService
|
||||
|
||||
/**
|
||||
* Handle the social registration process on callback.
|
||||
* @param $socialDriver
|
||||
* @return \Laravel\Socialite\Contracts\User
|
||||
* @throws SocialDriverNotConfigured
|
||||
* @param string $socialDriver
|
||||
* @param SocialUser $socialUser
|
||||
* @return SocialUser
|
||||
* @throws UserRegistrationException
|
||||
*/
|
||||
public function handleRegistrationCallback($socialDriver)
|
||||
public function handleRegistrationCallback(string $socialDriver, SocialUser $socialUser)
|
||||
{
|
||||
$driver = $this->validateDriver($socialDriver);
|
||||
|
||||
// Get user details from social driver
|
||||
$socialUser = $this->socialite->driver($driver)->user();
|
||||
|
||||
// Check social account has not already been used
|
||||
if ($this->socialAccount->where('driver_id', '=', $socialUser->getId())->exists()) {
|
||||
throw new UserRegistrationException(trans('errors.social_account_in_use', ['socialAccount'=>$socialDriver]), '/login');
|
||||
@@ -84,17 +78,26 @@ class SocialAuthService
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the login process on a oAuth callback.
|
||||
* @param $socialDriver
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
* Get the social user details via the social driver.
|
||||
* @param string $socialDriver
|
||||
* @return SocialUser
|
||||
* @throws SocialDriverNotConfigured
|
||||
* @throws SocialSignInException
|
||||
*/
|
||||
public function handleLoginCallback($socialDriver)
|
||||
public function getSocialUser(string $socialDriver)
|
||||
{
|
||||
$driver = $this->validateDriver($socialDriver);
|
||||
// Get user details from social driver
|
||||
$socialUser = $this->socialite->driver($driver)->user();
|
||||
return $this->socialite->driver($driver)->user();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the login process on a oAuth callback.
|
||||
* @param $socialDriver
|
||||
* @param SocialUser $socialUser
|
||||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector
|
||||
* @throws SocialSignInAccountNotUsed
|
||||
*/
|
||||
public function handleLoginCallback($socialDriver, SocialUser $socialUser)
|
||||
{
|
||||
$socialId = $socialUser->getId();
|
||||
|
||||
// Get any attached social accounts or users
|
||||
@@ -136,7 +139,7 @@ class SocialAuthService
|
||||
$message .= trans('errors.social_account_register_instructions', ['socialAccount' => title_case($socialDriver)]);
|
||||
}
|
||||
|
||||
throw new SocialSignInException($message, '/login');
|
||||
throw new SocialSignInAccountNotUsed($message, '/login');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,8 +202,28 @@ class SocialAuthService
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $socialDriver
|
||||
* @param \Laravel\Socialite\Contracts\User $socialUser
|
||||
* Check if the current config for the given driver allows auto-registration.
|
||||
* @param string $driver
|
||||
* @return bool
|
||||
*/
|
||||
public function driverAutoRegisterEnabled(string $driver)
|
||||
{
|
||||
return config('services.' . strtolower($driver) . '.auto_register') === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the current config for the given driver allow email address auto-confirmation.
|
||||
* @param string $driver
|
||||
* @return bool
|
||||
*/
|
||||
public function driverAutoConfirmEmailEnabled(string $driver)
|
||||
{
|
||||
return config('services.' . strtolower($driver) . '.auto_confirm') === true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $socialDriver
|
||||
* @param SocialUser $socialUser
|
||||
* @return SocialAccount
|
||||
*/
|
||||
public function fillSocialAccount($socialDriver, $socialUser)
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
"type": "project",
|
||||
"require": {
|
||||
"php": ">=7.0.0",
|
||||
"laravel/framework": "~5.5.22",
|
||||
"fideloper/proxy": "~3.3",
|
||||
"ext-tidy": "*",
|
||||
"ext-dom": "*",
|
||||
"laravel/framework": "~5.5.42",
|
||||
"fideloper/proxy": "~3.3",
|
||||
"intervention/image": "^2.4",
|
||||
"laravel/socialite": "^3.0",
|
||||
"league/flysystem-aws-s3-v3": "^1.0",
|
||||
@@ -20,7 +21,9 @@
|
||||
"socialiteproviders/microsoft-azure": "^3.0",
|
||||
"socialiteproviders/okta": "^1.0",
|
||||
"socialiteproviders/gitlab": "^3.0",
|
||||
"socialiteproviders/twitch": "^3.0"
|
||||
"socialiteproviders/twitch": "^3.0",
|
||||
"socialiteproviders/discord": "^2.0",
|
||||
"doctrine/dbal": "^2.5"
|
||||
},
|
||||
"require-dev": {
|
||||
"filp/whoops": "~2.0",
|
||||
|
||||
709
composer.lock
generated
709
composer.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,13 @@ return [
|
||||
'books' => env('APP_VIEWS_BOOKS', 'list')
|
||||
],
|
||||
|
||||
/**
|
||||
* The number of revisions to keep in the database.
|
||||
* Once this limit is reached older revisions will be deleted.
|
||||
* If set to false then a limit will not be enforced.
|
||||
*/
|
||||
'revision_limit' => env('REVISION_LIMIT', 50),
|
||||
|
||||
/**
|
||||
* Allow <script> tags to entered within page content.
|
||||
* <script> tags are escaped by default.
|
||||
@@ -77,7 +84,32 @@ return [
|
||||
*/
|
||||
|
||||
'locale' => env('APP_LANG', 'en'),
|
||||
'locales' => ['en', 'de', 'es', 'es_AR', 'fr', 'nl', 'pt_BR', 'sk', 'sv', 'ja', 'pl', 'it', 'ru', 'zh_CN', 'zh_TW'],
|
||||
'locales' => ['en', 'ar', 'de', 'es', 'es_AR', 'fr', 'nl', 'pt_BR', 'sk', 'sv', 'ja', 'pl', 'it', 'ru', 'zh_CN', 'zh_TW'],
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Right-to-left text control
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Right-to-left text control is set to false by default since English
|
||||
| is the primary supported application but this may be dynamically
|
||||
| altered by the applications localization system.
|
||||
|
|
||||
*/
|
||||
|
||||
'rtl' => false,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Auto-detect the locale for public users
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| For public users their locale can be guessed by headers sent by their
|
||||
| browser. This is usually set by users in their browser settings.
|
||||
| If not found the default app locale will be used.
|
||||
|
|
||||
*/
|
||||
'auto_detect_locale' => env('APP_AUTO_LANG_PUBLIC', true),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@@ -245,7 +277,7 @@ return [
|
||||
'Activity' => BookStack\Services\Facades\Activity::class,
|
||||
'Setting' => BookStack\Services\Facades\Setting::class,
|
||||
'Views' => BookStack\Services\Facades\Views::class,
|
||||
'Images' => \BookStack\Services\Facades\Images::class,
|
||||
'Images' => BookStack\Services\Facades\Images::class,
|
||||
|
||||
],
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ return [
|
||||
'client_secret' => env('GITHUB_APP_SECRET', false),
|
||||
'redirect' => env('APP_URL') . '/login/service/github/callback',
|
||||
'name' => 'GitHub',
|
||||
'auto_register' => env('GITHUB_AUTO_REGISTER', false),
|
||||
'auto_confirm' => env('GITHUB_AUTO_CONFIRM_EMAIL', false),
|
||||
],
|
||||
|
||||
'google' => [
|
||||
@@ -55,6 +57,8 @@ return [
|
||||
'client_secret' => env('GOOGLE_APP_SECRET', false),
|
||||
'redirect' => env('APP_URL') . '/login/service/google/callback',
|
||||
'name' => 'Google',
|
||||
'auto_register' => env('GOOGLE_AUTO_REGISTER', false),
|
||||
'auto_confirm' => env('GOOGLE_AUTO_CONFIRM_EMAIL', false),
|
||||
],
|
||||
|
||||
'slack' => [
|
||||
@@ -62,6 +66,8 @@ return [
|
||||
'client_secret' => env('SLACK_APP_SECRET', false),
|
||||
'redirect' => env('APP_URL') . '/login/service/slack/callback',
|
||||
'name' => 'Slack',
|
||||
'auto_register' => env('SLACK_AUTO_REGISTER', false),
|
||||
'auto_confirm' => env('SLACK_AUTO_CONFIRM_EMAIL', false),
|
||||
],
|
||||
|
||||
'facebook' => [
|
||||
@@ -69,6 +75,8 @@ return [
|
||||
'client_secret' => env('FACEBOOK_APP_SECRET', false),
|
||||
'redirect' => env('APP_URL') . '/login/service/facebook/callback',
|
||||
'name' => 'Facebook',
|
||||
'auto_register' => env('FACEBOOK_AUTO_REGISTER', false),
|
||||
'auto_confirm' => env('FACEBOOK_AUTO_CONFIRM_EMAIL', false),
|
||||
],
|
||||
|
||||
'twitter' => [
|
||||
@@ -76,6 +84,8 @@ return [
|
||||
'client_secret' => env('TWITTER_APP_SECRET', false),
|
||||
'redirect' => env('APP_URL') . '/login/service/twitter/callback',
|
||||
'name' => 'Twitter',
|
||||
'auto_register' => env('TWITTER_AUTO_REGISTER', false),
|
||||
'auto_confirm' => env('TWITTER_AUTO_CONFIRM_EMAIL', false),
|
||||
],
|
||||
|
||||
'azure' => [
|
||||
@@ -84,6 +94,8 @@ return [
|
||||
'tenant' => env('AZURE_TENANT', false),
|
||||
'redirect' => env('APP_URL') . '/login/service/azure/callback',
|
||||
'name' => 'Microsoft Azure',
|
||||
'auto_register' => env('AZURE_AUTO_REGISTER', false),
|
||||
'auto_confirm' => env('AZURE_AUTO_CONFIRM_EMAIL', false),
|
||||
],
|
||||
|
||||
'okta' => [
|
||||
@@ -92,6 +104,8 @@ return [
|
||||
'redirect' => env('APP_URL') . '/login/service/okta/callback',
|
||||
'base_url' => env('OKTA_BASE_URL'),
|
||||
'name' => 'Okta',
|
||||
'auto_register' => env('OKTA_AUTO_REGISTER', false),
|
||||
'auto_confirm' => env('OKTA_AUTO_CONFIRM_EMAIL', false),
|
||||
],
|
||||
|
||||
'gitlab' => [
|
||||
@@ -100,6 +114,8 @@ return [
|
||||
'redirect' => env('APP_URL') . '/login/service/gitlab/callback',
|
||||
'instance_uri' => env('GITLAB_BASE_URI'), // Needed only for self hosted instances
|
||||
'name' => 'GitLab',
|
||||
'auto_register' => env('GITLAB_AUTO_REGISTER', false),
|
||||
'auto_confirm' => env('GITLAB_AUTO_CONFIRM_EMAIL', false),
|
||||
],
|
||||
|
||||
'twitch' => [
|
||||
@@ -107,6 +123,17 @@ return [
|
||||
'client_secret' => env('TWITCH_APP_SECRET'),
|
||||
'redirect' => env('APP_URL') . '/login/service/twitch/callback',
|
||||
'name' => 'Twitch',
|
||||
'auto_register' => env('TWITCH_AUTO_REGISTER', false),
|
||||
'auto_confirm' => env('TWITCH_AUTO_CONFIRM_EMAIL', false),
|
||||
],
|
||||
|
||||
'discord' => [
|
||||
'client_id' => env('DISCORD_APP_ID'),
|
||||
'client_secret' => env('DISCORD_APP_SECRET'),
|
||||
'redirect' => env('APP_URL') . '/login/service/discord/callback',
|
||||
'name' => 'Discord',
|
||||
'auto_register' => env('DISCORD_AUTO_REGISTER', false),
|
||||
'auto_confirm' => env('DISCORD_AUTO_CONFIRM_EMAIL', false),
|
||||
],
|
||||
|
||||
'ldap' => [
|
||||
@@ -118,6 +145,9 @@ return [
|
||||
'version' => env('LDAP_VERSION', false),
|
||||
'email_attribute' => env('LDAP_EMAIL_ATTRIBUTE', 'mail'),
|
||||
'follow_referrals' => env('LDAP_FOLLOW_REFERRALS', false),
|
||||
]
|
||||
'user_to_groups' => env('LDAP_USER_TO_GROUPS',false),
|
||||
'group_attribute' => env('LDAP_GROUP_ATTRIBUTE', 'memberOf'),
|
||||
'remove_from_groups' => env('LDAP_REMOVE_FROM_GROUPS',false),
|
||||
]
|
||||
|
||||
];
|
||||
|
||||
@@ -109,7 +109,7 @@ return [
|
||||
|
|
||||
*/
|
||||
|
||||
'cookie' => 'laravel_session',
|
||||
'cookie' => env('SESSION_COOKIE_NAME', 'bookstack_session'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
||||
@@ -21,6 +21,14 @@ $factory->define(BookStack\User::class, function ($faker) {
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(BookStack\Bookshelf::class, function ($faker) {
|
||||
return [
|
||||
'name' => $faker->sentence,
|
||||
'slug' => str_random(10),
|
||||
'description' => $faker->paragraph
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(BookStack\Book::class, function ($faker) {
|
||||
return [
|
||||
'name' => $faker->sentence,
|
||||
|
||||
@@ -12,13 +12,7 @@ class CreateBooksTable extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$pdo = \DB::connection()->getPdo();
|
||||
$mysqlVersion = $pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||
$requiresISAM = strpos($mysqlVersion, '5.5') === 0;
|
||||
|
||||
Schema::create('books', function (Blueprint $table) use ($requiresISAM) {
|
||||
if($requiresISAM) $table->engine = 'MyISAM';
|
||||
|
||||
Schema::create('books', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('name');
|
||||
$table->string('slug')->indexed();
|
||||
|
||||
@@ -12,13 +12,9 @@ class CreatePagesTable extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$pdo = \DB::connection()->getPdo();
|
||||
$mysqlVersion = $pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||
$requiresISAM = strpos($mysqlVersion, '5.5') === 0;
|
||||
|
||||
Schema::create('pages', function (Blueprint $table) use ($requiresISAM) {
|
||||
if($requiresISAM) $table->engine = 'MyISAM';
|
||||
|
||||
|
||||
Schema::create('pages', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('book_id');
|
||||
$table->integer('chapter_id');
|
||||
|
||||
@@ -12,12 +12,7 @@ class CreateChaptersTable extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$pdo = \DB::connection()->getPdo();
|
||||
$mysqlVersion = $pdo->getAttribute(PDO::ATTR_SERVER_VERSION);
|
||||
$requiresISAM = strpos($mysqlVersion, '5.5') === 0;
|
||||
|
||||
Schema::create('chapters', function (Blueprint $table) use ($requiresISAM) {
|
||||
if($requiresISAM) $table->engine = 'MyISAM';
|
||||
Schema::create('chapters', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->integer('book_id');
|
||||
$table->string('slug')->indexed();
|
||||
|
||||
@@ -12,10 +12,13 @@ class AddSearchIndexes extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$prefix = DB::getTablePrefix();
|
||||
DB::statement("ALTER TABLE {$prefix}pages ADD FULLTEXT search(name, text)");
|
||||
DB::statement("ALTER TABLE {$prefix}books ADD FULLTEXT search(name, description)");
|
||||
DB::statement("ALTER TABLE {$prefix}chapters ADD FULLTEXT search(name, description)");
|
||||
// This was removed for v0.24 since these indexes are removed anyway
|
||||
// and will cause issues for db engines that don't support such indexes.
|
||||
|
||||
// $prefix = DB::getTablePrefix();
|
||||
// DB::statement("ALTER TABLE {$prefix}pages ADD FULLTEXT search(name, text)");
|
||||
// DB::statement("ALTER TABLE {$prefix}books ADD FULLTEXT search(name, description)");
|
||||
// DB::statement("ALTER TABLE {$prefix}chapters ADD FULLTEXT search(name, description)");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -25,14 +28,28 @@ class AddSearchIndexes extends Migration
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('pages', function(Blueprint $table) {
|
||||
$table->dropIndex('search');
|
||||
});
|
||||
Schema::table('books', function(Blueprint $table) {
|
||||
$table->dropIndex('search');
|
||||
});
|
||||
Schema::table('chapters', function(Blueprint $table) {
|
||||
$table->dropIndex('search');
|
||||
});
|
||||
$sm = Schema::getConnection()->getDoctrineSchemaManager();
|
||||
$pages = $sm->listTableDetails('pages');
|
||||
$books = $sm->listTableDetails('books');
|
||||
$chapters = $sm->listTableDetails('chapters');
|
||||
|
||||
if ($pages->hasIndex('search')) {
|
||||
Schema::table('pages', function(Blueprint $table) {
|
||||
$table->dropIndex('search');
|
||||
});
|
||||
}
|
||||
|
||||
if ($books->hasIndex('search')) {
|
||||
Schema::table('books', function(Blueprint $table) {
|
||||
$table->dropIndex('search');
|
||||
});
|
||||
}
|
||||
|
||||
if ($chapters->hasIndex('search')) {
|
||||
Schema::table('chapters', function(Blueprint $table) {
|
||||
$table->dropIndex('search');
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,13 @@ class FulltextWeighting extends Migration
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$prefix = DB::getTablePrefix();
|
||||
DB::statement("ALTER TABLE {$prefix}pages ADD FULLTEXT name_search(name)");
|
||||
DB::statement("ALTER TABLE {$prefix}books ADD FULLTEXT name_search(name)");
|
||||
DB::statement("ALTER TABLE {$prefix}chapters ADD FULLTEXT name_search(name)");
|
||||
// This was removed for v0.24 since these indexes are removed anyway
|
||||
// and will cause issues for db engines that don't support such indexes.
|
||||
|
||||
// $prefix = DB::getTablePrefix();
|
||||
// DB::statement("ALTER TABLE {$prefix}pages ADD FULLTEXT name_search(name)");
|
||||
// DB::statement("ALTER TABLE {$prefix}books ADD FULLTEXT name_search(name)");
|
||||
// DB::statement("ALTER TABLE {$prefix}chapters ADD FULLTEXT name_search(name)");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -25,14 +28,27 @@ class FulltextWeighting extends Migration
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('pages', function(Blueprint $table) {
|
||||
$table->dropIndex('name_search');
|
||||
});
|
||||
Schema::table('books', function(Blueprint $table) {
|
||||
$table->dropIndex('name_search');
|
||||
});
|
||||
Schema::table('chapters', function(Blueprint $table) {
|
||||
$table->dropIndex('name_search');
|
||||
});
|
||||
$sm = Schema::getConnection()->getDoctrineSchemaManager();
|
||||
$pages = $sm->listTableDetails('pages');
|
||||
$books = $sm->listTableDetails('books');
|
||||
$chapters = $sm->listTableDetails('chapters');
|
||||
|
||||
if ($pages->hasIndex('name_search')) {
|
||||
Schema::table('pages', function(Blueprint $table) {
|
||||
$table->dropIndex('name_search');
|
||||
});
|
||||
}
|
||||
|
||||
if ($books->hasIndex('name_search')) {
|
||||
Schema::table('books', function(Blueprint $table) {
|
||||
$table->dropIndex('name_search');
|
||||
});
|
||||
}
|
||||
|
||||
if ($chapters->hasIndex('name_search')) {
|
||||
Schema::table('chapters', function(Blueprint $table) {
|
||||
$table->dropIndex('name_search');
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,10 +74,6 @@ class CreateJointPermissionsTable extends Migration
|
||||
|
||||
// Update admin role with system name
|
||||
DB::table('roles')->where('name', '=', 'admin')->update(['system_name' => 'admin']);
|
||||
|
||||
// Generate the new entity jointPermissions
|
||||
$restrictionService = app(\BookStack\Services\PermissionService::class);
|
||||
$restrictionService->buildJointPermissions();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,21 +26,31 @@ class CreateSearchIndexTable extends Migration
|
||||
$table->index('score');
|
||||
});
|
||||
|
||||
// Drop search indexes
|
||||
Schema::table('pages', function(Blueprint $table) {
|
||||
$table->dropIndex('search');
|
||||
$table->dropIndex('name_search');
|
||||
});
|
||||
Schema::table('books', function(Blueprint $table) {
|
||||
$table->dropIndex('search');
|
||||
$table->dropIndex('name_search');
|
||||
});
|
||||
Schema::table('chapters', function(Blueprint $table) {
|
||||
$table->dropIndex('search');
|
||||
$table->dropIndex('name_search');
|
||||
});
|
||||
$sm = Schema::getConnection()->getDoctrineSchemaManager();
|
||||
$pages = $sm->listTableDetails('pages');
|
||||
$books = $sm->listTableDetails('books');
|
||||
$chapters = $sm->listTableDetails('chapters');
|
||||
|
||||
app(\BookStack\Services\SearchService::class)->indexAllEntities();
|
||||
if ($pages->hasIndex('search')) {
|
||||
Schema::table('pages', function(Blueprint $table) {
|
||||
$table->dropIndex('search');
|
||||
$table->dropIndex('name_search');
|
||||
});
|
||||
}
|
||||
|
||||
if ($books->hasIndex('search')) {
|
||||
Schema::table('books', function(Blueprint $table) {
|
||||
$table->dropIndex('search');
|
||||
$table->dropIndex('name_search');
|
||||
});
|
||||
}
|
||||
|
||||
if ($chapters->hasIndex('search')) {
|
||||
Schema::table('chapters', function(Blueprint $table) {
|
||||
$table->dropIndex('search');
|
||||
$table->dropIndex('name_search');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,14 +60,17 @@ class CreateSearchIndexTable extends Migration
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
$prefix = DB::getTablePrefix();
|
||||
DB::statement("ALTER TABLE {$prefix}pages ADD FULLTEXT search(name, text)");
|
||||
DB::statement("ALTER TABLE {$prefix}books ADD FULLTEXT search(name, description)");
|
||||
DB::statement("ALTER TABLE {$prefix}chapters ADD FULLTEXT search(name, description)");
|
||||
DB::statement("ALTER TABLE {$prefix}pages ADD FULLTEXT name_search(name)");
|
||||
DB::statement("ALTER TABLE {$prefix}books ADD FULLTEXT name_search(name)");
|
||||
DB::statement("ALTER TABLE {$prefix}chapters ADD FULLTEXT name_search(name)");
|
||||
// This was removed for v0.24 since these indexes are removed anyway
|
||||
// and will cause issues for db engines that don't support such indexes.
|
||||
|
||||
// $prefix = DB::getTablePrefix();
|
||||
// DB::statement("ALTER TABLE {$prefix}pages ADD FULLTEXT search(name, text)");
|
||||
// DB::statement("ALTER TABLE {$prefix}books ADD FULLTEXT search(name, description)");
|
||||
// DB::statement("ALTER TABLE {$prefix}chapters ADD FULLTEXT search(name, description)");
|
||||
// DB::statement("ALTER TABLE {$prefix}pages ADD FULLTEXT name_search(name)");
|
||||
// DB::statement("ALTER TABLE {$prefix}books ADD FULLTEXT name_search(name)");
|
||||
// DB::statement("ALTER TABLE {$prefix}chapters ADD FULLTEXT name_search(name)");
|
||||
|
||||
Schema::dropIfExists('search_terms');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddRoleExternalAuthId extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('roles', function (Blueprint $table) {
|
||||
$table->string('external_auth_id', 200)->default('');
|
||||
$table->index('external_auth_id');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('roles', function (Blueprint $table) {
|
||||
$table->dropColumn('external_auth_id');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateBookshelvesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('bookshelves', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('name', 200);
|
||||
$table->string('slug', 200);
|
||||
$table->text('description');
|
||||
$table->integer('created_by')->nullable()->default(null);
|
||||
$table->integer('updated_by')->nullable()->default(null);
|
||||
$table->boolean('restricted')->default(false);
|
||||
$table->integer('image_id')->nullable()->default(null);
|
||||
$table->timestamps();
|
||||
|
||||
$table->index('slug');
|
||||
$table->index('created_by');
|
||||
$table->index('updated_by');
|
||||
$table->index('restricted');
|
||||
});
|
||||
|
||||
Schema::create('bookshelves_books', function (Blueprint $table) {
|
||||
$table->integer('bookshelf_id')->unsigned();
|
||||
$table->integer('book_id')->unsigned();
|
||||
$table->integer('order')->unsigned();
|
||||
|
||||
$table->foreign('bookshelf_id')->references('id')->on('bookshelves')
|
||||
->onUpdate('cascade')->onDelete('cascade');
|
||||
$table->foreign('book_id')->references('id')->on('books')
|
||||
->onUpdate('cascade')->onDelete('cascade');
|
||||
|
||||
$table->primary(['bookshelf_id', 'book_id']);
|
||||
});
|
||||
|
||||
// Copy existing role permissions from Books
|
||||
$ops = ['View All', 'View Own', 'Create All', 'Create Own', 'Update All', 'Update Own', 'Delete All', 'Delete Own'];
|
||||
foreach ($ops as $op) {
|
||||
$dbOpName = strtolower(str_replace(' ', '-', $op));
|
||||
$roleIdsWithBookPermission = DB::table('role_permissions')
|
||||
->leftJoin('permission_role', 'role_permissions.id', '=', 'permission_role.permission_id')
|
||||
->leftJoin('roles', 'roles.id', '=', 'permission_role.role_id')
|
||||
->where('role_permissions.name', '=', 'book-' . $dbOpName)->get(['roles.id'])->pluck('id');
|
||||
|
||||
$permId = DB::table('role_permissions')->insertGetId([
|
||||
'name' => 'bookshelf-' . $dbOpName,
|
||||
'display_name' => $op . ' ' . 'BookShelves',
|
||||
'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
|
||||
'updated_at' => \Carbon\Carbon::now()->toDateTimeString()
|
||||
]);
|
||||
|
||||
$rowsToInsert = $roleIdsWithBookPermission->map(function($roleId) use ($permId) {
|
||||
return [
|
||||
'role_id' => $roleId,
|
||||
'permission_id' => $permId
|
||||
];
|
||||
})->toArray();
|
||||
|
||||
// Assign view permission to all current roles
|
||||
DB::table('permission_role')->insert($rowsToInsert);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
// Drop created permissions
|
||||
$ops = ['bookshelf-create-all','bookshelf-create-own','bookshelf-delete-all','bookshelf-delete-own','bookshelf-update-all','bookshelf-update-own','bookshelf-view-all','bookshelf-view-own'];
|
||||
|
||||
$permissionIds = DB::table('role_permissions')->whereIn('name', $ops)
|
||||
->get(['id'])->pluck('id')->toArray();
|
||||
DB::table('permission_role')->whereIn('permission_id', $permissionIds)->delete();
|
||||
DB::table('role_permissions')->whereIn('id', $permissionIds)->delete();
|
||||
|
||||
// Drop shelves table
|
||||
Schema::dropIfExists('bookshelves_books');
|
||||
Schema::dropIfExists('bookshelves');
|
||||
|
||||
// Drop related polymorphic items
|
||||
DB::table('activities')->where('entity_type', '=', 'BookStack\Bookshelf')->delete();
|
||||
DB::table('views')->where('viewable_type', '=', 'BookStack\Bookshelf')->delete();
|
||||
DB::table('entity_permissions')->where('restrictable_type', '=', 'BookStack\Bookshelf')->delete();
|
||||
DB::table('tags')->where('entity_type', '=', 'BookStack\Bookshelf')->delete();
|
||||
DB::table('search_terms')->where('entity_type', '=', 'BookStack\Bookshelf')->delete();
|
||||
DB::table('comments')->where('entity_type', '=', 'BookStack\Bookshelf')->delete();
|
||||
}
|
||||
}
|
||||
@@ -21,23 +21,29 @@ class DummyContentSeeder extends Seeder
|
||||
$role = \BookStack\Role::getRole('viewer');
|
||||
$viewerUser->attachRole($role);
|
||||
|
||||
factory(\BookStack\Book::class, 5)->create(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id])
|
||||
->each(function($book) use ($editorUser) {
|
||||
$chapters = factory(\BookStack\Chapter::class, 3)->create(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id])
|
||||
->each(function($chapter) use ($editorUser, $book){
|
||||
$pages = factory(\BookStack\Page::class, 3)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id, 'book_id' => $book->id]);
|
||||
$byData = ['created_by' => $editorUser->id, 'updated_by' => $editorUser->id];
|
||||
|
||||
factory(\BookStack\Book::class, 5)->create($byData)
|
||||
->each(function($book) use ($editorUser, $byData) {
|
||||
$chapters = factory(\BookStack\Chapter::class, 3)->create($byData)
|
||||
->each(function($chapter) use ($editorUser, $book, $byData){
|
||||
$pages = factory(\BookStack\Page::class, 3)->make(array_merge($byData, ['book_id' => $book->id]));
|
||||
$chapter->pages()->saveMany($pages);
|
||||
});
|
||||
$pages = factory(\BookStack\Page::class, 3)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
||||
$pages = factory(\BookStack\Page::class, 3)->make($byData);
|
||||
$book->chapters()->saveMany($chapters);
|
||||
$book->pages()->saveMany($pages);
|
||||
});
|
||||
|
||||
$largeBook = factory(\BookStack\Book::class)->create(['name' => 'Large book' . str_random(10), 'created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
||||
$pages = factory(\BookStack\Page::class, 200)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
||||
$chapters = factory(\BookStack\Chapter::class, 50)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
||||
$largeBook = factory(\BookStack\Book::class)->create(array_merge($byData, ['name' => 'Large book' . str_random(10)]));
|
||||
$pages = factory(\BookStack\Page::class, 200)->make($byData);
|
||||
$chapters = factory(\BookStack\Chapter::class, 50)->make($byData);
|
||||
$largeBook->pages()->saveMany($pages);
|
||||
$largeBook->chapters()->saveMany($chapters);
|
||||
|
||||
$shelves = factory(\BookStack\Bookshelf::class, 10)->create($byData);
|
||||
$largeBook->shelves()->attach($shelves->pluck('id'));
|
||||
|
||||
app(\BookStack\Services\PermissionService::class)->buildJointPermissions();
|
||||
app(\BookStack\Services\SearchService::class)->indexAllEntities();
|
||||
}
|
||||
|
||||
6327
package-lock.json
generated
6327
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -11,20 +11,20 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.0.0-beta.40",
|
||||
"@babel/polyfill": "^7.0.0-beta.40",
|
||||
"@babel/preset-env": "^7.0.0-beta.40",
|
||||
"autoprefixer": "^8.1.0",
|
||||
"babel-loader": "^8.0.0-beta.0",
|
||||
"@babel/polyfill": "^7.0.0-beta.40",
|
||||
"css-loader": "^0.28.10",
|
||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||
"livereload": "^0.7.0",
|
||||
"node-sass": "^4.7.2",
|
||||
"node-sass": "^4.9.2",
|
||||
"npm-run-all": "^4.1.2",
|
||||
"postcss-loader": "^2.1.1",
|
||||
"sass-loader": "^7.0.1",
|
||||
"style-loader": "^0.21.0",
|
||||
"uglifyjs-webpack-plugin": "^1.2.3",
|
||||
"webpack": "^4.1.1",
|
||||
"webpack": "^4.16.3",
|
||||
"webpack-cli": "^2.0.11"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -33,6 +33,7 @@
|
||||
"codemirror": "^5.26.0",
|
||||
"dropzone": "^5.4.0",
|
||||
"jquery": "^3.3.1",
|
||||
"jquery-sortable": "^0.9.13",
|
||||
"markdown-it": "^8.3.1",
|
||||
"markdown-it-task-lists": "^2.0.0",
|
||||
"vue": "^2.2.6",
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
<env name="APP_ENV" value="testing"/>
|
||||
<env name="APP_DEBUG" value="false"/>
|
||||
<env name="APP_LANG" value="en"/>
|
||||
<env name="APP_AUTO_LANG_PUBLIC" value="true"/>
|
||||
<env name="CACHE_DRIVER" value="array"/>
|
||||
<env name="SESSION_DRIVER" value="array"/>
|
||||
<env name="QUEUE_DRIVER" value="sync"/>
|
||||
@@ -34,8 +35,12 @@
|
||||
<env name="STORAGE_TYPE" value="local"/>
|
||||
<env name="GITHUB_APP_ID" value="aaaaaaaaaaaaaa"/>
|
||||
<env name="GITHUB_APP_SECRET" value="aaaaaaaaaaaaaa"/>
|
||||
<env name="GITHUB_AUTO_REGISTER" value=""/>
|
||||
<env name="GITHUB_AUTO_CONFIRM_EMAIL" value=""/>
|
||||
<env name="GOOGLE_APP_ID" value="aaaaaaaaaaaaaa"/>
|
||||
<env name="GOOGLE_APP_SECRET" value="aaaaaaaaaaaaaa"/>
|
||||
<env name="GOOGLE_AUTO_REGISTER" value=""/>
|
||||
<env name="GOOGLE_AUTO_CONFIRM_EMAIL" value=""/>
|
||||
<env name="APP_URL" value="http://bookstack.dev"/>
|
||||
</php>
|
||||
</phpunit>
|
||||
|
||||
2
public/dist/app.js
vendored
2
public/dist/app.js
vendored
File diff suppressed because one or more lines are too long
113
public/dist/export-styles.css
vendored
113
public/dist/export-styles.css
vendored
@@ -252,6 +252,13 @@ p.secondary, p .secondary, span.secondary, .text-secondary {
|
||||
color: #e27b41;
|
||||
fill: #e27b41; }
|
||||
|
||||
.text-bookshelf {
|
||||
color: #af5a5a;
|
||||
fill: #af5a5a; }
|
||||
.text-bookshelf:hover {
|
||||
color: #af5a5a;
|
||||
fill: #af5a5a; }
|
||||
|
||||
.text-book {
|
||||
color: #009688;
|
||||
fill: #009688; }
|
||||
@@ -305,6 +312,7 @@ ul, ol {
|
||||
|
||||
ul {
|
||||
padding-left: 20.8px;
|
||||
padding-right: 20.8px;
|
||||
list-style: disc; }
|
||||
ul ul {
|
||||
list-style: circle;
|
||||
@@ -315,7 +323,8 @@ ul {
|
||||
|
||||
ol {
|
||||
list-style: decimal;
|
||||
padding-left: 32px; }
|
||||
padding-left: 32px;
|
||||
padding-right: 32px; }
|
||||
|
||||
li.checkbox-item, li.task-list-item {
|
||||
list-style: none;
|
||||
@@ -544,13 +553,40 @@ div[class^="col-"] img {
|
||||
flex-direction: column;
|
||||
border: 1px solid #ddd;
|
||||
min-width: 100px; }
|
||||
.grid-card h2 {
|
||||
width: 100%;
|
||||
font-size: 1.5em;
|
||||
margin: 0 0 10px; }
|
||||
.grid-card h2 a {
|
||||
display: block;
|
||||
width: 100%;
|
||||
line-height: 1.2;
|
||||
text-decoration: none; }
|
||||
.grid-card p {
|
||||
font-size: .85em;
|
||||
margin: 0;
|
||||
line-height: 1.6em; }
|
||||
.grid-card .grid-card-content {
|
||||
flex: 1; }
|
||||
flex: 1;
|
||||
border-top: 0;
|
||||
border-bottom-width: 2px; }
|
||||
.grid-card .grid-card-content, .grid-card .grid-card-footer {
|
||||
padding: 24px; }
|
||||
.grid-card .grid-card-content + .grid-card-footer {
|
||||
padding-top: 0; }
|
||||
|
||||
.book-grid-item .grid-card-content h2 a {
|
||||
color: #009688;
|
||||
fill: #009688; }
|
||||
|
||||
.bookshelf-grid-item .grid-card-content h2 a {
|
||||
color: #af5a5a;
|
||||
fill: #af5a5a; }
|
||||
|
||||
.book-grid-item .grid-card-footer p.small {
|
||||
font-size: .8em;
|
||||
margin: 0; }
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
.grid.third {
|
||||
grid-template-columns: 1fr 1fr; } }
|
||||
@@ -1326,9 +1362,9 @@ div[class^="col-"] img {
|
||||
border: 1px solid #E84F4F; }
|
||||
.input-base.pos, .pos.fake-input, input.pos[type="text"], input.pos[type="number"], input.pos[type="email"], input.pos[type="date"], input.pos[type="search"], input.pos[type="url"], input.pos[type="password"], select.pos, textarea.pos, .input-base.valid, .valid.fake-input, input.valid[type="text"], input.valid[type="number"], input.valid[type="email"], input.valid[type="date"], input.valid[type="search"], input.valid[type="url"], input.valid[type="password"], select.valid, textarea.valid {
|
||||
border: 1px solid #52A256; }
|
||||
.input-base.disabled, .disabled.fake-input, input.disabled[type="text"], input.disabled[type="number"], input.disabled[type="email"], input.disabled[type="date"], input.disabled[type="search"], input.disabled[type="url"], input.disabled[type="password"], select.disabled, textarea.disabled, .input-base[disabled], [disabled].fake-input, input[disabled][type="text"], input[disabled][type="number"], input[disabled][type="email"], input[disabled][type="date"], input[disabled][type="search"], input[disabled][type="url"], input[disabled][type="password"], select[disabled], textarea[disabled] {
|
||||
.input-base.disabled, .disabled.fake-input, input.disabled[type="text"], input.disabled[type="number"], input.disabled[type="email"], input.disabled[type="date"], input.disabled[type="search"], input.disabled[type="url"], input.disabled[type="password"], select.disabled, textarea.disabled, .input-base[disabled], .fake-input[disabled], input[disabled][type="text"], input[disabled][type="number"], input[disabled][type="email"], input[disabled][type="date"], input[disabled][type="search"], input[disabled][type="url"], input[disabled][type="password"], select[disabled], textarea[disabled] {
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAMUlEQVQIW2NkwAGuXbv2nxGbHEhCS0uLEUMSJgHShCKJLIEiiS4Bl8QmAZbEJQGSBAC62BuJ+tt7zgAAAABJRU5ErkJggg==); }
|
||||
.input-base:focus, .fake-input:focus, input[type="text"]:focus, input[type="number"]:focus, input[type="email"]:focus, input[type="date"]:focus, input[type="search"]:focus, input[type="url"]:focus, input[type="password"]:focus, select:focus, textarea:focus {
|
||||
.input-base:focus, .fake-input:focus, input:focus[type="text"], input:focus[type="number"], input:focus[type="email"], input:focus[type="date"], input:focus[type="search"], input:focus[type="url"], input:focus[type="password"], select:focus, textarea:focus {
|
||||
outline: 0; }
|
||||
|
||||
.fake-input {
|
||||
@@ -1613,6 +1649,8 @@ table.table {
|
||||
text-align: right; }
|
||||
table.table .text-center {
|
||||
text-align: center; }
|
||||
table.table td.actions {
|
||||
overflow: visible; }
|
||||
|
||||
table.no-style td {
|
||||
border: 0;
|
||||
@@ -1975,7 +2013,7 @@ header .search-box {
|
||||
.book-tree .sidebar-page-list .sub-menu {
|
||||
display: none;
|
||||
padding-left: 0; }
|
||||
.book-tree .sidebar-page-list .sub-menu.open {
|
||||
.book-tree .sidebar-page-list [chapter-toggle].open + .sub-menu {
|
||||
display: block; }
|
||||
|
||||
.sortable-page-list, .sortable-page-list ul {
|
||||
@@ -2042,8 +2080,6 @@ ul.pagination {
|
||||
padding: 3px 12px;
|
||||
border: 1px solid #CCC;
|
||||
margin-left: -1px;
|
||||
color: #888;
|
||||
fill: #888;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
@@ -2051,13 +2087,7 @@ ul.pagination {
|
||||
ul.pagination a.disabled, ul.pagination span.disabled {
|
||||
cursor: not-allowed; }
|
||||
ul.pagination li.active span {
|
||||
background-color: rgba(2, 136, 209, 0.8);
|
||||
color: #EEE;
|
||||
fill: #EEE;
|
||||
border-color: rgba(2, 136, 209, 0.8); }
|
||||
ul.pagination a {
|
||||
color: #0288D1;
|
||||
fill: #0288D1; }
|
||||
color: #FFF; }
|
||||
|
||||
.compact ul.pagination {
|
||||
margin: 0; }
|
||||
@@ -2134,18 +2164,22 @@ ul.pagination {
|
||||
.dropdown-container ul li.padded {
|
||||
padding: 6px 16px;
|
||||
line-height: 1.2; }
|
||||
.dropdown-container ul a {
|
||||
.dropdown-container ul a, .dropdown-container ul button {
|
||||
display: block;
|
||||
padding: 6px 16px;
|
||||
color: #555;
|
||||
fill: #555; }
|
||||
.dropdown-container ul a:hover {
|
||||
fill: #555;
|
||||
white-space: nowrap; }
|
||||
.dropdown-container ul a:hover, .dropdown-container ul button:hover {
|
||||
text-decoration: none;
|
||||
background-color: #EEE; }
|
||||
.dropdown-container ul a svg {
|
||||
.dropdown-container ul a svg, .dropdown-container ul button svg {
|
||||
margin-right: 12px;
|
||||
display: inline-block;
|
||||
width: 16px; }
|
||||
.dropdown-container ul button {
|
||||
width: 100%;
|
||||
text-align: left; }
|
||||
.dropdown-container ul li.border-bottom {
|
||||
border-bottom: 1px solid #DDD; }
|
||||
|
||||
@@ -2166,29 +2200,6 @@ ul.pagination {
|
||||
transform: scale(1.15);
|
||||
opacity: .5; }
|
||||
|
||||
.book-grid-item .grid-card-content {
|
||||
border-top: 0;
|
||||
border-bottom-width: 2px; }
|
||||
.book-grid-item .grid-card-content h2 {
|
||||
width: 100%;
|
||||
font-size: 1.5em;
|
||||
margin: 0 0 10px; }
|
||||
.book-grid-item .grid-card-content h2 a {
|
||||
display: block;
|
||||
width: 100%;
|
||||
line-height: 1.2;
|
||||
color: #009688;
|
||||
fill: #009688;
|
||||
text-decoration: none; }
|
||||
.book-grid-item .grid-card-content p {
|
||||
font-size: .85em;
|
||||
margin: 0;
|
||||
line-height: 1.6em; }
|
||||
|
||||
.book-grid-item .grid-card-footer p.small {
|
||||
font-size: .8em;
|
||||
margin: 0; }
|
||||
|
||||
.page-editor {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -2262,6 +2273,8 @@ ul.pagination {
|
||||
background: #dbffdb; }
|
||||
.page-content del {
|
||||
background: #FFECEC; }
|
||||
.page-content.page-revision pre code {
|
||||
white-space: pre-wrap; }
|
||||
|
||||
.pointer-container {
|
||||
position: relative;
|
||||
@@ -2278,8 +2291,10 @@ ul.pagination {
|
||||
position: absolute;
|
||||
top: -60px;
|
||||
background-color: #FFF;
|
||||
width: 272px;
|
||||
width: 275px;
|
||||
z-index: 55; }
|
||||
.pointer.is-page-editable {
|
||||
width: 328px; }
|
||||
.pointer:before {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
@@ -2303,12 +2318,13 @@ ul.pagination {
|
||||
color: #666;
|
||||
width: 172px;
|
||||
z-index: 40; }
|
||||
.pointer input, .pointer button {
|
||||
.pointer input, .pointer button, .pointer a {
|
||||
position: relative;
|
||||
border-radius: 0;
|
||||
height: 28px;
|
||||
font-size: 12px;
|
||||
vertical-align: top; }
|
||||
vertical-align: top;
|
||||
padding: 5px 16px; }
|
||||
.pointer > i {
|
||||
color: #888;
|
||||
font-size: 18px;
|
||||
@@ -2319,10 +2335,17 @@ ul.pagination {
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none; }
|
||||
.pointer .button {
|
||||
.pointer .input-group .button {
|
||||
line-height: 1;
|
||||
margin: 0 0 0 -4px;
|
||||
box-shadow: none; }
|
||||
.pointer a.button {
|
||||
margin: 0 0 0 0; }
|
||||
.pointer a.button:hover {
|
||||
fill: #fff; }
|
||||
.pointer .svg-icon {
|
||||
width: 1.2em;
|
||||
height: 1.2em; }
|
||||
|
||||
.floating-toolbox {
|
||||
background-color: #FFF;
|
||||
|
||||
213
public/dist/styles.css
vendored
213
public/dist/styles.css
vendored
@@ -289,6 +289,13 @@ p.secondary, p .secondary, span.secondary, .text-secondary {
|
||||
color: #e27b41;
|
||||
fill: #e27b41; }
|
||||
|
||||
.text-bookshelf {
|
||||
color: #af5a5a;
|
||||
fill: #af5a5a; }
|
||||
.text-bookshelf:hover {
|
||||
color: #af5a5a;
|
||||
fill: #af5a5a; }
|
||||
|
||||
.text-book {
|
||||
color: #009688;
|
||||
fill: #009688; }
|
||||
@@ -342,6 +349,7 @@ ul, ol {
|
||||
|
||||
ul {
|
||||
padding-left: 20.8px;
|
||||
padding-right: 20.8px;
|
||||
list-style: disc; }
|
||||
ul ul {
|
||||
list-style: circle;
|
||||
@@ -352,7 +360,8 @@ ul {
|
||||
|
||||
ol {
|
||||
list-style: decimal;
|
||||
padding-left: 32px; }
|
||||
padding-left: 32px;
|
||||
padding-right: 32px; }
|
||||
|
||||
li.checkbox-item, li.task-list-item {
|
||||
list-style: none;
|
||||
@@ -581,13 +590,40 @@ div[class^="col-"] img {
|
||||
flex-direction: column;
|
||||
border: 1px solid #ddd;
|
||||
min-width: 100px; }
|
||||
.grid-card h2 {
|
||||
width: 100%;
|
||||
font-size: 1.5em;
|
||||
margin: 0 0 10px; }
|
||||
.grid-card h2 a {
|
||||
display: block;
|
||||
width: 100%;
|
||||
line-height: 1.2;
|
||||
text-decoration: none; }
|
||||
.grid-card p {
|
||||
font-size: .85em;
|
||||
margin: 0;
|
||||
line-height: 1.6em; }
|
||||
.grid-card .grid-card-content {
|
||||
flex: 1; }
|
||||
flex: 1;
|
||||
border-top: 0;
|
||||
border-bottom-width: 2px; }
|
||||
.grid-card .grid-card-content, .grid-card .grid-card-footer {
|
||||
padding: 24px; }
|
||||
.grid-card .grid-card-content + .grid-card-footer {
|
||||
padding-top: 0; }
|
||||
|
||||
.book-grid-item .grid-card-content h2 a {
|
||||
color: #009688;
|
||||
fill: #009688; }
|
||||
|
||||
.bookshelf-grid-item .grid-card-content h2 a {
|
||||
color: #af5a5a;
|
||||
fill: #af5a5a; }
|
||||
|
||||
.book-grid-item .grid-card-footer p.small {
|
||||
font-size: .8em;
|
||||
margin: 0; }
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
.grid.third {
|
||||
grid-template-columns: 1fr 1fr; } }
|
||||
@@ -1369,13 +1405,13 @@ div[class^="col-"] img {
|
||||
text-transform: uppercase;
|
||||
border: 1px solid #0288D1;
|
||||
vertical-align: top; }
|
||||
.button-base:hover, .button:hover, input[type="button"]:hover, input[type="submit"]:hover {
|
||||
.button-base:hover, .button:hover, input:hover[type="button"], input:hover[type="submit"] {
|
||||
background-color: #02a2f9;
|
||||
text-decoration: none;
|
||||
color: #EEE; }
|
||||
.button-base:active, .button:active, input[type="button"]:active, input[type="submit"]:active {
|
||||
.button-base:active, .button:active, input:active[type="button"], input:active[type="submit"] {
|
||||
background-color: #026ea9; }
|
||||
.button-base:focus, .button:focus, input[type="button"]:focus, input[type="submit"]:focus {
|
||||
.button-base:focus, .button:focus, input:focus[type="button"], input:focus[type="submit"] {
|
||||
background-color: #0295e5;
|
||||
box-shadow: 0 0 4px 1px #CCC;
|
||||
text-decoration: none;
|
||||
@@ -1604,6 +1640,8 @@ table.table {
|
||||
text-align: right; }
|
||||
table.table .text-center {
|
||||
text-align: center; }
|
||||
table.table td.actions {
|
||||
overflow: visible; }
|
||||
|
||||
table.no-style td {
|
||||
border: 0;
|
||||
@@ -1630,9 +1668,9 @@ table.list-table {
|
||||
border: 1px solid #E84F4F; }
|
||||
.input-base.pos, .pos.fake-input, input.pos[type="text"], input.pos[type="number"], input.pos[type="email"], input.pos[type="date"], input.pos[type="search"], input.pos[type="url"], input.pos[type="password"], select.pos, textarea.pos, .input-base.valid, .valid.fake-input, input.valid[type="text"], input.valid[type="number"], input.valid[type="email"], input.valid[type="date"], input.valid[type="search"], input.valid[type="url"], input.valid[type="password"], select.valid, textarea.valid {
|
||||
border: 1px solid #52A256; }
|
||||
.input-base.disabled, .disabled.fake-input, input.disabled[type="text"], input.disabled[type="number"], input.disabled[type="email"], input.disabled[type="date"], input.disabled[type="search"], input.disabled[type="url"], input.disabled[type="password"], select.disabled, textarea.disabled, .input-base[disabled], [disabled].fake-input, input[disabled][type="text"], input[disabled][type="number"], input[disabled][type="email"], input[disabled][type="date"], input[disabled][type="search"], input[disabled][type="url"], input[disabled][type="password"], select[disabled], textarea[disabled] {
|
||||
.input-base.disabled, .disabled.fake-input, input.disabled[type="text"], input.disabled[type="number"], input.disabled[type="email"], input.disabled[type="date"], input.disabled[type="search"], input.disabled[type="url"], input.disabled[type="password"], select.disabled, textarea.disabled, .input-base[disabled], .fake-input[disabled], input[disabled][type="text"], input[disabled][type="number"], input[disabled][type="email"], input[disabled][type="date"], input[disabled][type="search"], input[disabled][type="url"], input[disabled][type="password"], select[disabled], textarea[disabled] {
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAcAAAAHCAYAAADEUlfTAAAAMUlEQVQIW2NkwAGuXbv2nxGbHEhCS0uLEUMSJgHShCKJLIEiiS4Bl8QmAZbEJQGSBAC62BuJ+tt7zgAAAABJRU5ErkJggg==); }
|
||||
.input-base:focus, .fake-input:focus, input[type="text"]:focus, input[type="number"]:focus, input[type="email"]:focus, input[type="date"]:focus, input[type="search"]:focus, input[type="url"]:focus, input[type="password"]:focus, select:focus, textarea:focus {
|
||||
.input-base:focus, .fake-input:focus, input:focus[type="text"], input:focus[type="number"], input:focus[type="email"], input:focus[type="date"], input:focus[type="search"], input:focus[type="url"], input:focus[type="password"], select:focus, textarea:focus {
|
||||
outline: 0; }
|
||||
|
||||
.fake-input {
|
||||
@@ -2078,6 +2116,9 @@ div[editor-type="markdown"] .title-input.page-title input[type="text"] {
|
||||
.page-content.mce-content-body p {
|
||||
line-height: 1.6; }
|
||||
|
||||
.mce-colorbtn-trans {
|
||||
overflow: hidden; }
|
||||
|
||||
/* BASICS */
|
||||
.CodeMirror {
|
||||
/* Set height, width, borders, and global font properties here */
|
||||
@@ -2600,49 +2641,89 @@ span.CodeMirror-selectedtext {
|
||||
width: 100%;
|
||||
height: 100%; }
|
||||
|
||||
/**
|
||||
* Custom Copy Button
|
||||
*/
|
||||
.CodeMirror-copy {
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
right: -1px;
|
||||
background-color: #EEE;
|
||||
padding: 6px;
|
||||
line-height: 0;
|
||||
border: 1px solid #DDD;
|
||||
cursor: pointer;
|
||||
fill: #444;
|
||||
z-index: 5;
|
||||
transition: all ease-in 240ms;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
opacity: 0;
|
||||
pointer-events: none; }
|
||||
.CodeMirror-copy svg {
|
||||
transition: -webkit-transform ease-in 240ms;
|
||||
transition: transform ease-in 240ms;
|
||||
transition: transform ease-in 240ms, -webkit-transform ease-in 240ms;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
.CodeMirror-copy.success {
|
||||
background-color: #70b774;
|
||||
fill: #FFF; }
|
||||
.CodeMirror-copy.success svg {
|
||||
-webkit-transform: translateY(-3px);
|
||||
transform: translateY(-3px); }
|
||||
|
||||
.CodeMirror:hover .CodeMirror-copy {
|
||||
-webkit-user-select: all;
|
||||
-moz-user-select: all;
|
||||
-ms-user-select: all;
|
||||
user-select: all;
|
||||
opacity: 1;
|
||||
pointer-events: all; }
|
||||
|
||||
[notification] {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
margin: 64px 32px;
|
||||
padding: 24px 32px;
|
||||
padding: 16px 24px;
|
||||
background-color: #EEE;
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 1px 3px 1px rgba(76, 76, 76, 0.26);
|
||||
box-shadow: 0 1px 3px 1px rgba(76, 76, 76, 0.26), 0 1px 12px 0px rgba(76, 76, 76, 0.2);
|
||||
z-index: 999999;
|
||||
cursor: pointer;
|
||||
max-width: 360px;
|
||||
transition: -webkit-transform ease-in-out 280ms;
|
||||
transition: transform ease-in-out 280ms;
|
||||
transition: transform ease-in-out 280ms, -webkit-transform ease-in-out 280ms;
|
||||
-webkit-transform: translate3d(580px, 0, 0);
|
||||
transform: translate3d(580px, 0, 0);
|
||||
-webkit-transform: translateX(580px);
|
||||
transform: translateX(580px);
|
||||
display: grid;
|
||||
grid-template-columns: 64px 1fr; }
|
||||
grid-template-columns: 42px 1fr;
|
||||
color: #FFF; }
|
||||
[notification] span, [notification] svg {
|
||||
vertical-align: middle;
|
||||
justify-self: center;
|
||||
align-self: center; }
|
||||
[notification] svg {
|
||||
fill: #EEEEEE;
|
||||
width: 4em;
|
||||
height: 4em;
|
||||
padding-right: 16px; }
|
||||
width: 2.8rem;
|
||||
height: 2.8rem;
|
||||
padding-right: 12px; }
|
||||
[notification] span {
|
||||
vertical-align: middle;
|
||||
line-height: 1.3; }
|
||||
[notification].pos {
|
||||
background-color: #52A256;
|
||||
color: #EEE; }
|
||||
background-color: #52A256; }
|
||||
[notification].neg {
|
||||
background-color: #E84F4F;
|
||||
color: #EEE; }
|
||||
background-color: #E84F4F; }
|
||||
[notification].warning {
|
||||
background-color: #e27b41;
|
||||
color: #EEE; }
|
||||
background-color: #e27b41; }
|
||||
[notification].showing {
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0); }
|
||||
-webkit-transform: translateX(0);
|
||||
transform: translateX(0); }
|
||||
[notification].showing:hover {
|
||||
-webkit-transform: translate3d(0, -2px, 0);
|
||||
transform: translate3d(0, -2px, 0); }
|
||||
@@ -2749,7 +2830,7 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group {
|
||||
width: 16.66667%;
|
||||
height: auto;
|
||||
border: 1px solid #DDD;
|
||||
box-shadow: 0 0 0 0 transparent;
|
||||
box-shadow: 0 0 0 0 rgba(0, 0, 0, 0);
|
||||
transition: all cubic-bezier(0.4, 0, 1, 1) 160ms;
|
||||
overflow: hidden; }
|
||||
.image-manager-list .image.selected {
|
||||
@@ -3525,7 +3606,7 @@ header .search-box {
|
||||
.book-tree .sidebar-page-list .sub-menu {
|
||||
display: none;
|
||||
padding-left: 0; }
|
||||
.book-tree .sidebar-page-list .sub-menu.open {
|
||||
.book-tree .sidebar-page-list [chapter-toggle].open + .sub-menu {
|
||||
display: block; }
|
||||
|
||||
.sortable-page-list, .sortable-page-list ul {
|
||||
@@ -3592,8 +3673,6 @@ ul.pagination {
|
||||
padding: 3px 12px;
|
||||
border: 1px solid #CCC;
|
||||
margin-left: -1px;
|
||||
color: #888;
|
||||
fill: #888;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
@@ -3601,13 +3680,7 @@ ul.pagination {
|
||||
ul.pagination a.disabled, ul.pagination span.disabled {
|
||||
cursor: not-allowed; }
|
||||
ul.pagination li.active span {
|
||||
background-color: rgba(2, 136, 209, 0.8);
|
||||
color: #EEE;
|
||||
fill: #EEE;
|
||||
border-color: rgba(2, 136, 209, 0.8); }
|
||||
ul.pagination a {
|
||||
color: #0288D1;
|
||||
fill: #0288D1; }
|
||||
color: #FFF; }
|
||||
|
||||
.compact ul.pagination {
|
||||
margin: 0; }
|
||||
@@ -3684,18 +3757,22 @@ ul.pagination {
|
||||
.dropdown-container ul li.padded {
|
||||
padding: 6px 16px;
|
||||
line-height: 1.2; }
|
||||
.dropdown-container ul a {
|
||||
.dropdown-container ul a, .dropdown-container ul button {
|
||||
display: block;
|
||||
padding: 6px 16px;
|
||||
color: #555;
|
||||
fill: #555; }
|
||||
.dropdown-container ul a:hover {
|
||||
fill: #555;
|
||||
white-space: nowrap; }
|
||||
.dropdown-container ul a:hover, .dropdown-container ul button:hover {
|
||||
text-decoration: none;
|
||||
background-color: #EEE; }
|
||||
.dropdown-container ul a svg {
|
||||
.dropdown-container ul a svg, .dropdown-container ul button svg {
|
||||
margin-right: 12px;
|
||||
display: inline-block;
|
||||
width: 16px; }
|
||||
.dropdown-container ul button {
|
||||
width: 100%;
|
||||
text-align: left; }
|
||||
.dropdown-container ul li.border-bottom {
|
||||
border-bottom: 1px solid #DDD; }
|
||||
|
||||
@@ -3716,29 +3793,6 @@ ul.pagination {
|
||||
transform: scale(1.15);
|
||||
opacity: .5; }
|
||||
|
||||
.book-grid-item .grid-card-content {
|
||||
border-top: 0;
|
||||
border-bottom-width: 2px; }
|
||||
.book-grid-item .grid-card-content h2 {
|
||||
width: 100%;
|
||||
font-size: 1.5em;
|
||||
margin: 0 0 10px; }
|
||||
.book-grid-item .grid-card-content h2 a {
|
||||
display: block;
|
||||
width: 100%;
|
||||
line-height: 1.2;
|
||||
color: #009688;
|
||||
fill: #009688;
|
||||
text-decoration: none; }
|
||||
.book-grid-item .grid-card-content p {
|
||||
font-size: .85em;
|
||||
margin: 0;
|
||||
line-height: 1.6em; }
|
||||
|
||||
.book-grid-item .grid-card-footer p.small {
|
||||
font-size: .8em;
|
||||
margin: 0; }
|
||||
|
||||
.page-editor {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -3812,6 +3866,8 @@ ul.pagination {
|
||||
background: #dbffdb; }
|
||||
.page-content del {
|
||||
background: #FFECEC; }
|
||||
.page-content.page-revision pre code {
|
||||
white-space: pre-wrap; }
|
||||
|
||||
.pointer-container {
|
||||
position: relative;
|
||||
@@ -3828,8 +3884,10 @@ ul.pagination {
|
||||
position: absolute;
|
||||
top: -60px;
|
||||
background-color: #FFF;
|
||||
width: 272px;
|
||||
width: 275px;
|
||||
z-index: 55; }
|
||||
.pointer.is-page-editable {
|
||||
width: 328px; }
|
||||
.pointer:before {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
@@ -3853,12 +3911,13 @@ ul.pagination {
|
||||
color: #666;
|
||||
width: 172px;
|
||||
z-index: 40; }
|
||||
.pointer input, .pointer button {
|
||||
.pointer input, .pointer button, .pointer a {
|
||||
position: relative;
|
||||
border-radius: 0;
|
||||
height: 28px;
|
||||
font-size: 12px;
|
||||
vertical-align: top; }
|
||||
vertical-align: top;
|
||||
padding: 5px 16px; }
|
||||
.pointer > i {
|
||||
color: #888;
|
||||
font-size: 18px;
|
||||
@@ -3869,10 +3928,17 @@ ul.pagination {
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none; }
|
||||
.pointer .button {
|
||||
.pointer .input-group .button {
|
||||
line-height: 1;
|
||||
margin: 0 0 0 -4px;
|
||||
box-shadow: none; }
|
||||
.pointer a.button {
|
||||
margin: 0 0 0 0; }
|
||||
.pointer a.button:hover {
|
||||
fill: #fff; }
|
||||
.pointer .svg-icon {
|
||||
width: 1.2em;
|
||||
height: 1.2em; }
|
||||
|
||||
.floating-toolbox {
|
||||
background-color: #FFF;
|
||||
@@ -4128,8 +4194,6 @@ body.dragging, body.dragging * {
|
||||
[back-to-top]:hover {
|
||||
width: 136px;
|
||||
opacity: 1 !important; }
|
||||
[back-to-top]:hover span {
|
||||
display: inline-block; }
|
||||
[back-to-top] .inner {
|
||||
width: 136px; }
|
||||
[back-to-top] span {
|
||||
@@ -4186,10 +4250,25 @@ body.dragging, body.dragging * {
|
||||
background-color: #FFF;
|
||||
transition: all ease-in-out 120ms;
|
||||
cursor: pointer; }
|
||||
.entity-selector.compact {
|
||||
font-size: 10px; }
|
||||
.entity-selector.compact .entity-item-snippet {
|
||||
display: none; }
|
||||
|
||||
.entity-list-item.selected h3, .entity-list-item.selected i, .entity-list-item.selected p, .entity-list-item.selected a, .entity-list-item.selected span {
|
||||
color: #EEE; }
|
||||
|
||||
.scroll-box {
|
||||
max-height: 250px;
|
||||
overflow-y: scroll;
|
||||
border: 1px solid #DDD;
|
||||
border-radius: 3px; }
|
||||
.scroll-box .scroll-box-item {
|
||||
padding: 6px 16px;
|
||||
border-bottom: 1px solid #DDD; }
|
||||
.scroll-box .scroll-box-item:last-child {
|
||||
border-bottom: 0; }
|
||||
|
||||
.center-box {
|
||||
margin: 48px auto 0 auto;
|
||||
width: 420px;
|
||||
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),e=tinymce.util.Tools.resolve("tinymce.util.Tools"),n=function(t,e,n){var r="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(r,!1,!1===n?null:{"list-style-type":n})},r=function(t){t.addCommand("ApplyUnorderedListStyle",function(e,r){n(t,"UL",r["list-style-type"])}),t.addCommand("ApplyOrderedListStyle",function(e,r){n(t,"OL",r["list-style-type"])})},o=function(t){var e=t.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman");return e?e.split(/[ ,]/):[]},i=function(t){var e=t.getParam("advlist_bullet_styles","default,circle,disc,square");return e?e.split(/[ ,]/):[]},l=function(t){return t&&/^(TH|TD)$/.test(t.nodeName)},a=function(t){return function(e){return e&&/^(OL|UL|DL)$/.test(e.nodeName)&&(r=e,(n=t).$.contains(n.getBody(),r));var n,r}},s=function(t){var e=t.dom.getParent(t.selection.getNode(),"ol,ul");return t.dom.getStyle(e,"listStyleType")||""},u=function(t){return e.map(t,function(t){return{text:t.replace(/\-/g," ").replace(/\b\w/g,function(t){return t.toUpperCase()}),data:"default"===t?"":t}})},c=function(t,n){return function(r){var o=r.control;t.on("NodeChange",function(r){var i=function(t,e){for(var n=0;n<t.length;n++)if(e(t[n]))return n;return-1}(r.parents,l),s=-1!==i?r.parents.slice(0,i):r.parents,u=e.grep(s,a(t));o.active(u.length>0&&u[0].nodeName===n)})}},d=function(t,e,r,o,i,l){var a;t.addButton(e,{active:!1,type:"splitbutton",tooltip:r,menu:u(l),onPostRender:c(t,i),onshow:(a=t,function(t){var e=s(a);t.control.items().each(function(t){t.active(t.settings.data===e)})}),onselect:function(e){n(t,i,e.control.settings.data)},onclick:function(){t.execCommand(o)}})},p=function(t,e,n,r,o,i){var l,a,s,u,p;i.length>0?d(t,e,n,r,o,i):(a=e,s=n,u=r,p=o,(l=t).addButton(a,{active:!1,type:"button",tooltip:s,onPostRender:c(l,p),onclick:function(){l.execCommand(u)}}))},f=function(t){p(t,"numlist","Numbered list","InsertOrderedList","OL",o(t)),p(t,"bullist","Bullet list","InsertUnorderedList","UL",i(t))};t.add("advlist",function(t){var n,o,i;o="lists",i=(n=t).settings.plugins?n.settings.plugins:"",-1!==e.inArray(i.split(/[ ,]/),o)&&(f(t),r(t))})}();
|
||||
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.util.Tools"),s=function(t,e,n){var r="UL"===e?"InsertUnorderedList":"InsertOrderedList";t.execCommand(r,!1,!1===n?null:{"list-style-type":n})},o=function(n){n.addCommand("ApplyUnorderedListStyle",function(t,e){s(n,"UL",e["list-style-type"])}),n.addCommand("ApplyOrderedListStyle",function(t,e){s(n,"OL",e["list-style-type"])})},e=function(t){var e=t.getParam("advlist_number_styles","default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman");return e?e.split(/[ ,]/):[]},n=function(t){var e=t.getParam("advlist_bullet_styles","default,circle,disc,square");return e?e.split(/[ ,]/):[]},u=function(t){return t&&/^(TH|TD)$/.test(t.nodeName)},c=function(r){return function(t){return t&&/^(OL|UL|DL)$/.test(t.nodeName)&&(n=t,(e=r).$.contains(e.getBody(),n));var e,n}},d=function(t){var e=t.dom.getParent(t.selection.getNode(),"ol,ul");return t.dom.getStyle(e,"listStyleType")||""},p=function(t){return a.map(t,function(t){return{text:t.replace(/\-/g," ").replace(/\b\w/g,function(t){return t.toUpperCase()}),data:"default"===t?"":t}})},f=function(i,l){return function(t){var o=t.control;i.on("NodeChange",function(t){var e=function(t,e){for(var n=0;n<t.length;n++)if(e(t[n]))return n;return-1}(t.parents,u),n=-1!==e?t.parents.slice(0,e):t.parents,r=a.grep(n,c(i));o.active(0<r.length&&r[0].nodeName===l)})}},m=function(e,t,n,r,o,i){var l;e.addButton(t,{active:!1,type:"splitbutton",tooltip:n,menu:p(i),onPostRender:f(e,o),onshow:(l=e,function(t){var e=d(l);t.control.items().each(function(t){t.active(t.settings.data===e)})}),onselect:function(t){s(e,o,t.control.settings.data)},onclick:function(){e.execCommand(r)}})},r=function(t,e,n,r,o,i){var l,a,s,u,c;0<i.length?m(t,e,n,r,o,i):(a=e,s=n,u=r,c=o,(l=t).addButton(a,{active:!1,type:"button",tooltip:s,onPostRender:f(l,c),onclick:function(){l.execCommand(u)}}))},i=function(t){r(t,"numlist","Numbered list","InsertOrderedList","OL",e(t)),r(t,"bullist","Bullet list","InsertUnorderedList","UL",n(t))};t.add("advlist",function(t){var e,n,r;n="lists",r=(e=t).settings.plugins?e.settings.plugins:"",-1!==a.inArray(r.split(/[ ,]/),n)&&(i(t),o(t))})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),e=function(t){return/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)},n=function(t){var e=t.selection.getNode();return"A"===e.tagName&&""===t.dom.getAttrib(e,"href")?e.id||e.name:""},o=function(t,e){var n=t.selection.getNode();"A"===n.tagName&&""===t.dom.getAttrib(n,"href")?(n.removeAttribute("name"),n.id=e):(t.focus(),t.selection.collapse(!0),t.execCommand("mceInsertContent",!1,t.dom.createHTML("a",{id:e})))},r=function(t){var r=n(t);t.windowManager.open({title:"Anchor",body:{type:"textbox",name:"id",size:40,label:"Id",value:r},onsubmit:function(n){var r,a,i=n.data.id;r=t,(e(a=i)?(o(r,a),0):(r.windowManager.alert("Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),1))&&n.preventDefault()}})},a=function(t){t.addCommand("mceAnchor",function(){r(t)})},i=function(t){return function(e){for(var n=0;n<e.length;n++)(o=e[n]).attr("href")||!o.attr("id")&&!o.attr("name")||o.firstChild||e[n].attr("contenteditable",t);var o}},c=function(t){t.on("PreInit",function(){t.parser.addNodeFilter("a",i("false")),t.serializer.addNodeFilter("a",i(null))})},d=function(t){t.addButton("anchor",{icon:"anchor",tooltip:"Anchor",cmd:"mceAnchor",stateSelector:"a:not([href])"}),t.addMenuItem("anchor",{icon:"anchor",text:"Anchor",context:"insert",cmd:"mceAnchor"})};t.add("anchor",function(t){c(t),a(t),d(t)})}();
|
||||
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=function(t){return/^[A-Za-z][A-Za-z0-9\-:._]*$/.test(t)},e=function(t){var e=t.selection.getNode();return"A"===e.tagName&&""===t.dom.getAttrib(e,"href")?e.id||e.name:""},i=function(t,e){var n=t.selection.getNode();"A"===n.tagName&&""===t.dom.getAttrib(n,"href")?(n.removeAttribute("name"),n.id=e,t.undoManager.add()):(t.focus(),t.selection.collapse(!0),t.execCommand("mceInsertContent",!1,t.dom.createHTML("a",{id:e})))},n=function(r){var t=e(r);r.windowManager.open({title:"Anchor",body:{type:"textbox",name:"id",size:40,label:"Id",value:t},onsubmit:function(t){var e,n,o=t.data.id;e=r,(a(n=o)?(i(e,n),0):(e.windowManager.alert("Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores."),1))&&t.preventDefault()}})},o=function(t){t.addCommand("mceAnchor",function(){n(t)})},r=function(o){return function(t){for(var e=0;e<t.length;e++)(n=t[e]).attr("href")||!n.attr("id")&&!n.attr("name")||n.firstChild||t[e].attr("contenteditable",o);var n}},c=function(t){t.on("PreInit",function(){t.parser.addNodeFilter("a",r("false")),t.serializer.addNodeFilter("a",r(null))})},d=function(t){t.addButton("anchor",{icon:"anchor",tooltip:"Anchor",cmd:"mceAnchor",stateSelector:"a:not([href])"}),t.addMenuItem("anchor",{icon:"anchor",text:"Anchor",context:"insert",cmd:"mceAnchor"})};t.add("anchor",function(t){c(t),o(t),d(t)})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env"),n=function(e){return e.getParam("autolink_pattern",/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i)},i=function(e){return e.getParam("default_link_target","")},o=function(e,t){if(t<0&&(t=0),3===e.nodeType){var n=e.data.length;t>n&&(t=n)}return t},r=function(e,t,n){1!==t.nodeType||t.hasChildNodes()?e.setStart(t,o(t,n)):e.setStartBefore(t)},a=function(e,t,n){1!==t.nodeType||t.hasChildNodes()?e.setEnd(t,o(t,n)):e.setEndAfter(t)},f=function(e,t,o){var f,s,d,l,c,u,g,h,C,m,y=n(e),k=i(e);if("A"!==e.selection.getNode().tagName){if((f=e.selection.getRng(!0).cloneRange()).startOffset<5){if(!(h=f.endContainer.previousSibling)){if(!f.endContainer.firstChild||!f.endContainer.firstChild.nextSibling)return;h=f.endContainer.firstChild.nextSibling}if(C=h.length,r(f,h,C),a(f,h,C),f.endOffset<5)return;s=f.endOffset,l=h}else{if(3!==(l=f.endContainer).nodeType&&l.firstChild){for(;3!==l.nodeType&&l.firstChild;)l=l.firstChild;3===l.nodeType&&(r(f,l,0),a(f,l,l.nodeValue.length))}s=1===f.endOffset?2:f.endOffset-1-t}for(d=s;r(f,l,s>=2?s-2:0),a(f,l,s>=1?s-1:0),s-=1," "!==(m=f.toString())&&""!==m&&160!==m.charCodeAt(0)&&s-2>=0&&m!==o;);var p;(p=f.toString())===o||" "===p||160===p.charCodeAt(0)?(r(f,l,s),a(f,l,d),s+=1):0===f.startOffset?(r(f,l,0),a(f,l,d)):(r(f,l,s),a(f,l,d)),"."===(u=f.toString()).charAt(u.length-1)&&a(f,l,d-1),(g=(u=f.toString().trim()).match(y))&&("www."===g[1]?g[1]="http://www.":/@$/.test(g[1])&&!/^mailto:/.test(g[1])&&(g[1]="mailto:"+g[1]),c=e.selection.getBookmark(),e.selection.setRng(f),e.execCommand("createlink",!1,g[1]+g[2]),k&&e.dom.setAttrib(e.selection.getNode(),"target",k),e.selection.moveToBookmark(c),e.nodeChanged())}},s=function(e){var n;e.on("keydown",function(t){13!==t.keyCode||f(e,-1,"")}),t.ie?e.on("focus",function(){if(!n){n=!0;try{e.execCommand("AutoUrlDetect",!1,!0)}catch(t){}}}):(e.on("keypress",function(t){41!==t.keyCode||f(e,-1,"(")}),e.on("keyup",function(t){32!==t.keyCode||f(e,0,"")}))};e.add("autolink",function(e){s(e)})}();
|
||||
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=tinymce.util.Tools.resolve("tinymce.Env"),m=function(e){return e.getParam("autolink_pattern",/^(https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.|(?:mailto:)?[A-Z0-9._%+\-]+@)(.+)$/i)},y=function(e){return e.getParam("default_link_target","")},o=function(e,t){if(t<0&&(t=0),3===e.nodeType){var n=e.data.length;n<t&&(t=n)}return t},k=function(e,t,n){1!==t.nodeType||t.hasChildNodes()?e.setStart(t,o(t,n)):e.setStartBefore(t)},p=function(e,t,n){1!==t.nodeType||t.hasChildNodes()?e.setEnd(t,o(t,n)):e.setEndAfter(t)},r=function(e,t,n){var i,o,r,a,f,s,d,l,c,u,g=m(e),h=y(e);if("A"!==e.selection.getNode().tagName){if((i=e.selection.getRng(!0).cloneRange()).startOffset<5){if(!(l=i.endContainer.previousSibling)){if(!i.endContainer.firstChild||!i.endContainer.firstChild.nextSibling)return;l=i.endContainer.firstChild.nextSibling}if(c=l.length,k(i,l,c),p(i,l,c),i.endOffset<5)return;o=i.endOffset,a=l}else{if(3!==(a=i.endContainer).nodeType&&a.firstChild){for(;3!==a.nodeType&&a.firstChild;)a=a.firstChild;3===a.nodeType&&(k(i,a,0),p(i,a,a.nodeValue.length))}o=1===i.endOffset?2:i.endOffset-1-t}for(r=o;k(i,a,2<=o?o-2:0),p(i,a,1<=o?o-1:0),o-=1," "!==(u=i.toString())&&""!==u&&160!==u.charCodeAt(0)&&0<=o-2&&u!==n;);var C;(C=i.toString())===n||" "===C||160===C.charCodeAt(0)?(k(i,a,o),p(i,a,r),o+=1):(0===i.startOffset?k(i,a,0):k(i,a,o),p(i,a,r)),"."===(s=i.toString()).charAt(s.length-1)&&p(i,a,r-1),(d=(s=i.toString().trim()).match(g))&&("www."===d[1]?d[1]="http://www.":/@$/.test(d[1])&&!/^mailto:/.test(d[1])&&(d[1]="mailto:"+d[1]),f=e.selection.getBookmark(),e.selection.setRng(i),e.execCommand("createlink",!1,d[1]+d[2]),h&&e.dom.setAttrib(e.selection.getNode(),"target",h),e.selection.moveToBookmark(f),e.nodeChanged())}},t=function(t){var n;t.on("keydown",function(e){13!==e.keyCode||r(t,-1,"")}),i.ie?t.on("focus",function(){if(!n){n=!0;try{t.execCommand("AutoUrlDetect",!1,!0)}catch(e){}}}):(t.on("keypress",function(e){41!==e.keyCode||r(t,-1,"(")}),t.on("keyup",function(e){32!==e.keyCode||r(t,0,"")}))};e.add("autolink",function(e){t(e)})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var t=function(e){var n=e,i=function(){return n};return{get:i,set:function(t){n=t},clone:function(){return t(i())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=tinymce.util.Tools.resolve("tinymce.Env"),i=tinymce.util.Tools.resolve("tinymce.util.Delay"),o=function(t){return parseInt(t.getParam("autoresize_min_height",t.getElement().offsetHeight),10)},r=function(t){return parseInt(t.getParam("autoresize_max_height",0),10)},a=function(t){return t.getParam("autoresize_overflow_padding",1)},u=function(t){return t.getParam("autoresize_bottom_margin",50)},s=function(t){return t.getParam("autoresize_on_init",!0)},l=function(t,e,n,o,r){i.setEditorTimeout(t,function(){c(t,e),n--?l(t,e,n,o,r):r&&r()},o)},g=function(t,e){var n=t.getBody();n&&(n.style.overflowY=e?"":"hidden",e||(n.scrollTop=0))},c=function(t,e){var i,a,u,s,l,f,d,m,p,y,h,v=t.dom;if(a=t.getDoc())if((S=t).plugins.fullscreen&&S.plugins.fullscreen.isFullscreen())g(t,!0);else{var S;u=a.body,s=o(t),f=v.getStyle(u,"margin-top",!0),d=v.getStyle(u,"margin-bottom",!0),m=v.getStyle(u,"padding-top",!0),p=v.getStyle(u,"padding-bottom",!0),y=v.getStyle(u,"border-top-width",!0),h=v.getStyle(u,"border-bottom-width",!0),l=u.offsetHeight+parseInt(f,10)+parseInt(d,10)+parseInt(m,10)+parseInt(p,10)+parseInt(y,10)+parseInt(h,10),(isNaN(l)||l<=0)&&(l=n.ie?u.scrollHeight:n.webkit&&0===u.clientHeight?0:u.offsetHeight),l>o(t)&&(s=l);var _=r(t);_&&l>_?(s=_,g(t,!0)):g(t,!1),s!==e.get()&&(i=s-e.get(),v.setStyle(t.iframeElement,"height",s+"px"),e.set(s),n.webkit&&i<0&&c(t,e))}},f={setup:function(t,e){t.on("init",function(){var e,n,i=t.dom;e=a(t),n=u(t),!1!==e&&i.setStyles(t.getBody(),{paddingLeft:e,paddingRight:e}),!1!==n&&i.setStyles(t.getBody(),{paddingBottom:n})}),t.on("nodechange setcontent keyup FullscreenStateChanged",function(n){c(t,e)}),s(t)&&t.on("init",function(){l(t,e,20,100,function(){l(t,e,5,1e3)})})},resize:c},d=function(t,e){t.addCommand("mceAutoResize",function(){f.resize(t,e)})};e.add("autoresize",function(e){if(!e.inline){var n=t(0);d(e,n),f.setup(e,n)}})}();
|
||||
!function(){"use strict";var i=function(t){var e=t,n=function(){return e};return{get:n,set:function(t){e=t},clone:function(){return i(n())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),y=tinymce.util.Tools.resolve("tinymce.Env"),r=tinymce.util.Tools.resolve("tinymce.util.Delay"),h=function(t){return parseInt(t.getParam("autoresize_min_height",t.getElement().offsetHeight),10)},v=function(t){return parseInt(t.getParam("autoresize_max_height",0),10)},o=function(t){return t.getParam("autoresize_overflow_padding",1)},a=function(t){return t.getParam("autoresize_bottom_margin",50)},n=function(t){return t.getParam("autoresize_on_init",!0)},u=function(t,e,n,i,o){r.setEditorTimeout(t,function(){_(t,e),n--?u(t,e,n,i,o):o&&o()},i)},S=function(t,e){var n=t.getBody();n&&(n.style.overflowY=e?"":"hidden",e||(n.scrollTop=0))},_=function(t,e){var n,i,o,r,a,u,s,l,g,c,f,d=t.dom;if(i=t.getDoc())if((m=t).plugins.fullscreen&&m.plugins.fullscreen.isFullscreen())S(t,!0);else{var m;o=i.body,r=h(t),u=d.getStyle(o,"margin-top",!0),s=d.getStyle(o,"margin-bottom",!0),l=d.getStyle(o,"padding-top",!0),g=d.getStyle(o,"padding-bottom",!0),c=d.getStyle(o,"border-top-width",!0),f=d.getStyle(o,"border-bottom-width",!0),a=o.offsetHeight+parseInt(u,10)+parseInt(s,10)+parseInt(l,10)+parseInt(g,10)+parseInt(c,10)+parseInt(f,10),(isNaN(a)||a<=0)&&(a=y.ie?o.scrollHeight:y.webkit&&0===o.clientHeight?0:o.offsetHeight),a>h(t)&&(r=a);var p=v(t);p&&p<a?(r=p,S(t,!0)):S(t,!1),r!==e.get()&&(n=r-e.get(),d.setStyle(t.iframeElement,"height",r+"px"),e.set(r),y.webkit&&n<0&&_(t,e))}},s={setup:function(i,e){i.on("init",function(){var t,e,n=i.dom;t=o(i),e=a(i),!1!==t&&n.setStyles(i.getBody(),{paddingLeft:t,paddingRight:t}),!1!==e&&n.setStyles(i.getBody(),{paddingBottom:e})}),i.on("nodechange setcontent keyup FullscreenStateChanged",function(t){_(i,e)}),n(i)&&i.on("init",function(){u(i,e,20,100,function(){u(i,e,5,1e3)})})},resize:_},l=function(t,e){t.addCommand("mceAutoResize",function(){s.resize(t,e)})};t.add("autoresize",function(t){if(!t.inline){var e=i(0);l(t,e),s.setup(t,e)}})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var t=function(e){var r=e,n=function(){return r};return{get:n,set:function(t){r=t},clone:function(){return t(n())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),r=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),n=tinymce.util.Tools.resolve("tinymce.util.Tools"),a=function(t){return t.fire("RestoreDraft")},o=function(t){return t.fire("StoreDraft")},i=function(t){return t.fire("RemoveDraft")},s=function(t,e){return((t=/^(\d+)([ms]?)$/.exec(""+(t||e)))[2]?{s:1e3,m:6e4}[t[2]]:1)*parseInt(t,10)},u=function(t){return t.getParam("autosave_ask_before_unload",!0)},f=function(t){var e=t.getParam("autosave_prefix","tinymce-autosave-{path}{query}{hash}-{id}-");return e=(e=(e=(e=e.replace(/\{path\}/g,document.location.pathname)).replace(/\{query\}/g,document.location.search)).replace(/\{hash\}/g,document.location.hash)).replace(/\{id\}/g,t.id)},c=function(t){return s(t.settings.autosave_interval,"30s")},l=function(t){return s(t.settings.autosave_retention,"20m")},m=function(t,e){var r=t.settings.forced_root_block;return""===(e=n.trim(void 0===e?t.getBody().innerHTML:e))||new RegExp("^<"+r+"[^>]*>((\xa0| |[ \t]|<br[^>]*>)+?|)</"+r+">|<br>$","i").test(e)},v=function(t){var e=parseInt(r.getItem(f(t)+"time"),10)||0;return!((new Date).getTime()-e>l(t)&&(d(t,!1),1))},d=function(t,e){var n=f(t);r.removeItem(n+"draft"),r.removeItem(n+"time"),!1!==e&&i(t)},D=function(t){var e=f(t);!m(t)&&t.isDirty()&&(r.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),r.setItem(e+"time",(new Date).getTime().toString()),o(t))},g=function(t){var e=f(t);v(t)&&(t.setContent(r.getItem(e+"draft"),{format:"raw"}),a(t))},y={isEmpty:m,hasDraft:v,removeDraft:d,storeDraft:D,restoreDraft:g,startStoreDraft:function(t,e){var r=c(t);e.get()||(setInterval(function(){t.removed||D(t)},r),e.set(!0))},restoreLastDraft:function(t){t.undoManager.transact(function(){g(t),d(t)}),t.focus()}},p=function(t,e){return function(){var r=Array.prototype.slice.call(arguments);return t.apply(null,[e].concat(r))}},h=function(t){return{hasDraft:p(y.hasDraft,t),storeDraft:p(y.storeDraft,t),restoreDraft:p(y.restoreDraft,t),removeDraft:p(y.removeDraft,t),isEmpty:p(y.isEmpty,t)}},_=tinymce.util.Tools.resolve("tinymce.EditorManager");_._beforeUnloadHandler=function(){var t;return n.each(_.get(),function(e){e.plugins.autosave&&e.plugins.autosave.storeDraft(),!t&&e.isDirty()&&u(e)&&(t=e.translate("You have unsaved changes are you sure you want to navigate away?"))}),t};var b=function(t){window.onbeforeunload=_._beforeUnloadHandler},I=function(t,e){return function(r){var n=r.control;n.disabled(!y.hasDraft(t)),t.on("StoreDraft RestoreDraft RemoveDraft",function(){n.disabled(!y.hasDraft(t))}),y.startStoreDraft(t,e)}},w=function(t,e){t.addButton("restoredraft",{title:"Restore last draft",onclick:function(){y.restoreLastDraft(t)},onPostRender:I(t,e)}),t.addMenuItem("restoredraft",{text:"Restore last draft",onclick:function(){y.restoreLastDraft(t)},onPostRender:I(t,e),context:"file"})};e.add("autosave",function(e){var r=t(!1);return b(e),w(e,r),h(e)})}();
|
||||
!function(){"use strict";var n=function(t){var e=t,r=function(){return e};return{get:r,set:function(t){e=t},clone:function(){return n(r())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),o=tinymce.util.Tools.resolve("tinymce.util.Tools"),r=function(t){return t.fire("RestoreDraft")},i=function(t){return t.fire("StoreDraft")},s=function(t){return t.fire("RemoveDraft")},e=function(t,e){return((t=/^(\d+)([ms]?)$/.exec(""+(t||e)))[2]?{s:1e3,m:6e4}[t[2]]:1)*parseInt(t,10)},u=function(t){return t.getParam("autosave_ask_before_unload",!0)},f=function(t){var e=t.getParam("autosave_prefix","tinymce-autosave-{path}{query}{hash}-{id}-");return e=(e=(e=(e=e.replace(/\{path\}/g,document.location.pathname)).replace(/\{query\}/g,document.location.search)).replace(/\{hash\}/g,document.location.hash)).replace(/\{id\}/g,t.id)},c=function(t){return e(t.settings.autosave_interval,"30s")},l=function(t){return e(t.settings.autosave_retention,"20m")},m=function(t,e){var r=t.settings.forced_root_block;return""===(e=o.trim(void 0===e?t.getBody().innerHTML:e))||new RegExp("^<"+r+"[^>]*>((\xa0| |[ \t]|<br[^>]*>)+?|)</"+r+">|<br>$","i").test(e)},v=function(t){var e=parseInt(a.getItem(f(t)+"time"),10)||0;return!((new Date).getTime()-e>l(t)&&(d(t,!1),1))},d=function(t,e){var r=f(t);a.removeItem(r+"draft"),a.removeItem(r+"time"),!1!==e&&s(t)},D=function(t){var e=f(t);!m(t)&&t.isDirty()&&(a.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),a.setItem(e+"time",(new Date).getTime().toString()),i(t))},g=function(t){var e=f(t);v(t)&&(t.setContent(a.getItem(e+"draft"),{format:"raw"}),r(t))},y={isEmpty:m,hasDraft:v,removeDraft:d,storeDraft:D,restoreDraft:g,startStoreDraft:function(t,e){var r=c(t);e.get()||(setInterval(function(){t.removed||D(t)},r),e.set(!0))},restoreLastDraft:function(t){t.undoManager.transact(function(){g(t),d(t)}),t.focus()}},p=function(e,r){return function(){var t=Array.prototype.slice.call(arguments);return e.apply(null,[r].concat(t))}},h=function(t){return{hasDraft:p(y.hasDraft,t),storeDraft:p(y.storeDraft,t),restoreDraft:p(y.restoreDraft,t),removeDraft:p(y.removeDraft,t),isEmpty:p(y.isEmpty,t)}},_=tinymce.util.Tools.resolve("tinymce.EditorManager");_._beforeUnloadHandler=function(){var e;return o.each(_.get(),function(t){t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&u(t)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))}),e};var b=function(t){window.onbeforeunload=_._beforeUnloadHandler},I=function(r,n){return function(t){var e=t.control;e.disabled(!y.hasDraft(r)),r.on("StoreDraft RestoreDraft RemoveDraft",function(){e.disabled(!y.hasDraft(r))}),y.startStoreDraft(r,n)}},w=function(t,e){t.addButton("restoredraft",{title:"Restore last draft",onclick:function(){y.restoreLastDraft(t)},onPostRender:I(t,e)}),t.addMenuItem("restoredraft",{text:"Restore last draft",onclick:function(){y.restoreLastDraft(t)},onPostRender:I(t,e),context:"file"})};t.add("autosave",function(t){var e=n(!1);return b(t),w(t,e),h(t)})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var o=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.util.Tools"),e=function(o){o=t.trim(o);var e=function(t,e){o=o.replace(t,e)};return e(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]"),e(/<font.*?color=\"(.*?)\".*?class=\"codeStyle\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),e(/<font.*?color=\"(.*?)\".*?class=\"quoteStyle\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),e(/<font.*?class=\"codeStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),e(/<font.*?class=\"quoteStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),e(/<span style=\"color: ?(.*?);\">(.*?)<\/span>/gi,"[color=$1]$2[/color]"),e(/<font.*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[color=$1]$2[/color]"),e(/<span style=\"font-size:(.*?);\">(.*?)<\/span>/gi,"[size=$1]$2[/size]"),e(/<font>(.*?)<\/font>/gi,"$1"),e(/<img.*?src=\"(.*?)\".*?\/>/gi,"[img]$1[/img]"),e(/<span class=\"codeStyle\">(.*?)<\/span>/gi,"[code]$1[/code]"),e(/<span class=\"quoteStyle\">(.*?)<\/span>/gi,"[quote]$1[/quote]"),e(/<strong class=\"codeStyle\">(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]"),e(/<strong class=\"quoteStyle\">(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]"),e(/<em class=\"codeStyle\">(.*?)<\/em>/gi,"[code][i]$1[/i][/code]"),e(/<em class=\"quoteStyle\">(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]"),e(/<u class=\"codeStyle\">(.*?)<\/u>/gi,"[code][u]$1[/u][/code]"),e(/<u class=\"quoteStyle\">(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]"),e(/<\/(strong|b)>/gi,"[/b]"),e(/<(strong|b)>/gi,"[b]"),e(/<\/(em|i)>/gi,"[/i]"),e(/<(em|i)>/gi,"[i]"),e(/<\/u>/gi,"[/u]"),e(/<span style=\"text-decoration: ?underline;\">(.*?)<\/span>/gi,"[u]$1[/u]"),e(/<u>/gi,"[u]"),e(/<blockquote[^>]*>/gi,"[quote]"),e(/<\/blockquote>/gi,"[/quote]"),e(/<br \/>/gi,"\n"),e(/<br\/>/gi,"\n"),e(/<br>/gi,"\n"),e(/<p>/gi,""),e(/<\/p>/gi,"\n"),e(/ |\u00a0/gi," "),e(/"/gi,'"'),e(/</gi,"<"),e(/>/gi,">"),e(/&/gi,"&"),o},i=function(o){o=t.trim(o);var e=function(t,e){o=o.replace(t,e)};return e(/\n/gi,"<br />"),e(/\[b\]/gi,"<strong>"),e(/\[\/b\]/gi,"</strong>"),e(/\[i\]/gi,"<em>"),e(/\[\/i\]/gi,"</em>"),e(/\[u\]/gi,"<u>"),e(/\[\/u\]/gi,"</u>"),e(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,'<a href="$1">$2</a>'),e(/\[url\](.*?)\[\/url\]/gi,'<a href="$1">$1</a>'),e(/\[img\](.*?)\[\/img\]/gi,'<img src="$1" />'),e(/\[color=(.*?)\](.*?)\[\/color\]/gi,'<font color="$1">$2</font>'),e(/\[code\](.*?)\[\/code\]/gi,'<span class="codeStyle">$1</span> '),e(/\[quote.*?\](.*?)\[\/quote\]/gi,'<span class="quoteStyle">$1</span> '),o};o.add("bbcode",function(){return{init:function(o){o.on("beforeSetContent",function(o){o.content=i(o.content)}),o.on("postProcess",function(o){o.set&&(o.content=i(o.content)),o.get&&(o.content=e(o.content))})}}})}();
|
||||
!function(){"use strict";var o=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.util.Tools"),e=function(e){e=t.trim(e);var o=function(o,t){e=e.replace(o,t)};return o(/<a.*?href=\"(.*?)\".*?>(.*?)<\/a>/gi,"[url=$1]$2[/url]"),o(/<font.*?color=\"(.*?)\".*?class=\"codeStyle\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),o(/<font.*?color=\"(.*?)\".*?class=\"quoteStyle\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),o(/<font.*?class=\"codeStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[code][color=$1]$2[/color][/code]"),o(/<font.*?class=\"quoteStyle\".*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[quote][color=$1]$2[/color][/quote]"),o(/<span style=\"color: ?(.*?);\">(.*?)<\/span>/gi,"[color=$1]$2[/color]"),o(/<font.*?color=\"(.*?)\".*?>(.*?)<\/font>/gi,"[color=$1]$2[/color]"),o(/<span style=\"font-size:(.*?);\">(.*?)<\/span>/gi,"[size=$1]$2[/size]"),o(/<font>(.*?)<\/font>/gi,"$1"),o(/<img.*?src=\"(.*?)\".*?\/>/gi,"[img]$1[/img]"),o(/<span class=\"codeStyle\">(.*?)<\/span>/gi,"[code]$1[/code]"),o(/<span class=\"quoteStyle\">(.*?)<\/span>/gi,"[quote]$1[/quote]"),o(/<strong class=\"codeStyle\">(.*?)<\/strong>/gi,"[code][b]$1[/b][/code]"),o(/<strong class=\"quoteStyle\">(.*?)<\/strong>/gi,"[quote][b]$1[/b][/quote]"),o(/<em class=\"codeStyle\">(.*?)<\/em>/gi,"[code][i]$1[/i][/code]"),o(/<em class=\"quoteStyle\">(.*?)<\/em>/gi,"[quote][i]$1[/i][/quote]"),o(/<u class=\"codeStyle\">(.*?)<\/u>/gi,"[code][u]$1[/u][/code]"),o(/<u class=\"quoteStyle\">(.*?)<\/u>/gi,"[quote][u]$1[/u][/quote]"),o(/<\/(strong|b)>/gi,"[/b]"),o(/<(strong|b)>/gi,"[b]"),o(/<\/(em|i)>/gi,"[/i]"),o(/<(em|i)>/gi,"[i]"),o(/<\/u>/gi,"[/u]"),o(/<span style=\"text-decoration: ?underline;\">(.*?)<\/span>/gi,"[u]$1[/u]"),o(/<u>/gi,"[u]"),o(/<blockquote[^>]*>/gi,"[quote]"),o(/<\/blockquote>/gi,"[/quote]"),o(/<br \/>/gi,"\n"),o(/<br\/>/gi,"\n"),o(/<br>/gi,"\n"),o(/<p>/gi,""),o(/<\/p>/gi,"\n"),o(/ |\u00a0/gi," "),o(/"/gi,'"'),o(/</gi,"<"),o(/>/gi,">"),o(/&/gi,"&"),e},i=function(e){e=t.trim(e);var o=function(o,t){e=e.replace(o,t)};return o(/\n/gi,"<br />"),o(/\[b\]/gi,"<strong>"),o(/\[\/b\]/gi,"</strong>"),o(/\[i\]/gi,"<em>"),o(/\[\/i\]/gi,"</em>"),o(/\[u\]/gi,"<u>"),o(/\[\/u\]/gi,"</u>"),o(/\[url=([^\]]+)\](.*?)\[\/url\]/gi,'<a href="$1">$2</a>'),o(/\[url\](.*?)\[\/url\]/gi,'<a href="$1">$1</a>'),o(/\[img\](.*?)\[\/img\]/gi,'<img src="$1" />'),o(/\[color=(.*?)\](.*?)\[\/color\]/gi,'<font color="$1">$2</font>'),o(/\[code\](.*?)\[\/code\]/gi,'<span class="codeStyle">$1</span> '),o(/\[quote.*?\](.*?)\[\/quote\]/gi,'<span class="quoteStyle">$1</span> '),e};o.add("bbcode",function(){return{init:function(o){o.on("beforeSetContent",function(o){o.content=i(o.content)}),o.on("postProcess",function(o){o.set&&(o.content=i(o.content)),o.get&&(o.content=e(o.content))})}}})}();
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),e=function(t){return t.getParam("code_dialog_width",600)},o=function(t){return t.getParam("code_dialog_height",Math.min(n.DOM.getViewPort().h-200,500))},i=function(t,n){t.focus(),t.undoManager.transact(function(){t.setContent(n)}),t.selection.setCursorLocation(),t.nodeChanged()},c=function(t){return t.getContent({source_view:!0})},d=function(t){var n=e(t),d=o(t);t.windowManager.open({title:"Source code",body:{type:"textbox",name:"code",multiline:!0,minWidth:n,minHeight:d,spellcheck:!1,style:"direction: ltr; text-align: left"},onSubmit:function(n){i(t,n.data.code)}}).find("#code").value(c(t))},u=function(t){t.addCommand("mceCodeEditor",function(){d(t)})},a=function(t){t.addButton("code",{icon:"code",tooltip:"Source code",onclick:function(){d(t)}}),t.addMenuItem("code",{icon:"code",text:"Source code",onclick:function(){d(t)}})};t.add("code",function(t){return u(t),a(t),{}})}();
|
||||
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),o=function(t){return t.getParam("code_dialog_width",600)},i=function(t){return t.getParam("code_dialog_height",Math.min(n.DOM.getViewPort().h-200,500))},c=function(t,n){t.focus(),t.undoManager.transact(function(){t.setContent(n)}),t.selection.setCursorLocation(),t.nodeChanged()},d=function(t){return t.getContent({source_view:!0})},e=function(n){var t=o(n),e=i(n);n.windowManager.open({title:"Source code",body:{type:"textbox",name:"code",multiline:!0,minWidth:t,minHeight:e,spellcheck:!1,style:"direction: ltr; text-align: left"},onSubmit:function(t){c(n,t.data.code)}}).find("#code").value(d(n))},u=function(t){t.addCommand("mceCodeEditor",function(){e(t)})},a=function(t){t.addButton("code",{icon:"code",tooltip:"Source code",onclick:function(){e(t)}}),t.addMenuItem("code",{icon:"code",text:"Source code",onclick:function(){e(t)}})};t.add("code",function(t){return u(t),a(t),{}})}();
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=tinymce.util.Tools.resolve("tinymce.util.Color"),i=function(e,n){e.find("#preview")[0].getEl().style.background=n},t=function(e,t){var l=n(t),a=l.toRgb();e.fromJSON({r:a.r,g:a.g,b:a.b,hex:l.toHex().substr(1)}),i(e,l.toHex())},l=function(e,n,l){var a=e.windowManager.open({title:"Color",items:{type:"container",layout:"flex",direction:"row",align:"stretch",padding:5,spacing:10,items:[{type:"colorpicker",value:l,onchange:function(){var e=this.rgb();a&&(a.find("#r").value(e.r),a.find("#g").value(e.g),a.find("#b").value(e.b),a.find("#hex").value(this.value().substr(1)),i(a,this.value()))}},{type:"form",padding:0,labelGap:5,defaults:{type:"textbox",size:7,value:"0",flex:1,spellcheck:!1,onchange:function(){var e,n,i=a.find("colorpicker")[0];if(e=this.name(),n=this.value(),"hex"===e)return t(a,n="#"+n),void i.value(n);n={r:a.find("#r").value(),g:a.find("#g").value(),b:a.find("#b").value()},i.value(n),t(a,n)}},items:[{name:"r",label:"R",autofocus:1},{name:"g",label:"G"},{name:"b",label:"B"},{name:"hex",label:"#",value:"000000"},{name:"preview",type:"container",border:1}]}]},onSubmit:function(){n("#"+a.toJSON().hex)}});t(a,l)};e.add("colorpicker",function(e){e.settings.color_picker_callback||(e.settings.color_picker_callback=function(n,i){l(e,n,i)})})}();
|
||||
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),l=tinymce.util.Tools.resolve("tinymce.util.Color"),a=function(e,n){e.find("#preview")[0].getEl().style.background=n},o=function(e,n){var i=l(n),t=i.toRgb();e.fromJSON({r:t.r,g:t.g,b:t.b,hex:i.toHex().substr(1)}),a(e,i.toHex())},t=function(e,n,i){var t=e.windowManager.open({title:"Color",items:{type:"container",layout:"flex",direction:"row",align:"stretch",padding:5,spacing:10,items:[{type:"colorpicker",value:i,onchange:function(){var e=this.rgb();t&&(t.find("#r").value(e.r),t.find("#g").value(e.g),t.find("#b").value(e.b),t.find("#hex").value(this.value().substr(1)),a(t,this.value()))}},{type:"form",padding:0,labelGap:5,defaults:{type:"textbox",size:7,value:"0",flex:1,spellcheck:!1,onchange:function(){var e,n,i=t.find("colorpicker")[0];if(e=this.name(),n=this.value(),"hex"===e)return o(t,n="#"+n),void i.value(n);n={r:t.find("#r").value(),g:t.find("#g").value(),b:t.find("#b").value()},i.value(n),o(t,n)}},items:[{name:"r",label:"R",autofocus:1},{name:"g",label:"G"},{name:"b",label:"B"},{name:"hex",label:"#",value:"000000"},{name:"preview",type:"container",border:1}]}]},onSubmit:function(){n("#"+t.toJSON().hex)}});o(t,i)};e.add("colorpicker",function(i){i.settings.color_picker_callback||(i.settings.color_picker_callback=function(e,n){t(i,e,n)})})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var t=function(n){var e=n,o=function(){return e};return{get:o,set:function(t){e=t},clone:function(){return t(o())}}},n=tinymce.util.Tools.resolve("tinymce.PluginManager"),e=function(t){return{isContextMenuVisible:function(){return t.get()}}},o=function(t){return t.settings.contextmenu_never_use_native},i=function(t){return t.getParam("contextmenu","link openlink image inserttable | cell row column deletetable")},r=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),u=function(t){return r.DOM.select(t.settings.ui_container)[0]},c=function(t,n){return{x:t,y:n}},l=function(t,n,e){return c(t.x+n,t.y+e)},s=function(t,n){if(t&&"static"!==r.DOM.getStyle(t,"position",!0)){var e=r.DOM.getPos(t),o=e.x-t.scrollLeft,i=e.y-t.scrollTop;return l(n,-o,-i)}return l(n,0,0)},a=function(t,n){if(t.inline)return s(u(t),c((f=n).pageX,f.pageY));var e,o,i,a,f,m=(e=t.getContentAreaContainer(),o=c((a=n).clientX,a.clientY),i=r.DOM.getPos(e),l(o,i.x,i.y));return s(u(t),m)},f=tinymce.util.Tools.resolve("tinymce.ui.Factory"),m=tinymce.util.Tools.resolve("tinymce.util.Tools"),g=function(t,n,e,o){null===o.get()?o.set(function(t,n){var e,o,r=[];o=i(t),m.each(o.split(/[ ,]/),function(n){var e=t.menuItems[n];"|"===n&&(e={text:n}),e&&(e.shortcut="",r.push(e))});for(var c=0;c<r.length;c++)"|"===r[c].text&&(0!==c&&c!==r.length-1||r.splice(c,1));return(e=f.create("menu",{items:r,context:"contextmenu",classes:"contextmenu"})).uiContainer=u(t),e.renderTo(u(t)),e.on("hide",function(t){t.control===this&&n.set(!1)}),t.on("remove",function(){e.remove(),e=null}),e}(t,e)):o.get().show(),o.get().moveTo(n.x,n.y),e.set(!0)},v=function(t,n,e){t.on("contextmenu",function(i){var r;r=t,(!i.ctrlKey||o(r))&&(i.preventDefault(),g(t,a(t,i),n,e))})};n.add("contextmenu",function(n){var o=t(null),i=t(!1);return v(n,i,o),e(i)})}();
|
||||
!function(){"use strict";var o=function(t){var n=t,e=function(){return n};return{get:e,set:function(t){n=t},clone:function(){return o(e())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=function(t){return{isContextMenuVisible:function(){return t.get()}}},r=function(t){return t.settings.contextmenu_never_use_native},u=function(t){return t.getParam("contextmenu","link openlink image inserttable | cell row column deletetable")},l=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),s=function(t){return l.DOM.select(t.settings.ui_container)[0]},a=function(t,n){return{x:t,y:n}},f=function(t,n,e){return a(t.x+n,t.y+e)},m=function(t,n){if(t&&"static"!==l.DOM.getStyle(t,"position",!0)){var e=l.DOM.getPos(t),o=e.x-t.scrollLeft,i=e.y-t.scrollTop;return f(n,-o,-i)}return f(n,0,0)},c=function(t,n){if(t.inline)return m(s(t),a((u=n).pageX,u.pageY));var e,o,i,r,u,c=(e=t.getContentAreaContainer(),o=a((r=n).clientX,r.clientY),i=l.DOM.getPos(e),f(o,i.x,i.y));return m(s(t),c)},g=tinymce.util.Tools.resolve("tinymce.ui.Factory"),v=tinymce.util.Tools.resolve("tinymce.util.Tools"),y=function(t,n,e,o){null===o.get()?o.set(function(e,n){var t,o,i=[];o=u(e),v.each(o.split(/[ ,]/),function(t){var n=e.menuItems[t];"|"===t&&(n={text:t}),n&&(n.shortcut="",i.push(n))});for(var r=0;r<i.length;r++)"|"===i[r].text&&(0!==r&&r!==i.length-1||i.splice(r,1));return(t=g.create("menu",{items:i,context:"contextmenu",classes:"contextmenu"})).uiContainer=s(e),t.renderTo(s(e)),t.on("hide",function(t){t.control===this&&n.set(!1)}),e.on("remove",function(){t.remove(),t=null}),t}(t,e)):o.get().show(),o.get().moveTo(n.x,n.y),e.set(!0)},x=function(e,o,i){e.on("contextmenu",function(t){var n;n=e,(!t.ctrlKey||r(n))&&(t.preventDefault(),y(e,c(e,t),o,i))})};t.add("contextmenu",function(t){var n=o(null),e=o(!1);return x(t,e,n),i(e)})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),e=tinymce.util.Tools.resolve("tinymce.util.Tools"),i=function(t,i){var n,o=t.dom,c=t.selection.getSelectedBlocks();c.length&&(n=o.getAttrib(c[0],"dir"),e.each(c,function(t){o.getParent(t.parentNode,'*[dir="'+i+'"]',o.getRoot())||o.setAttrib(t,"dir",n!==i?i:null)}),t.nodeChanged())},n=function(t){t.addCommand("mceDirectionLTR",function(){i(t,"ltr")}),t.addCommand("mceDirectionRTL",function(){i(t,"rtl")})},o=function(t){var i=[];return e.each("h1 h2 h3 h4 h5 h6 div p".split(" "),function(e){i.push(e+"[dir="+t+"]")}),i.join(",")},c=function(t){t.addButton("ltr",{title:"Left to right",cmd:"mceDirectionLTR",stateSelector:o("ltr")}),t.addButton("rtl",{title:"Right to left",cmd:"mceDirectionRTL",stateSelector:o("rtl")})};t.add("directionality",function(t){n(t),c(t)})}();
|
||||
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),c=tinymce.util.Tools.resolve("tinymce.util.Tools"),e=function(t,e){var i,n=t.dom,o=t.selection.getSelectedBlocks();o.length&&(i=n.getAttrib(o[0],"dir"),c.each(o,function(t){n.getParent(t.parentNode,'*[dir="'+e+'"]',n.getRoot())||n.setAttrib(t,"dir",i!==e?e:null)}),t.nodeChanged())},i=function(t){t.addCommand("mceDirectionLTR",function(){e(t,"ltr")}),t.addCommand("mceDirectionRTL",function(){e(t,"rtl")})},n=function(e){var i=[];return c.each("h1 h2 h3 h4 h5 h6 div p".split(" "),function(t){i.push(t+"[dir="+e+"]")}),i.join(",")},o=function(t){t.addButton("ltr",{title:"Left to right",cmd:"mceDirectionLTR",stateSelector:n("ltr")}),t.addButton("rtl",{title:"Right to left",cmd:"mceDirectionRTL",stateSelector:n("rtl")})};t.add("directionality",function(t){i(t),o(t)})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),e=tinymce.util.Tools.resolve("tinymce.util.Tools"),i=[["cool","cry","embarassed","foot-in-mouth"],["frown","innocent","kiss","laughing"],["money-mouth","sealed","smile","surprised"],["tongue-out","undecided","wink","yell"]],o=function(t){var o;return o='<table role="list" class="mce-grid">',e.each(i,function(i){o+="<tr>",e.each(i,function(e){var i=t+"/img/smiley-"+e+".gif";o+='<td><a href="#" data-mce-url="'+i+'" data-mce-alt="'+e+'" tabindex="-1" role="option" aria-label="'+e+'"><img src="'+i+'" style="width: 18px; height: 18px" role="presentation" /></a></td>'}),o+="</tr>"}),o+="</table>"},n=function(t,e){var i=o(e);t.addButton("emoticons",{type:"panelbutton",panel:{role:"application",autohide:!0,html:i,onclick:function(e){var i,o,n,a=t.dom.getParent(e.target,"a");a&&(i=t,o=a.getAttribute("data-mce-url"),n=a.getAttribute("data-mce-alt"),i.insertContent(i.dom.createHTML("img",{src:o,alt:n})),this.hide())}},tooltip:"Emoticons"})};t.add("emoticons",function(t,e){n(t,e)})}();
|
||||
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),e=tinymce.util.Tools.resolve("tinymce.util.Tools"),n=[["cool","cry","embarassed","foot-in-mouth"],["frown","innocent","kiss","laughing"],["money-mouth","sealed","smile","surprised"],["tongue-out","undecided","wink","yell"]],i=function(i){var o;return o='<table role="list" class="mce-grid">',e.each(n,function(t){o+="<tr>",e.each(t,function(t){var e=i+"/img/smiley-"+t+".gif";o+='<td><a href="#" data-mce-url="'+e+'" data-mce-alt="'+t+'" tabindex="-1" role="option" aria-label="'+t+'"><img src="'+e+'" style="width: 18px; height: 18px" role="presentation" /></a></td>'}),o+="</tr>"}),o+="</table>"},o=function(a,t){var e=i(t);a.addButton("emoticons",{type:"panelbutton",panel:{role:"application",autohide:!0,html:e,onclick:function(t){var e,i,o,n=a.dom.getParent(t.target,"a");n&&(e=a,i=n.getAttribute("data-mce-url"),o=n.getAttribute("data-mce-alt"),e.insertContent(e.dom.createHTML("img",{src:i,alt:o})),this.hide())}},tooltip:"Emoticons"})};t.add("emoticons",function(t,e){o(t,e)})}();
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
!function(){"use strict";var e=function(n){var t=n,i=function(){return t};return{get:i,set:function(e){t=e},clone:function(){return e(i())}}},n=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=function(e){return{isFullscreen:function(){return null!==e.get()}}},i=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),r=function(e,n){e.fire("FullscreenStateChanged",{state:n})},l=i.DOM,o=function(e,n){var t,i,o,c,s,u,d=document.body,a=document.documentElement,h=n.get(),f=function(){var e,n,t,r;l.setStyle(o,"height",(t=window,r=document.body,r.offsetWidth&&(e=r.offsetWidth,n=r.offsetHeight),t.innerWidth&&t.innerHeight&&(e=t.innerWidth,n=t.innerHeight),{w:e,h:n}).h-(i.clientHeight-o.clientHeight))},m=function(){l.unbind(window,"resize",f)};if(t=(i=e.getContainer()).style,c=(o=e.getContentAreaContainer().firstChild).style,h)c.width=h.iframeWidth,c.height=h.iframeHeight,h.containerWidth&&(t.width=h.containerWidth),h.containerHeight&&(t.height=h.containerHeight),l.removeClass(d,"mce-fullscreen"),l.removeClass(a,"mce-fullscreen"),l.removeClass(i,"mce-fullscreen"),s=h.scrollPos,window.scrollTo(s.x,s.y),l.unbind(window,"resize",h.resizeHandler),e.off("remove",h.removeHandler),n.set(null),r(e,!1);else{var g={scrollPos:(u=l.getViewPort(),{x:u.x,y:u.y}),containerWidth:t.width,containerHeight:t.height,iframeWidth:c.width,iframeHeight:c.height,resizeHandler:f,removeHandler:m};c.width=c.height="100%",t.width=t.height="",l.addClass(d,"mce-fullscreen"),l.addClass(a,"mce-fullscreen"),l.addClass(i,"mce-fullscreen"),l.bind(window,"resize",f),e.on("remove",m),f(),n.set(g),r(e,!0)}},c=function(e,n){e.addCommand("mceFullScreen",function(){o(e,n)})},s=function(e){return function(n){var t=n.control;e.on("FullscreenStateChanged",function(e){t.active(e.state)})}},u=function(e){e.addMenuItem("fullscreen",{text:"Fullscreen",shortcut:"Ctrl+Shift+F",selectable:!0,cmd:"mceFullScreen",onPostRender:s(e),context:"view"}),e.addButton("fullscreen",{active:!1,tooltip:"Fullscreen",cmd:"mceFullScreen",onPostRender:s(e)})};n.add("fullscreen",function(n){var i=e(null);return n.settings.inline?t(i):(c(n,i),u(n),n.addShortcut("Ctrl+Shift+F","","mceFullScreen"),t(i))})}();
|
||||
!function(){"use strict";var i=function(e){var n=e,t=function(){return n};return{get:t,set:function(e){n=e},clone:function(){return i(t())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=function(e){return{isFullscreen:function(){return null!==e.get()}}},n=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),m=function(e,n){e.fire("FullscreenStateChanged",{state:n})},g=n.DOM,r=function(e,n){var t,r,l,i,o,c,s=document.body,u=document.documentElement,d=n.get(),a=function(){var e,n,t,i;g.setStyle(l,"height",(t=window,i=document.body,i.offsetWidth&&(e=i.offsetWidth,n=i.offsetHeight),t.innerWidth&&t.innerHeight&&(e=t.innerWidth,n=t.innerHeight),{w:e,h:n}).h-(r.clientHeight-l.clientHeight))},h=function(){g.unbind(window,"resize",a)};if(t=(r=e.getContainer()).style,i=(l=e.getContentAreaContainer().firstChild).style,d)i.width=d.iframeWidth,i.height=d.iframeHeight,d.containerWidth&&(t.width=d.containerWidth),d.containerHeight&&(t.height=d.containerHeight),g.removeClass(s,"mce-fullscreen"),g.removeClass(u,"mce-fullscreen"),g.removeClass(r,"mce-fullscreen"),o=d.scrollPos,window.scrollTo(o.x,o.y),g.unbind(window,"resize",d.resizeHandler),e.off("remove",d.removeHandler),n.set(null),m(e,!1);else{var f={scrollPos:(c=g.getViewPort(),{x:c.x,y:c.y}),containerWidth:t.width,containerHeight:t.height,iframeWidth:i.width,iframeHeight:i.height,resizeHandler:a,removeHandler:h};i.width=i.height="100%",t.width=t.height="",g.addClass(s,"mce-fullscreen"),g.addClass(u,"mce-fullscreen"),g.addClass(r,"mce-fullscreen"),g.bind(window,"resize",a),e.on("remove",h),a(),n.set(f),m(e,!0)}},l=function(e,n){e.addCommand("mceFullScreen",function(){r(e,n)})},o=function(t){return function(e){var n=e.control;t.on("FullscreenStateChanged",function(e){n.active(e.state)})}},c=function(e){e.addMenuItem("fullscreen",{text:"Fullscreen",shortcut:"Ctrl+Shift+F",selectable:!0,cmd:"mceFullScreen",onPostRender:o(e),context:"view"}),e.addButton("fullscreen",{active:!1,tooltip:"Fullscreen",cmd:"mceFullScreen",onPostRender:o(e)})};e.add("fullscreen",function(e){var n=i(null);return e.settings.inline||(l(e,n),c(e),e.addShortcut("Ctrl+Shift+F","","mceFullScreen")),t(n)})}();
|
||||
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(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),n=tinymce.util.Tools.resolve("tinymce.EditorManager"),r=tinymce.util.Tools.resolve("tinymce.Env"),i=tinymce.util.Tools.resolve("tinymce.util.Tools"),c=function(e){return e.getParam("importcss_merge_classes")},o=function(e){return e.getParam("importcss_exclusive")},s=function(e){return e.getParam("importcss_selector_converter")},u=function(e){return e.getParam("importcss_selector_filter")},l=function(e){return e.getParam("importcss_groups")},a=function(e){return e.getParam("importcss_append")},f=function(e){return e.getParam("importcss_file_filter")},m=function(e){var t=r.cacheSuffix;return"string"==typeof e&&(e=e.replace("?"+t,"").replace("&"+t,"")),e},g=function(e,t){var r=e.settings,i=!1!==r.skin&&(r.skin||"lightgray");return!!i&&t===(r.skin_url?e.documentBaseURI.toAbsolute(r.skin_url):n.baseURL+"/skins/"+i)+"/content"+(e.inline?".inline":"")+".min.css"},p=function(e){return"string"==typeof e?function(t){return-1!==t.indexOf(e)}:e instanceof RegExp?function(t){return e.test(t)}:e},v=function(e,t,n){var r=[],c={};i.each(e.contentCSS,function(e){c[e]=!0}),n||(n=function(e,t){return t||c[e]});try{i.each(t.styleSheets,function(t){!function c(t,o){var s,u=t.href;if((u=m(u))&&n(u,o)&&!g(e,u)){i.each(t.imports,function(e){c(e,!0)});try{s=t.cssRules||t.rules}catch(l){}i.each(s,function(e){e.styleSheet?c(e.styleSheet,!0):e.selectorText&&i.each(e.selectorText.split(","),function(e){r.push(i.trim(e))})})}}(t)})}catch(o){}return r},h=function(e,t){var n,r=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(t);if(r){var o=r[1],s=r[2].substr(1).split(".").join(" "),u=i.makeMap("a,img");return r[1]?(n={title:t},e.schema.getTextBlockElements()[o]?n.block=o:e.schema.getBlockElements()[o]||u[o.toLowerCase()]?n.selector=o:n.inline=o):r[2]&&(n={inline:"span",title:t.substr(1),classes:s}),!1!==c(e)?n.classes=s:n.attributes={"class":s},n}},d=function(e,t){return null===t||!1!==o(e)},y=h,_=function(e){e.on("renderFormatsMenu",function(n){var r,c={},o=p(u(e)),m=n.control,g=(r=l(e),i.map(r,function(e){return i.extend({},e,{original:e,selectors:{},filter:p(e.filter),item:{text:e.title,menu:[]}})})),y=function(n,r){if(_=n,T=c,!(d(e,x=r)?_ in T:_ in x.selectors)){p=n,y=c,d(e,v=r)?y[p]=!0:v.selectors[p]=!0;var o=(l=e,a=e.plugins.importcss,f=n,((g=r)&&g.selector_converter?g.selector_converter:s(l)?s(l):function(){return h(l,f)}).call(a,f,g));if(o){var u=o.name||t.DOM.uniqueId();return e.formatter.register(u,o),i.extend({},m.settings.itemDefaults,{text:o.title,format:u})}}var l,a,f,g,p,v,y,_,x,T;return null};a(e)||m.items().remove(),i.each(v(e,n.doc||e.getDoc(),p(f(e))),function(e){if(-1===e.indexOf(".mce-")&&(!o||o(e))){var t=(r=g,c=e,i.grep(r,function(e){return!e.filter||e.filter(c)}));if(t.length>0)i.each(t,function(t){var n=y(e,t);n&&t.item.menu.push(n)});else{var n=y(e,null);n&&m.add(n)}}var r,c}),i.each(g,function(e){e.item.menu.length>0&&m.add(e.item)}),n.control.renderNew()})},x=function(e){return{convertSelectorToFormat:function(t){return y(e,t)}}};e.add("importcss",function(e){return _(e),x(e)})}();
|
||||
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),d=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),v=tinymce.util.Tools.resolve("tinymce.EditorManager"),h=tinymce.util.Tools.resolve("tinymce.Env"),y=tinymce.util.Tools.resolve("tinymce.util.Tools"),o=function(e){return e.getParam("importcss_merge_classes")},n=function(e){return e.getParam("importcss_exclusive")},_=function(e){return e.getParam("importcss_selector_converter")},r=function(e){return e.getParam("importcss_selector_filter")},i=function(e){return e.getParam("importcss_groups")},u=function(e){return e.getParam("importcss_append")},l=function(e){return e.getParam("importcss_file_filter")},a=function(t){return"string"==typeof t?function(e){return-1!==e.indexOf(t)}:t instanceof RegExp?function(e){return t.test(e)}:t},f=function(f,e,m){var g=[],n={};function p(e,t){var n,r,i,c=e.href;if(r=c,i=h.cacheSuffix,"string"==typeof r&&(r=r.replace("?"+i,"").replace("&"+i,"")),(c=r)&&m(c,t)&&(o=c,u=(s=f).settings,!(l=!1!==u.skin&&(u.skin||"lightgray"))||o!==(u.skin_url?s.documentBaseURI.toAbsolute(u.skin_url):v.baseURL+"/skins/"+l)+"/content"+(s.inline?".inline":"")+".min.css")){var s,o,u,l;y.each(e.imports,function(e){p(e,!0)});try{n=e.cssRules||e.rules}catch(a){}y.each(n,function(e){e.styleSheet?p(e.styleSheet,!0):e.selectorText&&y.each(e.selectorText.split(","),function(e){g.push(y.trim(e))})})}}y.each(f.contentCSS,function(e){n[e]=!0}),m||(m=function(e,t){return t||n[e]});try{y.each(e.styleSheets,function(e){p(e)})}catch(t){}return g},x=function(e,t){var n,r=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(t);if(r){var i=r[1],c=r[2].substr(1).split(".").join(" "),s=y.makeMap("a,img");return r[1]?(n={title:t},e.schema.getTextBlockElements()[i]?n.block=i:e.schema.getBlockElements()[i]||s[i.toLowerCase()]?n.selector=i:n.inline=i):r[2]&&(n={inline:"span",title:t.substr(1),classes:c}),!1!==o(e)?n.classes=c:n.attributes={"class":c},n}},T=function(e,t){return null===t||!1!==n(e)},c=x,t=function(h){h.on("renderFormatsMenu",function(e){var t,p={},c=a(r(h)),v=e.control,s=(t=i(h),y.map(t,function(e){return y.extend({},e,{original:e,selectors:{},filter:a(e.filter),item:{text:e.title,menu:[]}})})),o=function(e,t){if(f=e,g=p,!(T(h,m=t)?f in g:f in m.selectors)){u=e,a=p,T(h,l=t)?a[u]=!0:l.selectors[u]=!0;var n=(c=(i=h).plugins.importcss,s=e,((o=t)&&o.selector_converter?o.selector_converter:_(i)?_(i):function(){return x(i,s)}).call(c,s,o));if(n){var r=n.name||d.DOM.uniqueId();return h.formatter.register(r,n),y.extend({},v.settings.itemDefaults,{text:n.title,format:r})}}var i,c,s,o,u,l,a,f,m,g;return null};u(h)||v.items().remove(),y.each(f(h,e.doc||h.getDoc(),a(l(h))),function(n){if(-1===n.indexOf(".mce-")&&(!c||c(n))){var e=(r=s,i=n,y.grep(r,function(e){return!e.filter||e.filter(i)}));if(0<e.length)y.each(e,function(e){var t=o(n,e);t&&e.item.menu.push(t)});else{var t=o(n,null);t&&v.add(t)}}var r,i}),y.each(s,function(e){0<e.item.menu.length&&v.add(e.item)}),e.control.renderNew()})},s=function(t){return{convertSelectorToFormat:function(e){return c(t,e)}}};e.add("importcss",function(e){return t(e),s(e)})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var e=function(t){var n=t,r=function(){return n};return{get:r,set:function(e){n=e},clone:function(){return e(r())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=function(e){return e.getParam("insertdatetime_timeformat",e.translate("%H:%M:%S"))},r=function(e){return e.getParam("insertdatetime_formats",["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"])},a=function(e){return e.getParam("insertdatetime_dateformat",e.translate("%Y-%m-%d"))},i=n,o=r,u=function(e){var t=r(e);return t.length>0?t[0]:n(e)},c=function(e){return e.getParam("insertdatetime_element",!1)},l="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),m="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),s="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),d="January February March April May June July August September October November December".split(" "),p=function(e,t){if((e=""+e).length<t)for(var n=0;n<t-e.length;n++)e="0"+e;return e},f=function(e,t,n){return n=n||new Date,t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace("%D","%m/%d/%Y")).replace("%r","%I:%M:%S %p")).replace("%Y",""+n.getFullYear())).replace("%y",""+n.getYear())).replace("%m",p(n.getMonth()+1,2))).replace("%d",p(n.getDate(),2))).replace("%H",""+p(n.getHours(),2))).replace("%M",""+p(n.getMinutes(),2))).replace("%S",""+p(n.getSeconds(),2))).replace("%I",""+((n.getHours()+11)%12+1))).replace("%p",n.getHours()<12?"AM":"PM")).replace("%B",""+e.translate(d[n.getMonth()]))).replace("%b",""+e.translate(s[n.getMonth()]))).replace("%A",""+e.translate(m[n.getDay()]))).replace("%a",""+e.translate(l[n.getDay()]))).replace("%%","%")},g=function(e,t){if(c(e)){var n=f(e,t),r=void 0;r=/%[HMSIp]/.test(t)?f(e,"%Y-%m-%dT%H:%M"):f(e,"%Y-%m-%d");var a=e.dom.getParent(e.selection.getStart(),"time");a?(o=a,u=r,l=n,m=(i=e).dom.create("time",{datetime:u},l),o.parentNode.insertBefore(m,o),i.dom.remove(o),i.selection.select(m,!0),i.selection.collapse(!1)):e.insertContent('<time datetime="'+r+'">'+n+"</time>")}else e.insertContent(f(e,t));var i,o,u,l,m},y=f,M=function(e){e.addCommand("mceInsertDate",function(){g(e,a(e))}),e.addCommand("mceInsertTime",function(){g(e,i(e))})},v=tinymce.util.Tools.resolve("tinymce.util.Tools"),S=function(e,t){var n,r,a,i=(r=t,a=o(n=e),v.map(a,function(e){return{text:y(n,e),onclick:function(){r.set(e),g(n,e)}}}));e.addButton("insertdatetime",{type:"splitbutton",title:"Insert date/time",menu:i,onclick:function(){var n=t.get();g(e,n||u(e))}}),e.addMenuItem("insertdatetime",{icon:"date",text:"Date/time",menu:i,context:"insert"})};t.add("insertdatetime",function(t){var n=e(null);M(t),S(t,n)})}();
|
||||
!function(){"use strict";var r=function(e){var t=e,n=function(){return t};return{get:n,set:function(e){t=e},clone:function(){return r(n())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=function(e){return e.getParam("insertdatetime_timeformat",e.translate("%H:%M:%S"))},a=function(e){return e.getParam("insertdatetime_formats",["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"])},t=function(e){return e.getParam("insertdatetime_dateformat",e.translate("%Y-%m-%d"))},i=n,o=a,u=function(e){var t=a(e);return 0<t.length?t[0]:n(e)},m=function(e){return e.getParam("insertdatetime_element",!1)},c="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),l="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),s="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),d="January February March April May June July August September October November December".split(" "),p=function(e,t){if((e=""+e).length<t)for(var n=0;n<t-e.length;n++)e="0"+e;return e},f=function(e,t,n){return n=n||new Date,t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace("%D","%m/%d/%Y")).replace("%r","%I:%M:%S %p")).replace("%Y",""+n.getFullYear())).replace("%y",""+n.getYear())).replace("%m",p(n.getMonth()+1,2))).replace("%d",p(n.getDate(),2))).replace("%H",""+p(n.getHours(),2))).replace("%M",""+p(n.getMinutes(),2))).replace("%S",""+p(n.getSeconds(),2))).replace("%I",""+((n.getHours()+11)%12+1))).replace("%p",n.getHours()<12?"AM":"PM")).replace("%B",""+e.translate(d[n.getMonth()]))).replace("%b",""+e.translate(s[n.getMonth()]))).replace("%A",""+e.translate(l[n.getDay()]))).replace("%a",""+e.translate(c[n.getDay()]))).replace("%%","%")},g=function(e,t){if(m(e)){var n=f(e,t),r=void 0;r=/%[HMSIp]/.test(t)?f(e,"%Y-%m-%dT%H:%M"):f(e,"%Y-%m-%d");var a=e.dom.getParent(e.selection.getStart(),"time");a?(o=a,u=r,c=n,l=(i=e).dom.create("time",{datetime:u},c),o.parentNode.insertBefore(l,o),i.dom.remove(o),i.selection.select(l,!0),i.selection.collapse(!1)):e.insertContent('<time datetime="'+r+'">'+n+"</time>")}else e.insertContent(f(e,t));var i,o,u,c,l},y=f,M=function(e){e.addCommand("mceInsertDate",function(){g(e,t(e))}),e.addCommand("mceInsertTime",function(){g(e,i(e))})},v=tinymce.util.Tools.resolve("tinymce.util.Tools"),S=function(t,n){var r,a,e,i=(a=n,e=o(r=t),v.map(e,function(e){return{text:y(r,e),onclick:function(){a.set(e),g(r,e)}}}));t.addButton("insertdatetime",{type:"splitbutton",title:"Insert date/time",menu:i,onclick:function(){var e=n.get();g(t,e||u(t))}}),t.addMenuItem("insertdatetime",{icon:"date",text:"Date/time",menu:i,context:"insert"})};e.add("insertdatetime",function(e){var t=r(null);M(e),S(e,t)})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.util.Tools"),n=function(e){e.settings.inline_styles=!1,e.on("init",function(){var n,i,a,o;n=e,i="p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img",a=t.explode(n.settings.font_size_style_values),o=n.schema,n.formatter.register({alignleft:{selector:i,attributes:{align:"left"}},aligncenter:{selector:i,attributes:{align:"center"}},alignright:{selector:i,attributes:{align:"right"}},alignjustify:{selector:i,attributes:{align:"justify"}},bold:[{inline:"b",remove:"all"},{inline:"strong",remove:"all"},{inline:"span",styles:{fontWeight:"bold"}}],italic:[{inline:"i",remove:"all"},{inline:"em",remove:"all"},{inline:"span",styles:{fontStyle:"italic"}}],underline:[{inline:"u",remove:"all"},{inline:"span",styles:{textDecoration:"underline"},exact:!0}],strikethrough:[{inline:"strike",remove:"all"},{inline:"span",styles:{textDecoration:"line-through"},exact:!0}],fontname:{inline:"font",attributes:{face:"%value"}},fontsize:{inline:"font",attributes:{size:function(e){return t.inArray(a,e.value)+1}}},forecolor:{inline:"font",attributes:{color:"%value"}},hilitecolor:{inline:"font",styles:{backgroundColor:"%value"}}}),t.each("b,i,u,strike".split(","),function(e){o.addValidElements(e+"[*]")}),o.getElementRule("font")||o.addValidElements("font[face|size|color|style]"),t.each(i.split(","),function(e){var t=o.getElementRule(e);t&&(t.attributes.align||(t.attributes.align={},t.attributesOrder.push("align")))})})},i=function(e){e.addButton("fontsizeselect",function(){var t=[],n=e.settings.fontsizeFormats||"8pt=1 10pt=2 12pt=3 14pt=4 18pt=5 24pt=6 36pt=7";return e.$.each(n.split(" "),function(e,n){var i=n,a=n,o=n.split("=");o.length>1&&(i=o[0],a=o[1]),t.push({text:i,value:a})}),{type:"listbox",text:"Font Sizes",tooltip:"Font Sizes",values:t,fixedWidth:!0,onPostRender:function(){var t=this;e.on("NodeChange",function(){var n;(n=e.dom.getParent(e.selection.getNode(),"font"))?t.value(n.size):t.value("")})},onclick:function(t){t.control.settings.value&&e.execCommand("FontSize",!1,t.control.settings.value)}}}),e.addButton("fontselect",function(){var t=[],n=function(e){for(var t=(e=e.replace(/;$/,"").split(";")).length;t--;)e[t]=e[t].split("=");return e}(e.settings.font_formats||"Andale Mono=andale mono,monospace;Arial=arial,helvetica,sans-serif;Arial Black=arial black,sans-serif;Book Antiqua=book antiqua,palatino,serif;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,palatino,serif;Helvetica=helvetica,arial,sans-serif;Impact=impact,sans-serif;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco,monospace;Times New Roman=times new roman,times,serif;Trebuchet MS=trebuchet ms,geneva,sans-serif;Verdana=verdana,geneva,sans-serif;Webdings=webdings;Wingdings=wingdings,zapf dingbats");return e.$.each(n,function(e,n){t.push({text:{raw:n[0]},value:n[1],textStyle:-1===n[1].indexOf("dings")?"font-family:"+n[1]:""})}),{type:"listbox",text:"Font Family",tooltip:"Font Family",values:t,fixedWidth:!0,onPostRender:function(){var t=this;e.on("NodeChange",function(){var n;(n=e.dom.getParent(e.selection.getNode(),"font"))?t.value(n.face):t.value("")})},onselect:function(t){t.control.settings.value&&e.execCommand("FontName",!1,t.control.settings.value)}}})};e.add("legacyoutput",function(e){n(e),i(e)})}();
|
||||
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),o=tinymce.util.Tools.resolve("tinymce.util.Tools"),t=function(a){a.settings.inline_styles=!1,a.on("init",function(){var e,t,n,i;e=a,t="p,h1,h2,h3,h4,h5,h6,td,th,div,ul,ol,li,table,img",n=o.explode(e.settings.font_size_style_values),i=e.schema,e.formatter.register({alignleft:{selector:t,attributes:{align:"left"}},aligncenter:{selector:t,attributes:{align:"center"}},alignright:{selector:t,attributes:{align:"right"}},alignjustify:{selector:t,attributes:{align:"justify"}},bold:[{inline:"b",remove:"all"},{inline:"strong",remove:"all"},{inline:"span",styles:{fontWeight:"bold"}}],italic:[{inline:"i",remove:"all"},{inline:"em",remove:"all"},{inline:"span",styles:{fontStyle:"italic"}}],underline:[{inline:"u",remove:"all"},{inline:"span",styles:{textDecoration:"underline"},exact:!0}],strikethrough:[{inline:"strike",remove:"all"},{inline:"span",styles:{textDecoration:"line-through"},exact:!0}],fontname:{inline:"font",attributes:{face:"%value"}},fontsize:{inline:"font",attributes:{size:function(e){return o.inArray(n,e.value)+1}}},forecolor:{inline:"font",attributes:{color:"%value"}},hilitecolor:{inline:"font",styles:{backgroundColor:"%value"}}}),o.each("b,i,u,strike".split(","),function(e){i.addValidElements(e+"[*]")}),i.getElementRule("font")||i.addValidElements("font[face|size|color|style]"),o.each(t.split(","),function(e){var t=i.getElementRule(e);t&&(t.attributes.align||(t.attributes.align={},t.attributesOrder.push("align")))})})},n=function(i){i.addButton("fontsizeselect",function(){var o=[],e=i.settings.fontsizeFormats||"8pt=1 10pt=2 12pt=3 14pt=4 18pt=5 24pt=6 36pt=7";return i.$.each(e.split(" "),function(e,t){var n=t,i=t,a=t.split("=");1<a.length&&(n=a[0],i=a[1]),o.push({text:n,value:i})}),{type:"listbox",text:"Font Sizes",tooltip:"Font Sizes",values:o,fixedWidth:!0,onPostRender:function(){var t=this;i.on("NodeChange",function(){var e;(e=i.dom.getParent(i.selection.getNode(),"font"))?t.value(e.size):t.value("")})},onclick:function(e){e.control.settings.value&&i.execCommand("FontSize",!1,e.control.settings.value)}}}),i.addButton("fontselect",function(){var n=[],e=function(e){for(var t=(e=e.replace(/;$/,"").split(";")).length;t--;)e[t]=e[t].split("=");return e}(i.settings.font_formats||"Andale Mono=andale mono,monospace;Arial=arial,helvetica,sans-serif;Arial Black=arial black,sans-serif;Book Antiqua=book antiqua,palatino,serif;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier,monospace;Georgia=georgia,palatino,serif;Helvetica=helvetica,arial,sans-serif;Impact=impact,sans-serif;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco,monospace;Times New Roman=times new roman,times,serif;Trebuchet MS=trebuchet ms,geneva,sans-serif;Verdana=verdana,geneva,sans-serif;Webdings=webdings;Wingdings=wingdings,zapf dingbats");return i.$.each(e,function(e,t){n.push({text:{raw:t[0]},value:t[1],textStyle:-1===t[1].indexOf("dings")?"font-family:"+t[1]:""})}),{type:"listbox",text:"Font Family",tooltip:"Font Family",values:n,fixedWidth:!0,onPostRender:function(){var t=this;i.on("NodeChange",function(){var e;(e=i.dom.getParent(i.selection.getNode(),"font"))?t.value(e.face):t.value("")})},onselect:function(e){e.control.settings.value&&i.execCommand("FontName",!1,e.control.settings.value)}}})};e.add("legacyoutput",function(e){t(e),n(e)})}();
|
||||
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(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager"),e=function(n,e){var t,a=(t=n).plugins.visualchars&&t.plugins.visualchars.isEnabled()?'<span class="mce-nbsp"> </span>':" ";n.insertContent(function(n,e){for(var t="",a=0;a<e;a++)t+=n;return t}(a,e)),n.dom.setAttrib(n.dom.select("span.mce-nbsp"),"data-mce-bogus","1")},t=function(n){n.addCommand("mceNonBreaking",function(){e(n,1)})},a=tinymce.util.Tools.resolve("tinymce.util.VK"),i=function(n){var e=n.getParam("nonbreaking_force_tab",0);return"boolean"==typeof e?!0===e?3:0:e},o=function(n){var t=i(n);t>0&&n.on("keydown",function(i){if(i.keyCode===a.TAB&&!i.isDefaultPrevented()){if(i.shiftKey)return;i.preventDefault(),i.stopImmediatePropagation(),e(n,t)}})},r=function(n){n.addButton("nonbreaking",{title:"Nonbreaking space",cmd:"mceNonBreaking"}),n.addMenuItem("nonbreaking",{text:"Nonbreaking space",cmd:"mceNonBreaking",context:"insert"})};n.add("nonbreaking",function(n){t(n),r(n),o(n)})}();
|
||||
!function(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=function(n,e){var t,i=(t=n).plugins.visualchars&&t.plugins.visualchars.isEnabled()?'<span class="mce-nbsp"> </span>':" ";n.insertContent(function(n,e){for(var t="",i=0;i<e;i++)t+=n;return t}(i,e)),n.dom.setAttrib(n.dom.select("span.mce-nbsp"),"data-mce-bogus","1")},e=function(n){n.addCommand("mceNonBreaking",function(){i(n,1)})},o=tinymce.util.Tools.resolve("tinymce.util.VK"),a=function(n){var e=n.getParam("nonbreaking_force_tab",0);return"boolean"==typeof e?!0===e?3:0:e},t=function(e){var t=a(e);0<t&&e.on("keydown",function(n){if(n.keyCode===o.TAB&&!n.isDefaultPrevented()){if(n.shiftKey)return;n.preventDefault(),n.stopImmediatePropagation(),i(e,t)}})},r=function(n){n.addButton("nonbreaking",{title:"Nonbreaking space",cmd:"mceNonBreaking"}),n.addMenuItem("nonbreaking",{icon:"nonbreaking",text:"Nonbreaking space",cmd:"mceNonBreaking",context:"insert"})};n.add("nonbreaking",function(n){e(n),r(n),t(n)})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=tinymce.util.Tools.resolve("tinymce.util.Tools"),e=function(t){return t.getParam("noneditable_noneditable_class","mceNonEditable")},r=function(t){return t.getParam("noneditable_editable_class","mceEditable")},a=function(t){var n=t.getParam("noneditable_regexp",[]);return n&&n.constructor===RegExp?[n]:n},i=function(t){return function(n){return-1!==(" "+n.attr("class")+" ").indexOf(t)}},o=function(t,n,e){return function(r){var a=arguments,i=a[a.length-2],o=i>0?n.charAt(i-1):"";if('"'===o)return r;if(">"===o){var c=n.lastIndexOf("<",i);if(-1!==c&&-1!==n.substring(c,i).indexOf('contenteditable="false"'))return r}return'<span class="'+e+'" data-mce-content="'+t.dom.encode(a[0])+'">'+t.dom.encode("string"==typeof a[1]?a[1]:a[0])+"</span>"}},c=function(t){var c,l,u="contenteditable";c=" "+n.trim(r(t))+" ",l=" "+n.trim(e(t))+" ";var f=i(c),s=i(l),d=a(t);t.on("PreInit",function(){d.length>0&&t.on("BeforeSetContent",function(n){!function(t,n,r){var a=n.length,i=r.content;if("raw"!==r.format){for(;a--;)i=i.replace(n[a],o(t,i,e(t)));r.content=i}}(t,d,n)}),t.parser.addAttributeFilter("class",function(t){for(var n,e=t.length;e--;)n=t[e],f(n)?n.attr(u,"true"):s(n)&&n.attr(u,"false")}),t.serializer.addAttributeFilter(u,function(t){for(var n,e=t.length;e--;)n=t[e],(f(n)||s(n))&&(d.length>0&&n.attr("data-mce-content")?(n.name="#text",n.type=3,n.raw=!0,n.value=n.attr("data-mce-content")):n.attr(u,null))})})};t.add("noneditable",function(t){c(t)})}();
|
||||
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),c=tinymce.util.Tools.resolve("tinymce.util.Tools"),l=function(t){return t.getParam("noneditable_noneditable_class","mceNonEditable")},u=function(t){return t.getParam("noneditable_editable_class","mceEditable")},f=function(t){var n=t.getParam("noneditable_regexp",[]);return n&&n.constructor===RegExp?[n]:n},s=function(n){return function(t){return-1!==(" "+t.attr("class")+" ").indexOf(n)}},d=function(i,o,c){return function(t){var n=arguments,e=n[n.length-2],r=0<e?o.charAt(e-1):"";if('"'===r)return t;if(">"===r){var a=o.lastIndexOf("<",e);if(-1!==a&&-1!==o.substring(a,e).indexOf('contenteditable="false"'))return t}return'<span class="'+c+'" data-mce-content="'+i.dom.encode(n[0])+'">'+i.dom.encode("string"==typeof n[1]?n[1]:n[0])+"</span>"}},n=function(n){var t,e,r="contenteditable";t=" "+c.trim(u(n))+" ",e=" "+c.trim(l(n))+" ";var a=s(t),i=s(e),o=f(n);n.on("PreInit",function(){0<o.length&&n.on("BeforeSetContent",function(t){!function(t,n,e){var r=n.length,a=e.content;if("raw"!==e.format){for(;r--;)a=a.replace(n[r],d(t,a,l(t)));e.content=a}}(n,o,t)}),n.parser.addAttributeFilter("class",function(t){for(var n,e=t.length;e--;)n=t[e],a(n)?n.attr(r,"true"):i(n)&&n.attr(r,"false")}),n.serializer.addAttributeFilter(r,function(t){for(var n,e=t.length;e--;)n=t[e],(a(n)||i(n))&&(0<o.length&&n.attr("data-mce-content")?(n.name="#text",n.type=3,n.raw=!0,n.value=n.attr("data-mce-content")):n.attr(r,null))})})};t.add("noneditable",function(t){n(t)})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.Env"),n=function(e){return e.getParam("pagebreak_separator","\x3c!-- pagebreak --\x3e")},t=function(e){return e.getParam("pagebreak_split_block",!1)},r=function(){return"mce-pagebreak"},c=function(){return'<img src="'+a.transparentSrc+'" class="mce-pagebreak" data-mce-resize="false" data-mce-placeholder />'},o=function(e){var a=n(e),r=new RegExp(a.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,function(e){return"\\"+e}),"gi");e.on("BeforeSetContent",function(e){e.content=e.content.replace(r,c())}),e.on("PreInit",function(){e.serializer.addNodeFilter("img",function(n){for(var r,c,o=n.length;o--;)if((c=(r=n[o]).attr("class"))&&-1!==c.indexOf("mce-pagebreak")){var i=r.parent;if(e.schema.getBlockElements()[i.name]&&t(e)){i.type=3,i.value=a,i.raw=!0,r.remove();continue}r.type=3,r.value=a,r.raw=!0}})})},i=c,g=r,u=function(e){e.addCommand("mcePageBreak",function(){e.settings.pagebreak_split_block?e.insertContent("<p>"+i()+"</p>"):e.insertContent(i())})},m=function(e){e.on("ResolveName",function(a){"IMG"===a.target.nodeName&&e.dom.hasClass(a.target,g())&&(a.name="pagebreak")})},s=function(e){e.addButton("pagebreak",{title:"Page break",cmd:"mcePageBreak"}),e.addMenuItem("pagebreak",{text:"Page break",icon:"pagebreak",cmd:"mcePageBreak",context:"insert"})};e.add("pagebreak",function(e){u(e),s(e),o(e),m(e)})}();
|
||||
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.Env"),n=function(e){return e.getParam("pagebreak_separator","\x3c!-- pagebreak --\x3e")},i=function(e){return e.getParam("pagebreak_split_block",!1)},t=function(){return"mce-pagebreak"},r=function(){return'<img src="'+a.transparentSrc+'" class="mce-pagebreak" data-mce-resize="false" data-mce-placeholder />'},c=function(c){var o=n(c),a=new RegExp(o.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,function(e){return"\\"+e}),"gi");c.on("BeforeSetContent",function(e){e.content=e.content.replace(a,r())}),c.on("PreInit",function(){c.serializer.addNodeFilter("img",function(e){for(var a,n,t=e.length;t--;)if((n=(a=e[t]).attr("class"))&&-1!==n.indexOf("mce-pagebreak")){var r=a.parent;if(c.schema.getBlockElements()[r.name]&&i(c)){r.type=3,r.value=o,r.raw=!0,a.remove();continue}a.type=3,a.value=o,a.raw=!0}})})},o=r,g=t,u=function(e){e.addCommand("mcePageBreak",function(){e.settings.pagebreak_split_block?e.insertContent("<p>"+o()+"</p>"):e.insertContent(o())})},m=function(a){a.on("ResolveName",function(e){"IMG"===e.target.nodeName&&a.dom.hasClass(e.target,g())&&(e.name="pagebreak")})},s=function(e){e.addButton("pagebreak",{title:"Page break",cmd:"mcePageBreak"}),e.addMenuItem("pagebreak",{text:"Page break",icon:"pagebreak",cmd:"mcePageBreak",context:"insert"})};e.add("pagebreak",function(e){u(e),s(e),c(e),m(e)})}();
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env"),n=function(e){return parseInt(e.getParam("plugin_preview_width","650"),10)},i=function(e){return parseInt(e.getParam("plugin_preview_height","500"),10)},o=function(e){return e.getParam("content_style","")},r=tinymce.util.Tools.resolve("tinymce.util.Tools"),c=function(e){var t="",n=e.dom.encode,i=o(e);t+='<base href="'+n(e.documentBaseURI.getURI())+'">',i&&(t+='<style type="text/css">'+i+"</style>"),r.each(e.contentCSS,function(i){t+='<link type="text/css" rel="stylesheet" href="'+n(e.documentBaseURI.toAbsolute(i))+'">'});var c=e.settings.body_id||"tinymce";-1!==c.indexOf("=")&&(c=(c=e.getParam("body_id","","hash"))[e.id]||c);var a=e.settings.body_class||"";-1!==a.indexOf("=")&&(a=(a=e.getParam("body_class","","hash"))[e.id]||"");var s=e.settings.directionality?' dir="'+e.settings.directionality+'"':"";return"<!DOCTYPE html><html><head>"+t+'</head><body id="'+n(c)+'" class="mce-content-body '+n(a)+'"'+n(s)+">"+e.getContent()+'<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> </body></html>'},a=function(e,t,n){var i=c(e);if(n)t.src="data:text/html;charset=utf-8,"+encodeURIComponent(i);else{var o=t.contentWindow.document;o.open(),o.write(i),o.close()}},s=function(e){var o=!t.ie,r='<iframe src="" frameborder="0"'+(o?' sandbox="allow-scripts"':"")+"></iframe>",c=n(e),s=i(e);e.windowManager.open({title:"Preview",width:c,height:s,html:r,buttons:{text:"Close",onclick:function(e){e.control.parent().parent().close()}},onPostRender:function(t){var n=t.control.getEl("body").firstChild;a(e,n,o)}})},d=function(e){e.addCommand("mcePreview",function(){s(e)})},l=function(e){e.addButton("preview",{title:"Preview",cmd:"mcePreview"}),e.addMenuItem("preview",{text:"Preview",cmd:"mcePreview",context:"view"})};e.add("preview",function(e){d(e),l(e)})}();
|
||||
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),r=tinymce.util.Tools.resolve("tinymce.Env"),c=function(e){return parseInt(e.getParam("plugin_preview_width","650"),10)},a=function(e){return parseInt(e.getParam("plugin_preview_height","500"),10)},s=function(e){return e.getParam("content_style","")},d=tinymce.util.Tools.resolve("tinymce.util.Tools"),l=function(t){var n="",i=t.dom.encode,e=s(t);n+='<base href="'+i(t.documentBaseURI.getURI())+'">',e&&(n+='<style type="text/css">'+e+"</style>"),d.each(t.contentCSS,function(e){n+='<link type="text/css" rel="stylesheet" href="'+i(t.documentBaseURI.toAbsolute(e))+'">'});var o=t.settings.body_id||"tinymce";-1!==o.indexOf("=")&&(o=(o=t.getParam("body_id","","hash"))[t.id]||o);var r=t.settings.body_class||"";-1!==r.indexOf("=")&&(r=(r=t.getParam("body_class","","hash"))[t.id]||"");var c=t.settings.directionality?' dir="'+t.settings.directionality+'"':"";return"<!DOCTYPE html><html><head>"+n+'</head><body id="'+i(o)+'" class="mce-content-body '+i(r)+'"'+i(c)+">"+t.getContent()+'<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> </body></html>'},m=function(e,t,n){var i=l(e);if(n)t.src="data:text/html;charset=utf-8,"+encodeURIComponent(i);else{var o=t.contentWindow.document;o.open(),o.write(i),o.close()}},t=function(n){var i=!r.ie,e='<iframe src="" frameborder="0"'+(i?' sandbox="allow-scripts"':"")+"></iframe>",t=c(n),o=a(n);n.windowManager.open({title:"Preview",width:t,height:o,html:e,buttons:{text:"Close",onclick:function(e){e.control.parent().parent().close()}},onPostRender:function(e){var t=e.control.getEl("body").firstChild;m(n,t,i)}})},n=function(e){e.addCommand("mcePreview",function(){t(e)})},i=function(e){e.addButton("preview",{title:"Preview",cmd:"mcePreview"}),e.addMenuItem("preview",{text:"Preview",cmd:"mcePreview",context:"view"})};e.add("preview",function(e){n(e),i(e)})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager"),e=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),t=tinymce.util.Tools.resolve("tinymce.util.Tools"),a=function(n){return n.getParam("save_enablewhendirty",!0)},o=function(n){return!!n.getParam("save_onsavecallback")},c=function(n){return!!n.getParam("save_oncancelcallback")},i=function(n,e){n.notificationManager.open({text:n.translate(e),type:"error"})},r=function(n){var t;if(t=e.DOM.getParent(n.id,"form"),!a(n)||n.isDirty()){if(n.save(),o(n))return n.execCallback("save_onsavecallback",n),void n.nodeChanged();t?(n.setDirty(!1),t.onsubmit&&!t.onsubmit()||("function"==typeof t.submit?t.submit():i(n,"Error: Form submit field collision.")),n.nodeChanged()):i(n,"Error: No form element found.")}},l=function(n){var e=t.trim(n.startContent);c(n)?n.execCallback("save_oncancelcallback",n):(n.setContent(e),n.undoManager.clear(),n.nodeChanged())},d=function(n){n.addCommand("mceSave",function(){r(n)}),n.addCommand("mceCancel",function(){l(n)})},s=function(n){return function(e){var t=e.control;n.on("nodeChange dirty",function(){t.disabled(a(n)&&!n.isDirty())})}},u=function(n){n.addButton("save",{icon:"save",text:"Save",cmd:"mceSave",disabled:!0,onPostRender:s(n)}),n.addButton("cancel",{text:"Cancel",icon:!1,cmd:"mceCancel",disabled:!0,onPostRender:s(n)}),n.addShortcut("Meta+S","","mceSave")};n.add("save",function(n){u(n),d(n)})}();
|
||||
!function(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),a=tinymce.util.Tools.resolve("tinymce.util.Tools"),o=function(n){return n.getParam("save_enablewhendirty",!0)},c=function(n){return!!n.getParam("save_onsavecallback")},i=function(n){return!!n.getParam("save_oncancelcallback")},r=function(n,e){n.notificationManager.open({text:n.translate(e),type:"error"})},e=function(n){var e;if(e=t.DOM.getParent(n.id,"form"),!o(n)||n.isDirty()){if(n.save(),c(n))return n.execCallback("save_onsavecallback",n),void n.nodeChanged();e?(n.setDirty(!1),e.onsubmit&&!e.onsubmit()||("function"==typeof e.submit?e.submit():r(n,"Error: Form submit field collision.")),n.nodeChanged()):r(n,"Error: No form element found.")}},l=function(n){var e=a.trim(n.startContent);i(n)?n.execCallback("save_oncancelcallback",n):(n.setContent(e),n.undoManager.clear(),n.nodeChanged())},d=function(n){n.addCommand("mceSave",function(){e(n)}),n.addCommand("mceCancel",function(){l(n)})},s=function(t){return function(n){var e=n.control;t.on("nodeChange dirty",function(){e.disabled(o(t)&&!t.isDirty())})}},u=function(n){n.addButton("save",{icon:"save",text:"Save",cmd:"mceSave",disabled:!0,onPostRender:s(n)}),n.addButton("cancel",{text:"Cancel",icon:!1,cmd:"mceCancel",disabled:!0,onPostRender:s(n)}),n.addShortcut("Meta+S","","mceSave")};n.add("save",function(n){u(n),d(n)})}();
|
||||
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(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),n=tinymce.util.Tools.resolve("tinymce.EditorManager"),i=tinymce.util.Tools.resolve("tinymce.Env"),o=tinymce.util.Tools.resolve("tinymce.util.Delay"),l=tinymce.util.Tools.resolve("tinymce.util.Tools"),u=tinymce.util.Tools.resolve("tinymce.util.VK"),r={getTabFocus:function(e){return e.getParam("tab_focus",e.getParam("tabfocus_elements",":prev,:next"))}},c=t.DOM,s=function(e){e.keyCode!==u.TAB||e.ctrlKey||e.altKey||e.metaKey||e.preventDefault()},a=function(e){function t(t){var s,a,y,f;if(!(t.keyCode!==u.TAB||t.ctrlKey||t.altKey||t.metaKey||t.isDefaultPrevented())&&(1===(y=l.explode(r.getTabFocus(e))).length&&(y[1]=y[0],y[0]=":prev"),a=t.shiftKey?":prev"===y[0]?m(-1):c.get(y[0]):":next"===y[1]?m(1):c.get(y[1]))){var d=n.get(a.id||a.name);a.id&&d?d.focus():o.setTimeout(function(){i.webkit||window.focus(),a.focus()},10),t.preventDefault()}function m(i){function o(e){return/INPUT|TEXTAREA|BUTTON/.test(e.tagName)&&n.get(t.id)&&-1!==e.tabIndex&&function i(e){return"BODY"===e.nodeName||"hidden"!==e.type&&"none"!==e.style.display&&"hidden"!==e.style.visibility&&i(e.parentNode)}(e)}if(a=c.select(":input:enabled,*[tabindex]:not(iframe)"),l.each(a,function(t,n){if(t.id===e.id)return s=n,!1}),i>0){for(f=s+1;f<a.length;f++)if(o(a[f]))return a[f]}else for(f=s-1;f>=0;f--)if(o(a[f]))return a[f];return null}}e.on("init",function(){e.inline&&c.setAttrib(e.getBody(),"tabIndex",null),e.on("keyup",s),i.gecko?e.on("keypress keydown",t):e.on("keydown",t)})};e.add("tabfocus",function(e){a(e)})}();
|
||||
!function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),c=tinymce.util.Tools.resolve("tinymce.EditorManager"),s=tinymce.util.Tools.resolve("tinymce.Env"),a=tinymce.util.Tools.resolve("tinymce.util.Delay"),y=tinymce.util.Tools.resolve("tinymce.util.Tools"),f=tinymce.util.Tools.resolve("tinymce.util.VK"),d=function(e){return e.getParam("tab_focus",e.getParam("tabfocus_elements",":prev,:next"))},m=t.DOM,n=function(e){e.keyCode!==f.TAB||e.ctrlKey||e.altKey||e.metaKey||e.preventDefault()},i=function(r){function e(n){var i,o,e,l;if(!(n.keyCode!==f.TAB||n.ctrlKey||n.altKey||n.metaKey||n.isDefaultPrevented())&&(1===(e=y.explode(d(r))).length&&(e[1]=e[0],e[0]=":prev"),o=n.shiftKey?":prev"===e[0]?u(-1):m.get(e[0]):":next"===e[1]?u(1):m.get(e[1]))){var t=c.get(o.id||o.name);o.id&&t?t.focus():a.setTimeout(function(){s.webkit||window.focus(),o.focus()},10),n.preventDefault()}function u(e){function t(t){return/INPUT|TEXTAREA|BUTTON/.test(t.tagName)&&c.get(n.id)&&-1!==t.tabIndex&&function e(t){return"BODY"===t.nodeName||"hidden"!==t.type&&"none"!==t.style.display&&"hidden"!==t.style.visibility&&e(t.parentNode)}(t)}if(o=m.select(":input:enabled,*[tabindex]:not(iframe)"),y.each(o,function(e,t){if(e.id===r.id)return i=t,!1}),0<e){for(l=i+1;l<o.length;l++)if(t(o[l]))return o[l]}else for(l=i-1;0<=l;l--)if(t(o[l]))return o[l];return null}}r.on("init",function(){r.inline&&m.setAttrib(r.getBody(),"tabIndex",null),r.on("keyup",n),s.gecko?r.on("keypress keydown",e):r.on("keydown",e)})};e.add("tabfocus",function(e){i(e)})}();
|
||||
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(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),e=function(t,e){var o;return t.dom.getParents(t.selection.getStart(),function(t){var r;(r=t.style["forecolor"===e?"color":"background-color"])&&(o=r)}),o},o=function(t){var e,o=[];for(e=0;e<t.length;e+=2)o.push({text:t[e+1],color:"#"+t[e]});return o},r=function(t,e,o){t.undoManager.transact(function(){t.focus(),t.formatter.apply(e,{value:o}),t.nodeChanged()})},n=function(t,e){t.undoManager.transact(function(){t.focus(),t.formatter.remove(e,{value:null},null,!0),t.nodeChanged()})},a=function(t){t.addCommand("mceApplyTextcolor",function(e,o){r(t,e,o)}),t.addCommand("mceRemoveTextcolor",function(e){n(t,e)})},l=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),c=tinymce.util.Tools.resolve("tinymce.util.Tools"),i=["000000","Black","993300","Burnt orange","333300","Dark olive","003300","Dark green","003366","Dark azure","000080","Navy Blue","333399","Indigo","333333","Very dark gray","800000","Maroon","FF6600","Orange","808000","Olive","008000","Green","008080","Teal","0000FF","Blue","666699","Grayish blue","808080","Gray","FF0000","Red","FF9900","Amber","99CC00","Yellow green","339966","Sea green","33CCCC","Turquoise","3366FF","Royal blue","800080","Purple","999999","Medium gray","FF00FF","Magenta","FFCC00","Gold","FFFF00","Yellow","00FF00","Lime","00FFFF","Aqua","00CCFF","Sky blue","993366","Red violet","FFFFFF","White","FF99CC","Pink","FFCC99","Peach","FFFF99","Light yellow","CCFFCC","Pale green","CCFFFF","Pale cyan","99CCFF","Light sky blue","CC99FF","Plum"],u=function(t){return t.getParam("textcolor_map",i)},m=function(t){return t.getParam("textcolor_rows",5)},s=function(t){return t.getParam("textcolor_cols",8)},d=function(t){return t.getParam("color_picker_callback",null)},f=function(t){return t.getParam("forecolor_map",u(t))},g=function(t){return t.getParam("backcolor_map",u(t))},F=function(t){return t.getParam("forecolor_rows",m(t))},b=function(t){return t.getParam("backcolor_rows",m(t))},p=function(t){return t.getParam("forecolor_cols",s(t))},C=function(t){return t.getParam("backcolor_cols",s(t))},y=d,v=function(t){return"function"==typeof d(t)},h=tinymce.util.Tools.resolve("tinymce.util.I18n"),P=function(t,e,r,n){var a,c,i,u,m,s,d,f=0,g=l.DOM.uniqueId("mcearia"),F=function(t,e){var o="transparent"===t;return'<td class="mce-grid-cell'+(o?" mce-colorbtn-trans":"")+'"><div id="'+g+"-"+f+++'" data-mce-color="'+(t||"")+'" role="option" tabIndex="-1" style="'+(t?"background-color: "+t:"")+'" title="'+h.translate(e)+'">'+(o?"×":"")+"</div></td>"};for((a=o(r)).push({text:h.translate("No color"),color:"transparent"}),i='<table class="mce-grid mce-grid-border mce-colorbutton-grid" role="list" cellspacing="0"><tbody>',u=a.length-1,s=0;s<e;s++){for(i+="<tr>",m=0;m<t;m++)i+=(d=s*t+m)>u?"<td></td>":F((c=a[d]).color,c.text);i+="</tr>"}if(n){for(i+='<tr><td colspan="'+t+'" class="mce-custom-color-btn"><div id="'+g+'-c" class="mce-widget mce-btn mce-btn-small mce-btn-flat" role="button" tabindex="-1" aria-labelledby="'+g+'-c" style="width: 100%"><button type="button" role="presentation" tabindex="-1">'+h.translate("Custom...")+"</button></div></td></tr>",i+="<tr>",m=0;m<t;m++)i+=F("","Custom color");i+="</tr>"}return i+="</tbody></table>"},k=function(t,e){t.style.background=e,t.setAttribute("data-mce-color",e)},x=function(t){return function(e){var o=e.control;o._color?t.execCommand("mceApplyTextcolor",o.settings.format,o._color):t.execCommand("mceRemoveTextcolor",o.settings.format)}},T=function(t,o){return function(r){var n,a=this.parent(),i=e(t,a.settings.format),u=function(e){a.hidePanel(),a.color(e),t.execCommand("mceApplyTextcolor",a.settings.format,e)};l.DOM.getParent(r.target,".mce-custom-color-btn")&&(a.hidePanel(),y(t).call(t,function(t){var e,r,n,l=a.panel.getEl().getElementsByTagName("table")[0];for(e=c.map(l.rows[l.rows.length-1].childNodes,function(t){return t.firstChild}),n=0;n<e.length&&(r=e[n]).getAttribute("data-mce-color");n++);if(n===o)for(n=0;n<o-1;n++)k(e[n],e[n+1].getAttribute("data-mce-color"));k(r,t),u(t)},i)),(n=r.target.getAttribute("data-mce-color"))?(this.lastId&&l.DOM.get(this.lastId).setAttribute("aria-selected",!1),r.target.setAttribute("aria-selected",!0),this.lastId=r.target.id,"transparent"===n?(a.hidePanel(),a.resetColor(),t.execCommand("mceRemoveTextcolor",a.settings.format)):u(n)):null!==n&&a.hidePanel()}},_=function(t,e){return function(){var o=e?p(t):C(t),r=e?F(t):b(t),n=e?f(t):g(t),a=v(t);return P(o,r,n,a)}},A=function(t){t.addButton("forecolor",{type:"colorbutton",tooltip:"Text color",format:"forecolor",panel:{role:"application",ariaRemember:!0,html:_(t,!0),onclick:T(t,p(t))},onclick:x(t)}),t.addButton("backcolor",{type:"colorbutton",tooltip:"Background color",format:"hilitecolor",panel:{role:"application",ariaRemember:!0,html:_(t,!1),onclick:T(t,C(t))},onclick:x(t)})};t.add("textcolor",function(t){a(t),A(t)})}();
|
||||
!function(){"use strict";var t=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=function(t,o){var r;return t.dom.getParents(t.selection.getStart(),function(t){var e;(e=t.style["forecolor"===o?"color":"background-color"])&&(r=r||e)}),r},g=function(t){var e,o=[];for(e=0;e<t.length;e+=2)o.push({text:t[e+1],color:"#"+t[e]});return o},r=function(t,e,o){t.undoManager.transact(function(){t.focus(),t.formatter.apply(e,{value:o}),t.nodeChanged()})},e=function(t,e){t.undoManager.transact(function(){t.focus(),t.formatter.remove(e,{value:null},null,!0),t.nodeChanged()})},o=function(o){o.addCommand("mceApplyTextcolor",function(t,e){r(o,t,e)}),o.addCommand("mceRemoveTextcolor",function(t){e(o,t)})},F=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),i=tinymce.util.Tools.resolve("tinymce.util.Tools"),a=["000000","Black","993300","Burnt orange","333300","Dark olive","003300","Dark green","003366","Dark azure","000080","Navy Blue","333399","Indigo","333333","Very dark gray","800000","Maroon","FF6600","Orange","808000","Olive","008000","Green","008080","Teal","0000FF","Blue","666699","Grayish blue","808080","Gray","FF0000","Red","FF9900","Amber","99CC00","Yellow green","339966","Sea green","33CCCC","Turquoise","3366FF","Royal blue","800080","Purple","999999","Medium gray","FF00FF","Magenta","FFCC00","Gold","FFFF00","Yellow","00FF00","Lime","00FFFF","Aqua","00CCFF","Sky blue","993366","Red violet","FFFFFF","White","FF99CC","Pink","FFCC99","Peach","FFFF99","Light yellow","CCFFCC","Pale green","CCFFFF","Pale cyan","99CCFF","Light sky blue","CC99FF","Plum"],l=function(t){return t.getParam("textcolor_map",a)},c=function(t){return t.getParam("textcolor_rows",5)},u=function(t){return t.getParam("textcolor_cols",8)},m=function(t){return t.getParam("color_picker_callback",null)},s=function(t){return t.getParam("forecolor_map",l(t))},d=function(t){return t.getParam("backcolor_map",l(t))},f=function(t){return t.getParam("forecolor_rows",c(t))},b=function(t){return t.getParam("backcolor_rows",c(t))},p=function(t){return t.getParam("forecolor_cols",u(t))},C=function(t){return t.getParam("backcolor_cols",u(t))},y=m,v=function(t){return"function"==typeof m(t)},h=tinymce.util.Tools.resolve("tinymce.util.I18n"),P=function(t,e,o,r){var n,a,l,c,i,u,m,s=0,d=F.DOM.uniqueId("mcearia"),f=function(t,e){var o="transparent"===t;return'<td class="mce-grid-cell'+(o?" mce-colorbtn-trans":"")+'"><div id="'+d+"-"+s+++'" data-mce-color="'+(t||"")+'" role="option" tabIndex="-1" style="'+(t?"background-color: "+t:"")+'" title="'+h.translate(e)+'">'+(o?"×":"")+"</div></td>"};for((n=g(o)).push({text:h.translate("No color"),color:"transparent"}),l='<table class="mce-grid mce-grid-border mce-colorbutton-grid" role="list" cellspacing="0"><tbody>',c=n.length-1,u=0;u<e;u++){for(l+="<tr>",i=0;i<t;i++)l+=c<(m=u*t+i)?"<td></td>":f((a=n[m]).color,a.text);l+="</tr>"}if(r){for(l+='<tr><td colspan="'+t+'" class="mce-custom-color-btn"><div id="'+d+'-c" class="mce-widget mce-btn mce-btn-small mce-btn-flat" role="button" tabindex="-1" aria-labelledby="'+d+'-c" style="width: 100%"><button type="button" role="presentation" tabindex="-1">'+h.translate("Custom...")+"</button></div></td></tr>",l+="<tr>",i=0;i<t;i++)l+=f("","Custom color");l+="</tr>"}return l+="</tbody></table>"},k=function(t,e){t.style.background=e,t.setAttribute("data-mce-color",e)},x=function(o){return function(t){var e=t.control;e._color?o.execCommand("mceApplyTextcolor",e.settings.format,e._color):o.execCommand("mceRemoveTextcolor",e.settings.format)}},T=function(r,c){return function(t){var e,a=this.parent(),o=n(r,a.settings.format),l=function(t){r.execCommand("mceApplyTextcolor",a.settings.format,t),a.hidePanel(),a.color(t)};F.DOM.getParent(t.target,".mce-custom-color-btn")&&(a.hidePanel(),y(r).call(r,function(t){var e,o,r,n=a.panel.getEl().getElementsByTagName("table")[0];for(e=i.map(n.rows[n.rows.length-1].childNodes,function(t){return t.firstChild}),r=0;r<e.length&&(o=e[r]).getAttribute("data-mce-color");r++);if(r===c)for(r=0;r<c-1;r++)k(e[r],e[r+1].getAttribute("data-mce-color"));k(o,t),l(t)},o)),(e=t.target.getAttribute("data-mce-color"))?(this.lastId&&F.DOM.get(this.lastId).setAttribute("aria-selected","false"),t.target.setAttribute("aria-selected",!0),this.lastId=t.target.id,"transparent"===e?(r.execCommand("mceRemoveTextcolor",a.settings.format),a.hidePanel(),a.resetColor()):l(e)):null!==e&&a.hidePanel()}},_=function(n,a){return function(){var t=a?p(n):C(n),e=a?f(n):b(n),o=a?s(n):d(n),r=v(n);return P(t,e,o,r)}},A=function(t){t.addButton("forecolor",{type:"colorbutton",tooltip:"Text color",format:"forecolor",panel:{role:"application",ariaRemember:!0,html:_(t,!0),onclick:T(t,p(t))},onclick:x(t)}),t.addButton("backcolor",{type:"colorbutton",tooltip:"Background color",format:"hilitecolor",panel:{role:"application",ariaRemember:!0,html:_(t,!1),onclick:T(t,C(t))},onclick:x(t)})};t.add("textcolor",function(t){o(t),A(t)})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var t=function(e){var n=e,r=function(){return n};return{get:r,set:function(t){n=t},clone:function(){return t(r())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=function(t){return{setPatterns:function(e){t.set(e)},getPatterns:function(){return t.get()}}},r=[{start:"*",end:"*",format:"italic"},{start:"**",end:"**",format:"bold"},{start:"***",end:"***",format:["bold","italic"]},{start:"#",format:"h1"},{start:"##",format:"h2"},{start:"###",format:"h3"},{start:"####",format:"h4"},{start:"#####",format:"h5"},{start:"######",format:"h6"},{start:"1. ",cmd:"InsertOrderedList"},{start:"* ",cmd:"InsertUnorderedList"},{start:"- ",cmd:"InsertUnorderedList"}],a=function(t){return t.textpattern_patterns!==undefined?t.textpattern_patterns:r},o=tinymce.util.Tools.resolve("tinymce.util.Delay"),i=tinymce.util.Tools.resolve("tinymce.util.VK"),s=tinymce.util.Tools.resolve("tinymce.dom.TreeWalker"),l=tinymce.util.Tools.resolve("tinymce.util.Tools"),d=function(t,e){for(var n=0;n<t.length;n++)if(0===e.indexOf(t[n].start)&&(!t[n].end||e.lastIndexOf(t[n].end)===e.length-t[n].end.length))return t[n]},f=function(t,e,n,r){var a,o,i,s,l,d,f=t.sort(function(t,e){return t.start.length>e.start.length?-1:t.start.length<e.start.length?1:0});for(o=0;o<f.length;o++)if((a=f[o]).end!==undefined&&(s=a,l=n,d=r,e.substr(l-s.end.length-d,s.end.length)===s.end)&&n-r-(i=a).end.length-i.start.length>0)return a},c=function(t,e,n){if(!1!==e.collapsed){var r=e.startContainer,a=r.data,o=!0===n?1:0;if(3===r.nodeType){var i=f(t,a,e.startOffset,o);if(i!==undefined){var s=a.lastIndexOf(i.end,e.startOffset-o),l=a.lastIndexOf(i.start,s-i.end.length);if(s=a.indexOf(i.end,l+i.start.length),-1!==l){var c=document.createRange();c.setStart(r,l),c.setEnd(r,s+i.end.length);var u=d(t,c.toString());if(!(i===undefined||u!==i||r.data.length<=i.start.length+i.end.length))return{pattern:i,startOffset:l,endOffset:s}}}}}},u=function(t,e,n){var r=t.selection.getRng(!0),a=c(e,r,n);if(a)return function(t,e,n,r){var a=l.isArray(n.pattern.format)?n.pattern.format:[n.pattern.format];if(0!==l.grep(a,function(e){var n=t.formatter.get(e);return n&&n[0].inline}).length)return t.undoManager.transact(function(){var r,o,i,s;r=e,o=n.pattern,i=n.endOffset,s=n.startOffset,(r=s>0?r.splitText(s):r).splitText(i-s+o.end.length),r.deleteData(0,o.start.length),r.deleteData(r.data.length-o.end.length,o.end.length),e=r,a.forEach(function(n){t.formatter.apply(n,{},e)})}),e}(t,r.startContainer,a)},g={patternFromRng:c,applyInlineFormatSpace:function(t,e){return u(t,e,!0)},applyInlineFormatEnter:function(t,e){return u(t,e,!1)},applyBlockFormat:function(t,e){var n,r,a,o,i,f,c,u,g,h,m;if(n=t.selection,r=t.dom,n.isCollapsed()&&(c=r.getParent(n.getStart(),"p"))){for(g=new s(c,c);i=g.next();)if(3===i.nodeType){o=i;break}if(o){if(!(u=d(e,o.data)))return;if(a=(h=n.getRng(!0)).startContainer,m=h.startOffset,o===a&&(m=Math.max(0,m-u.start.length)),l.trim(o.data).length===u.start.length)return;u.format&&(f=t.formatter.get(u.format))&&f[0].block&&(o.deleteData(0,u.start.length),t.formatter.apply(u.format,{},o),h.setStart(a,m),h.collapse(!0),n.setRng(h)),u.cmd&&t.undoManager.transact(function(){o.deleteData(0,u.start.length),t.execCommand(u.cmd)})}}}},h=function(t,e,n){for(var r=0;r<t.length;r++)if(n(t[r],e))return!0},m={handleEnter:function(t,e){var n,r;(n=g.applyInlineFormatEnter(t,e))&&((r=t.dom.createRng()).setStart(n,n.data.length),r.setEnd(n,n.data.length),t.selection.setRng(r)),g.applyBlockFormat(t,e)},handleInlineKey:function(t,e){var n,r,a,o,i;(n=g.applyInlineFormatSpace(t,e))&&(i=t.dom,r=n.data.slice(-1),/[\u00a0 ]/.test(r)&&(n.deleteData(n.data.length-1,1),a=i.doc.createTextNode(r),i.insertAfter(a,n.parentNode),(o=i.createRng()).setStart(a,1),o.setEnd(a,1),t.selection.setRng(o)))},checkCharCode:function(t,e){return h(t,e,function(t,e){return t.charCodeAt(0)===e.charCode})},checkKeyCode:function(t,e){return h(t,e,function(t,e){return t===e.keyCode&&!1===i.modifierPressed(e)})}},p=function(t,e){var n=[",",".",";",":","!","?"],r=[32];t.on("keydown",function(n){13!==n.keyCode||i.modifierPressed(n)||m.handleEnter(t,e.get())},!0),t.on("keyup",function(n){m.checkKeyCode(r,n)&&m.handleInlineKey(t,e.get())}),t.on("keypress",function(r){m.checkCharCode(n,r)&&o.setEditorTimeout(t,function(){m.handleInlineKey(t,e.get())})})};e.add("textpattern",function(e){var r=t(a(e.settings));return p(e,r),n(r)})}();
|
||||
!function(){"use strict";var r=function(t){var e=t,n=function(){return e};return{get:n,set:function(t){e=t},clone:function(){return r(n())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=function(e){return{setPatterns:function(t){e.set(t)},getPatterns:function(){return e.get()}}},e=[{start:"*",end:"*",format:"italic"},{start:"**",end:"**",format:"bold"},{start:"***",end:"***",format:["bold","italic"]},{start:"#",format:"h1"},{start:"##",format:"h2"},{start:"###",format:"h3"},{start:"####",format:"h4"},{start:"#####",format:"h5"},{start:"######",format:"h6"},{start:"1. ",cmd:"InsertOrderedList"},{start:"* ",cmd:"InsertUnorderedList"},{start:"- ",cmd:"InsertUnorderedList"}],a=function(t){return t.textpattern_patterns!==undefined?t.textpattern_patterns:e},o=tinymce.util.Tools.resolve("tinymce.util.Delay"),i=tinymce.util.Tools.resolve("tinymce.util.VK"),g=tinymce.util.Tools.resolve("tinymce.dom.TreeWalker"),h=tinymce.util.Tools.resolve("tinymce.util.Tools"),m=function(t,e){for(var n=0;n<t.length;n++)if(0===e.indexOf(t[n].start)&&(!t[n].end||e.lastIndexOf(t[n].end)===e.length-t[n].end.length))return t[n]},c=function(t,e,n,r){var a,o,i,s,d,f,l=t.sort(function(t,e){return t.start.length>e.start.length?-1:t.start.length<e.start.length?1:0});for(o=0;o<l.length;o++)if((a=l[o]).end!==undefined&&(s=a,d=n,f=r,e.substr(d-s.end.length-f,s.end.length)===s.end)&&0<n-r-(i=a).end.length-i.start.length)return a},s=function(t,e,n){if(!1!==e.collapsed){var r=e.startContainer,a=r.data,o=!0===n?1:0;if(3===r.nodeType){var i=c(t,a,e.startOffset,o);if(i!==undefined){var s=a.lastIndexOf(i.end,e.startOffset-o),d=a.lastIndexOf(i.start,s-i.end.length);if(s=a.indexOf(i.end,d+i.start.length),-1!==d){var f=document.createRange();f.setStart(r,d),f.setEnd(r,s+i.end.length);var l=m(t,f.toString());if(!(i===undefined||l!==i||r.data.length<=i.start.length+i.end.length))return{pattern:i,startOffset:d,endOffset:s}}}}}},d=function(t,e,n){var r=t.selection.getRng(!0),a=s(e,r,n);if(a)return function(a,o,i,t){var s=h.isArray(i.pattern.format)?i.pattern.format:[i.pattern.format];if(0!==h.grep(s,function(t){var e=a.formatter.get(t);return e&&e[0].inline}).length)return a.undoManager.transact(function(){var t,e,n,r;t=o,e=i.pattern,n=i.endOffset,r=i.startOffset,(t=0<r?t.splitText(r):t).splitText(n-r+e.end.length),t.deleteData(0,e.start.length),t.deleteData(t.data.length-e.end.length,e.end.length),o=t,s.forEach(function(t){a.formatter.apply(t,{},o)})}),o}(t,r.startContainer,a)},f=function(t,e){return d(t,e,!0)},l=function(t,e){return d(t,e,!1)},u=function(t,e){var n,r,a,o,i,s,d,f,l,c,u;if(n=t.selection,r=t.dom,n.isCollapsed()&&(d=r.getParent(n.getStart(),"p"))){for(l=new g(d,d);i=l.next();)if(3===i.nodeType){o=i;break}if(o){if(!(f=m(e,o.data)))return;if(a=(c=n.getRng(!0)).startContainer,u=c.startOffset,o===a&&(u=Math.max(0,u-f.start.length)),h.trim(o.data).length===f.start.length)return;f.format&&(s=t.formatter.get(f.format))&&s[0].block&&(o.deleteData(0,f.start.length),t.formatter.apply(f.format,{},o),c.setStart(a,u),c.collapse(!0),n.setRng(c)),f.cmd&&t.undoManager.transact(function(){o.deleteData(0,f.start.length),t.execCommand(f.cmd)})}}},p=function(t,e,n){for(var r=0;r<t.length;r++)if(n(t[r],e))return!0},y={handleEnter:function(t,e){var n,r;(n=l(t,e))&&((r=t.dom.createRng()).setStart(n,n.data.length),r.setEnd(n,n.data.length),t.selection.setRng(r)),u(t,e)},handleInlineKey:function(t,e){var n,r,a,o,i;(n=f(t,e))&&(i=t.dom,r=n.data.slice(-1),/[\u00a0 ]/.test(r)&&(n.deleteData(n.data.length-1,1),a=i.doc.createTextNode(r),i.insertAfter(a,n.parentNode),(o=i.createRng()).setStart(a,1),o.setEnd(a,1),t.selection.setRng(o)))},checkCharCode:function(t,e){return p(t,e,function(t,e){return t.charCodeAt(0)===e.charCode})},checkKeyCode:function(t,e){return p(t,e,function(t,e){return t===e.keyCode&&!1===i.modifierPressed(e)})}},v=function(e,n){var r=[",",".",";",":","!","?"],a=[32];e.on("keydown",function(t){13!==t.keyCode||i.modifierPressed(t)||y.handleEnter(e,n.get())},!0),e.on("keyup",function(t){y.checkKeyCode(a,t)&&y.handleInlineKey(e,n.get())}),e.on("keypress",function(t){y.checkCharCode(r,t)&&o.setEditorTimeout(e,function(){y.handleInlineKey(e,n.get())})})};t.add("textpattern",function(t){var e=r(a(t.settings));return v(t,e),n(e)})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var t,e,n=tinymce.util.Tools.resolve("tinymce.PluginManager"),o=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),r=tinymce.util.Tools.resolve("tinymce.util.I18n"),i=tinymce.util.Tools.resolve("tinymce.util.Tools"),c=function(t){return t.getParam("toc_class","mce-toc")},l=function(t){var e=t.getParam("toc_header","h2");return/^h[1-6]$/.test(e)?e:"h2"},a=function(t){var e=parseInt(t.getParam("toc_depth","3"),10);return e>=1&&e<=9?e:3},d=(t="mcetoc_",e=0,function(){var n=(new Date).getTime().toString(32);return t+n+(e++).toString(32)}),u=function(t){var e=c(t),n=l(t),o=function(t){var e,n=[];for(e=1;e<=t;e++)n.push("h"+e);return n.join(",")}(a(t)),r=t.$(o);return r.length&&/^h[1-9]$/i.test(n)&&(r=r.filter(function(n,o){return!t.dom.hasClass(o.parentNode,e)})),i.map(r,function(e){return{id:e.id?e.id:d(),level:parseInt(e.nodeName.replace(/^H/i,""),10),title:t.$.text(e),element:e}})},s=function(t){var e,n,i,c,a,d,s,f="",m=u(t),v=function(t){var e,n=9;for(e=0;e<t.length;e++)if(t[e].level<n&&(n=t[e].level),1===n)return n;return n}(m)-1;if(!m.length)return"";for(f+=(a=l(t),d=r.translate("Table of Contents"),s="</"+a+">","<"+a+' contenteditable="true">'+o.DOM.encode(d)+s),e=0;e<m.length;e++){if((i=m[e]).element.id=i.id,c=m[e+1]&&m[e+1].level,v===i.level)f+="<li>";else for(n=v;n<i.level;n++)f+="<ul><li>";if(f+='<a href="#'+i.id+'">'+i.title+"</a>",c!==i.level&&c)for(n=i.level;n>c;n--)f+="</li></ul><li>";else f+="</li>",c||(f+="</ul>");v=i.level}return f},f=function(t){var e=c(t),n=t.$("."+e);n.length&&t.undoManager.transact(function(){n.html(s(t))})},m={hasHeaders:function(t){return u(t).length>0},insertToc:function(t){var e,n,o,r,i=c(t),l=t.$("."+i);o=t,!(r=l).length||o.dom.getParents(r[0],".mce-offscreen-selection").length>0?t.insertContent((n=s(e=t),'<div class="'+e.dom.encode(c(e))+'" contenteditable="false">'+n+"</div>")):f(t)},updateToc:f},v=function(t){t.addCommand("mceInsertToc",function(){m.insertToc(t)}),t.addCommand("mceUpdateToc",function(){m.updateToc(t)})},h=function(t){var e=t.$,n=c(t);t.on("PreProcess",function(t){var o=e("."+n,t.node);o.length&&(o.removeAttr("contentEditable"),o.find("[contenteditable]").removeAttr("contentEditable"))}),t.on("SetContent",function(){var t=e("."+n);t.length&&(t.attr("contentEditable",!1),t.children(":first-child").attr("contentEditable",!0))})},g=function(t){return function(e){var n=e.control;t.on("LoadContent SetContent change",function(){n.disabled(t.readonly||!m.hasHeaders(t))})}},T=function(t){var e;t.addButton("toc",{tooltip:"Table of Contents",cmd:"mceInsertToc",icon:"toc",onPostRender:g(t)}),t.addButton("tocupdate",{tooltip:"Update",cmd:"mceUpdateToc",icon:"reload"}),t.addMenuItem("toc",{text:"Table of Contents",context:"insert",cmd:"mceInsertToc",onPostRender:g(t)}),t.addContextToolbar((e=t,function(t){return t&&e.dom.is(t,"."+c(e))&&e.getBody().contains(t)}),"tocupdate")};n.add("toc",function(t){v(t),T(t),h(t)})}();
|
||||
!function(){"use strict";var e,n,t=tinymce.util.Tools.resolve("tinymce.PluginManager"),s=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),f=tinymce.util.Tools.resolve("tinymce.util.I18n"),i=tinymce.util.Tools.resolve("tinymce.util.Tools"),l=function(t){return t.getParam("toc_class","mce-toc")},m=function(t){var e=t.getParam("toc_header","h2");return/^h[1-6]$/.test(e)?e:"h2"},c=function(t){var e=parseInt(t.getParam("toc_depth","3"),10);return 1<=e&&e<=9?e:3},a=(e="mcetoc_",n=0,function(){var t=(new Date).getTime().toString(32);return e+t+(n++).toString(32)}),v=function(n){var o=l(n),t=m(n),e=function(t){var e,n=[];for(e=1;e<=t;e++)n.push("h"+e);return n.join(",")}(c(n)),r=n.$(e);return r.length&&/^h[1-9]$/i.test(t)&&(r=r.filter(function(t,e){return!n.dom.hasClass(e.parentNode,o)})),i.map(r,function(t){return{id:t.id?t.id:a(),level:parseInt(t.nodeName.replace(/^H/i,""),10),title:n.$.text(t),element:t}})},d=function(t){var e,n,o,r,i,c,l,a="",d=v(t),u=function(t){var e,n=9;for(e=0;e<t.length;e++)if(t[e].level<n&&(n=t[e].level),1===n)return n;return n}(d)-1;if(!d.length)return"";for(a+=(i=m(t),c=f.translate("Table of Contents"),l="</"+i+">","<"+i+' contenteditable="true">'+s.DOM.encode(c)+l),e=0;e<d.length;e++){if((o=d[e]).element.id=o.id,r=d[e+1]&&d[e+1].level,u===o.level)a+="<li>";else for(n=u;n<o.level;n++)a+="<ul><li>";if(a+='<a href="#'+o.id+'">'+o.title+"</a>",r!==o.level&&r)for(n=o.level;r<n;n--)a+="</li></ul><li>";else a+="</li>",r||(a+="</ul>");u=o.level}return a},u=function(t){var e=l(t),n=t.$("."+e);n.length&&t.undoManager.transact(function(){n.html(d(t))})},o={hasHeaders:function(t){return 0<v(t).length},insertToc:function(t){var e,n,o,r,i=l(t),c=t.$("."+i);o=t,!(r=c).length||0<o.dom.getParents(r[0],".mce-offscreen-selection").length?t.insertContent((n=d(e=t),'<div class="'+e.dom.encode(l(e))+'" contenteditable="false">'+n+"</div>")):u(t)},updateToc:u},r=function(t){t.addCommand("mceInsertToc",function(){o.insertToc(t)}),t.addCommand("mceUpdateToc",function(){o.updateToc(t)})},h=function(t){var n=t.$,o=l(t);t.on("PreProcess",function(t){var e=n("."+o,t.node);e.length&&(e.removeAttr("contentEditable"),e.find("[contenteditable]").removeAttr("contentEditable"))}),t.on("SetContent",function(){var t=n("."+o);t.length&&(t.attr("contentEditable",!1),t.children(":first-child").attr("contentEditable",!0))})},g=function(n){return function(t){var e=t.control;n.on("LoadContent SetContent change",function(){e.disabled(n.readonly||!o.hasHeaders(n))})}},T=function(t){var e;t.addButton("toc",{tooltip:"Table of Contents",cmd:"mceInsertToc",icon:"toc",onPostRender:g(t)}),t.addButton("tocupdate",{tooltip:"Update",cmd:"mceUpdateToc",icon:"reload"}),t.addMenuItem("toc",{text:"Table of Contents",context:"insert",cmd:"mceInsertToc",onPostRender:g(t)}),t.addContextToolbar((e=t,function(t){return t&&e.dom.is(t,"."+l(e))&&e.getBody().contains(t)}),"tocupdate")};t.add("toc",function(t){r(t),T(t),h(t)})}();
|
||||
@@ -1 +1 @@
|
||||
!function(){"use strict";var e=function(t){var n=t,o=function(){return n};return{get:o,set:function(e){n=e},clone:function(){return e(o())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),n=function(e,t){e.fire("VisualBlocks",{state:t})},o=function(e){return e.getParam("visualblocks_default_state",!1)},s=function(e){return e.settings.visualblocks_content_css},i=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),c=tinymce.util.Tools.resolve("tinymce.util.Tools"),l=i.DOM.uniqueId(),u=function(e,t){var n=c.toArray(e.getElementsByTagName("link"));if(0===c.grep(n,function(e){return e.id===l}).length){var o=i.DOM.create("link",{id:l,rel:"stylesheet",href:t});e.getElementsByTagName("head")[0].appendChild(o)}},a=function(e,t,o){var i=e.dom,c=s(e);u(e.getDoc(),c||t+"/css/visualblocks.css"),i.toggleClass(e.getBody(),"mce-visualblocks"),o.set(!o.get()),n(e,o.get())},r=function(e,t,n){e.addCommand("mceVisualBlocks",function(){a(e,t,n)})},m=function(e,t,n){e.on("PreviewFormats AfterPreviewFormats",function(t){n.get()&&e.dom.toggleClass(e.getBody(),"mce-visualblocks","afterpreviewformats"===t.type)}),e.on("init",function(){o(e)&&a(e,t,n)}),e.on("remove",function(){e.dom.removeClass(e.getBody(),"mce-visualblocks")})},f=function(e,t){return function(n){var o=n.control;o.active(t.get()),e.on("VisualBlocks",function(e){o.active(e.state)})}},d=function(e,t){e.addButton("visualblocks",{active:!1,title:"Show blocks",cmd:"mceVisualBlocks",onPostRender:f(e,t)}),e.addMenuItem("visualblocks",{text:"Show blocks",cmd:"mceVisualBlocks",onPostRender:f(e,t),selectable:!0,context:"view",prependToContext:!0})};t.add("visualblocks",function(t,n){var o=e(!1);r(t,n,o),d(t,o),m(t,n,o)})}();
|
||||
!function(){"use strict";var o=function(e){var t=e,n=function(){return t};return{get:n,set:function(e){t=e},clone:function(){return o(n())}}},e=tinymce.util.Tools.resolve("tinymce.PluginManager"),i=function(e,t){e.fire("VisualBlocks",{state:t})},s=function(e){return e.getParam("visualblocks_default_state",!1)},c=function(e){return e.settings.visualblocks_content_css},l=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),u=tinymce.util.Tools.resolve("tinymce.util.Tools"),a=l.DOM.uniqueId(),r=function(e,t){var n=u.toArray(e.getElementsByTagName("link"));if(0===u.grep(n,function(e){return e.id===a}).length){var o=l.DOM.create("link",{id:a,rel:"stylesheet",href:t});e.getElementsByTagName("head")[0].appendChild(o)}},m=function(e,t,n){var o=e.dom,s=c(e);r(e.getDoc(),s||t+"/css/visualblocks.css"),o.toggleClass(e.getBody(),"mce-visualblocks"),n.set(!n.get()),i(e,n.get())},f=function(e,t,n){e.addCommand("mceVisualBlocks",function(){m(e,t,n)})},d=function(t,e,n){t.on("PreviewFormats AfterPreviewFormats",function(e){n.get()&&t.dom.toggleClass(t.getBody(),"mce-visualblocks","afterpreviewformats"===e.type)}),t.on("init",function(){s(t)&&m(t,e,n)}),t.on("remove",function(){t.dom.removeClass(t.getBody(),"mce-visualblocks")})},n=function(n,o){return function(e){var t=e.control;t.active(o.get()),n.on("VisualBlocks",function(e){t.active(e.state)})}},v=function(e,t){e.addButton("visualblocks",{active:!1,title:"Show blocks",cmd:"mceVisualBlocks",onPostRender:n(e,t)}),e.addMenuItem("visualblocks",{text:"Show blocks",cmd:"mceVisualBlocks",onPostRender:n(e,t),selectable:!0,context:"view",prependToContext:!0})};e.add("visualblocks",function(e,t){var n=o(!1);f(e,t,n),v(e,n),d(e,t,n)})}();
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
.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 rgba(208,2,27,0.5);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:#2276d2 !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2276d2}.mce-content-body *[data-mce-selected="inline-boundary"]{background:#bfe6ff}.mce-content-body .mce-item-anchor[data-mce-selected]{background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-content-body hr{cursor:default}.ephox-snooker-resizer-bar{background-color:#2276d2;opacity:0}.ephox-snooker-resizer-cols{cursor:col-resize}.ephox-snooker-resizer-rows{cursor:row-resize}.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging{opacity:.2}.mce-content-body{line-height:1.3}
|
||||
.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 rgba(208,2,27,0.5);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:#2276d2 !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2276d2}.mce-content-body.mce-content-readonly *[contentEditable=true]:focus,.mce-content-body.mce-content-readonly *[contentEditable=true]:hover{outline:none}.mce-content-body *[data-mce-selected="inline-boundary"]{background:#bfe6ff}.mce-content-body .mce-item-anchor[data-mce-selected]{background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-content-body hr{cursor:default}.mce-content-body table{-webkit-nbsp-mode:normal}.ephox-snooker-resizer-bar{background-color:#2276d2;opacity:0}.ephox-snooker-resizer-cols{cursor:col-resize}.ephox-snooker-resizer-rows{cursor:row-resize}.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging{opacity:.2}.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;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 rgba(208,2,27,0.5);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:#2276d2 !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2276d2}.mce-content-body *[data-mce-selected="inline-boundary"]{background:#bfe6ff}.mce-content-body .mce-item-anchor[data-mce-selected]{background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-content-body hr{cursor:default}.ephox-snooker-resizer-bar{background-color:#2276d2;opacity:0}.ephox-snooker-resizer-cols{cursor:col-resize}.ephox-snooker-resizer-rows{cursor:row-resize}.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging{opacity:.2}
|
||||
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 rgba(208,2,27,0.5);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:#2276d2 !important}.mce-edit-focus{outline:1px dotted #333}.mce-content-body *[contentEditable=false] *[contentEditable=true]:focus{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false] *[contentEditable=true]:hover{outline:2px solid #2276d2}.mce-content-body *[contentEditable=false][data-mce-selected]{outline:2px solid #2276d2}.mce-content-body.mce-content-readonly *[contentEditable=true]:focus,.mce-content-body.mce-content-readonly *[contentEditable=true]:hover{outline:none}.mce-content-body *[data-mce-selected="inline-boundary"]{background:#bfe6ff}.mce-content-body .mce-item-anchor[data-mce-selected]{background:#D5D5D5 url(img/anchor.gif) no-repeat center}.mce-content-body hr{cursor:default}.mce-content-body table{-webkit-nbsp-mode:normal}.ephox-snooker-resizer-bar{background-color:#2276d2;opacity:0}.ephox-snooker-resizer-cols{cursor:col-resize}.ephox-snooker-resizer-rows{cursor:row-resize}.ephox-snooker-resizer-bar.ephox-snooker-resizer-bar-dragging{opacity:.2}
|
||||
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user