Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Atto: Difference between revisions

From MoodleDocs
(19 intermediate revisions by 7 users not shown)
Line 3: Line 3:
Atto is a javascript text editor built specifically for Moodle. Atto is the default text editor in Moodle from 2.7 onwards.
Atto is a javascript text editor built specifically for Moodle. Atto is the default text editor in Moodle from 2.7 onwards.


Atto is implemented as a standard Moodle text editor plugin. Most of the code is written in javascript as a standard Moodle YUI module.  
Atto is implemented as a standard Moodle text editor plugin ([[Editors]]). Most of the code is written in javascript as a standard Moodle YUI module.  
 
Follow the development of ATTO here: https://tracker.moodle.org/browse/MDL-43996
 
==What does Atto mean?==
 
Really really small. (10^-18). It used to be :)
 
The name still ties in with some of the design concepts for Atto which is to be a simple, fast editor  users.
 
==Where can I get Atto?==
 
GIT - and you can check here: https://moodle.org/plugins/view.php?plugin=editor_atto


==Atto Plugins==
==Atto Plugins==
Line 17: Line 29:


/settings.php  
/settings.php  
Optional. Only required if your plugin wants to support custom admin settings. See: https://docs.moodle.org/dev/Admin_settings#Individual_settings for more info on settings.  
Optional. Only required if your plugin wants to support custom admin settings. See: [[Admin_settings#Individual_settings]] for more info on settings.  


/version.php  
/version.php  
Required. Moodle plugin version. See: https://docs.moodle.org/dev/version.php for more info on version files.
Required. Moodle plugin version. See:[[version.php]] for more info on version files.


/lang/en/atto_pluginname.php  
/lang/en/atto_pluginname.php  
Line 26: Line 38:


/yui/src/button/
/yui/src/button/
Required. The plugin must implement a YUI module that will be included by the editor when the page loads. That YUI module must be named 'button' and must insert itself a class into the M.<plugin name> namespace, with an init function that will be called to initialise the editor.
Required. The plugin must implement a YUI module that will be included by the editor when the page loads. That YUI module must be named 'button' and must insert itself a class into the Y.M.<plugin name> namespace, with constructor that will be called to initialise the editor. It is recommended that you extend the EditorPlugin class as described below.
See: https://docs.moodle.org/dev/YUI/Modules for more information about YUI modules.
See: [[YUI/Modules]] for more information about YUI modules.


==Atto subplugin Php API==
==Atto subplugin Php API==
Line 65: Line 77:
</pre>
</pre>


The purpose of this callback is to allow the plugin to initialise the strings that it will use in it's user interface. Note: that the pluginname string for each plugin is automatically loaded, and if this is the only string your plugin requires, then it is not necessary to implement this callback in your plugin. See: https://docs.moodle.org/dev/JavaScript_guidelines#Getting_Moodle_to_load_your_JavaScript_files for more information on strings_for_js.
The purpose of this callback is to allow the plugin to initialise the strings that it will use in it's user interface. Note: that the pluginname string for each plugin is automatically loaded, and if this is the only string your plugin requires, then it is not necessary to implement this callback in your plugin. See: [[JavaScript_guidelines#Getting_Moodle_to_load_your_JavaScript_files]] for more information on strings_for_js.


The second php callback that can be implemented in lib.php is: "XXX_params_for_js" (fictional example, not used in core):
The second php callback that can be implemented in lib.php is: "XXX_params_for_js" (fictional example, not used in core):
Line 80: Line 92:
</pre>
</pre>


==Atto subplugin Javascript API==
If you are using this second callback, you need to specify these parameters in your JavaScript source file, passing it as an argument in the constructor:
Atto subplugins must implement a yui module named "moodle-atto_pluginname-button". This module will be automatically loaded when Atto is displayed on a page (and the subplugin is listed in the toolbar configuration). This plugin should register a class at the M.atto_pluginname namespace and this class should have an init function, which will be called to add the button to the toolbar.
 
The init function will accept a params array containing, the dom id of the textarea element (params.elementid), the toolbar group (params.group), and any additional params supplied by the "atto_pluginname_params_for_js" callback.
 
The atto subplugin can and should make use of the functions in the M.editor_atto class to perform common operations like, adding a toolbar button, adding a toolbar menu, and manipulating the contenteditable region.
 
A list of useful functions available in M.editor_atto follows (But the best place to check this is in the source file itself):
 
<pre>
<pre>
     /**
{
    * Determine if the specified toolbar button/menu is enabled.
     ATTRS: {
    * @param string elementid, the element id of this editor.
        bestodds: {
    * @param string plugin, the plugin that created the button/menu.
            value: '<defaultvalue>'
    */
        },
     M.editor_atto.is_enabled(elementid, plugin);
        worstodds: {
            value: '<defaultvalue>'
        }
     }
}
</pre>


    /**
==Atto subplugin Javascript API==
    * Disable all buttons and menus in the toolbar.
Atto subplugins must implement a yui module named "moodle-atto_pluginname-button".
    * @param string elementid, the element id of this editor.
This module will be automatically loaded when Atto is displayed on a page (and the subplugin is listed in the toolbar configuration).
    */
    M.editor_atto.disable_all_widgets(elementid);


    /**
The plugin:
    * Enable a single widget in the toolbar.
* '''must''' register a class at Y.M.atto_PLUGINNAME.button;
    * @param string elementid, the element id of this editor.
* '''must''' provide a constructor; and
    * @param string plugin, the name of the plugin that created the widget.
* '''''should''''' extend [https://github.com/moodle/moodle/blob/MOODLE_37_STABLE/lib/editor/atto/yui/src/editor/js/editor-plugin.js Y.M.editor_atto.EditorPlugin].
    */
    M.editor_atto.enable_widget(elementid, plugin);


    /**
It is up to the plugin author to decide how best to write their plugin, but it is highly advisable to extend EditorPlugin class, which provides a number of useful functions for dealing with the Editor, Toolbars, Keyboard Navigation, and other related areas.
    * Enable all buttons and menus in the toolbar.
    * @param string elementid, the element id of this editor.
    */
    M.editor_atto.enable_all_widgets(elementid);


    /**
Of particular interest are:
    * Add a content update handler to be called whenever the content is updated.
    * This is used to add inline editing controls to the content that are cleaned on submission.
    *
    * @param string elementid - the id of the textarea we created this editor from.
    * @handler function callback - The function to do the cleaning.
    * @param object context - the context to set for the callback.
    * @handler function handler - A function to call when the button is clicked.
    */
    M.editor_atto.add_text_updated_handler(elementid, callback);


    /**
* [https://github.com/moodle/moodle/blob/MOODLE_37_STABLE/lib/editor/atto/yui/src/editor/js/editor-plugin-buttons.js#L293 addBasicButton] - to add a basic button which directly uses document.execCommand with minimal effort;
    * Add a button to the toolbar belonging to the editor for element with id "elementid".
* [https://github.com/moodle/moodle/blob/MOODLE_37_STABLE/lib/editor/atto/yui/src/editor/js/editor-plugin-buttons.js#L161] - to add a button giving you a greater degree of control via your own callback;
    * @param string elementid - the id of the textarea we created this editor from.
* [https://github.com/moodle/moodle/blob/MOODLE_37_STABLE/lib/editor/atto/yui/src/editor/js/editor-plugin-buttons.js#L337 addToolbarMenu] - to add a dropdown toolbar menu;
    * @param string plugin - the plugin defining the button
* [https://github.com/moodle/moodle/blob/MOODLE_37_STABLE/lib/editor/atto/yui/src/editor/js/editor-plugin.js#L91 markUpdated] - should be called after making changes to the content area; and
    * @param string icon - the html used for the content of the button
* [https://github.com/moodle/moodle/blob/MOODLE_37_STABLE/lib/editor/atto/yui/src/editor/js/editor-plugin-dialogue.js#L54 getDialogue] - return a standard dialogue, creating one if it does not already exist.
    * @param string groupname - the group the button should be appended to.
    * @param array entries - List of menu entries with the string (entry.text) and the handlers (entry.handler).
    */
    M.editor_atto.add_toolbar_menu(elementid, plugin, iconurl, groupname, entries);


    /**
=== Examples ===
    * Add a button to the toolbar belonging to the editor for element with id "elementid".
You may also wish to take a look at some of the existing plugins for examples on how to create the different types:
    * @param string elementid - the id of the textarea we created this editor from.
    * @param string plugin - the plugin defining the button.
    * @param string icon - the url to the image for the icon
    * @param string groupname - the group the button should be appended to.
    * @handler function handler- A function to call when the button is clicked.
    */
    M.editor_atto.add_toolbar_button(elementid, plugin, iconurl, groupname, handler);


    /**
* [https://github.com/moodle/moodle/tree/master/lib/editor/atto/plugins/strike/yui/src/button/js/button.js A basic plugin];
    * Work out if the cursor is in the editable area for this editor instance.
* [https://github.com/moodle/moodle/tree/master/lib/editor/atto/plugins/bold/yui/src/button/js/button.js A basic plugin which has a keyboard shortcuts];
    * @param string elementid of this editor
* [https://github.com/moodle/moodle/tree/master/lib/editor/atto/plugins/indent/yui/src/button/js/button.js A plugin with two buttons (one basic, one slightly more complex)];
    * @return bool
* [https://github.com/moodle/moodle/tree/master/lib/editor/atto/plugins/rtl/yui/src/button/js/button.js A plugin with multiple buttons which take arguments];
    */
* [https://github.com/moodle/moodle/tree/master/lib/editor/atto/plugins/title/yui/src/button/js/button.js A plugin which utilises a toolbar menu];
    M.editor_atto.is_active(elementid);
* [https://github.com/moodle/moodle/tree/master/lib/editor/atto/plugins/image/yui/src/button/js/button.js A plugin with a dialogue]; and
* [https://github.com/moodle/moodle/tree/master/lib/editor/atto/plugins/charmap/yui/src/button/js/button.js A plugin which uses templates to build its dialogue].


    /**
== See Also ==
    * Focus on the editable area for this editor.
    * @param string elementid of this editor
    */
    M.editor_atto.focus(elementid);


    /**
Atto makes accessibility tools available to content authors. See https://docs.moodle.org/dev/Accessibility#Authoring_features
    * The text in the contenteditable region has been updated,
    * clean and copy the buffer to the text area.
    * @param string elementid - the id of the textarea we created this editor from.
    */
    M.editor_atto.text_updated(elementid);


    /**
Atto makes use of contenteditable regions, and the rich text editing API supported by modern browsers. See https://developer.mozilla.org/en/docs/Rich-Text_Editing_in_Mozilla for further reading.
    * Show the filepicker.
    * @param string elementid for this editor instance.
    * @param string type The media type for the file picker
    * @param function callback
    */
    M.editor_atto.show_filepicker(elementid, type, callback);
 
    /**
    * Create a cross browser selection object that represents a yui node.
    * @param Node yui node for the selection
    * @return range (browser dependent)
    */
    M.editor_atto.get_selection_from_node(node);


    /**
See the comparision (pros, cons, technical notes, missing features, etc) of Atto versus other candidate editors for Moodle 2.7 in [https://docs.moodle.org/dev/Editor_2.7 https://docs.moodle.org/dev/Editor_2.7]
    * Get the selection object that can be passed back to set_selection.
    * @return range (browser dependent)
    */
    M.editor_atto.get_selection();
 
    /**
    * Check that a YUI node it at least partly contained by the selection.
    * @param Range selection
    * @param Y.Node node
    * @return boolean
    */
    M.editor_atto.selection_contains_node(node);
 
    /**
    * Get the dom node representing the common anscestor of the selection nodes.
    * @return DOMNode
    */
    M.editor_atto.get_selection_parent_node();
 
    /**
    * Get the list of child nodes of the selection.
    * @return DOMNode[]
    */
    M.editor_atto.get_selection_text();
   
    /**
    * Set the current selection. Used to restore a selection.
    */
    M.editor_atto.set_selection(selection);
 
</pre>
 
Atto also allows "control" menus within the contenteditable text. These are links which open a context menu, but are removed from the text before it is saved. An example of this is the table editing controls added by the table plugin. In order for this to work, there are some conventions that should be followed. Firstly - any content with a class of "atto_control" will be removed from the source when it is saved. Second, there is a subclass of M.core.dialogue available to produce a context menu (see atto/yui/src/editor/js/controlmenu.js).  
 
== See Also ==
 
Atto makes use of contenteditable regions, and the rich text editing API supported by modern browsers. See https://developer.mozilla.org/en/docs/Rich-Text_Editing_in_Mozilla for further reading.


For opening dialogues it is recommended to use M.core.dialogue : https://github.com/moodle/moodle/blob/master/lib/yui/src/notification/js/dialogue.js
For opening dialogues it is recommended to use M.core.dialogue : https://github.com/moodle/moodle/blob/master/lib/yui/src/notification/js/dialogue.js

Revision as of 04:04, 24 May 2019

Moodle 2.7


Atto is a javascript text editor built specifically for Moodle. Atto is the default text editor in Moodle from 2.7 onwards.

Atto is implemented as a standard Moodle text editor plugin (Editors). Most of the code is written in javascript as a standard Moodle YUI module.

Follow the development of ATTO here: https://tracker.moodle.org/browse/MDL-43996

What does Atto mean?

Really really small. (10^-18). It used to be :)

The name still ties in with some of the design concepts for Atto which is to be a simple, fast editor users.

Where can I get Atto?

GIT - and you can check here: https://moodle.org/plugins/view.php?plugin=editor_atto

Atto Plugins

All of the buttons/menus in Atto are implemented as true Moodle subplugins. This means that the subplugins can do anything a subplugin can do including, lang strings, db tables, yui modules.

There are a couple of extra functions/structure required for an Atto subplugin which are required in order to load a plugin on the toolbar.

Structure of an Atto Plugin

/lib.php Optional. Only required if your plugin needs to implement one of the component callbacks listed below.

/settings.php Optional. Only required if your plugin wants to support custom admin settings. See: Admin_settings#Individual_settings for more info on settings.

/version.php Required. Moodle plugin version. See:version.php for more info on version files.

/lang/en/atto_pluginname.php Required. Language file. This file is required and must at least define the language string 'pluginname'.

/yui/src/button/ Required. The plugin must implement a YUI module that will be included by the editor when the page loads. That YUI module must be named 'button' and must insert itself a class into the Y.M.<plugin name> namespace, with constructor that will be called to initialise the editor. It is recommended that you extend the EditorPlugin class as described below. See: YUI/Modules for more information about YUI modules.

Atto subplugin Php API

Atto sub plugins can contain a lib.php file with 2 callbacks that will be looked for when the plugin is loaded.

The first is "XXX_strings_for_js" (example taken from atto_table plugin):

/**
 * Initialise the js strings required for this module.
 */
function atto_table_strings_for_js() {
    global $PAGE;

    $PAGE->requires->strings_for_js(array('createtable',
                                          'accessibilityhint',
                                          'headers',
                                          'caption',
                                          'columns',
                                          'rows',
                                          'numberofcolumns',
                                          'numberofrows',
                                          'both',
                                          'edittable',
                                          'addcolumnafter',
                                          'addrowafter',
                                          'movecolumnright',
                                          'movecolumnleft',
                                          'moverowdown',
                                          'moverowup',
                                          'deleterow',
                                          'deletecolumn'),
                                    'atto_table');
}

The purpose of this callback is to allow the plugin to initialise the strings that it will use in it's user interface. Note: that the pluginname string for each plugin is automatically loaded, and if this is the only string your plugin requires, then it is not necessary to implement this callback in your plugin. See: JavaScript_guidelines#Getting_Moodle_to_load_your_JavaScript_files for more information on strings_for_js.

The second php callback that can be implemented in lib.php is: "XXX_params_for_js" (fictional example, not used in core):

/**
 * Return the js params required for this module.
 * @return array of additional params to pass to javascript init function for this module.
 */
function atto_gambling_params_for_js() {
    return array('bestodds' => '34 to 1', 'worstodds' => '5 to 1');
}

If you are using this second callback, you need to specify these parameters in your JavaScript source file, passing it as an argument in the constructor:

{
    ATTRS: {
        bestodds: {
            value: '<defaultvalue>'
        },
        worstodds: {
            value: '<defaultvalue>'
        }
    }
}

Atto subplugin Javascript API

Atto subplugins must implement a yui module named "moodle-atto_pluginname-button". This module will be automatically loaded when Atto is displayed on a page (and the subplugin is listed in the toolbar configuration).

The plugin:

It is up to the plugin author to decide how best to write their plugin, but it is highly advisable to extend EditorPlugin class, which provides a number of useful functions for dealing with the Editor, Toolbars, Keyboard Navigation, and other related areas.

Of particular interest are:

  • addBasicButton - to add a basic button which directly uses document.execCommand with minimal effort;
  • [1] - to add a button giving you a greater degree of control via your own callback;
  • addToolbarMenu - to add a dropdown toolbar menu;
  • markUpdated - should be called after making changes to the content area; and
  • getDialogue - return a standard dialogue, creating one if it does not already exist.

Examples

You may also wish to take a look at some of the existing plugins for examples on how to create the different types:

See Also

Atto makes accessibility tools available to content authors. See https://docs.moodle.org/dev/Accessibility#Authoring_features

Atto makes use of contenteditable regions, and the rich text editing API supported by modern browsers. See https://developer.mozilla.org/en/docs/Rich-Text_Editing_in_Mozilla for further reading.

See the comparision (pros, cons, technical notes, missing features, etc) of Atto versus other candidate editors for Moodle 2.7 in https://docs.moodle.org/dev/Editor_2.7

For opening dialogues it is recommended to use M.core.dialogue : https://github.com/moodle/moodle/blob/master/lib/yui/src/notification/js/dialogue.js