Merge branch 'MDL-32750' of git://github.com/colchambers/moodle

This commit is contained in:
Sam Hemelryk
2013-01-28 11:57:17 +13:00
7 changed files with 214 additions and 5 deletions
+2
View File
@@ -41,6 +41,7 @@ $string['err_rangelength'] = 'You must enter between {$a->format[0]} and {$a->fo
$string['err_required'] = 'You must supply a value here.';
$string['general'] = 'General';
$string['hideadvanced'] = 'Hide advanced';
$string['hideeditortoolbar'] = 'Hide editing tools';
$string['hour'] = 'Hour';
$string['minute'] = 'Minute';
$string['miscellaneoussettings'] = 'Miscellaneous settings';
@@ -57,6 +58,7 @@ $string['security'] = 'Security';
$string['selectallornone'] = 'Select all/none';
$string['selected'] = 'Selected';
$string['showadvanced'] = 'Show advanced';
$string['showeditortoolbar'] = 'Show editing tools';
$string['somefieldsrequired'] = 'There are required fields in this form marked {$a}.';
$string['time'] = 'Time';
$string['timeunit'] = 'Time unit';
+20
View File
@@ -106,6 +106,7 @@ class tinymce_texteditor extends texteditor {
if ($fpoptions) {
$PAGE->requires->js_init_call('M.editor_tinymce.init_filepicker', array($elementid, $fpoptions), true);
}
$this->initialise_collapse_js();
}
protected function get_init_params($elementid, array $options=null) {
@@ -274,4 +275,23 @@ class tinymce_texteditor extends texteditor {
global $CFG;
return new moodle_url("$CFG->httpswwwroot/lib/editor/tinymce/tiny_mce/$this->version/");
}
/**
* Initialise javascript form elements
* @return void
*/
public function initialise_collapse_js() {
global $PAGE;
// This method is called for every editor instance. Ensure it's only run once.
// Static is a clunky solution but the best we could find to keep everything simple and encapsulated.
static $isinitialised;
if ($isinitialised) {
return;
}
// Initialise language strings.
$PAGE->requires->strings_for_js(array('hideeditortoolbar', 'showeditortoolbar'), 'form');
$PAGE->requires->yui_module('moodle-editor_tinymce-collapse', 'M.editor_collapse.init');
$isinitialised = true;
}
}
+3
View File
@@ -0,0 +1,3 @@
.mform .felement.feditor .toggle_editor_toolbar {background: #EEEEEE;border-color: #BBBBBB;border-radius: 4px 4px 0 0;border-style: solid solid none;border-width: 1px 1px 0;display: inline-block;font-size: 0.7em;padding: 3px 6px;width: 9em;}
.mform .felement.feditor .mceStatusbar,
.mform .felement.feditor iframe {min-width: 35em;}
+166
View File
@@ -0,0 +1,166 @@
YUI.add('moodle-editor_tinymce-collapse', function(Y) {
var COLLAPSE = function() {
COLLAPSE.superclass.constructor.apply(this, arguments);
};
Y.extend(COLLAPSE, Y.Base, {
toggleNodeTemplate : null,
/**
* Set up basic values for static access.
*/
init : function() {
this.initialise_toggles(10);
},
/**
* Has TinyMCE been loaded and the editors been initialised?
* Designed mainly for IE
* @return bool
*/
editors_initialised : function() {
return typeof tinyMCE !== 'undefined';
},
initialise_toggles : function(refreshes) {
var editors_initialised = this.editors_initialised(), self = this, editor;
if (!editors_initialised && refreshes) {
setTimeout(function() {
self.initialise_toggles(refreshes - 1);
}, 100);
return;
}
// Create the toggle template for use later
this.toggleNodeTemplate = Y.Node.create('<a class="toggle_editor_toolbar" />');
this.toggleNodeTemplate.setContent(M.util.get_string('showeditortoolbar', 'form'));
// Delegate clicks of the toggle_editor_toolbar
Y.one('body').delegate('click', this.toggle_collapse_from_event, 'a.toggle_editor_toolbar', this);
// Set up editors which have already been created
for (editor in tinyMCE.editors) {
this.setup_collapse(tinyMCE.editors[editor]);
}
// Set up for future editors.
// I haven't yet found a way of directly delegating the editor.onInit event. Instead we have to listen for the
// tinyMCE.onAddEditor event, and then add a further event listener to the editor's onInit event.
// onAddEditor is triggered before the editor has been created.
// We use Y.Bind to ensure that context is maintained.
tinyMCE.onAddEditor.add(Y.bind(this.add_setup_collapse_listener, this));
},
/**
* Setup a listener for a new editor which will actually set the editor up
* @param {Manager} mgr
* @param {Editor} ed
*/
add_setup_collapse_listener : function (mgr, ed) {
// Bind the editor.onInit function to set this editor up. This ensures we maintain our context (this)
ed.onInit.add(Y.bind(this.setup_collapse, this));
},
/**
* Setup the toggle system for the provided editor
*
* @param {Editor} ed The TinyMCE editor instance
*/
setup_collapse : function(ed) {
var textarea = Y.Node(ed.getElement()),
editortable = Y.Node(ed.getContainer()).one('> table'),
thisToggleNode;
// Does this text area support collapsing at all?
if (!textarea.hasClass('collapsible')) {
return;
}
// Did we find an appropriate table to work with
if (!editortable) {
return;
}
// Add toggle button.
thisToggleNode = this.toggleNodeTemplate.cloneNode(true);
editortable.get('parentNode').insert(thisToggleNode, editortable);
// Toggle the toolbars initially.
if (Y.Node(ed.getElement()).hasClass('collapsed')) {
this.toggle_collapse(thisToggleNode, editortable, 0);
} else {
this.toggle_collapse(thisToggleNode, editortable, 1);
}
},
/**
* Toggle the specified editor toolbars.
*
* @param {Node} button The toggle button which we have to change the text for
* @param {Node} editortable The table which the tinyMCE editor is in
* @param {Boolean} newstate The intended toggle state
*/
toggle_collapse : function(button, editortable, newstate) {
var toolbar = editortable.one('td.mceToolbar').ancestor('tr'),
statusbar = editortable.one('.mceStatusbar').ancestor('tr'),
editor, iframe, size;
// Check whether we have a state already.
if (typeof newstate === 'undefined') {
if (toolbar.getStyle('display') === 'none') {
newstate = 1;
} else {
newstate = 0;
}
}
// Toggle the various states and update the button text to suit
if (newstate === 0) {
toolbar.hide();
statusbar.hide();
button.setContent(M.util.get_string('showeditortoolbar', 'form'));
} else {
toolbar.show();
statusbar.show();
button.setContent(M.util.get_string('hideeditortoolbar', 'form'));
}
// TinyMCE renders the toolbar and path bar as part of the textarea. So toggling these items
// changes the required size of the rendered textarea. Frustrating but it's the way it's built.
// So we get TinyMCE to resize itself for us. Clunky but it works.
// Get the tinyMCE editor object for this text area.
editorid = editortable.ancestor('div').one('textarea').get('id');
editor = tinyMCE.getInstanceById(editorid);
// Somehow, this editor did not exist.
if (!editor) {
return;
}
// Resize editor to reflect presence of toolbar and path bar..
iframe = editor.getBody();
if (iframe) {
size = tinymce.DOM.getSize(iframe);
// If objects exist resize editor.
if (size) {
editor.theme.resizeTo(size.w, size.h);
}
}
},
toggle_collapse_from_event : function(thisevent) {
var button = thisevent.target.ancestor('a', true),
editortable = thisevent.target.ancestor('span', true).one('table.mceLayout');
this.toggle_collapse(button, editortable);
}
});
M.editor_collapse = M.editor_collapse || {};
M.editor_collapse.init = function(params) {
return new COLLAPSE(params);
};
}, '@VERSION@', {requires:['base', 'node', 'dom']});
+12 -2
View File
@@ -53,7 +53,7 @@ class MoodleQuickForm_editor extends HTML_QuickForm_element {
/** @var array options provided to initalize filepicker */
protected $_options = array('subdirs' => 0, 'maxbytes' => 0, 'maxfiles' => 0, 'changeformat' => 0,
'areamaxbytes' => FILE_AREA_MAX_BYTES_UNLIMITED, 'context' => null, 'noclean' => 0, 'trusttext' => 0,
'return_types' => 7);
'return_types' => 7, 'collapsible' => 0, 'collapsed' => 0);
// $_options['return_types'] = FILE_INTERNAL | FILE_EXTERNAL | FILE_REFERENCE
/** @var array values for editor */
@@ -383,7 +383,17 @@ class MoodleQuickForm_editor extends HTML_QuickForm_element {
if (!is_null($this->getAttribute('onblur')) && !is_null($this->getAttribute('onchange'))) {
$editorrules = ' onblur="'.htmlspecialchars($this->getAttribute('onblur')).'" onchange="'.htmlspecialchars($this->getAttribute('onchange')).'"';
}
$str .= '<div><textarea id="'.$id.'" name="'.$elname.'[text]" rows="'.$rows.'" cols="'.$cols.'"'.$editorrules.'>';
$str .= '<div><textarea id="'.$id.'" name="'.$elname.'[text]" rows="'.$rows.'" cols="'.$cols.'"';
$classes = array();
if (isset($this->_options['collapsed']) && $this->_options['collapsed']) {
$this->_options['collapsible'] = 1;
$classes[] = 'collapsed';
}
if (isset($this->_options['collapsible']) && $this->_options['collapsible']) {
$classes[] = 'collapsible';
}
$str .= ' class="' . implode(' ', $classes) . '"';
$str .= $editorrules.'>';
$str .= s($text);
$str .= '</textarea></div>';
+11 -3
View File
@@ -104,7 +104,7 @@ abstract class question_edit_form extends question_wizard_form {
$this->context = context::instance_by_id($record->contextid);
$this->editoroptions = array('subdirs' => 1, 'maxfiles' => EDITOR_UNLIMITED_FILES,
'context' => $this->context);
'context' => $this->context, 'collapsed' => 1);
$this->fileoptions = array('subdirs' => 1, 'maxfiles' => -1, 'maxbytes' => -1);
$this->category = $category;
@@ -186,7 +186,7 @@ abstract class question_edit_form extends question_wizard_form {
$mform->addRule('name', null, 'required', null, 'client');
$mform->addElement('editor', 'questiontext', get_string('questiontext', 'question'),
array('rows' => 15), $this->editoroptions);
array('rows' => 15), $this->get_non_collabsible_editor_options());
$mform->setType('questiontext', PARAM_RAW);
$mform->addElement('text', 'defaultmark', get_string('defaultmark', 'question'),
@@ -196,7 +196,7 @@ abstract class question_edit_form extends question_wizard_form {
$mform->addRule('defaultmark', null, 'required', null, 'client');
$mform->addElement('editor', 'generalfeedback', get_string('generalfeedback', 'question'),
array('rows' => 10), $this->editoroptions);
array('rows' => 10), $this->get_non_collabsible_editor_options());
$mform->setType('generalfeedback', PARAM_RAW);
$mform->addHelpButton('generalfeedback', 'generalfeedback', 'question');
@@ -673,4 +673,12 @@ abstract class question_edit_form extends question_wizard_form {
* in the question type class.
*/
public abstract function qtype();
/**
* Returns an array of editor options with collapsed options turned off.
* @return array
*/
protected function get_non_collabsible_editor_options() {
return array_merge($this->editoroptions, array('collapsed' => 0));
}
}