Open esmaei1 opened 1 year ago
Has anyone managed to integrate?
Да, вам потребуется написать собственный плагин для ckeditor 5
ckeditor5.blade.php
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'File Manager') }}</title>
<!-- Styles -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.2/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="{{ asset('vendor/file-manager/css/file-manager.css') }}">
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-12" id="fm-main-block">
<div id="fm"></div>
</div>
</div>
</div>
<!-- File manager -->
<script src="{{ asset('vendor/file-manager/js/file-manager.js') }}"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// set fm height
document.getElementById('fm-main-block').setAttribute('style', 'height:' + window.innerHeight + 'px');
fm.$store.commit('fm/setFileCallBack', function(fileUrl) {
const data = {
url: fileUrl
};
window.opener.postMessage(data, document.referrer);
});
window.addEventListener('message', event => {
if (event.origin === new URL(document.referrer).origin) {
alert(event.data);
}
});
});
</script>
</body>
</html>
ckeditor.js
import ClassicEditor from "@ckeditor/ckeditor5-editor-classic/src/classiceditor.js";
import Autoformat from "@ckeditor/ckeditor5-autoformat/src/autoformat.js";
import BlockQuote from "@ckeditor/ckeditor5-block-quote/src/blockquote.js";
import Bold from "@ckeditor/ckeditor5-basic-styles/src/bold.js";
import CloudServices from "@ckeditor/ckeditor5-cloud-services/src/cloudservices.js";
import Essentials from "@ckeditor/ckeditor5-essentials/src/essentials.js";
import FontBackgroundColor from "@ckeditor/ckeditor5-font/src/fontbackgroundcolor.js";
import FontColor from "@ckeditor/ckeditor5-font/src/fontcolor.js";
import FontFamily from "@ckeditor/ckeditor5-font/src/fontfamily.js";
import FontSize from "@ckeditor/ckeditor5-font/src/fontsize.js";
import Heading from "@ckeditor/ckeditor5-heading/src/heading.js";
import Image from "@ckeditor/ckeditor5-image/src/image.js";
import ImageCaption from "@ckeditor/ckeditor5-image/src/imagecaption.js";
import ImageInsert from "@ckeditor/ckeditor5-image/src/imageinsert.js";
import ImageStyle from "@ckeditor/ckeditor5-image/src/imagestyle.js";
import ImageToolbar from "@ckeditor/ckeditor5-image/src/imagetoolbar.js";
import ImageUpload from "@ckeditor/ckeditor5-image/src/imageupload.js";
import Indent from "@ckeditor/ckeditor5-indent/src/indent.js";
import Italic from "@ckeditor/ckeditor5-basic-styles/src/italic.js";
import Link from "@ckeditor/ckeditor5-link/src/link.js";
import List from "@ckeditor/ckeditor5-list/src/list.js";
import MediaEmbed from "@ckeditor/ckeditor5-media-embed/src/mediaembed.js";
import Paragraph from "@ckeditor/ckeditor5-paragraph/src/paragraph.js";
import PasteFromOffice from "@ckeditor/ckeditor5-paste-from-office/src/pastefromoffice.js";
import SourceEditing from "@ckeditor/ckeditor5-source-editing/src/sourceediting.js";
import Table from "@ckeditor/ckeditor5-table/src/table.js";
import TableToolbar from "@ckeditor/ckeditor5-table/src/tabletoolbar.js";
import TextTransformation from "@ckeditor/ckeditor5-typing/src/texttransformation.js";
import TodoList from "@ckeditor/ckeditor5-list/src/todolist";
import GeneralHtmlSupport from "@ckeditor/ckeditor5-html-support/src/generalhtmlsupport.js";
import FileManager from "./FileManager";
import {
ImageResizeEditing,
ImageResizeHandles,
} from "@ckeditor/ckeditor5-image";
class Editor extends ClassicEditor {}
// Plugins to include in the build.
Editor.builtinPlugins = [
// Autoformat,
BlockQuote,
Bold,
CloudServices,
Essentials,
FontBackgroundColor,
FontColor,
FontFamily,
FontSize,
GeneralHtmlSupport,
Heading,
Image,
ImageCaption,
ImageInsert,
ImageStyle,
ImageToolbar,
ImageUpload,
ImageResizeEditing,
ImageResizeHandles,
Indent,
Italic,
Link,
List,
MediaEmbed,
Paragraph,
PasteFromOffice,
SourceEditing,
Table,
TableToolbar,
TextTransformation,
TodoList,
FileManager,
];
Editor.defaultConfig = {
toolbar: {
items: [
"heading",
"|",
"undo",
"redo",
"|",
"bold",
"italic",
"fontFamily",
"fontSize",
"fontBackgroundColor",
"fontColor",
"|",
"todoList",
"bulletedList",
"numberedList",
"|",
"outdent",
"indent",
"|",
"link",
"imageInsert",
"mediaEmbed",
"blockQuote",
"insertTable",
"|",
"fileManager",
"|",
"sourceEditing",
],
},
language: "ru",
image: {
toolbar: [
"imageTextAlternative",
"imageStyle:inline",
"imageStyle:block",
"imageStyle:side",
],
},
table: {
contentToolbar: ["tableColumn", "tableRow", "mergeTableCells"],
},
htmlSupport: {
allow: [
{
name: /.*/,
attributes: true,
classes: true,
styles: true,
},
],
},
licenseKey: "",
};
export default Editor;
FileManager.js
import ButtonView from "@ckeditor/ckeditor5-ui/src/button/buttonview";
import Plugin from "@ckeditor/ckeditor5-core/src/plugin";
import BrowseFilesIcon from "./icons/browse-files.svg";
import extToMime from "./extToMime";
export default class FileManager extends Plugin {
init() {
const editor = this.editor;
let popupWindow = null;
// register toolbar button
editor.ui.componentFactory.add("fileManager", () => {
const button = new ButtonView();
button.set({
label: "Файловый менеджер",
icon: BrowseFilesIcon,
withText: true,
});
button.on("execute", handleButtonClick);
return button;
});
// subscribe to messages from popup
window.addEventListener("message", handlePopupMessage);
function handleButtonClick(e) {
const { w, h, x, y } = calculatePopupSize();
const settings = `toolbar=no, width=${w}, height=${h}, top=${y}, left=${x}`;
popupWindow = window.open(window.urls.fileManager, "fm", settings);
}
function handlePopupMessage(e) {
const popupOrigin = new URL(window.urls.fileManager).origin;
if (e.origin !== popupOrigin) return;
const TEXT_NO_SUPPORT = "Ваш браузер не поддерживает";
const fileUrl = e.data.url;
const fileExtension = fileUrl.split(".").reverse()[0].toLowerCase();
const fileMimeType = extToMime["." + fileExtension];
let html = "";
if (isImage(fileMimeType)) {
html = `<img src="${fileUrl}" />`;
} else if (isVideo(fileMimeType)) {
html = `<video width="640" height="360" controls>
<source src="${fileUrl}" type="${fileMimeType}">
${TEXT_NO_SUPPORT} видео. <a href="${fileUrl}">Скачать видеозапись</a>
</video>`;
} else if (isAudio(fileMimeType)) {
html = `<audio controls>
<source src="${fileUrl}" type="${fileMimeType}">
${TEXT_NO_SUPPORT} аудио. <a href="${fileUrl}">Скачать аудиозапись</a>
</audio>`;
} else if (isPdf(fileMimeType)) {
html = `
<object data="${fileUrl}" type="application/pdf" width="700" height="1050">
${TEXT_NO_SUPPORT} PDF. <a href="${fileUrl}">Скачать PDF</a>
</object>`;
} else {
html = `<a href="${fileUrl}">${fileUrl}</a>`;
}
const viewFragment = editor.data.processor.toView(html);
const modelFragment = editor.data.toModel(viewFragment);
editor.model.insertContent(modelFragment);
popupWindow.close();
}
function calculatePopupSize() {
const w = 1050;
const h = 650;
const x = window.top.outerWidth / 2 + window.top.screenX - w / 2;
const y = window.top.outerHeight / 2 + window.top.screenY - h / 2;
return { w, h, x, y };
}
function isImage(mimeType) {
return mimeType && mimeType.split("/")[0] === "image";
}
function isVideo(mimeType) {
return mimeType && mimeType.split("/")[0] === "video";
}
function isAudio(mimeType) {
return mimeType && mimeType.split("/")[0] === "audio";
}
function isPdf(mimeType) {
return mimeType === "application/pdf";
}
}
}
extToMime.js
const extToMime = {
".mp4": "video/mp4",
".webm": "video/webm",
".ogg": "video/ogg",
".qt": "video/quicktime",
".mov": "video/quicktime",
".avi": "video/x-msvideo",
".aac": "audio/aac",
".aiff": "audio/aiff",
".amr": "audio/amr",
".au": "audio/basic",
".flac": "audio/flac",
".m4a": "audio/mp4",
".mid": "audio/midi",
".mp3": "audio/mpeg",
".ogg": "audio/ogg",
".wav": "audio/wav",
".wma": "audio/x-ms-wma",
".bmp": "image/bmp",
".gif": "image/gif",
".jpeg": "image/jpeg",
".jpg": "image/jpeg",
".png": "image/png",
".svg": "image/svg+xml",
".webp": "image/webp",
".heic": "image/heic",
".heif": "image/heif",
".ico": "image/vnd.microsoft.icon",
".pdf": "application/pdf",
};
export default extToMime;
icons/browse-files.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M11.627 16.5zm5.873-.196zm0-7.001V8h-13v8.5h4.341c.191.54.457 1.044.785 1.5H2a1.5 1.5 0 0 1-1.5-1.5v-13A1.5 1.5 0 0 1 2 2h4.5a1.5 1.5 0 0 1 1.06.44L9.122 4H16a1.5 1.5 0 0 1 1.5 1.5v1A1.5 1.5 0 0 1 19 8v2.531a6.027 6.027 0 0 0-1.5-1.228zM16 6.5v-1H8.5l-2-2H2v13h1V8a1.5 1.5 0 0 1 1.5-1.5H16z"/><path d="M14.5 19.5a5 5 0 1 1 0-10 5 5 0 0 1 0 10zM15 14v-2h-1v2h-2v1h2v2h1v-2h2v-1h-2z"/></svg>
routes/filemanager.php
<?php
use Alexusmai\LaravelFileManager\Services\ConfigService\ConfigRepository;
use App\Http\Controllers\FilemanagerController;
use Illuminate\Support\Facades\Route;
$config = resolve(ConfigRepository::class);
$middleware = $config->getMiddleware();
if ($config->getAcl()) {
$middleware[] = 'fm-acl';
}
Route::group([
'middleware' => $middleware,
'prefix' => $config->getRoutePrefix()
], function () {
Route::get('ckeditor5', [FilemanagerController::class, 'ckeditor5'])
->name('fm.ckeditor5');
});
RouteServiceProvider.php
...
public function boot(): void
{
...
Route::middleware(config('file-manager.middleware'))
->group(base_path('routes/filemanager.php'));
});
}
...
FilemanagerController.php
<?php
namespace App\Http\Controllers;
use Alexusmai\LaravelFileManager\Controllers\FileManagerController as BaseFileManagerController;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
class FilemanagerController extends BaseFileManagerController
{
public function ckeditor5(): Factory|View
{
return view('file-manager::ckeditor5');
}
}
AppServiceProvider.php
<?php
declare(strict_types=1);
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
final class AppServiceProvider extends ServiceProvider
{
public function boot(): void
{
...
$this->app->bind(\Alexusmai\LaravelFileManager\Controllers\FileManagerController::class, \App\Http\Controllers\FilemanagerController::class);
}
}
там где будете выводить редактор
window.urls = {
fileManager: 'ваш хост/ckeditor5',
};
это можно было бы включить в сам пакет, но инициализация ckeditor 5, требует свой собственный билд, для добавления своего плагина
Is it possible to integrate with ckeditor 5?