Bug 30474: (follow-up) Tie editor initialization to tab activation
The way Bootstrap tabs manipulate the DOM, CodeMirror has problems initializing correctly, I think because of redraws and CodeMirror's attemps to position things absolutely. The solution seems to be to wait until after a Bootstrap tab has activated before initializing the CodeMirror instance. This patch implements that, along with a check to prevent double-initializing the same textarea. I've also made a similar change to the way TinyMCE is initialized, which I hope will help with the issue of the editor not always loading correctly. To test, apply the patch and go to Tools -> HTML customizations. - Test creation and editing of HTML customization entries using both the default editor and the text editor (Edit -> Edit with text editor). - Verify that the editor (CodeMirror or TinyMCE) loads correctly and looks correct, both upon page load and upon switching tabs between "Default" and other language tabs - Verify that your edits are saved correctly. Signed-off-by: Lucas Gass <lucas@bywatersolutions.com> Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com> Signed-off-by: Fridolin Somers <fridolin.somers@biblibre.com>
This commit is contained in:
parent
f1d77a64bb
commit
dc8a9657b1
|
|
@ -567,14 +567,11 @@
|
|||
[% ELSE %]
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
if( $("#tabs .tab-pane.active").length < 1 ){
|
||||
$("#tabs a:first").tab("show");
|
||||
}
|
||||
[% IF category == 'news' %]
|
||||
$("#add_additional_content").validate({
|
||||
submitHandler: function(form){
|
||||
if ( ! $("#title_default").val().length > 0 ) {
|
||||
alert(__("Please specify a title for 'Default'"));
|
||||
alert(_("Please specify a title for 'Default'"));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -603,40 +600,83 @@
|
|||
[% Asset.js( "lib/linters/htmlhint.min.js" ) | $raw %]
|
||||
[% Asset.js( "lib/codemirror/html-lint.min.js" ) | $raw %]
|
||||
<script>
|
||||
$("textarea[name^='content_']").each( function(index) {
|
||||
var this_lang = $(this).attr('data-lang');
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById('content_' + this_lang), {
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
lint: true,
|
||||
mode: "text/html",
|
||||
gutters: ["CodeMirror-lint-markers"],
|
||||
viewportMargin: Infinity,
|
||||
let editors = new Object(); /* Keeps track of initialized CodeMirror instances */
|
||||
$(document).ready(function(){
|
||||
|
||||
if( $("#tabs .tab-pane.active").length < 1 ){
|
||||
/* Activate first tab and initialize its CodeMirror instance */
|
||||
let firstTab = $("#tabs a:first");
|
||||
firstTab.tab("show");
|
||||
initCodeMirror( firstTab[0].hash );
|
||||
}
|
||||
|
||||
$("#tabs a[data-toggle='tab']").on("shown.bs.tab", function (e) {
|
||||
/* Try to initialize CodeMirror instance when tab opens */
|
||||
initCodeMirror( e.target.hash );
|
||||
});
|
||||
});
|
||||
|
||||
function initCodeMirror( container ){
|
||||
/* Initialize CodeMirror instance only if it doesn't exist */
|
||||
if( !editors[ container ] ){
|
||||
let textarea = $( container ).find("textarea[name^='content_']");
|
||||
let this_lang = textarea.attr('data-lang');
|
||||
let editor = CodeMirror.fromTextArea( document.getElementById('content_' + this_lang), {
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
lint: true,
|
||||
mode: "text/html",
|
||||
gutters: ["CodeMirror-lint-markers"],
|
||||
viewportMargin: Infinity,
|
||||
});
|
||||
editors[ container ] = editor;
|
||||
return editor;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
[% ELSE %]
|
||||
[% Asset.js("lib/tiny_mce/tinymce.min.js") | $raw %]
|
||||
[% INCLUDE 'str/tinymce_i18n.inc' %]
|
||||
<script>
|
||||
tinyMCE.init({
|
||||
verify_html: false,
|
||||
force_br_newlines : false,
|
||||
force_p_newlines : false,
|
||||
forced_root_block : '',
|
||||
branding : false,
|
||||
relative_urls : false,
|
||||
content_css : "[% interface | html %]/[% theme | html %]/css/tinymce.css",
|
||||
menubar : "file edit view insert format tools table",
|
||||
mode : "specific_textareas",
|
||||
plugins : "autoresize table hr link image charmap lists code emoticons",
|
||||
extended_valid_elements:"style,link[href|rel]",
|
||||
custom_elements:"style,link,~link",
|
||||
toolbar : [
|
||||
"formatselect | bold italic | cut copy paste | alignleft aligncenter alignright | outdent indent | image link unlink anchor cleanup hr",
|
||||
"table | bullist numlist | undo redo | removeformat | emoticons charmap | forecolor backcolor | code"
|
||||
],
|
||||
|
||||
$(document).ready(function(){
|
||||
if( $("#tabs .tab-pane.active").length < 1 ){
|
||||
/* Activate first tab and initialize its tinyMCE instance */
|
||||
let firstTab = $("#tabs a:first");
|
||||
firstTab.tab("show");
|
||||
initTinyMce( firstTab[0].hash );
|
||||
}
|
||||
|
||||
$("#tabs a[data-toggle='tab']").on("shown.bs.tab", function (e) {
|
||||
/* Try to initialize tinyMCE instance when tab opens */
|
||||
initTinyMce( e.target.hash );
|
||||
});
|
||||
});
|
||||
|
||||
function initTinyMce( container ){
|
||||
let textarea = $( container ).find("textarea[name^='content_']");
|
||||
/* TinyMCE seems to do its own check to prevent double-initialization
|
||||
so We don't need to keep track of it */
|
||||
let editor = tinyMCE.init({
|
||||
branding : false,
|
||||
content_css : "[% interface | html %]/[% theme | html %]/css/tinymce.css",
|
||||
custom_elements:"style,link,~link",
|
||||
extended_valid_elements:"style,link[href|rel]",
|
||||
force_br_newlines : false,
|
||||
force_p_newlines : false,
|
||||
forced_root_block : '',
|
||||
menubar : "file edit view insert format tools table",
|
||||
plugins : "autoresize table hr link image charmap lists code emoticons",
|
||||
relative_urls : false,
|
||||
selector: "#" + textarea[0].id,
|
||||
verify_html: false,
|
||||
toolbar : [
|
||||
"formatselect | bold italic | cut copy paste | alignleft aligncenter alignright | outdent indent | image link unlink anchor cleanup hr",
|
||||
"table | bullist numlist | undo redo | removeformat | emoticons charmap | forecolor backcolor | code"
|
||||
],
|
||||
});
|
||||
return editor;
|
||||
}
|
||||
</script>
|
||||
[% END # /UNLESS wysiwyg %]
|
||||
[% END %]
|
||||
|
|
|
|||
Loading…
Reference in New Issue