export {UserSelect} from './user-select';
export {WebhookEvents} from './webhook-events';
export {WysiwygEditor} from './wysiwyg-editor';
+export {WysiwygInput} from './wysiwyg-input';
-import {build as buildEditorConfig} from '../wysiwyg/config';
+import {buildForEditor as buildEditorConfig} from '../wysiwyg/config';
import {Component} from './component';
export class WysiwygEditor extends Component {
setup() {
this.elem = this.$el;
- this.pageId = this.$opts.pageId;
- this.textDirection = this.$opts.textDirection;
- this.isDarkMode = document.documentElement.classList.contains('dark-mode');
-
this.tinyMceConfig = buildEditorConfig({
language: this.$opts.language,
containerElement: this.elem,
- darkMode: this.isDarkMode,
- textDirection: this.textDirection,
+ darkMode: document.documentElement.classList.contains('dark-mode'),
+ textDirection: this.$opts.textDirection,
drawioUrl: this.getDrawIoUrl(),
- pageId: Number(this.pageId),
+ pageId: Number(this.$opts.pageId),
translations: {
imageUploadErrorText: this.$opts.imageUploadErrorText,
serverUploadLimitText: this.$opts.serverUploadLimitText,
--- /dev/null
+import {Component} from './component';
+import {buildForInput} from '../wysiwyg/config';
+
+export class WysiwygInput extends Component {
+
+ setup() {
+ this.elem = this.$el;
+
+ const config = buildForInput({
+ language: this.$opts.language,
+ containerElement: this.elem,
+ darkMode: document.documentElement.classList.contains('dark-mode'),
+ textDirection: this.textDirection,
+ translations: {
+ imageUploadErrorText: this.$opts.imageUploadErrorText,
+ serverUploadLimitText: this.$opts.serverUploadLimitText,
+ },
+ translationMap: window.editor_translations,
+ });
+
+ window.tinymce.init(config).then(editors => {
+ this.editor = editors[0];
+ });
+ }
+
+}
* @param {WysiwygConfigOptions} options
* @return {Object}
*/
-export function build(options) {
+export function buildForEditor(options) {
// Set language
window.tinymce.addI18n(options.language, options.translationMap);
};
}
+/**
+ * @param {WysiwygConfigOptions} options
+ * @return {RawEditorOptions}
+ */
+export function buildForInput(options) {
+ // Set language
+ window.tinymce.addI18n(options.language, options.translationMap);
+
+ // BookStack Version
+ const version = document.querySelector('script[src*="/dist/app.js"]').getAttribute('src').split('?version=')[1];
+
+ // Return config object
+ return {
+ width: '100%',
+ height: '300px',
+ target: options.containerElement,
+ cache_suffix: `?version=${version}`,
+ content_css: [
+ window.baseUrl('/dist/styles.css'),
+ ],
+ branding: false,
+ skin: options.darkMode ? 'tinymce-5-dark' : 'tinymce-5',
+ body_class: 'page-content',
+ browser_spellcheck: true,
+ relative_urls: false,
+ language: options.language,
+ directionality: options.textDirection,
+ remove_script_host: false,
+ document_base_url: window.baseUrl('/'),
+ end_container_on_empty_block: true,
+ remove_trailing_brs: false,
+ statusbar: false,
+ menubar: false,
+ plugins: 'link autolink',
+ contextmenu: false,
+ toolbar: 'bold italic underline link',
+ content_style: getContentStyle(options),
+ color_map: colorMap,
+ init_instance_callback(editor) {
+ const head = editor.getDoc().querySelector('head');
+ head.innerHTML += fetchCustomHeadContent();
+ },
+ setup(editor) {
+ //
+ },
+ };
+}
+
/**
* @typedef {Object} WysiwygConfigOptions
* @property {Element} containerElement
+@push('head')
+ <script src="{{ versioned_asset('libs/tinymce/tinymce.min.js') }}" nonce="{{ $cspNonce }}"></script>
+@endpush
{{ csrf_field() }}
<div class="form-group title-input">
<div class="form-group description-input">
<label for="description">{{ trans('common.description') }}</label>
@include('form.textarea', ['name' => 'description'])
+
+ <textarea component="wysiwyg-input"
+ option:wysiwyg-input:language="{{ $locale->htmlLang() }}"
+ option:wysiwyg-input:text-direction="{{ $locale->htmlDirection() }}"
+ id="description_html" name="description_html" rows="5"
+ @if($errors->has('description_html')) class="text-neg" @endif>@if(isset($model) || old('description_html')){{ old('description_html') ? old($name) : $model->description_html}}@endif</textarea>
+ @if($errors->has('description_html'))
+ <div class="text-neg text-small">{{ $errors->first('description_html') }}</div>
+ @endif
</div>
<div class="form-group collapsible" component="collapsible" id="logo-control">
<button type="submit" class="button">{{ trans('entities.books_save') }}</button>
</div>
-@include('entities.selector-popup', ['entityTypes' => 'page', 'selectorEndpoint' => '/search/entity-selector-templates'])
\ No newline at end of file
+@include('entities.selector-popup', ['entityTypes' => 'page', 'selectorEndpoint' => '/search/entity-selector-templates'])
+@include('form.editor-translations')
\ No newline at end of file
<div class="text-neg text-small">{{ $errors->first('html') }}</div>
@endif
-@include('pages.parts.editor-translations')
\ No newline at end of file
+@include('form.editor-translations')
\ No newline at end of file