How do I add a CKEditor plugin from within a plugin? - ckeditor

I am developing a CKEditor plugin that I would like to be vehicle to deliver multiple plugins all required for the correct editing experience. Basically I want the user to be able to include a single "the_framework" plugin, which in turn adds 10 more plugins (each a widget with toolbar button and possibly context menu) that provides the full editing support. I do not want the "plugin" configuration to be responsible for loading these plugins. It's really an all or nothing proposition in my case.
I've tried having the master plugin add external plugins with CKEDITOR.plugins.addExternal but they don't load. I realize now this is because the plugins or extraPlugins configuration doesn't name the external plugins so Editor.loadPlugins never tries them. However, by the time my master plugin loads and executes onLoad it's already too late to change the configuration.
I'm fine with having multiple plugin definitions in one plugin file, but it appears it still won't work if the editor config doesn't explicitly name them all.
How can I load a plugin from another plugin?

After some more debugging, I have determined this to be impossible.
I realized to load the "sub-plugins" registered as externals I simply needed to call CKEDITOR.plugins.load with the names of the plugins after registering them. That is the same method called by the editor, however, the editor follows up with a lot of extra steps including loading language files and critical callbacks (beforeInit, init, and afterInit).
The editor.js loadPlugins function is where all the action occurs, but it only accepts an Editor argument without a list of plugins to load, because the editor's config is used for determining which plugins to load. Once the list is determined, they are all loaded in parallel. If the sub-plugins are not in this array from the beginning, even if the master plugin loads them manually later, they will never be fully initialized with an editor.
The only work-around I have come up with involves loading one extra script after loading the CKEditor source, ideally a script distributed with the master plugin. The script sets up the external sub-plugin definitions (which are actually in a local subfolder named "master_plugin/plugins") and registers an instanceCreated callback, which basically looks at the a new editor's config and determines if the sub-plugins need to be added to the list before the editor initializes. If any of this occurs from within a plugin, vs the extra script, it is too late and it will fail.
UPDATE
It was actually necessary to register a configLoaded listener inside the instanceCreated callback, because when instanceCreated occurs the user's config is not yet loaded into the editor. The customConfigLoaded event is also too early to receive the user's config, so any modifications to plugins or extendedPlugins will still be lost. Surprisingly, the configLoaded event is fired after the editor makes use of several config options (readOnly, enterMode, shiftEnterMode, tabIndex, skin, maybe others), but plugins is not yet touched.
The configLoaded event is the only hook point I could find to guarantee edits to the page-supplied config. With the config.customConfig option, it would be possible to listen for customConfigLoaded within the editorConfig function and get the full config, because CKEditor only merges the page config inside its own customConfigLoaded listener. (The order of operations makes this possible.)
Returning to the original goal of loading many plugins through a single plugin (add-on package), it is possible but obviously nothing intended by the design of the plugin system.

Related

Lazy load CKEditor 4

Currently finding issue lazy loading CKEditor 4, appreciate any advice. What I tried:
Including ckeditor_basic.js but this already needs a CKEDITOR
instance
Loading ckeditor.js on click but this complains
'Synchronous XMLHttpRequest on the main thread is deprecated because
of its detrimental effects to the end user's experience.' as well as
some others errors, fails badly.
Any advice appreciated!
If you would like to insert CKEditor script dynamically you can use technique from this code pen - https://codepen.io/j_swiderski/pen/qPGRGb. It is important to wait for ckeditor.js to load before creating editor instance thus using setInterval to check if CKEDITOR object is available seems like a good idea.
In your comments you have written, you don't want editor to load every time you load the page. One of the reasons for that might be the size of ckeditor.js file.
If you think editor.js is too big it is important to answer yourself how much plugins you really need and then create editor accordingly to your needs using the online builder. Please have a look at below samples using dev-tools and notice the difference in ckeditor.js size: Full package has 600KB while Basic Package has only 400KB. If you just need the basic formatting then your ckeditor.js could get even smaller and should not be a problem when loading the page.
If you have created some custom plugins then recommended practice is to get CKEditor source code from Githhub, fork it, make changes/add custom plugins, build your editor. That way you will get minified and obfuscated editor instance which includes your custom plugins and again should not be a problem when loading the page.

Does CKEditor's "config.removePlugins" setting affect its loading time?

I have a custom CKEditor build. Eventually, after I've done code changes, which I don't want to lose, I decided that not all of the plugins, which I included in the initial build, were necessary, so I removed some of them through the config.js file by using config.removePlugins.
My questions are:
Does this method improve the loading speed of the editor at all or does it remove the plugins after they have been loaded?
If the first is true, does it only affect the loading of resources from the plugins folder or does it also affect the loaded content of the ckeditor.js file?
If you downloaded the Full package from CKEditor download page then while loading the editor, the whole package gets loaded even if config.removePlugins is used.
The less plugins you have, the faster the editor loads. This is the general rule. Another one is that the editor should be served in release and not the source mode.
The best practice is to get the editor source code from here, create your own fork which you can update to newest stable branches, create your custom plugins and build your own custom editor release according to this link.
This way you will get all the plugins you want and the editor code will be minified, obfuscated and combined into a single ckeditor.js file which should guarantee the fastest load time.

Joomla cannot unset mod_languages/css/template.css

Joomla 3.x
The following code is not working
unset($doc->_styleSheets[JURI::root(true).'/media/mod_languages/css/template.css']);
thank you
The code is correct and I tested it, it's working fine.
Possibly you are running it in a plugin event after the head is rendered, or you have cached the page and the code is not really running.
In either case, try to put it at the component level, clear cache, and it should work
Update
to identify the component: turn SEF off, and look at the URL it shows as option=com_componentname;
to identify the module, simply rename the modules folder, and update the site; if it works, it's a module.
For plugins, rename the plugins/system and plugins/content first, then drill down until you spot it.
Alternatively, but much slower, you can turn modules and plugins on and off from the backend, until you find the culprit.
A variation which I've used with success in the past:
unset($doc->_styleSheets[$this->baseurl.'/media/mod_languages/css/template.css']);
Update
Here's an alternate method using a module override which should work for you.
if it doesn't already exist, create a new directory titled html in your template's folder, ie: /templates/your-template/html/
inside this, create an new mod_languages folder, ie /templates/your-template/html/mod_languages/
copy the file from joomla-site-root/modules/mod_languages/tmp/default.php to the folder above, ie /templates/your-template/html/mod_languages/default.php
open this file with a text editor and around line 12 look for the line where JHtml is loading the mod_languages CSS, and comment it out.
// JHtml::_('stylesheet', 'mod_languages/template.css', array(), true);
That's it, hopefully, this will do the trick for you.
Overriding Joomla core output using this method is safe and you won't loose your work with future Joomla updates.
More info about Joomla overrides:
https://docs.joomla.org/How_to_override_the_output_from_the_Joomla!_core
Good luck!

Icons path altered in built editor

I've made a couple plugins for ckeditor and added icons for them. These icons show up when I embed the unbuilt code on a test page, but, when I build the editor, the minimized code thinks the icons at 'original/path/to/the/icon.png?t=D5AK' instead of 'original/path/to/the/icon.png'. This error does not occur when I copy an icon from another plugin in the src code. At the moment the only way I am adding the icon is through "icon: this.path + 'icons/icon.png'," in plugin.js. Is there somewhere I need to add a reference to the icon?
This is an intentional addition to resources' paths. It ensures that every two CKEditor releases have different paths to the same resource what disables cache. And this works perfectly unless you're trying to load CKEditor from local file system than from a web server.

What buttons have changed labels from fckeditor to ckeditor 4?

It appears that some of the button names have been changed in ckeditor version 4.
Is there a complete list of these changes?
There is a partial list here.
I'm pretty sure that names haven't been changed. If something is not working check if plugin you need is included in your build (most likely it is a standard preset) and if not:
download a full preset (which in fact does not include all plugins too, but most of them) or
add required plugins to your custom CKEditor build.
[EDIT] another useful resource is the toolbar sample shipped with CKEditor package. E.g. here's one for a standard package.

Resources