TinyMCE Inline mode: Get content of edited area on editor closing - javascript

I use TinyMCE plugin with inline mode on. What I want to do is get the content of the area that's been edited after the editor has been closed. This is what I have for now:
tinymce.init({
selector: '.editable',
plugins: "link",
inline: true,
init_instance_callback: function (editor) {
editor.on('GetContent', function (e) {
console.log(e.content);
});
}
});
However, this on doesn't log anything. Any ideas?

Each time you leave the editor it fires the blur event (https://www.tinymce.com/docs/advanced/events/#blur) ... and you can capture this in your TinyMCE configuration:
tinymce.init({
selector: '#my_div",
...
setup: function (editor) {
editor.on('blur', function (e) {
console.log('Editor was blurred!');
// Do what you want when the editor is blurred here
console.log(editor.getContent()); //get the content from the editor
});
}
});

Related

Codemirror plugin Tinymce inline mode IndexSizeError

I'm using tinymce in inline mode on a contenteditable div.
I have used the CodeMirror tinymce plugin before (not inline mode) with no issues, but it doesn't seem to work correctly in inline mode.
I've tried changing the config to inline: false and it works.
Clicking the Source button opens the HTML with CodeMirror and seems ok.
But when I click Ok to save it, it seems to work fine in Chrome and Firefox but in Safari it adds an  and I can't close the modal (however, I can see that it has changed the content of the editable div), clicking the Ok button again, it adds another  and console error. Clicking the cancel or X button just adds console error.
In the console I get IndexSizeError: DOM Exception 1: Index or size was negative, or greater than the allowed value tinymce.min.js:5724
In Chrome, it seems to work but I still get a console error The given range isn't in document.
My tinymce config is below:
var tinymceEditText = tinymce.init({
selector: '.editableEl',
// target: ".editableElTinyMCE",
// theme: 'inlite',
inline: true,
plugins: [
'advlist autolink lists link image charmap anchor media',
'searchreplace visualblocks code fullscreen',
'template textcolor colorpicker hr fontawesome noneditable hr',
'insertdatetime contextmenu paste save codemirror',
'OBstock emoji_one'
],
toolbar1: 'save undo redo | styleselect | bold italic underline | forecolor backcolor | alignleft aligncenter alignright alignjustify | | code',
toolbar2: 'bullist numlist outdent indent | template | hr | anchor link unlink | image media OBstock emoji_one fontawesome ',
relative_urls: false,
remove_script_host: true,
templates: "/admin/JS/tinymce/js/tinymce/lists/template_list.php",
external_filemanager_path: "/filemanager/",
external_plugins: {"filemanager": "/filemanager/plugin.min.js"},
filemanager_title: "Uploaded Files", //the title of filemanager window default="Responsive filemanager",
filemanager_sort_by: "name", //the element to sorting (values: name,size,extension,date) default="",
filemanager_descending: 0, //descending ? or ascending (values=1 or 0) default="0"
codemirror: {
indentOnInit: true, // Whether or not to indent code on init.
smartIndent: true,
indentWithTabs: true,
saveCursorPosition: false,
path: '/admin/JS/codemirror-' + CODEMIRRORVERSION, // Path to CodeMirror distribution
config: { // CodeMirror config object
theme: CODETHEME,
indentUnit: 4,
lineNumbers: true,
mode: "htmlmixed",
matchBrackets: true,
autoCloseBrackets: true,
autoCloseTags: true,
matchTags: {bothTags: true},
indentOnInit: true, // Whether or not to indent code on init.
smartIndent: true,
indentWithTabs: true,
lineWrapping: true,
paletteHints: false,
lint: true,
lintOnChange: true,
showHint: true,
HTMLHint: true,
CSSHint: true,
JSHint: true,
getAnnotations: true,
gutters: ['CodeMirror-lint-markers', 'CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
foldGutter: true,
profile: 'xhtml', /* define Emmet output profile */
extraKeys: {
"Ctrl-Space": "autocomplete",
"F11": function (cm) {
cm.setOption("fullScreen", !cm.getOption("fullScreen"));
},
"Esc": function (cm) {
if (cm.getOption("fullScreen")) cm.setOption("fullScreen", false);
}
}
},
jsFiles: [
'mode/php/php.js',
'mode/htmlembedded/htmlembedded.js',
'addon/edit/matchbrackets.js',
'addon/edit/closebrackets.js',
'addon/edit/closetag.js',
'addon/fold/xml-fold.js',
'addon/fold/comment-fold.js',
'addon/edit/matchtags.js',
'mode/htmlmixed/htmlmixed.js',
'addon/search/searchcursor.js',
'addon/search/search.js',
'addon/hint/show-hint.js',
'addon/hint/anyword-hint.js',
'addon/hint/html-hint.js',
'addon/hint/css-hint.js',
'addon/hint/xml-hint.js',
'addon/hint/javascript-hint.js',
'addon/lint/lint.js',
'addon/lint/javascript-lint.js',
'addon/lint/json-lint.js',
'addon/lint/css-lint.js',
'addon/lint/html-lint.js',
'addon/customplugins/lint/csslint.js',
'addon/customplugins/hint/htmlhint.js'
],
cssFiles: [
'theme/' + CODETHEME + '.css',
'addon/dialog/dialog.css',
'addon/hint/show-hint.css',
'addon/lint/lint.css',
'addon/fold/foldgutter.css',
]
}
});
EDIT: I've now managed to recreate this in Chrome and Firefox, by opening the source editor, clicking cancel, opening the source editor again and clicking Ok. Different errors in the console though:
Chrome:
Uncaught DOMException: Failed to execute 'setStart' on 'Range': There is no child at offset 3. tinymce.min.js:5
Firefox:
IndexSizeError: Index or size is negative or greater than the allowed amount tinymce.mins.js:5
Finally managed to figure this one out be myself.
The issue wasn't with CodeMirror itself but actually tinymce's setContent function.
This fix for this was using the insertContent function instead and adding an extra setting in the tinymce.init
if(CMsettings.config.inlineFix) {
editor.selection.select(editor.getBody(), true);
editor.insertContent(codemirror.getValue().replace(cc, '<span id="CmCaReT"></span>'));
} else {
editor.setContent(codemirror.getValue().replace(cc, '<span id="CmCaReT"></span>'));
}
This made the insert button work but the cancel button still had some weird behaviour with the cursor, so I ended up duplicating and modifying the whole plugin to remove the insert and cancel buttons, and add them myself in the html

How can I inject a store into a panel's toolbar?

My app uses Deft to inject stores. However, when I try to inject a store into a pagingtoolbar at the bottom of a grid panel, it does not work.
Ext.define("My.grid.Panel", {
...
inject: {
store: 'myStore' // works fine
},
...
dockedItems:[{
xtype: 'pagingtoolbar',
...
inject: {
store: 'myStore' // does not work
}
]
}
My current workaround is adding this to the panel:
listeners: {
afterrender: function(panel) {
let toolbar = panel.down('pagingtoolbar');
if (toolbar) {
toolbar.setStore(panel.getStore());
}
}
}
We ended up just creating a separate class that extended PagingToolbar. This solved the problem as Deft was then able to inject into it.

CKEditor "Permission denied" error inside IE8

I'm using CKEditor v4.5.6 (along with Angular 1.2.0 and jQuery 1.11.3) in my app which has to be IE8 compatibile.
Other browsers are not throwing any errors but when I load page with editor inside IE8 it throws "Permission denied" error inside line 54 of ckeditor.js file:
getDocument:function(){return new CKEDITOR.dom.document(this.$.ownerDocument||
this.$.parentNode.ownerDocument)}
Also, I was unable to open cdn link inside IE8, I get error:
Code used inside ckEditor directive is rather simple - couple of config setters, replace method for toolbar and then getData() and setData() on model update, something like this:
CKEDITOR.config.resize_enabled = false;
var ck = CKEDITOR.replace(elm[0],
{
toolbar: [
{name: 'basicstyles', items: ['Bold', 'Italic', 'Strike', '-', 'Undo', 'Redo']}
]
});
ck.on('instanceReady', function () {
if(ngModel.$viewValue){
ck.setData(ngModel.$viewValue);
}
});
function updateModel() {
scope.$apply(function () {
ngModel.$setViewValue(ck.getData());
});
}
ck.on('change', updateModel);
Inside html file:
<script src="//cdn.ckeditor.com/4.5.6/standard-all/ckeditor.js"></script>
<textarea class="textarea form-control" ng-if="!loading"
data-ck-editor="" ng-model="test.editorContent"> </textarea>
Although editor is loaded and data is correctly diplayed, this error is iritating. Any help?

Unable to add resize event to tinymce editor

I am not able to add resize event to tinymce editor. it is giving me:-
Uncaught TypeError: tinymce.dom.Event.add is not a function
What is the right way to do so?
tinymce.init({
selector: ".tinymceTextarea",
width: '100%',
height: '100%',
plugins: plugins,
statusbar: false,
menubar: false,
toolbar: toolbar,
fontsize_formats : "8px 10px 12px 14px 16px 18px 20px 24px 32px 36px",
// init_instance_callback: "initTinyMCE",
setup: function(e) {
e.on('init', function() {
tinymce.dom.Event.add(e.getWin(), "resize", function(e1) {
console.log("=====")
})
});
});
Thanks in advance
Try the below snippet without chaining
$("#your_textarea_id").tinymce().getWin().bind('resize',function() {
console.log('resize triggered !');
// Your Code goes here.
});
This can easiliy be achieved using the setup tinymce configuration parameter setup to add a window resize handler:
setup: function(ed){
ed.on('init', function() {
$(ed.getWin()).bind('resize', function(e){
console.log('Editor window resized!');
})
});
}
See my tinymce fiddle here: http://fiddle.tinymce.com/snfaab

How to require mode, theme or addon of code mirror in browserify

Has anybody try to use code mirror via browserify?
I find nothing is visible, even though it already generated all the html tags.
The code :
var CodeMirror = require('codemirror');
require('codemirror/mode/javascript/javascript.js');
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
lineNumbers: true,
extraKeys: {
"Ctrl-Space": "autocomplete"
},
mode: {
name: "javascript",
globalVars: true
}
});
i wonder how i should require the js mode?
I actually dealed with that problem by using require() for all dependencies of the demonstration of html5complete mode demo like that:
// require('codemirror/addon/hint/show-hint');
// require('codemirror/addon/hint/xml-hint');
// require('codemirror/addon/hint/html-hint');
require('codemirror/mode/xml/xml');
require('codemirror/mode/javascript/javascript');
require('codemirror/mode/css/css');
require('codemirror/mode/htmlmixed/htmlmixed');
var CodeMirror = require('codemirror/lib/codemirror');
var editor = CodeMirror.fromTextArea(textareaElement, {
mode: 'text/html',
lineWrapping: true,
extraKeys: {
'Ctrl-Space': 'autocomplete'
},
lineNumbers: true,
theme: 'monokai'
});
In my .less files, I imported the CSS like that:
#import (inline) "./../../node_modules/codemirror/lib/codemirror.css";
#import (inline) "./../../node_modules/codemirror/theme/monokai.css";
// #import (inline) "./../../node_modules/codemirror/addon/hint/show-hint.css";
I did not took really care about the quality of that trick.
Here's what's working for me. Using import instead of require, but same gist:
import 'codemirror/theme/3024-night.css'
const options = {
lineNumbers: true,
readOnly: false,
mode: 'htmlmixed',
theme:'3024-night'
};
...
<Codemirror ref="editor" value={this.props.value} onChange={this.props.updateCode} options={options}/>

Categories