Separate editor and uploader related PHP and JS code into their own native files

This commit is contained in:
Kijin Sung 2024-04-30 01:42:37 +09:00
parent d127e334b0
commit 579201fe7c
5 changed files with 308 additions and 245 deletions

View file

@ -0,0 +1,83 @@
@php
// Basic configuration
$ckconfig = new \stdClass;
$ckconfig->skin = $colorset;
$ckconfig->auto_dark_mode = $editor_auto_dark_mode ?? false;
$ckconfig->legacy_html_mode = $html_mode ?? false;
$ckconfig->language = str_replace('jp', 'ja', Context::getLangType());
$ckconfig->height = $editor_height ?? 100;
$ckconfig->toolbar = $editor_toolbar ?? 'default';
$ckconfig->hide_toolbar = $editor_toolbar_hide ?? false;
$ckconfig->focus = $editor_focus ?? false;
$ckconfig->ios_patch = (bool)preg_match('/i(Phone|Pad|Pod)/', $_SERVER['HTTP_USER_AGENT'] ?? '');
// Plugin configuration
$ckconfig->add_plugins = $editor_additional_plugins ?? [];
$ckconfig->remove_plugins = $editor_remove_plugins ?? [];
$ckconfig->add_plugins[] = 'rx_upload';
if ($ckconfig->ios_patch) {
$ckconfig->add_plugins[] = 'divarea';
$ckconfig->add_plugins[] = 'ios_enterkey';
$ckconfig->remove_plugins[] = 'enterkey';
}
// Font configuration
$ckconfig->default_font = $content_font ?: 'none';
$ckconfig->default_font_size = intval(preg_replace('/\D/', '', $content_font_size ?? '13'), 10);
$ckconfig->fonts = array_values(array_map('strval', $lang->edit->fontlist ?: []));
$ckconfig->font_sizes = [8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 24, 28, 32, 36, 40, 48];
if (!in_array($ckconfig->default_font, $ckconfig->fonts) && $ckconfig->default_font !== 'none') {
array_unshift($ckconfig->fonts, $ckconfig->default_font);
}
if (!in_array($ckconfig->default_font_size, $ckconfig->font_sizes)) {
$ckconfig->font_sizes[] = $ckconfig->default_font_size;
sort($ckconfig->font_sizes);
}
foreach ($ckconfig->fonts as &$_font_name) {
$_font_name = trim(array_first(explode(',', $_font_name, 2))) . '/' . $_font_name;
}
foreach ($ckconfig->font_sizes as &$_font_size) {
$_font_size = $_font_size . '/' . $_font_size . 'px';
}
// CSS configuration
$ckconfig->css_files = array_values($editor_additional_css ?: []);
$ckconfig->css_content = '';
$ckconfig->css_vars = (object)[
'colorset' => $colorset,
'content_font' => $content_font ?: 'none',
'content_font_size' => $content_font_size ?: '13',
'content_line_height' => $content_line_height ?: 'none',
'content_word_break' => $content_word_break ?: 'none',
'content_paragraph_spacing' => $content_paragraph_spacing ?: 'none',
];
// Legacy editor component configuration
$ckconfig->enable_component = $enable_component ?? false;
$ckconfig->enable_default_component = $enable_default_component ?? false;
$ckconfig->components = [];
foreach ($component_list ?? [] as $component_name => $component) {
$ckconfig->components[$component_name] = escape($component->title, false);
}
// Cache-busting timestamp
$ckconfig->custom_config_exists = file_exists(RX_BASEDIR . 'common/js/plugins/ckeditor/ckeditor/config.js');
$_filemtime1 = filemtime(RX_BASEDIR . 'common/js/plugins/ckeditor/ckeditor/ckeditor.js');
$_filemtime2 = $ckconfig->custom_config_exists ? filemtime(RX_BASEDIR . 'common/js/plugins/ckeditor/ckeditor/config.js') : 0;
$ckconfig->timestamp = max($_filemtime1, $_filemtime2, $ckconfig_timestamp ?? 0);
// Set initial min-height to prevent layout shift when editor is loaded.
if ($editor_toolbar_hide) {
$ckconfig->initial_height = $editor_height + 55;
} elseif ($editor_toolbar === 'simple') {
$ckconfig->initial_height = $editor_height + 71;
} else {
$ckconfig->initial_height = $editor_height + 137;
}
if (str_contains($_SERVER['HTTP_USER_AGENT'] ?? '', 'Firefox/')) {
$ckconfig->initial_height += 2;
}
@endphp

View file

@ -1,42 +1,17 @@
<config autoescape="on" />
<!--// Configuration -->
{@
$css_var = new stdClass;
$css_var->colorset = $colorset;
$css_var->content_font = $content_font ?: 'none';
$css_var->content_font_size = $content_font_size ?: 'none';
$css_var->content_line_height = $content_line_height ?: 'none';
$css_var->content_word_break = $content_word_break ?: 'none';
$css_var->content_paragraph_spacing = $content_paragraph_spacing ?: 'none';
<include target="config.blade.php" />
$css_file_list = array_values($editor_additional_css ?: []);
$css_content = '';
<!--// CSS -->
<load target="css/ckeditor.scss" vars="$ckconfig->css_vars" />
<load target="^/common/css/xeicon/xeicon.min.css" />
$filemtime1 = filemtime(RX_BASEDIR . 'common/js/plugins/ckeditor/ckeditor/ckeditor.js');
$filemtime2 = file_exists(RX_BASEDIR . 'common/js/plugins/ckeditor/ckeditor/config.js') ? filemtime(RX_BASEDIR . 'common/js/plugins/ckeditor/ckeditor/config.js') : 0;
$filemtimestamp = max($filemtime1, $filemtime2, $editor_config_timestamp ?? 0);
// Start with fixed min-height to prevent layout shift when editor is loaded.
if ($editor_toolbar_hide):
$editor_height_fixed = $editor_height + 55;
elseif ($editor_toolbar === 'simple'):
$editor_height_fixed = $editor_height + 71;
else:
$editor_height_fixed = $editor_height + 137;
endif;
if (str_contains($_SERVER['HTTP_USER_AGENT'], 'Firefox/')):
$editor_height_fixed += 2;
endif;
}
<!-- CSS -->
<load target="css/ckeditor.scss" vars="$css_var" />
<load target="../../../../common/css/xeicon/xeicon.min.css" />
<!-- JS -->
<!--// JS -->
<!--%load_js_plugin("ckeditor")-->
<load target="../../tpl/js/editor_common.js" />
<load target="../../tpl/js/editor.app.js" />
<load target="js/editor.js" />
<load target="js/xe_interface.js" />
<script>
@ -44,192 +19,25 @@
</script>
<!--@if($enable_autosave)-->
<input type="hidden" name="_saved_doc_title" value="{(isset($saved_doc) && $saved_doc) ? escape($saved_doc->title) : ''}" />
<input type="hidden" name="_saved_doc_content" value="{(isset($saved_doc) && $saved_doc) ? escape($saved_doc->content) : ''}" />
<input type="hidden" name="_saved_doc_document_srl" value="{(isset($saved_doc) && $saved_doc) ? $saved_doc->document_srl : ''}" />
<input type="hidden" name="_saved_doc_title" value="{empty($saved_doc) ? '' : $saved_doc->title|escape}" />
<input type="hidden" name="_saved_doc_content" value="{empty($saved_doc) ? '' : $saved_doc->content|escape}" />
<input type="hidden" name="_saved_doc_document_srl" value="{empty($saved_doc) ? '' : $saved_doc->document_srl}" />
<input type="hidden" name="_saved_doc_message" value="{$lang->msg_load_saved_doc}" />
<!--@end-->
<div id="ckeditor_instance_{$editor_sequence}" class="rx_ckeditor" data-editor-sequence="{$editor_sequence}" data-editor-primary-key-name="{$editor_primary_key_name}" data-editor-content-key-name="{$editor_content_key_name}" style="min-height:{$editor_height_fixed}px;"></div>
<!--// Main Editor Area -->
<div id="ckeditor_instance_{$editor_sequence}" class="rx_ckeditor"
data-editor-sequence="{$editor_sequence}"
data-editor-primary-key-name="{$editor_primary_key_name}"
data-editor-content-key-name="{$editor_content_key_name}"
data-editor-config="{json_encode($ckconfig)|escape}"
style="min-height:{$ckconfig->initial_height}px;">
</div>
<p cond="$enable_autosave" class="editor_autosaved_message autosave_message" id="editor_autosaved_message_{$editor_sequence}">&nbsp;</p>
<!--@if($enable_autosave)-->
<p id="editor_autosaved_message_{$editor_sequence}" class="editor_autosaved_message autosave_message">&nbsp;</p>
<!--@endif-->
<block cond="$allow_fileupload">
<include target="file_upload.html" />
</block>
<script>
jQuery(function($){
"use strict";
<!--@if(!$filemtime2)-->CKEDITOR.config.customConfig = '';<!--@endif-->
// Import CSS content from PHP.
var css_content = {json_encode($css_content)};
// Get default font name and list of other supported fonts.
var default_font_name = {json_encode($content_font ? trim(array_first(explode(',', $content_font)), '\'" ') : null)};
var default_font_fullname = {json_encode($content_font ?: null)};
if (default_font_fullname === null && window.getComputedStyle) {
var test_content = $('<div class="rhymix_content xe_content"></div>').hide().appendTo($(document.body));
var test_styles = window.getComputedStyle(test_content[0], null);
if (test_styles && test_styles.getPropertyValue) {
default_font_fullname = test_styles.getPropertyValue("font-family");
if (default_font_fullname) {
default_font_name = $.trim(default_font_fullname.split(',')[0].replace(/['"]/g, ''));
css_content = ".rhymix_content.editable { font-family:" + default_font_fullname + "; } " + css_content;
}
}
}
var font_list = [];
<!--@foreach($lang->edit->fontlist as $fontname)-->
font_list.push({json_encode(strval($fontname))});
<!--@endforeach-->
if (default_font_fullname !== null && !$.inArray(default_font_fullname, font_list)) {
font_list.push(default_font_fullname);
}
font_list = $.map(font_list, function(val) {
return $.trim(val.split(",")[0]) + "/" + val;
}).join(";");
// Get default font size and list of other supported sizes.
var default_font_size = {json_encode(strval($content_font_size ?: '13'))};
default_font_size = parseInt(default_font_size.replace(/\D/, ''), 10);
var font_sizes = [8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 24, 28, 32, 36, 40, 48];
if (!$.inArray(default_font_size, font_sizes)) {
font_sizes.push(default_font_size);
font_sizes.sort();
}
font_sizes = $.map(font_sizes, function(val) {
return val + "/" + val + "px";
}).join(";");
// Apply auto dark mode.
var editor_skin = '{$colorset}';
var editor_color = null;
<!--@if($editor_auto_dark_mode)-->
$('body').addClass('cke_auto_dark_mode');
if (getColorScheme() === 'dark') {
if (editor_skin !== 'moono-lisa' ) {
editor_skin = 'moono-dark';
}
}
<!--@endif-->
// Initialize CKEditor settings.
var settings = {
ckeconfig: {
height: '{$editor_height}',
skin: editor_skin,
contentsCss: {json_encode($css_file_list)},
xe_editor_sequence: {$editor_sequence},
font_defaultLabel: default_font_name,
font_names: font_list,
fontSize_defaultLabel: default_font_size,
fontSize_sizes: font_sizes,
toolbarCanCollapse: true,
allowedContent: true,
startupFocus: {json_encode($editor_focus)},
language: "{str_replace('jp','ja',$lang_type)}",
iframe_attributes: {},
versionCheck: false
},
loadXeComponent: true,
enableToolbar: true
};
// Add style-sheet for the WYSIWYG
$(document.getElementsByTagName('link')).each(function() {
if ($(this).attr('rel') == 'stylesheet') {
settings.ckeconfig.contentsCss.push($(this).attr('href'));
}
});
// Prevent removal of icon fonts and Google code.
CKEDITOR.dtd.$removeEmpty.i = 0;
CKEDITOR.dtd.$removeEmpty.ins = 0;
// Set the timestamp for plugins.
CKEDITOR.timestamp = '{$filemtimestamp}';
// Add editor components.
<!--@if($enable_component)-->
{@ $xe_component = array(); }
<!--@foreach($component_list as $component_name => $component)-->
{@ $xe_component[$component_name] = escape($component->title, false)}
<!--@endforeach-->
settings.ckeconfig.xe_component_arrays = {json_encode($xe_component)};
<!--@else-->
settings.ckeconfig.xe_component_arrays = {};
<!--@endif-->
<!--@if(!$enable_default_component)-->
settings.enableToolbar = false;
settings.ckeconfig.toolbarCanCollapse = false;
<!--@endif-->
<!--@if(!$enable_component)-->
settings.loadXeComponent = false;
<!--@endif-->
// Set default toolbar status.
settings.ckeconfig.toolbarStartupExpanded = {$editor_toolbar_hide ? 'false' : 'true'};
// Add or remove plugins based on Rhymix configuration.
{@ $editor_additional_plugins[] = 'rx_upload'}
<!--@if($editor_additional_plugins)-->
settings.ckeconfig.extraPlugins = {json_encode(implode(',', $editor_additional_plugins))};
<!--@endif-->
<!--@if($editor_remove_plugins)-->
settings.ckeconfig.removePlugins = {json_encode(implode(',', $editor_remove_plugins))};
<!--@endif-->
// https://github.com/rhymix/rhymix/issues/932
if (CKEDITOR.env.iOS) {
settings.ckeconfig.extraPlugins = (settings.ckeconfig.extraPlugins ? (settings.ckeconfig.extraPlugins + ',') : '') + 'divarea,ios_enterkey';
settings.ckeconfig.removePlugins = (settings.ckeconfig.removePlugins ? (settings.ckeconfig.removePlugins + ',') : '') + 'enterkey';
settings.loadXeComponent = false;
var additional_styles = '.cke_wysiwyg_div { padding: 8px !important; }';
additional_styles += 'html { min-width: unset; min-height: unset; width: unset; height: unset; margin: unset; padding: unset; }';
$('head').append('<st' + 'yle>' + additional_styles + String(css_content).replace(/\.rhymix_content\.editable/g, '.cke_wysiwyg_div') + '</st' + 'yle>');
}
// Define the simple toolbar.
<!--@if($editor_toolbar === 'simple')-->
CKEDITOR.toolbarMode = 'simple';
settings.ckeconfig.toolbar = [
{ name: 'styles', items: [ 'Font', 'FontSize', '-', 'Bold', 'Italic', 'Underline', 'Strike', 'TextColor', 'BGColor' ] },
{ name: 'paragraph', items: [ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ] },
{ name: 'clipboard', items: [ 'Cut', 'Copy', 'Paste' ] },
{ name: 'insert', items: [ 'Link', 'Image', 'Table' ] },
{ name: 'tools', items: [ 'Maximize', '-', 'Source' ] }
];
<!--@else-->
CKEDITOR.toolbarMode = 'default';
<!--@endif-->
<!--@if(!$html_mode)-->
settings.ckeconfig.removeButtons = 'Save,Preview,Print,Cut,Copy,Paste,Source';
<!--@endif-->
CKEDITOR.addCss(css_content);
// Initialize CKEditor.
var ckeApp = $('#ckeditor_instance_{$editor_sequence}').XeCkEditor(settings);
// Add use_editor and use_html fields to parent form.
var parentform = $('#ckeditor_instance_{$editor_sequence}').closest('form');
var use_editor = parentform.find("input[name='use_editor']");
var use_html = parentform.find("input[name='use_html']");
if (use_editor.length) {
use_editor.val("Y");
} else {
parentform.append('<input type="hidden" name="use_editor" value="Y" />');
}
if (use_html.length) {
use_html.val("Y");
} else {
parentform.append('<input type="hidden" name="use_html" value="Y" />');
}
});
</script>
<!--@if($allow_fileupload)-->
<include target="file_upload.html" />
<!--@endif-->

View file

@ -1,10 +1,12 @@
<config autoescape="on" />
<load target="./lang" />
<!--%load_js_plugin("jquery.fileupload")-->
<!--%load_js_plugin("jquery.finderSelect")-->
<!--%load_js_plugin("handlebars")-->
<load target="./lang" />
<load target="js/file_upload.js" />
<div cond="$allow_fileupload" id="xefu-container-{$editor_sequence}" class="xefu-container xe-clearfix"
data-editor-sequence="{$editor_sequence}"
data-editor-status="{json_encode(FileModel::getInstance()->getFileList($editor_sequence), JSON_UNESCAPED_UNICODE)}"
@ -56,31 +58,10 @@
</div>
<script>
jQuery(function($){
var container = $('#xefu-container-{$editor_sequence}');
if (container.length) {
container.data('instance', container.xeUploader({
maxFileSize: parseInt(container.data('maxFileSize'), 10),
maxChunkSize: parseInt(container.data('maxChunkSize'), 10),
autoinsertTypes: container.data('autoinsertTypes'),
autoinsertPosition: container.data('autoinsertPosition'),
singleFileUploads: true
}));
}
window.xe.msg_exceeds_limit_size = '{$lang->msg_exceeds_limit_size}';
window.xe.msg_checked_file_is_deleted = '{$lang->msg_checked_file_is_deleted}';
window.xe.msg_file_cart_is_null = '{$lang->msg_file_cart_is_null}';
window.xe.msg_checked_file_is_deleted = '{$lang->msg_checked_file_is_deleted}';
window.xe.msg_not_allowed_filetype = '{$lang->msg_not_allowed_filetype}';
window.xe.msg_file_upload_error = '{$lang->msg_file_upload_error}';
});
function reloadUploader(editor_sequence) {
var container = $('#xefu-container-' + editor_sequence);
if (container.length) {
container.data('instance').loadFilelist(container);
}
}
window.xe.msg_exceeds_limit_size = '{$lang->msg_exceeds_limit_size}';
window.xe.msg_checked_file_is_deleted = '{$lang->msg_checked_file_is_deleted}';
window.xe.msg_file_cart_is_null = '{$lang->msg_file_cart_is_null}';
window.xe.msg_checked_file_is_deleted = '{$lang->msg_checked_file_is_deleted}';
window.xe.msg_not_allowed_filetype = '{$lang->msg_not_allowed_filetype}';
window.xe.msg_file_upload_error = '{$lang->msg_file_upload_error}';
</script>

View file

@ -0,0 +1,162 @@
'use strict';
/**
* Initialize each instance of CKEditor on the page.
*/
$(function() {
$('.rx_ckeditor').each(function() {
// Load editor configuration.
const container = $(this);
const form = container.closest('form');
const editor_sequence = parseInt(container.data('editorSequence'), 10);
const config = container.data('editorConfig');
// Apply auto dark mode.
if (config.auto_dark_mode) {
$('body').addClass('cke_auto_dark_mode');
if (getColorScheme() === 'dark') {
if (config.skin !== 'moono-lisa') {
config.skin = 'moono-dark';
}
}
}
// If the default font is not set, use the browser default font.
if (config.default_font === 'none' && window.getComputedStyle) {
let test_content = $('<div class="rhymix_content xe_content"></div>').hide().appendTo($(document.body));
let test_styles = window.getComputedStyle(test_content[0], null);
if (test_styles && test_styles.getPropertyValue) {
default_font = test_styles.getPropertyValue('font-family');
if (default_font) {
config.default_font = $.trim(default_font.split(',')[0].replace(/['"]/g, ''));
config.css_content = '.rhymix_content.editable { font-family:' + default_font + '; } ' + config.css_content;
}
}
}
// Define the initial structure for CKEditor settings.
const settings = {
ckeconfig: {
height: config.height,
skin: config.skin,
contentsCss: config.css_files,
font_defaultLabel: config.default_font,
font_names: config.fonts.join(';'),
fontSize_defaultLabel: config.default_font_size,
fontSize_sizes: config.font_sizes.join(';'),
toolbarStartupExpanded: !config.hide_toolbar,
toolbarCanCollapse: true,
allowedContent: true,
startupFocus: config.focus,
language: config.language,
iframe_attributes: {},
versionCheck: false,
xe_editor_sequence: editor_sequence
},
loadXeComponent: true,
enableToolbar: true
};
// Add stylesheets from the current document.
$('link[rel=stylesheet]').each(function() {
settings.ckeconfig.contentsCss.push($(this).attr('href'));
});
// Add and remove plugins.
if (config.add_plugins) {
settings.ckeconfig.extraPlugins = config.add_plugins.join(',');
}
if (config.remove_plugins) {
settings.ckeconfig.removePlugins = config.remove_plugins.join(',');
}
// Add editor components.
if (config.enable_component) {
settings.ckeconfig.xe_component_arrays = config.components;
} else {
settings.ckeconfig.xe_component_arrays = {};
settings.loadXeComponent = false;
}
if (!config.enable_default_component) {
settings.enableToolbar = false;
settings.ckeconfig.toolbarCanCollapse = false;
}
// Patch for iOS: https://github.com/rhymix/rhymix/issues/932
if (config.ios_patch) {
settings.loadXeComponent = false;
$('head').append('<style>'
+ '.cke_wysiwyg_div { padding: 8px !important; }'
+ 'html { min-width: unset; min-height: unset; width: unset; height: unset; margin: unset; padding: unset; }'
+ config.css_content.replace(/\.rhymix_content\.editable/g, '.cke_wysiwyg_div')
+ '</style>'
);
}
// Define the simple toolbar.
if (config.toolbar === 'simple') {
settings.ckeconfig.toolbar = [
{ name: 'styles', items: [ 'Font', 'FontSize', '-', 'Bold', 'Italic', 'Underline', 'Strike', 'TextColor', 'BGColor' ] },
{ name: 'paragraph', items: [ 'JustifyLeft', 'JustifyCenter', 'JustifyRight' ] },
{ name: 'clipboard', items: [ 'Cut', 'Copy', 'Paste' ] },
{ name: 'insert', items: [ 'Link', 'Image', 'Table' ] },
{ name: 'tools', items: [ 'Maximize', '-', 'Source' ] }
];
}
// Support legacy HTML (full editing) mode.
if (!config.legacy_html_mode) {
settings.ckeconfig.removeButtons = 'Save,Preview,Print,Cut,Copy,Paste,Source';
}
// Disable loading of custom configuration if config.js does not exist.
if (!config.custom_config_exists) {
CKEDITOR.config.customConfig = '';
}
// Prevent removal of icon fonts and Google code.
CKEDITOR.dtd.$removeEmpty.i = 0;
CKEDITOR.dtd.$removeEmpty.ins = 0;
// Set the cache-busting timestamp for plugins.
CKEDITOR.timestamp = config.timestamp;
// Set the custom CSS content.
CKEDITOR.addCss(config.css_content);
// Initialize the CKEditor XE app.
const ckeApp = container.XeCkEditor(settings);
// Add use_editor and use_html fields to the parent form.
const use_editor = form.find('input[name=use_editor]');
const use_html = form.find('input[name=use_html]');
if (use_editor.length) {
use_editor.val('Y');
} else {
form.append('<input type="hidden" name="use_editor" value="Y" />');
}
if (use_html.length) {
use_html.val('Y');
} else {
form.append('<input type="hidden" name="use_html" value="Y" />');
}
});
});
/**
* This function is only retained for backward compatibility.
* Do not depend on it for any reason.
*/
function ckInsertUploadedFile() {
if (typeof console == "object" && typeof console.warn == "function") {
const msg = "DEPRECATED : ckInsertUploadedFile() is obsolete in Rhymix.";
if (navigator.userAgent.match(/Firefox/)) {
console.error(msg);
} else {
console.warn(msg);
}
}
}

View file

@ -0,0 +1,29 @@
'use strict';
/**
* Initialize each instance of file uploader on the page.
*/
$(function() {
$('.xefu-container').each(function() {
const container = $(this);
const data = container.data();
container.data('instance', container.xeUploader({
maxFileSize: parseInt(data.maxFileSize, 10),
maxChunkSize: parseInt(data.maxChunkSize, 10),
autoinsertTypes: data.autoinsertTypes,
autoinsertPosition: data.autoinsertPosition,
singleFileUploads: true
}));
});
});
/**
* This function is only retained for backward compatibility.
* Do not depend on it for any reason.
*/
function reloadUploader(editor_sequence) {
var container = $('#xefu-container-' + editor_sequence);
if (container.length) {
container.data('instance').loadFilelist(container);
}
}