From ea862ad72177213f44e8d50836490bd0c511a672 Mon Sep 17 00:00:00 2001 From: justinhunt Date: Thu, 18 Jul 2019 13:54:18 +0900 Subject: [PATCH] fixed default permissions for authenticated user and a code tidy up --- CHANGES.txt | 4 + db/access.php | 136 +- dialog/poodll.css | 93 +- dialog/poodll.php | 78 +- lang/en/atto_poodll.php | 1 - lib.php | 377 ++--- settings.php | 38 +- styles.css | 5 +- version.php | 8 +- .../moodle-atto_poodll-button-debug.js | 1219 +++++++++-------- .../moodle-atto_poodll-button.js | 1213 ++++++++-------- yui/src/button/js/button.js | 689 +++++----- yui/src/button/meta/button.json | 10 +- 13 files changed, 1970 insertions(+), 1901 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index e7c42bd..58c0f9e 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,9 @@ Change List ========= +Version 3.1.2(Build 2019071300) +-Fixed default permission for authenticated user + + Version 3.1.1(Build 2018090300) -Added support for Cloud Poodll API token diff --git a/db/access.php b/db/access.php index addf395..872bd32 100644 --- a/db/access.php +++ b/db/access.php @@ -26,72 +26,78 @@ $capabilities = array( - 'atto/poodll:visible' => array( - 'captype' => 'write', - 'contextlevel' => CONTEXT_COURSE, - 'archetypes' => array( - 'coursecreator' => CAP_ALLOW, - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'student' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ), - 'atto/poodll:allowaudiomp3' => array( - 'captype' => 'write', - 'contextlevel' => CONTEXT_COURSE, - 'archetypes' => array( - 'coursecreator' => CAP_ALLOW, - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'student' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ), + 'atto/poodll:visible' => array( + 'captype' => 'write', + 'contextlevel' => CONTEXT_MODULE, + 'archetypes' => array( + 'coursecreator' => CAP_ALLOW, + 'teacher' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + 'student' => CAP_ALLOW, + 'manager' => CAP_ALLOW, + 'user' => CAP_ALLOW + ) + ), + 'atto/poodll:allowaudiomp3' => array( + 'captype' => 'write', + 'contextlevel' => CONTEXT_MODULE, + 'archetypes' => array( + 'coursecreator' => CAP_ALLOW, + 'teacher' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + 'student' => CAP_ALLOW, + 'manager' => CAP_ALLOW, + 'user' => CAP_ALLOW + ) + ), - 'atto/poodll:allowvideo' => array( - 'captype' => 'write', - 'contextlevel' => CONTEXT_COURSE, - 'archetypes' => array( - 'coursecreator' => CAP_ALLOW, - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'student' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ), - 'atto/poodll:allowwhiteboard' => array( - 'captype' => 'write', - 'contextlevel' => CONTEXT_COURSE, - 'archetypes' => array( - 'coursecreator' => CAP_ALLOW, - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'student' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ), - 'atto/poodll:allowsnapshot' => array( - 'captype' => 'write', - 'contextlevel' => CONTEXT_COURSE, - 'archetypes' => array( - 'coursecreator' => CAP_ALLOW, - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'student' => CAP_ALLOW, - 'manager' => CAP_ALLOW - ) - ), - 'atto/poodll:allowwidgets' => array( - 'captype' => 'write', - 'contextlevel' => CONTEXT_COURSE, - 'archetypes' => array( - 'coursecreator' => CAP_ALLOW, - 'teacher' => CAP_ALLOW, - 'editingteacher' => CAP_ALLOW, - 'student' => CAP_ALLOW, - 'manager' => CAP_ALLOW + 'atto/poodll:allowvideo' => array( + 'captype' => 'write', + 'contextlevel' => CONTEXT_MODULE, + 'archetypes' => array( + 'coursecreator' => CAP_ALLOW, + 'teacher' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + 'student' => CAP_ALLOW, + 'manager' => CAP_ALLOW, + 'user' => CAP_ALLOW + ) + ), + 'atto/poodll:allowwhiteboard' => array( + 'captype' => 'write', + 'contextlevel' => CONTEXT_MODULE, + 'archetypes' => array( + 'coursecreator' => CAP_ALLOW, + 'teacher' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + 'student' => CAP_ALLOW, + 'manager' => CAP_ALLOW, + 'user' => CAP_ALLOW + ) + ), + 'atto/poodll:allowsnapshot' => array( + 'captype' => 'write', + 'contextlevel' => CONTEXT_MODULE, + 'archetypes' => array( + 'coursecreator' => CAP_ALLOW, + 'teacher' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + 'student' => CAP_ALLOW, + 'manager' => CAP_ALLOW, + 'user' => CAP_ALLOW + ) + ), + 'atto/poodll:allowwidgets' => array( + 'captype' => 'write', + 'contextlevel' => CONTEXT_MODULE, + 'archetypes' => array( + 'coursecreator' => CAP_ALLOW, + 'teacher' => CAP_ALLOW, + 'editingteacher' => CAP_ALLOW, + 'student' => CAP_ALLOW, + 'manager' => CAP_ALLOW, + 'user' => CAP_ALLOW + ) ) - ) ); diff --git a/dialog/poodll.css b/dialog/poodll.css index 701434d..f02cbd3 100644 --- a/dialog/poodll.css +++ b/dialog/poodll.css @@ -1,34 +1,73 @@ -.mceLinkList, .mceAnchorList, #targetlist {width:280px;} -.mceActionPanel {margin-top:7px;} -.panel_wrapper div.current {height:320px;} -#classlist, #title, #href {width:280px;} -#popupurl, #popupname {width:200px;} -#popupwidth, #popupheight, #popupleft, #popuptop {width:30px;vertical-align:middle;text-align:center;} -#id, #style, #classes, #target, #dir, #hreflang, #lang, #charset, #type, #rel, #rev, #tabindex, #accesskey {width:200px;} -#events_panel input {width:200px;} -.pagelayout-embedded #content {padding-top: 0px;} -#content {width:0px;height:0px;} -#page {top:0px;margin-top:0px;padding-top:0px;} -#tinymce_poodll_container{ - position: fixed; - left: 0px; - top: 0px; - margin: 5px; +.mceLinkList, .mceAnchorList, #targetlist { + width: 280px; +} + +.mceActionPanel { + margin-top: 7px; +} + +.panel_wrapper div.current { + height: 320px; +} + +#classlist, #title, #href { + width: 280px; +} + +#popupurl, #popupname { + width: 200px; +} + +#popupwidth, #popupheight, #popupleft, #popuptop { + width: 30px; + vertical-align: middle; + text-align: center; +} + +#id, #style, #classes, #target, #dir, #hreflang, #lang, #charset, #type, #rel, #rev, #tabindex, #accesskey { + width: 200px; +} + +#events_panel input { + width: 200px; +} + +.pagelayout-embedded #content { + padding-top: 0px; +} + +#content { + width: 0px; + height: 0px; +} + +#page { + top: 0px; + margin-top: 0px; + padding-top: 0px; +} + +#tinymce_poodll_container { + position: fixed; + left: 0px; + top: 0px; + margin: 5px; } .atto_poodll_iframe_container { - padding: relative; - padding-bottom: 56.25%; - padding-top: 30px; - height: 0; - overflow: hidden; + padding: relative; + padding-bottom: 56.25%; + padding-top: 30px; + height: 0; + overflow: hidden; } + .atto_poodll_iframe_container iframe, .atto_poodll_iframe_container object, -.atto_poodll_iframe_container embed{ - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; +.atto_poodll_iframe_container embed { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; } diff --git a/dialog/poodll.php b/dialog/poodll.php index 6ac07e7..e706d83 100644 --- a/dialog/poodll.php +++ b/dialog/poodll.php @@ -55,43 +55,51 @@ $modulecontextid = optional_param('modulecontextid', 0, PARAM_INT); //contextid -$usercontextid=context_user::instance($USER->id)->id; +$usercontextid = context_user::instance($USER->id)->id; $callbackjs = '';//'atto_poodll_button.updatefilename'; -$hints= Array('size'=>'small'); -if($coursecontextid){ - $hints['coursecontextid']=$coursecontextid; +$hints = Array('size' => 'small'); +if ($coursecontextid) { + $hints['coursecontextid'] = $coursecontextid; } -if($modulecontextid){ - $hints['modulecontextid']=$modulecontextid; +if ($modulecontextid) { + $hints['modulecontextid'] = $modulecontextid; } // Load the recorder. -switch($recorder){ - case 'video': - $recorderhtml = \filter_poodll\poodlltools::fetchVideoRecorderForSubmission('auto', 'none', $updatecontrol, $usercontextid,'user','draft',$itemid,0,$callbackjs,$hints); - $instruction = get_string('recordtheninsert', 'atto_poodll'); - break; - case 'snapshot': - $recorderhtml = \filter_poodll\poodlltools::fetchHTML5SnapshotCamera($updatecontrol,350,400,$usercontextid,'user','draft',$itemid,$callbackjs,$hints); - $instruction = get_string('snaptheninsert', 'atto_poodll'); - break; - case 'whiteboard': - $recorderhtml = \filter_poodll\poodlltools::fetchWhiteboardForSubmission($updatecontrol, $usercontextid,'user','draft',$itemid,400,350,"",$usewhiteboard,$callbackjs); - $recorderhtml = "
" . $recorderhtml . "
"; - $instruction = get_string('drawtheninsert', 'atto_poodll'); - break; - case 'audiored5': - case 'audiomp3': - default: - $hints['size'] ='auto'; - $recorderhtml = \filter_poodll\poodlltools::fetchMP3RecorderForSubmission($updatecontrol, $usercontextid ,'user','draft',$itemid,0,$callbackjs,$hints); - $instruction = get_string('recordtheninsert', 'atto_poodll'); +switch ($recorder) { + case 'video': + $recorderhtml = + \filter_poodll\poodlltools::fetchVideoRecorderForSubmission('auto', 'none', $updatecontrol, $usercontextid, 'user', + 'draft', $itemid, 0, $callbackjs, $hints); + $instruction = get_string('recordtheninsert', 'atto_poodll'); + break; + case 'snapshot': + $recorderhtml = + \filter_poodll\poodlltools::fetchHTML5SnapshotCamera($updatecontrol, 350, 400, $usercontextid, 'user', 'draft', + $itemid, $callbackjs, $hints); + $instruction = get_string('snaptheninsert', 'atto_poodll'); + break; + case 'whiteboard': + $recorderhtml = + \filter_poodll\poodlltools::fetchWhiteboardForSubmission($updatecontrol, $usercontextid, 'user', 'draft', $itemid, + 400, 350, "", $usewhiteboard, $callbackjs); + $recorderhtml = "
" . $recorderhtml . "
"; + $instruction = get_string('drawtheninsert', 'atto_poodll'); + break; + case 'audiored5': + case 'audiomp3': + default: + $hints['size'] = 'auto'; + $recorderhtml = + \filter_poodll\poodlltools::fetchMP3RecorderForSubmission($updatecontrol, $usercontextid, 'user', 'draft', $itemid, + 0, $callbackjs, $hints); + $instruction = get_string('recordtheninsert', 'atto_poodll'); } $PAGE->set_pagelayout('embedded'); $PAGE->set_title(get_string('dialogtitle', 'atto_poodll')); $PAGE->requires->css(new moodle_url($CFG->wwwroot . '/lib/editor/atto/plugins/poodll/dialog/poodll.css')); -$PAGE->requires->js(new moodle_url($CFG->wwwroot. '/filter/poodll/module.js'),true); +$PAGE->requires->js(new moodle_url($CFG->wwwroot . '/filter/poodll/module.js'), true); $PAGE->requires->jquery(); //load our resize script @@ -100,13 +108,13 @@ echo $OUTPUT->header(); ?> -
-
-

- -
-
+
+
+

+ +
+
footer(); diff --git a/lang/en/atto_poodll.php b/lang/en/atto_poodll.php index 5f5afb6..0bec14b 100644 --- a/lang/en/atto_poodll.php +++ b/lang/en/atto_poodll.php @@ -30,7 +30,6 @@ $string['settings'] = 'PoodLL Anywhere(Atto)'; $string['unpoodll'] = 'Unpoodll'; - $string['browse'] = 'Browse'; $string['visible'] = 'Visible'; $string['audiomp3_desc'] = 'Record Audio'; diff --git a/lib.php b/lib.php index e1b39b1..d57d766 100644 --- a/lib.php +++ b/lib.php @@ -26,227 +26,230 @@ /** * Initialise this plugin + * * @param string $elementid */ function atto_poodll_strings_for_js() { global $PAGE; $PAGE->requires->strings_for_js(array('insert', - 'cancel', - 'chooseinsert', - 'fieldsheader', - 'nofieldsheader', - 'dialogtitle', - 'audiomp3_desc', - 'video_desc', - 'whiteboard_desc', - 'snapshot_desc', - 'widgets_desc'), - 'atto_poodll'); + 'cancel', + 'chooseinsert', + 'fieldsheader', + 'nofieldsheader', + 'dialogtitle', + 'audiomp3_desc', + 'video_desc', + 'whiteboard_desc', + 'snapshot_desc', + 'widgets_desc'), + 'atto_poodll'); } /** * Return the js params required for this module. + * * @return array of additional params to pass to javascript init function for this module. */ function atto_poodll_params_for_js($elementid, $options, $fpoptions) { - global $USER, $COURSE; - //coursecontext - $coursecontext=context_course::instance($COURSE->id); - - //usercontextid - if($USER->id ==0){ - $usercontextid=0; - }else { + global $USER, $COURSE; + + //the context + $thecontext = $options['context']; + + //coursecontext + $coursecontext = context_course::instance($COURSE->id); + + //usercontextid + if ($USER->id == 0) { + $usercontextid = 0; + } else { $usercontextid = context_user::instance($USER->id)->id; } - $disabled=false; - - //config our array of data - $params = array(); - $params['usercontextid'] = $usercontextid; - $params['coursecontextid'] = $coursecontext->id; - - //If they don't have permission don't show it - if(!has_capability('atto/poodll:visible', $coursecontext) ){ - $disabled=true; - } - - //if this textarea allows no files, we also bail - if (!isset($options['maxfiles']) || $options['maxfiles'] == 0) { - $disabled=true; + $disabled = false; + + //config our array of data + $params = array(); + $params['usercontextid'] = $usercontextid; + $params['coursecontextid'] = $coursecontext->id; + + //If they don't have permission don't show it + if (!has_capability('atto/poodll:visible', $thecontext)) { + $disabled = true; + } + + //if this textarea allows no files, we also bail + if (!isset($options['maxfiles']) || $options['maxfiles'] == 0) { + $disabled = true; + } + + //add our disabled param + $params['disabled'] = $disabled; + + //add our use whiteboard option + $params['usewhiteboard'] = get_config('atto_poodll', 'usewhiteboard'); + + //add icons to editor if the permissions are all ok + $recorders = array('audiomp3', 'video', 'whiteboard', 'snapshot', 'widgets'); + $allowedrecorders = get_config('atto_poodll', 'recorderstoshow'); + if (!empty($allowedrecorders)) { + $allowedrecorders = explode(',', $allowedrecorders); + //we deleted the red5 option, just in case, we map it here to mp3 + if (array_key_exists('show_audiored5', $allowedrecorders) && !array_key_exists('show_audiomp3', $allowedrecorders)) { + $allowedrecorders[] = 'show_audiomp3'; } - - //add our disabled param - $params['disabled'] = $disabled; - - //add our use whiteboard option - $params['usewhiteboard'] = get_config('atto_poodll','usewhiteboard'); - - //add icons to editor if the permissions are all ok - $recorders = array('audiomp3','video','whiteboard','snapshot','widgets'); - $allowedrecorders = get_config('atto_poodll','recorderstoshow'); - if(!empty($allowedrecorders)){ - $allowedrecorders = explode(',',$allowedrecorders); - //we deleted the red5 option, just in case, we map it here to mp3 - if(array_key_exists('show_audiored5',$allowedrecorders) && !array_key_exists('show_audiomp3',$allowedrecorders) ){ - $allowedrecorders[]='show_audiomp3'; + foreach ($recorders as $recorder) { + if ((array_search('show_' . $recorder, $allowedrecorders) !== false) && + has_capability('atto/poodll:allow' . $recorder, $thecontext)) { + $params[$recorder] = true; } - foreach($recorders as $recorder){ - if((array_search('show_' . $recorder,$allowedrecorders)!==false) && has_capability('atto/poodll:allow' . $recorder, $coursecontext)){ - $params[$recorder]=true; - } - } - } - - $widgetparams = atto_poodll_widgets_params_for_js(); - $params['keys']=$widgetparams['keys']; - $params['names']=$widgetparams['names']; - $params['instructions']=$widgetparams['instructions']; - $params['defaults']=$widgetparams['defaults']; - $params['variables']=$widgetparams['variables']; - $params['ends']=$widgetparams['ends']; + } + } + + $widgetparams = atto_poodll_widgets_params_for_js(); + $params['keys'] = $widgetparams['keys']; + $params['names'] = $widgetparams['names']; + $params['instructions'] = $widgetparams['instructions']; + $params['defaults'] = $widgetparams['defaults']; + $params['variables'] = $widgetparams['variables']; + $params['ends'] = $widgetparams['ends']; return $params; } /** * Return the js params required for this module. + * * @return array of additional params to pass to javascript init function for this module. */ -function atto_poodll_widgets_params_for_js() -{ - global $USER, $COURSE; - - //coursecontext - $coursecontext = context_course::instance($COURSE->id); - - //generico specific - $templates = get_object_vars(get_config('filter_poodll')); - - $instructions = array(); - $names=array(); - $keys = array(); - $variables = array(); - $defaults = array(); - $ends = array(); - - //get the no. of templates - if (!array_key_exists('templatecount', $templates)) { - $templatecount = \filter_poodll\filtertools::FILTER_POODLL_TEMPLATE_COUNT +1; - } else { - $templatecount = $templates['templatecount'] + 1; - } - //put our template into a form thats easy to process in JS - for ($tempindex = 1; $tempindex < $templatecount; $tempindex++) { - if (empty($templates['template_' . $tempindex]) && - empty($templates['templatescript_' . $tempindex]) && - empty($templates['templatestyle_' . $tempindex]) - ) { - continue; - } - - //make sure its to be shown in atto - if(!$templates['template_showatto_' . $tempindex]){ - continue; - } - - //stash the key and name for this template - $keys[] = $templates['templatekey_' . $tempindex]; - $usename = trim($templates['templatename_' . $tempindex]); - if($usename==''){ - $names[] = $templates['templatekey_' . $tempindex]; - }else{ - $names[]=$usename; - } - - - //instructions - //stash the instructions for this template - $instructions[] = rawurlencode($templates['templateinstructions_' . $tempindex]); - - //NB each of the $allvariables contains an array of variables (not a string) - //there might be duplicates where the variable is used multiple times in a template - //se we uniqu'ify it. That makes it look complicated. But we are just removing doubles - $allvariables = atto_poodll_widgets_fetch_variables($templates['template_' . $tempindex] . $templates['templatescript_' . $tempindex] . $templates['datasetvars_' . $tempindex]); - $uniquevariables = array_unique($allvariables); - $usevariables = array(); - - //we need to reallocate array keys if the array size was changed in unique'ifying it - //we also take the opportunity to remove user variables, since they aren't needed here. - //NB DATASET can be referred to without the : - while (count($uniquevariables) > 0) { - $tempvar = array_shift($uniquevariables); - if (strpos($tempvar, 'COURSE:') === false - && strpos($tempvar, 'USER:') === false - && strpos($tempvar, 'DATASET:') === false - && strpos($tempvar, 'URLPARAM:') === false - && $tempvar != 'MOODLEPAGEID' - && $tempvar != 'WWWROOT' - && $tempvar != 'AUTOID' - && $tempvar != 'CLOUDPOODLLTOKEN') { - $usevariables[] = $tempvar; - } - } - $variables[] = $usevariables; - - //stash the defaults for this template - //$defaults[] = $templates['templatedefaults_' . $tempindex]; - $defaults[] = atto_poodll_widgets_fetch_filter_properties($templates['templatedefaults_' . $tempindex]); - - $ends[] = $templates['templateend_' . $tempindex]; - } - - - //config our array of data - $params = array(); - $params['keys'] = $keys; - $params['names'] = $names; - $params['instructions'] = $instructions; - $params['variables'] = $variables; - $params['defaults'] = $defaults; - $params['ends'] = $ends; +function atto_poodll_widgets_params_for_js() { + global $USER, $COURSE; + + //generico specific + $templates = get_object_vars(get_config('filter_poodll')); + + $instructions = array(); + $names = array(); + $keys = array(); + $variables = array(); + $defaults = array(); + $ends = array(); + + //get the no. of templates + if (!array_key_exists('templatecount', $templates)) { + $templatecount = \filter_poodll\filtertools::FILTER_POODLL_TEMPLATE_COUNT + 1; + } else { + $templatecount = $templates['templatecount'] + 1; + } + //put our template into a form thats easy to process in JS + for ($tempindex = 1; $tempindex < $templatecount; $tempindex++) { + if (empty($templates['template_' . $tempindex]) && + empty($templates['templatescript_' . $tempindex]) && + empty($templates['templatestyle_' . $tempindex]) + ) { + continue; + } + + //make sure its to be shown in atto + if (!$templates['template_showatto_' . $tempindex]) { + continue; + } + + //stash the key and name for this template + $keys[] = $templates['templatekey_' . $tempindex]; + $usename = trim($templates['templatename_' . $tempindex]); + if ($usename == '') { + $names[] = $templates['templatekey_' . $tempindex]; + } else { + $names[] = $usename; + } + + //instructions + //stash the instructions for this template + $instructions[] = rawurlencode($templates['templateinstructions_' . $tempindex]); + + //NB each of the $allvariables contains an array of variables (not a string) + //there might be duplicates where the variable is used multiple times in a template + //se we uniqu'ify it. That makes it look complicated. But we are just removing doubles + $allvariables = atto_poodll_widgets_fetch_variables($templates['template_' . $tempindex] . + $templates['templatescript_' . $tempindex] . $templates['datasetvars_' . $tempindex]); + $uniquevariables = array_unique($allvariables); + $usevariables = array(); + + //we need to reallocate array keys if the array size was changed in unique'ifying it + //we also take the opportunity to remove user variables, since they aren't needed here. + //NB DATASET can be referred to without the : + while (count($uniquevariables) > 0) { + $tempvar = array_shift($uniquevariables); + if (strpos($tempvar, 'COURSE:') === false + && strpos($tempvar, 'USER:') === false + && strpos($tempvar, 'DATASET:') === false + && strpos($tempvar, 'URLPARAM:') === false + && $tempvar != 'MOODLEPAGEID' + && $tempvar != 'WWWROOT' + && $tempvar != 'AUTOID' + && $tempvar != 'CLOUDPOODLLTOKEN') { + $usevariables[] = $tempvar; + } + } + $variables[] = $usevariables; + + //stash the defaults for this template + //$defaults[] = $templates['templatedefaults_' . $tempindex]; + $defaults[] = atto_poodll_widgets_fetch_filter_properties($templates['templatedefaults_' . $tempindex]); + + $ends[] = $templates['templateend_' . $tempindex]; + } + //config our array of data + $params = array(); + $params['keys'] = $keys; + $params['names'] = $names; + $params['instructions'] = $instructions; + $params['variables'] = $variables; + $params['defaults'] = $defaults; + $params['ends'] = $ends; return $params; } /** * Return an array of variable names - * @param string template containing @@variable@@ variables + * + * @param string template containing @@variable@@ variables * @return array of variable names parsed from template string */ -function atto_poodll_widgets_fetch_variables($template){ - $matches = array(); - $t = preg_match_all('/@@(.*?)@@/s', $template, $matches); - if(count($matches)>1){ - return($matches[1]); - }else{ - return array(); - } +function atto_poodll_widgets_fetch_variables($template) { + $matches = array(); + $t = preg_match_all('/@@(.*?)@@/s', $template, $matches); + if (count($matches) > 1) { + return ($matches[1]); + } else { + return array(); + } } -function atto_poodll_widgets_fetch_filter_properties($propstring){ - //Now we just have our properties string - //Lets run our regular expression over them - //string should be property=value,property=value - //got this regexp from http://stackoverflow.com/questions/168171/regular-expression-for-parsing-name-value-pairs - $regexpression='/([^=,]*)=("[^"]*"|[^,"]*)/'; - $matches=array(); - - //here we match the filter string and split into name array (matches[1]) and value array (matches[2]) - //we then add those to a name value array. - $itemprops = array(); - if (preg_match_all($regexpression, $propstring,$matches,PREG_PATTERN_ORDER)){ - $propscount = count($matches[1]); - for ($cnt =0; $cnt < $propscount; $cnt++){ - // echo $matches[1][$cnt] . "=" . $matches[2][$cnt] . " "; - $newvalue = $matches[2][$cnt]; - //this could be done better, I am sure. WE are removing the quotes from start and end - //this wil however remove multiple quotes id they exist at start and end. NG really - $newvalue = trim($newvalue,'"'); - $itemprops[trim($matches[1][$cnt])]=$newvalue; - } - } - return $itemprops; +function atto_poodll_widgets_fetch_filter_properties($propstring) { + //Now we just have our properties string + //Lets run our regular expression over them + //string should be property=value,property=value + //got this regexp from http://stackoverflow.com/questions/168171/regular-expression-for-parsing-name-value-pairs + $regexpression = '/([^=,]*)=("[^"]*"|[^,"]*)/'; + $matches = array(); + + //here we match the filter string and split into name array (matches[1]) and value array (matches[2]) + //we then add those to a name value array. + $itemprops = array(); + if (preg_match_all($regexpression, $propstring, $matches, PREG_PATTERN_ORDER)) { + $propscount = count($matches[1]); + for ($cnt = 0; $cnt < $propscount; $cnt++) { + // echo $matches[1][$cnt] . "=" . $matches[2][$cnt] . " "; + $newvalue = $matches[2][$cnt]; + //this could be done better, I am sure. WE are removing the quotes from start and end + //this wil however remove multiple quotes id they exist at start and end. NG really + $newvalue = trim($newvalue, '"'); + $itemprops[trim($matches[1][$cnt])] = $newvalue; + } + } + return $itemprops; } \ No newline at end of file diff --git a/settings.php b/settings.php index 6c5d201..c42c46d 100644 --- a/settings.php +++ b/settings.php @@ -22,7 +22,6 @@ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ - defined('MOODLE_INTERNAL') || die(); $ADMIN->add('editoratto', new admin_category('atto_poodll', new lang_string('pluginname', 'atto_poodll'))); @@ -31,22 +30,23 @@ if ($ADMIN->fulltree) { - // Recorder settings - $recoptions = array('show_audiomp3' => new lang_string('show_audiomp3', 'atto_poodll'), - 'show_video' => new lang_string('show_video', 'atto_poodll'), - 'show_whiteboard' => new lang_string('show_whiteboard', 'atto_poodll'), - 'show_snapshot' => new lang_string('show_snapshot', 'atto_poodll'), - 'show_widgets' => new lang_string('show_widgets', 'atto_poodll')); - - $recoptiondefaults = array('show_audiomp3' => 1,'show_video' => 1,'show_whiteboard' => 1,'show_snapshot' => 1,'show_widgets' => 1); - $settings->add(new admin_setting_configmulticheckbox('atto_poodll/recorderstoshow', - get_string('recorderstoshow', 'atto_poodll'), - get_string('recorderstoshowdetails', 'atto_poodll'), $recoptiondefaults,$recoptions)); - - //PoodLL Whiteboard - $settings->add(new admin_setting_heading('atto_poodll/whiteboards', get_string('whiteboardheading', 'atto_poodll'), '')); - $wboptions = array('drawingboard' => 'Drawing Board(js)', 'literallycanvas' => 'Literally Canvas(js)'); - $settings->add(new admin_setting_configselect('atto_poodll/usewhiteboard', get_string('usewhiteboard', 'atto_poodll'), '', 'drawingboard', $wboptions)); - - + // Recorder settings + $recoptions = array('show_audiomp3' => new lang_string('show_audiomp3', 'atto_poodll'), + 'show_video' => new lang_string('show_video', 'atto_poodll'), + 'show_whiteboard' => new lang_string('show_whiteboard', 'atto_poodll'), + 'show_snapshot' => new lang_string('show_snapshot', 'atto_poodll'), + 'show_widgets' => new lang_string('show_widgets', 'atto_poodll')); + + $recoptiondefaults = + array('show_audiomp3' => 1, 'show_video' => 1, 'show_whiteboard' => 1, 'show_snapshot' => 1, 'show_widgets' => 1); + $settings->add(new admin_setting_configmulticheckbox('atto_poodll/recorderstoshow', + get_string('recorderstoshow', 'atto_poodll'), + get_string('recorderstoshowdetails', 'atto_poodll'), $recoptiondefaults, $recoptions)); + + //PoodLL Whiteboard + $settings->add(new admin_setting_heading('atto_poodll/whiteboards', get_string('whiteboardheading', 'atto_poodll'), '')); + $wboptions = array('drawingboard' => 'Drawing Board(js)', 'literallycanvas' => 'Literally Canvas(js)'); + $settings->add(new admin_setting_configselect('atto_poodll/usewhiteboard', get_string('usewhiteboard', 'atto_poodll'), '', + 'drawingboard', $wboptions)); + } diff --git a/styles.css b/styles.css index 69b5dd9..2add87e 100644 --- a/styles.css +++ b/styles.css @@ -1,8 +1,9 @@ .atto_poodll_buttons { display: inline; } -.atto_poodll_field{ - width: 200px; + +.atto_poodll_field { + width: 200px; } div.atto_widget_buttons { diff --git a/version.php b/version.php index 4e30c90..af95895 100644 --- a/version.php +++ b/version.php @@ -24,10 +24,10 @@ defined('MOODLE_INTERNAL') || die(); -$plugin->version = 2018090300; -$plugin->requires = 2016052300;//moodle 3.1.0 +$plugin->version = 2019071300; +$plugin->requires = 2016052300;//moodle 3.1.0 $plugin->component = 'atto_poodll'; // Full name of the plugin (used for diagnostics). -$plugin->maturity = MATURITY_STABLE; +$plugin->maturity = MATURITY_STABLE; // Human readable version information -$plugin->release = '3.1.1(Build 2018090300)'; +$plugin->release = '3.1.2(Build 2019071300)'; $plugin->dependencies = array('filter_poodll' => 2016081401); \ No newline at end of file diff --git a/yui/build/moodle-atto_poodll-button/moodle-atto_poodll-button-debug.js b/yui/build/moodle-atto_poodll-button/moodle-atto_poodll-button-debug.js index ca01b9f..f20c49c 100644 --- a/yui/build/moodle-atto_poodll-button/moodle-atto_poodll-button-debug.js +++ b/yui/build/moodle-atto_poodll-button/moodle-atto_poodll-button-debug.js @@ -15,657 +15,660 @@ YUI.add('moodle-atto_poodll-button', function (Y, NAME) { // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/* - * @package atto_poodll - * @copyright 2016 Justin Hunt - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -/** - * @module moodle-atto_poodll-button - */ + /* + * @package atto_poodll + * @copyright 2016 Justin Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ -/** - * Atto text editor poodll plugin. - * - * @namespace M.atto_poodll - * @class button - * @extends M.editor_atto.EditorPlugin - */ + /** + * @module moodle-atto_poodll-button + */ -var COMPONENTNAME = 'atto_poodll'; -var POODLLFILENAME = 'poodllfilename'; -var LOGNAME = 'atto_poodll'; + /** + * Atto text editor poodll plugin. + * + * @namespace M.atto_poodll + * @class button + * @extends M.editor_atto.EditorPlugin + */ + var COMPONENTNAME = 'atto_poodll'; + var POODLLFILENAME = 'poodllfilename'; + var LOGNAME = 'atto_poodll'; -var CSS = { + var CSS = { INPUTSUBMIT: 'atto_media_urlentrysubmit', INPUTCANCEL: 'atto_media_urlentrycancel', NAMEBUTTON: 'atto_poodll_templatebutton', HEADERTEXT: 'atto_poodll_headertext', INSTRUCTIONSTEXT: 'atto_poodll_instructionstext', - TEMPLATEVARIABLE: 'atto_poodll_templatevariable' + TEMPLATEVARIABLE: 'atto_poodll_templatevariable' }; -var TEMPLATE = '' + - '
' + - '
' + - '' + - '' + - '
' + - '
'; + var TEMPLATE = '' + + '
' + + '
' + + '' + + '' + + '
' + + '
'; -var IMAGETEMPLATE = '' + '{{alt}}'; + var IMAGETEMPLATE = '' + '{{alt}}'; -var FIELDSHEADERTEMPLATE = '' + + var FIELDSHEADERTEMPLATE = '' + '
' + - '

{{headertext}} {{key}}

' + - '
{{instructions}}
' + + '

{{headertext}} {{key}}

' + + '
{{instructions}}
' + '
'; -var BUTTONSHEADERTEMPLATE = '' + + var BUTTONSHEADERTEMPLATE = '' + '
' + - '

{{headertext}}

' + + '

{{headertext}}

' + '
'; - -var BUTTONTEMPLATE = '' + + + var BUTTONTEMPLATE = '' + '
' + - '' + + '' + '
'; - -var FIELDTEMPLATE = '' + + + var FIELDTEMPLATE = '' + '
{{variable}}' + - ' ' + + ' ' + '
'; -var SELECTCONTAINERTEMPLATE = '' + - '
{{variable}}
'; - -var SELECTTEMPLATE = '' + - ''; + var SELECTCONTAINERTEMPLATE = '' + + '
{{variable}}
'; -var OPTIONTEMPLATE ='' + - ''; + var SELECTTEMPLATE = '' + + ''; -var SUBMITTEMPLATE = '' + - '
' + - '
' + - '' + - '
' + - '
'; + var OPTIONTEMPLATE = '' + + ''; + var SUBMITTEMPLATE = '' + + '
' + + '
' + + '' + + '
' + + '
'; -Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { + Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { - /** - * A reference to the current selection at the time that the dialogue - * was opened. - * - * @property _currentSelection - * @type Range - * @private - */ - _currentSelection: null, + /** + * A reference to the current selection at the time that the dialogue + * was opened. + * + * @property _currentSelection + * @type Range + * @private + */ + _currentSelection: null, - /** - * A reference to the dialogue content. - * - * @property _content - * @type Node - * @private - */ - _content: null, - _currentrecorder: null, - _itemid: null, - _usercontextid: null, - _coursecontextid: null, - _modulecontextid: null, - _usewhiteboard: null, - - initializer: function(config) { - this._usercontextid = config.usercontextid; - this._coursecontextid = config.coursecontextid; - this._usewhiteboard = config.usewhiteboard; - - var host = this.get('host'); - var options = host.get('filepickeroptions'); - if (options.image && options.image.itemid) { - this._itemid = options.image.itemid; - if (options.image.context && options.image.context.id) { - this._modulecontextid = options.image.context.id; - } - } else { - Y.log('Plugin PoodLL Anywhere not available because itemid is missing.', + /** + * A reference to the dialogue content. + * + * @property _content + * @type Node + * @private + */ + _content: null, + _currentrecorder: null, + _itemid: null, + _usercontextid: null, + _coursecontextid: null, + _modulecontextid: null, + _usewhiteboard: null, + + initializer: function (config) { + this._usercontextid = config.usercontextid; + this._coursecontextid = config.coursecontextid; + this._usewhiteboard = config.usewhiteboard; + + var host = this.get('host'); + var options = host.get('filepickeroptions'); + if (options.image && options.image.itemid) { + this._itemid = options.image.itemid; + if (options.image.context && options.image.context.id) { + this._modulecontextid = options.image.context.id; + } + } else { + Y.log('Plugin PoodLL Anywhere not available because itemid is missing.', 'warn', LOGNAME); - return; - } - - //if we don't have the capability, or no file uploads allowed, give up. - if(config.disabled){ - return; - } - - - var recorders = new Array('audiomp3','video', 'whiteboard','snapshot','widgets'); - for (var therecorder = 0; therecorder < recorders.length; therecorder++) { - // Add the poodll button first (if we are supposed to) - if(config.hasOwnProperty(recorders[therecorder])){ - this.addButton({ - icon: recorders[therecorder], - iconComponent: 'atto_poodll', - title: recorders[therecorder] + '_desc', - buttonName: recorders[therecorder], - callback: this._displayDialogue, - callbackArgs: recorders[therecorder] - }); - } - } - - - }, - - /** - * Display the PoodLL Recorder files. - * - * @method _displayDialogue - * @private - */ - _displayDialogue: function(e, therecorder) { - e.preventDefault(); - this._currentrecorder = therecorder; - - if(therecorder=='widgets'){ - this._displayWidgetsDialogue(e,therecorder); - return; - } - - var width=400; - var height=260; - switch(therecorder){ - case 'audiomp3': - width=400; - height=300; - break; - case 'video': - case 'snapshot':width=360; - height=450; - break; - case 'whiteboard': width=680; - height=540; - break; - } - - //the dialogue widths are a bit bogus - var dialogue = this.getDialogue({ - headerContent: M.util.get_string('dialogtitle', COMPONENTNAME), - width: width + 'px', - focusAfterHide: therecorder - }); - if(dialogue.width != width + 'px'){ - dialogue.set('width',width + 30 +'px'); - } + return; + } + + //if we don't have the capability, or no file uploads allowed, give up. + if (config.disabled) { + return; + } + + + var recorders = new Array('audiomp3', 'video', 'whiteboard', 'snapshot', 'widgets'); + for (var therecorder = 0; therecorder < recorders.length; therecorder++) { + // Add the poodll button first (if we are supposed to) + if (config.hasOwnProperty(recorders[therecorder])) { + this.addButton({ + icon: recorders[therecorder], + iconComponent: 'atto_poodll', + title: recorders[therecorder] + '_desc', + buttonName: recorders[therecorder], + callback: this._displayDialogue, + callbackArgs: recorders[therecorder] + }); + } + } + + + }, - var iframeid = 'atto_poodll_dialog_iframe_' + new Date().getTime(); - //var iframe = Y.Node.create(''); - // var iframe = Y.Node.create(''); - var iframe = Y.Node.create(''); - - iframe.setStyles({ - border: 'none', - overflow: 'hidden' - }); - - //set attributes on the iframe - iframe.setAttribute('src', this._getIframeURL(therecorder, iframeid)); - iframe.setAttribute('scrolling', 'no'); - - //append buttons to iframe - var buttonform = this._getFormContent(); - - var bodycontent = Y.Node.create('
'); - bodycontent.append(iframe).append(buttonform); - - //set to bodycontent - dialogue.set('bodyContent', bodycontent); - dialogue.show(); - this.markUpdated(); - }, - - /** - * Returns the URL to the file manager. - * - * @param _getIframeURL - * @return {String} URL - * @private - */ - _getIframeURL: function(therecorder, iframeid) { - return M.cfg.wwwroot + '/lib/editor/atto/plugins/poodll/dialog/poodll.php?' + - 'itemid='+ this._itemid + '&recorder=' + therecorder + '&usewhiteboard=' + this._usewhiteboard + - '&iframeid=' + iframeid + '&coursecontextid=' + this._coursecontextid + '&modulecontextid=' + this._modulecontextid + - '&updatecontrol=' + this._getFilenameControlName(); - }, - /** - * Return the dialogue content for the tool, attaching any required - * events. - * - * @method _getDialogueContent - * @return {Node} The content to place in the dialogue. - * @private - */ - _getFormContent: function() { - var template = Y.Handlebars.compile(TEMPLATE), - content = Y.Node.create(template({ - elementid: this.get('host').get('elementid'), - CSS: CSS, - poodllfilename: POODLLFILENAME, - component: COMPONENTNAME - })); - - this._form = content; - this._form.one('.' + CSS.INPUTSUBMIT).on('click', this._doInsert, this); - return content; - }, - - + * Display the PoodLL Recorder files. + * + * @method _displayDialogue + * @private + */ + _displayDialogue: function (e, therecorder) { + e.preventDefault(); + this._currentrecorder = therecorder; + + if (therecorder == 'widgets') { + this._displayWidgetsDialogue(e, therecorder); + return; + } + + var width = 400; + var height = 260; + switch (therecorder) { + case 'audiomp3': + width = 400; + height = 300; + break; + case 'video': + case 'snapshot': + width = 360; + height = 450; + break; + case 'whiteboard': + width = 680; + height = 540; + break; + } + + //the dialogue widths are a bit bogus + var dialogue = this.getDialogue({ + headerContent: M.util.get_string('dialogtitle', COMPONENTNAME), + width: width + 'px', + focusAfterHide: therecorder + }); + if (dialogue.width != width + 'px') { + dialogue.set('width', width + 30 + 'px'); + } + + var iframeid = 'atto_poodll_dialog_iframe_' + new Date().getTime(); + //var iframe = Y.Node.create(''); + // var iframe = Y.Node.create(''); + var iframe = Y.Node.create(''); + + iframe.setStyles({ + border: 'none', + overflow: 'hidden' + }); + + //set attributes on the iframe + iframe.setAttribute('src', this._getIframeURL(therecorder, iframeid)); + iframe.setAttribute('scrolling', 'no'); + + //append buttons to iframe + var buttonform = this._getFormContent(); + + var bodycontent = Y.Node.create('
'); + bodycontent.append(iframe).append(buttonform); + + //set to bodycontent + dialogue.set('bodyContent', bodycontent); + dialogue.show(); + this.markUpdated(); + }, + /** - * Get the id of the filename control where poodll stores filename - * - * @method _getFilenameControlName - * @return {String} the name/id of the filename form field - * @private - */ - _getFilenameControlName: function(){ - return(this.get('host').get('elementid') + '_' + POODLLFILENAME); - }, - - + * Returns the URL to the file manager. + * + * @param _getIframeURL + * @return {String} URL + * @private + */ + _getIframeURL: function (therecorder, iframeid) { + return M.cfg.wwwroot + '/lib/editor/atto/plugins/poodll/dialog/poodll.php?' + + 'itemid=' + this._itemid + '&recorder=' + therecorder + '&usewhiteboard=' + this._usewhiteboard + + '&iframeid=' + iframeid + '&coursecontextid=' + this._coursecontextid + '&modulecontextid=' + this._modulecontextid + + '&updatecontrol=' + this._getFilenameControlName(); + }, + /** - * Inserts the url/link onto the page - * @method _getDialogueContent - * @private - */ - _doInsert : function(e){ - e.preventDefault(); - this.getDialogue({ - focusAfterHide: null - }).hide(); - - var thefilename = document.getElementById(this._getFilenameControlName()); - //if no file is there to insert, don't do it - if(!thefilename.value){ - Y.log('No filename control or value could be found.','warn', LOGNAME); - return; - } + * Return the dialogue content for the tool, attaching any required + * events. + * + * @method _getDialogueContent + * @return {Node} The content to place in the dialogue. + * @private + */ + _getFormContent: function () { + var template = Y.Handlebars.compile(TEMPLATE), + content = Y.Node.create(template({ + elementid: this.get('host').get('elementid'), + CSS: CSS, + poodllfilename: POODLLFILENAME, + component: COMPONENTNAME + })); - var thefilename = thefilename.value; - var wwwroot = M.cfg.wwwroot; - var mediahtml=''; - - // It will store in mdl_question with the "@@PLUGINFILE@@/myfile.mp3" for the filepath. - var filesrc =wwwroot+'/draftfile.php/'+ this._usercontextid +'/user/draft/'+this._itemid+'/'+thefilename; - - //if this is an image, insert the image - if(this._currentrecorder==='snapshot' ||this._currentrecorder==='whiteboard'){ - template = Y.Handlebars.compile(IMAGETEMPLATE); - mediahtml = template({ - url: filesrc, - alt: thefilename - }); - //otherwise insert the link - }else{ - mediahtml = ''+thefilename+''; - } - - this.editor.focus(); - this.get('host').insertContentAtFocusPoint(mediahtml); - this.markUpdated(); - - }, - - /** - * Called by PoodLL recorders directly to update filename field on page - * @method updatefilename - * @public - */ - updatefilename : function(args) { - //record the url on the html page - //var filenamecontrol = document.getElementById(args[3]); - var filenamecontrol = document.getElementById(this._getFilenameControlName()); - if(filenamecontrol===null){ filenamecontrol = parent.document.getElementById(args[3]);} - if(filenamecontrol){ - filenamecontrol.value = args[2]; - //var insertbutton = document.getElementById('insert'); - this._form.one('.' + CSS.INPUTSUBMIT).disabled=false; - //insertbutton.disabled = false; - } - - //console.log("just updated: " + args[3] + ' with ' + args[2]); - }, - - - /** - * Display the widgets dialog - * - * @method _displayDialogue - * @private - */ - _displayWidgetsDialogue: function(e, clickedicon) { - e.preventDefault(); - var width=400; - - - var dialogue = this.getDialogue({ - headerContent: M.util.get_string('dialogtitle', COMPONENTNAME), - width: width + 'px', - focusAfterHide: clickedicon - }); - //dialog doesn't detect changes in width without this - //if you reuse the dialog, this seems necessary - if(dialogue.width !== width + 'px'){ - dialogue.set('width',width+'px'); - } - - //create content container - var bodycontent = Y.Node.create('
'); - - //create and append header - var template = Y.Handlebars.compile(BUTTONSHEADERTEMPLATE), - content = Y.Node.create(template({ - headertext: M.util.get_string('chooseinsert', COMPONENTNAME) - })); - bodycontent.append(content); - - //get button nodes - var buttons = this._getButtonsForNames(clickedicon); - - - Y.Array.each(buttons, function(button) { - //loop start + this._form = content; + this._form.one('.' + CSS.INPUTSUBMIT).on('click', this._doInsert, this); + return content; + }, + + + /** + * Get the id of the filename control where poodll stores filename + * + * @method _getFilenameControlName + * @return {String} the name/id of the filename form field + * @private + */ + _getFilenameControlName: function () { + return (this.get('host').get('elementid') + '_' + POODLLFILENAME); + }, + + + /** + * Inserts the url/link onto the page + * @method _getDialogueContent + * @private + */ + _doInsert: function (e) { + e.preventDefault(); + this.getDialogue({ + focusAfterHide: null + }).hide(); + + var thefilename = document.getElementById(this._getFilenameControlName()); + //if no file is there to insert, don't do it + if (!thefilename.value) { + Y.log('No filename control or value could be found.', 'warn', LOGNAME); + return; + } + + var thefilename = thefilename.value; + var wwwroot = M.cfg.wwwroot; + var mediahtml = ''; + + // It will store in mdl_question with the "@@PLUGINFILE@@/myfile.mp3" for the filepath. + var filesrc = wwwroot + '/draftfile.php/' + this._usercontextid + '/user/draft/' + this._itemid + '/' + thefilename; + + //if this is an image, insert the image + if (this._currentrecorder === 'snapshot' || this._currentrecorder === 'whiteboard') { + template = Y.Handlebars.compile(IMAGETEMPLATE); + mediahtml = template({ + url: filesrc, + alt: thefilename + }); + //otherwise insert the link + } else { + mediahtml = '' + thefilename + ''; + } + + this.editor.focus(); + this.get('host').insertContentAtFocusPoint(mediahtml); + this.markUpdated(); + + }, + + /** + * Called by PoodLL recorders directly to update filename field on page + * @method updatefilename + * @public + */ + updatefilename: function (args) { + //record the url on the html page + //var filenamecontrol = document.getElementById(args[3]); + var filenamecontrol = document.getElementById(this._getFilenameControlName()); + if (filenamecontrol === null) { + filenamecontrol = parent.document.getElementById(args[3]); + } + if (filenamecontrol) { + filenamecontrol.value = args[2]; + //var insertbutton = document.getElementById('insert'); + this._form.one('.' + CSS.INPUTSUBMIT).disabled = false; + //insertbutton.disabled = false; + } + + //console.log("just updated: " + args[3] + ' with ' + args[2]); + }, + + + /** + * Display the widgets dialog + * + * @method _displayDialogue + * @private + */ + _displayWidgetsDialogue: function (e, clickedicon) { + e.preventDefault(); + var width = 400; + + + var dialogue = this.getDialogue({ + headerContent: M.util.get_string('dialogtitle', COMPONENTNAME), + width: width + 'px', + focusAfterHide: clickedicon + }); + //dialog doesn't detect changes in width without this + //if you reuse the dialog, this seems necessary + if (dialogue.width !== width + 'px') { + dialogue.set('width', width + 'px'); + } + + //create content container + var bodycontent = Y.Node.create('
'); + + //create and append header + var template = Y.Handlebars.compile(BUTTONSHEADERTEMPLATE), + content = Y.Node.create(template({ + headertext: M.util.get_string('chooseinsert', COMPONENTNAME) + })); + bodycontent.append(content); + + //get button nodes + var buttons = this._getButtonsForNames(clickedicon); + + + Y.Array.each(buttons, function (button) { + //loop start bodycontent.append(button); - //loop end - }, bodycontent); - - - //set to bodycontent - dialogue.set('bodyContent', bodycontent); - dialogue.show(); - this.markUpdated(); - }, - - /** - * Display the chosen widgets template form - * - * @method _showTemplateForm - * @private - */ - _showTemplateForm: function(e,templateindex) { - e.preventDefault(); - var width=400; - - - var dialogue = this.getDialogue({ - headerContent: M.util.get_string('dialogtitle', COMPONENTNAME), - width: width + 'px' - }); - //dialog doesn't detect changes in width without this - //if you reuse the dialog, this seems necessary - if(dialogue.width !== width + 'px'){ - dialogue.set('width',width+'px'); - } + //loop end + }, bodycontent); - //get fields , 1 per variable - var fields = this._getTemplateFields(templateindex); - var instructions = this.get('instructions')[templateindex]; + + //set to bodycontent + dialogue.set('bodyContent', bodycontent); + dialogue.show(); + this.markUpdated(); + }, + + /** + * Display the chosen widgets template form + * + * @method _showTemplateForm + * @private + */ + _showTemplateForm: function (e, templateindex) { + e.preventDefault(); + var width = 400; + + + var dialogue = this.getDialogue({ + headerContent: M.util.get_string('dialogtitle', COMPONENTNAME), + width: width + 'px' + }); + //dialog doesn't detect changes in width without this + //if you reuse the dialog, this seems necessary + if (dialogue.width !== width + 'px') { + dialogue.set('width', width + 'px'); + } + + //get fields , 1 per variable + var fields = this._getTemplateFields(templateindex); + var instructions = this.get('instructions')[templateindex]; instructions = decodeURIComponent(instructions); - - //get header node. It will be different if we have no fields - if(fields && fields.length>0){ - var useheadertext = M.util.get_string('fieldsheader', COMPONENTNAME); - }else{ - var useheadertext = M.util.get_string('nofieldsheader', COMPONENTNAME); - } - var template = Y.Handlebars.compile(FIELDSHEADERTEMPLATE), - content = Y.Node.create(template({ - key: this.get('keys')[templateindex], - headertext: useheadertext, - instructions: instructions - })); - var header = content; - - //set container for our nodes (header, fields, buttons) - var bodycontent = Y.Node.create('
'); - - //add our header - bodycontent.append(header); - - //add fields - Y.Array.each(fields, function(field) { - //loop start + + //get header node. It will be different if we have no fields + if (fields && fields.length > 0) { + var useheadertext = M.util.get_string('fieldsheader', COMPONENTNAME); + } else { + var useheadertext = M.util.get_string('nofieldsheader', COMPONENTNAME); + } + var template = Y.Handlebars.compile(FIELDSHEADERTEMPLATE), + content = Y.Node.create(template({ + key: this.get('keys')[templateindex], + headertext: useheadertext, + instructions: instructions + })); + var header = content; + + //set container for our nodes (header, fields, buttons) + var bodycontent = Y.Node.create('
'); + + //add our header + bodycontent.append(header); + + //add fields + Y.Array.each(fields, function (field) { + //loop start bodycontent.append(field); - //loop end - }, bodycontent); - - //add submit button - var submitbuttons = this._getSubmitButtons(templateindex); - bodycontent.append(submitbuttons) - - //set to bodycontent - dialogue.set('bodyContent', bodycontent); - dialogue.show(); - this.markUpdated(); - }, - - /** - * Return the widget dialogue content for the tool, attaching any required - * events. - * - * @method _getSubmitButtons - * @return {Node} The content to place in the dialogue. - * @private - */ - _getSubmitButtons: function(templateindex) { - - var template = Y.Handlebars.compile(SUBMITTEMPLATE), - - content = Y.Node.create(template({ - elementid: this.get('host').get('elementid'), - inserttext: M.util.get_string('insert', COMPONENTNAME) - })); - - content.one('.' + CSS.INPUTSUBMIT).on('click', this._doWidgetsInsert, this, templateindex); - return content; - }, - - - /** - * Return a field (yui node) for each variable in the template - * - * @method _getTemplateFields - * @return {Node} The content to place in the dialogue. - * @private - */ - _getTemplateFields: function(templateindex) { - - var allcontent=[]; - var thekey=this.get('keys')[templateindex]; - var thevariables=this.get('variables')[templateindex]; - var thedefaults=this.get('defaults')[templateindex]; - - //defaults array - //var defaultsarray=this._getDefArray(thedefaults); - var defaultsarray=thedefaults; - - Y.Array.each(thevariables, function(thevariable, currentindex) { - //loop start - if((thevariable in defaultsarray) && defaultsarray[thevariable].indexOf('|')>-1){ - - var containertemplate = Y.Handlebars.compile(SELECTCONTAINERTEMPLATE), - content = Y.Node.create(containertemplate({ - elementid: this.get('host').get('elementid'), - variable: thevariable, - defaultvalue: defaultsarray[thevariable], - variableindex: currentindex - })); - - var selecttemplate = Y.Handlebars.compile(SELECTTEMPLATE), - selectbox = Y.Node.create(selecttemplate({ - variable: thevariable, - defaultvalue: defaultsarray[thevariable], - variableindex: currentindex - })); - - var opts = defaultsarray[thevariable].split('|'); - var htmloptions=""; - var opttemplate = Y.Handlebars.compile(OPTIONTEMPLATE); - Y.Array.each(opts, function(opt, optindex) { - var optcontent = Y.Node.create(opttemplate({ - option: opt - })); - selectbox.appendChild(optcontent); - }); - content.appendChild(selectbox); - - }else{ - - var template = Y.Handlebars.compile(FIELDTEMPLATE), - content = Y.Node.create(template({ - elementid: this.get('host').get('elementid'), - variable: thevariable, - defaultvalue: defaultsarray[thevariable], - variableindex: currentindex - })); - } - - - allcontent.push(content); - //loop end - }, this); - - - return allcontent; - }, - - - /** - * Return the dialogue content for the tool, attaching any required - * events. - * - * @method _getButtonsForNames - * @return {Node} The content to place in the dialogue. - * @private - */ - _getButtonsForNames: function(clickedicon) { - - var allcontent=[]; - Y.Array.each(this.get('names'), function(thename, currentindex) { - //loop start - var template = Y.Handlebars.compile(BUTTONTEMPLATE), - content = Y.Node.create(template({ - elementid: this.get('host').get('elementid'), - name: thename, - templateindex: currentindex - })); - this._form = content; - content.one('.' + CSS.NAMEBUTTON + '_' + currentindex).on('click', this._showTemplateForm, this,currentindex); - allcontent.push(content); - //loop end - }, this); - - return allcontent; - }, - - _getDefArray: function(thedefaults){ - //defaults array - var defaultsarray=[]; - var defaultstemparray = thedefaults.match(/([^=,]*)=("[^"]*"|[^,"]*)/g);//thedefaults.split(','); - Y.Array.each(defaultstemparray, function(defset){ - //loop start - var defsetarray = defset.split('='); - if(defsetarray && defsetarray.length>1){ - defaultsarray[defsetarray[0]] = defsetarray[1].replace(/"/g,''); - } - //loop end - }, this); - return defaultsarray; - - }, + //loop end + }, bodycontent); + + //add submit button + var submitbuttons = this._getSubmitButtons(templateindex); + bodycontent.append(submitbuttons) + + //set to bodycontent + dialogue.set('bodyContent', bodycontent); + dialogue.show(); + this.markUpdated(); + }, + + /** + * Return the widget dialogue content for the tool, attaching any required + * events. + * + * @method _getSubmitButtons + * @return {Node} The content to place in the dialogue. + * @private + */ + _getSubmitButtons: function (templateindex) { + + var template = Y.Handlebars.compile(SUBMITTEMPLATE), + + content = Y.Node.create(template({ + elementid: this.get('host').get('elementid'), + inserttext: M.util.get_string('insert', COMPONENTNAME) + })); + + content.one('.' + CSS.INPUTSUBMIT).on('click', this._doWidgetsInsert, this, templateindex); + return content; + }, + + + /** + * Return a field (yui node) for each variable in the template + * + * @method _getTemplateFields + * @return {Node} The content to place in the dialogue. + * @private + */ + _getTemplateFields: function (templateindex) { + + var allcontent = []; + var thekey = this.get('keys')[templateindex]; + var thevariables = this.get('variables')[templateindex]; + var thedefaults = this.get('defaults')[templateindex]; + + //defaults array + //var defaultsarray=this._getDefArray(thedefaults); + var defaultsarray = thedefaults; + + Y.Array.each(thevariables, function (thevariable, currentindex) { + //loop start + if ((thevariable in defaultsarray) && defaultsarray[thevariable].indexOf('|') > -1) { + + var containertemplate = Y.Handlebars.compile(SELECTCONTAINERTEMPLATE), + content = Y.Node.create(containertemplate({ + elementid: this.get('host').get('elementid'), + variable: thevariable, + defaultvalue: defaultsarray[thevariable], + variableindex: currentindex + })); + + var selecttemplate = Y.Handlebars.compile(SELECTTEMPLATE), + selectbox = Y.Node.create(selecttemplate({ + variable: thevariable, + defaultvalue: defaultsarray[thevariable], + variableindex: currentindex + })); + + var opts = defaultsarray[thevariable].split('|'); + var htmloptions = ""; + var opttemplate = Y.Handlebars.compile(OPTIONTEMPLATE); + Y.Array.each(opts, function (opt, optindex) { + var optcontent = Y.Node.create(opttemplate({ + option: opt + })); + selectbox.appendChild(optcontent); + }); + content.appendChild(selectbox); + + } else { + + var template = Y.Handlebars.compile(FIELDTEMPLATE), + content = Y.Node.create(template({ + elementid: this.get('host').get('elementid'), + variable: thevariable, + defaultvalue: defaultsarray[thevariable], + variableindex: currentindex + })); + } + + + allcontent.push(content); + //loop end + }, this); + + + return allcontent; + }, + + + /** + * Return the dialogue content for the tool, attaching any required + * events. + * + * @method _getButtonsForNames + * @return {Node} The content to place in the dialogue. + * @private + */ + _getButtonsForNames: function (clickedicon) { + + var allcontent = []; + Y.Array.each(this.get('names'), function (thename, currentindex) { + //loop start + var template = Y.Handlebars.compile(BUTTONTEMPLATE), + content = Y.Node.create(template({ + elementid: this.get('host').get('elementid'), + name: thename, + templateindex: currentindex + })); + this._form = content; + content.one('.' + CSS.NAMEBUTTON + '_' + currentindex).on('click', this._showTemplateForm, this, currentindex); + allcontent.push(content); + //loop end + }, this); + + return allcontent; + }, + + _getDefArray: function (thedefaults) { + //defaults array + var defaultsarray = []; + var defaultstemparray = thedefaults.match(/([^=,]*)=("[^"]*"|[^,"]*)/g);//thedefaults.split(','); + Y.Array.each(defaultstemparray, function (defset) { + //loop start + var defsetarray = defset.split('='); + if (defsetarray && defsetarray.length > 1) { + defaultsarray[defsetarray[0]] = defsetarray[1].replace(/"/g, ''); + } + //loop end + }, this); + return defaultsarray; + + }, + + /** + * Inserts the users input onto the page + * @method _getDialogueContent + * @private + */ + _doWidgetsInsert: function (e, templateindex) { + e.preventDefault(); + this.getDialogue({ + focusAfterHide: null + }).hide(); + + var retstring = "{POODLL:type="; + var thekey = this.get('keys')[templateindex]; + var thevariables = this.get('variables')[templateindex]; + var thedefaults = this.get('defaults')[templateindex]; + var theend = this.get('ends')[templateindex]; + var defaultsarray = thedefaults; + + //add key to return string + retstring += '"' + thekey + '"'; + + //add variables to return string + Y.Array.each(thevariables, function (variable, currentindex) { + //loop start + var thefield = Y.one('.' + CSS.TEMPLATEVARIABLE + '_' + currentindex); + var thevalue = thefield.get('value'); + if (thevalue && thevalue != defaultsarray[variable]) { + retstring += ',' + variable + '="' + thevalue + '"'; + } + //loop end + }, this); + + //close out return string + retstring += "}"; + + //add an end tag, if we need to + if (theend) { + retstring += '
{POODLL:type="' + thekey + '_end"}'; + } + + this.editor.focus(); + this.get('host').insertContentAtFocusPoint(retstring); + this.markUpdated(); - /** - * Inserts the users input onto the page - * @method _getDialogueContent - * @private - */ - _doWidgetsInsert : function(e,templateindex){ - e.preventDefault(); - this.getDialogue({ - focusAfterHide: null - }).hide(); - - var retstring = "{POODLL:type="; - var thekey = this.get('keys')[templateindex]; - var thevariables=this.get('variables')[templateindex]; - var thedefaults=this.get('defaults')[templateindex]; - var theend=this.get('ends')[templateindex]; - var defaultsarray=thedefaults; - - //add key to return string - retstring += '"' + thekey + '"'; - - //add variables to return string - Y.Array.each(thevariables, function(variable, currentindex) { - //loop start - var thefield = Y.one('.' + CSS.TEMPLATEVARIABLE + '_' + currentindex); - var thevalue = thefield.get('value'); - if(thevalue && thevalue!=defaultsarray[variable]){ - retstring += ',' + variable + '="' + thevalue + '"'; - } - //loop end - }, this); - - //close out return string - retstring += "}"; - - //add an end tag, if we need to - if(theend){ - retstring += '
{POODLL:type="' + thekey + '_end"}'; } - this.editor.focus(); - this.get('host').insertContentAtFocusPoint(retstring); - this.markUpdated(); - - } - -}, {ATTRS: { - names: { - value: null - }, - - keys: { - value: null - }, - - variables: { - value: null - }, - - defaults: { - value: null - } - , - instructions: { - value: null - }, - customicon: { - value: null - }, - ends: { - value: null - } - } -}); + }, { + ATTRS: { + names: { + value: null + }, + + keys: { + value: null + }, + + variables: { + value: null + }, + + defaults: { + value: null + } + , + instructions: { + value: null + }, + customicon: { + value: null + }, + ends: { + value: null + } + } + }); }, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]}); diff --git a/yui/build/moodle-atto_poodll-button/moodle-atto_poodll-button.js b/yui/build/moodle-atto_poodll-button/moodle-atto_poodll-button.js index 221f6eb..0ae2839 100644 --- a/yui/build/moodle-atto_poodll-button/moodle-atto_poodll-button.js +++ b/yui/build/moodle-atto_poodll-button/moodle-atto_poodll-button.js @@ -15,654 +15,657 @@ YUI.add('moodle-atto_poodll-button', function (Y, NAME) { // You should have received a copy of the GNU General Public License // along with Moodle. If not, see . -/* - * @package atto_poodll - * @copyright 2016 Justin Hunt - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - -/** - * @module moodle-atto_poodll-button - */ + /* + * @package atto_poodll + * @copyright 2016 Justin Hunt + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ -/** - * Atto text editor poodll plugin. - * - * @namespace M.atto_poodll - * @class button - * @extends M.editor_atto.EditorPlugin - */ + /** + * @module moodle-atto_poodll-button + */ -var COMPONENTNAME = 'atto_poodll'; -var POODLLFILENAME = 'poodllfilename'; -var LOGNAME = 'atto_poodll'; + /** + * Atto text editor poodll plugin. + * + * @namespace M.atto_poodll + * @class button + * @extends M.editor_atto.EditorPlugin + */ + var COMPONENTNAME = 'atto_poodll'; + var POODLLFILENAME = 'poodllfilename'; + var LOGNAME = 'atto_poodll'; -var CSS = { + var CSS = { INPUTSUBMIT: 'atto_media_urlentrysubmit', INPUTCANCEL: 'atto_media_urlentrycancel', NAMEBUTTON: 'atto_poodll_templatebutton', HEADERTEXT: 'atto_poodll_headertext', INSTRUCTIONSTEXT: 'atto_poodll_instructionstext', - TEMPLATEVARIABLE: 'atto_poodll_templatevariable' + TEMPLATEVARIABLE: 'atto_poodll_templatevariable' }; -var TEMPLATE = '' + - '
' + - '
' + - '' + - '' + - '
' + - '
'; + var TEMPLATE = '' + + '
' + + '
' + + '' + + '' + + '
' + + '
'; -var IMAGETEMPLATE = '' + '{{alt}}'; + var IMAGETEMPLATE = '' + '{{alt}}'; -var FIELDSHEADERTEMPLATE = '' + + var FIELDSHEADERTEMPLATE = '' + '
' + - '

{{headertext}} {{key}}

' + - '
{{instructions}}
' + + '

{{headertext}} {{key}}

' + + '
{{instructions}}
' + '
'; -var BUTTONSHEADERTEMPLATE = '' + + var BUTTONSHEADERTEMPLATE = '' + '
' + - '

{{headertext}}

' + + '

{{headertext}}

' + '
'; - -var BUTTONTEMPLATE = '' + + + var BUTTONTEMPLATE = '' + '
' + - '' + + '' + '
'; - -var FIELDTEMPLATE = '' + + + var FIELDTEMPLATE = '' + '
{{variable}}' + - ' ' + + ' ' + '
'; -var SELECTCONTAINERTEMPLATE = '' + - '
{{variable}}
'; - -var SELECTTEMPLATE = '' + - ''; + var SELECTCONTAINERTEMPLATE = '' + + '
{{variable}}
'; -var OPTIONTEMPLATE ='' + - ''; + var SELECTTEMPLATE = '' + + ''; -var SUBMITTEMPLATE = '' + - '
' + - '
' + - '' + - '
' + - '
'; + var OPTIONTEMPLATE = '' + + ''; + var SUBMITTEMPLATE = '' + + '
' + + '
' + + '' + + '
' + + '
'; -Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { + Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { - /** - * A reference to the current selection at the time that the dialogue - * was opened. - * - * @property _currentSelection - * @type Range - * @private - */ - _currentSelection: null, + /** + * A reference to the current selection at the time that the dialogue + * was opened. + * + * @property _currentSelection + * @type Range + * @private + */ + _currentSelection: null, - /** - * A reference to the dialogue content. - * - * @property _content - * @type Node - * @private - */ - _content: null, - _currentrecorder: null, - _itemid: null, - _usercontextid: null, - _coursecontextid: null, - _modulecontextid: null, - _usewhiteboard: null, - - initializer: function(config) { - this._usercontextid = config.usercontextid; - this._coursecontextid = config.coursecontextid; - this._usewhiteboard = config.usewhiteboard; - - var host = this.get('host'); - var options = host.get('filepickeroptions'); - if (options.image && options.image.itemid) { - this._itemid = options.image.itemid; - if (options.image.context && options.image.context.id) { - this._modulecontextid = options.image.context.id; + /** + * A reference to the dialogue content. + * + * @property _content + * @type Node + * @private + */ + _content: null, + _currentrecorder: null, + _itemid: null, + _usercontextid: null, + _coursecontextid: null, + _modulecontextid: null, + _usewhiteboard: null, + + initializer: function (config) { + this._usercontextid = config.usercontextid; + this._coursecontextid = config.coursecontextid; + this._usewhiteboard = config.usewhiteboard; + + var host = this.get('host'); + var options = host.get('filepickeroptions'); + if (options.image && options.image.itemid) { + this._itemid = options.image.itemid; + if (options.image.context && options.image.context.id) { + this._modulecontextid = options.image.context.id; + } + } else { + return; } - } else { - return; - } - - //if we don't have the capability, or no file uploads allowed, give up. - if(config.disabled){ - return; - } - - - var recorders = new Array('audiomp3','video', 'whiteboard','snapshot','widgets'); - for (var therecorder = 0; therecorder < recorders.length; therecorder++) { - // Add the poodll button first (if we are supposed to) - if(config.hasOwnProperty(recorders[therecorder])){ - this.addButton({ - icon: recorders[therecorder], - iconComponent: 'atto_poodll', - title: recorders[therecorder] + '_desc', - buttonName: recorders[therecorder], - callback: this._displayDialogue, - callbackArgs: recorders[therecorder] - }); - } - } - - - }, - - /** - * Display the PoodLL Recorder files. - * - * @method _displayDialogue - * @private - */ - _displayDialogue: function(e, therecorder) { - e.preventDefault(); - this._currentrecorder = therecorder; - - if(therecorder=='widgets'){ - this._displayWidgetsDialogue(e,therecorder); - return; - } - - var width=400; - var height=260; - switch(therecorder){ - case 'audiomp3': - width=400; - height=300; - break; - case 'video': - case 'snapshot':width=360; - height=450; - break; - case 'whiteboard': width=680; - height=540; - break; - } - - //the dialogue widths are a bit bogus - var dialogue = this.getDialogue({ - headerContent: M.util.get_string('dialogtitle', COMPONENTNAME), - width: width + 'px', - focusAfterHide: therecorder - }); - if(dialogue.width != width + 'px'){ - dialogue.set('width',width + 30 +'px'); - } - var iframeid = 'atto_poodll_dialog_iframe_' + new Date().getTime(); - //var iframe = Y.Node.create(''); - // var iframe = Y.Node.create(''); - var iframe = Y.Node.create(''); - - iframe.setStyles({ - border: 'none', - overflow: 'hidden' - }); - - //set attributes on the iframe - iframe.setAttribute('src', this._getIframeURL(therecorder, iframeid)); - iframe.setAttribute('scrolling', 'no'); - - //append buttons to iframe - var buttonform = this._getFormContent(); - - var bodycontent = Y.Node.create('
'); - bodycontent.append(iframe).append(buttonform); - - //set to bodycontent - dialogue.set('bodyContent', bodycontent); - dialogue.show(); - this.markUpdated(); - }, - - /** - * Returns the URL to the file manager. - * - * @param _getIframeURL - * @return {String} URL - * @private - */ - _getIframeURL: function(therecorder, iframeid) { - return M.cfg.wwwroot + '/lib/editor/atto/plugins/poodll/dialog/poodll.php?' + - 'itemid='+ this._itemid + '&recorder=' + therecorder + '&usewhiteboard=' + this._usewhiteboard + - '&iframeid=' + iframeid + '&coursecontextid=' + this._coursecontextid + '&modulecontextid=' + this._modulecontextid + - '&updatecontrol=' + this._getFilenameControlName(); - }, - + //if we don't have the capability, or no file uploads allowed, give up. + if (config.disabled) { + return; + } + + + var recorders = new Array('audiomp3', 'video', 'whiteboard', 'snapshot', 'widgets'); + for (var therecorder = 0; therecorder < recorders.length; therecorder++) { + // Add the poodll button first (if we are supposed to) + if (config.hasOwnProperty(recorders[therecorder])) { + this.addButton({ + icon: recorders[therecorder], + iconComponent: 'atto_poodll', + title: recorders[therecorder] + '_desc', + buttonName: recorders[therecorder], + callback: this._displayDialogue, + callbackArgs: recorders[therecorder] + }); + } + } + + + }, + /** - * Return the dialogue content for the tool, attaching any required - * events. - * - * @method _getDialogueContent - * @return {Node} The content to place in the dialogue. - * @private - */ - _getFormContent: function() { - var template = Y.Handlebars.compile(TEMPLATE), - content = Y.Node.create(template({ - elementid: this.get('host').get('elementid'), - CSS: CSS, - poodllfilename: POODLLFILENAME, - component: COMPONENTNAME - })); - - this._form = content; - this._form.one('.' + CSS.INPUTSUBMIT).on('click', this._doInsert, this); - return content; - }, - - + * Display the PoodLL Recorder files. + * + * @method _displayDialogue + * @private + */ + _displayDialogue: function (e, therecorder) { + e.preventDefault(); + this._currentrecorder = therecorder; + + if (therecorder == 'widgets') { + this._displayWidgetsDialogue(e, therecorder); + return; + } + + var width = 400; + var height = 260; + switch (therecorder) { + case 'audiomp3': + width = 400; + height = 300; + break; + case 'video': + case 'snapshot': + width = 360; + height = 450; + break; + case 'whiteboard': + width = 680; + height = 540; + break; + } + + //the dialogue widths are a bit bogus + var dialogue = this.getDialogue({ + headerContent: M.util.get_string('dialogtitle', COMPONENTNAME), + width: width + 'px', + focusAfterHide: therecorder + }); + if (dialogue.width != width + 'px') { + dialogue.set('width', width + 30 + 'px'); + } + + var iframeid = 'atto_poodll_dialog_iframe_' + new Date().getTime(); + //var iframe = Y.Node.create(''); + // var iframe = Y.Node.create(''); + var iframe = Y.Node.create(''); + + iframe.setStyles({ + border: 'none', + overflow: 'hidden' + }); + + //set attributes on the iframe + iframe.setAttribute('src', this._getIframeURL(therecorder, iframeid)); + iframe.setAttribute('scrolling', 'no'); + + //append buttons to iframe + var buttonform = this._getFormContent(); + + var bodycontent = Y.Node.create('
'); + bodycontent.append(iframe).append(buttonform); + + //set to bodycontent + dialogue.set('bodyContent', bodycontent); + dialogue.show(); + this.markUpdated(); + }, + /** - * Get the id of the filename control where poodll stores filename - * - * @method _getFilenameControlName - * @return {String} the name/id of the filename form field - * @private - */ - _getFilenameControlName: function(){ - return(this.get('host').get('elementid') + '_' + POODLLFILENAME); - }, - - + * Returns the URL to the file manager. + * + * @param _getIframeURL + * @return {String} URL + * @private + */ + _getIframeURL: function (therecorder, iframeid) { + return M.cfg.wwwroot + '/lib/editor/atto/plugins/poodll/dialog/poodll.php?' + + 'itemid=' + this._itemid + '&recorder=' + therecorder + '&usewhiteboard=' + this._usewhiteboard + + '&iframeid=' + iframeid + '&coursecontextid=' + this._coursecontextid + '&modulecontextid=' + this._modulecontextid + + '&updatecontrol=' + this._getFilenameControlName(); + }, + /** - * Inserts the url/link onto the page - * @method _getDialogueContent - * @private - */ - _doInsert : function(e){ - e.preventDefault(); - this.getDialogue({ - focusAfterHide: null - }).hide(); - - var thefilename = document.getElementById(this._getFilenameControlName()); - //if no file is there to insert, don't do it - if(!thefilename.value){ - return; - } + * Return the dialogue content for the tool, attaching any required + * events. + * + * @method _getDialogueContent + * @return {Node} The content to place in the dialogue. + * @private + */ + _getFormContent: function () { + var template = Y.Handlebars.compile(TEMPLATE), + content = Y.Node.create(template({ + elementid: this.get('host').get('elementid'), + CSS: CSS, + poodllfilename: POODLLFILENAME, + component: COMPONENTNAME + })); - var thefilename = thefilename.value; - var wwwroot = M.cfg.wwwroot; - var mediahtml=''; - - // It will store in mdl_question with the "@@PLUGINFILE@@/myfile.mp3" for the filepath. - var filesrc =wwwroot+'/draftfile.php/'+ this._usercontextid +'/user/draft/'+this._itemid+'/'+thefilename; - - //if this is an image, insert the image - if(this._currentrecorder==='snapshot' ||this._currentrecorder==='whiteboard'){ - template = Y.Handlebars.compile(IMAGETEMPLATE); - mediahtml = template({ - url: filesrc, - alt: thefilename - }); - //otherwise insert the link - }else{ - mediahtml = ''+thefilename+''; - } - - this.editor.focus(); - this.get('host').insertContentAtFocusPoint(mediahtml); - this.markUpdated(); - - }, - - /** - * Called by PoodLL recorders directly to update filename field on page - * @method updatefilename - * @public - */ - updatefilename : function(args) { - //record the url on the html page - //var filenamecontrol = document.getElementById(args[3]); - var filenamecontrol = document.getElementById(this._getFilenameControlName()); - if(filenamecontrol===null){ filenamecontrol = parent.document.getElementById(args[3]);} - if(filenamecontrol){ - filenamecontrol.value = args[2]; - //var insertbutton = document.getElementById('insert'); - this._form.one('.' + CSS.INPUTSUBMIT).disabled=false; - //insertbutton.disabled = false; - } - - //console.log("just updated: " + args[3] + ' with ' + args[2]); - }, - - - /** - * Display the widgets dialog - * - * @method _displayDialogue - * @private - */ - _displayWidgetsDialogue: function(e, clickedicon) { - e.preventDefault(); - var width=400; - - - var dialogue = this.getDialogue({ - headerContent: M.util.get_string('dialogtitle', COMPONENTNAME), - width: width + 'px', - focusAfterHide: clickedicon - }); - //dialog doesn't detect changes in width without this - //if you reuse the dialog, this seems necessary - if(dialogue.width !== width + 'px'){ - dialogue.set('width',width+'px'); - } - - //create content container - var bodycontent = Y.Node.create('
'); - - //create and append header - var template = Y.Handlebars.compile(BUTTONSHEADERTEMPLATE), - content = Y.Node.create(template({ - headertext: M.util.get_string('chooseinsert', COMPONENTNAME) - })); - bodycontent.append(content); - - //get button nodes - var buttons = this._getButtonsForNames(clickedicon); - - - Y.Array.each(buttons, function(button) { - //loop start + this._form = content; + this._form.one('.' + CSS.INPUTSUBMIT).on('click', this._doInsert, this); + return content; + }, + + + /** + * Get the id of the filename control where poodll stores filename + * + * @method _getFilenameControlName + * @return {String} the name/id of the filename form field + * @private + */ + _getFilenameControlName: function () { + return (this.get('host').get('elementid') + '_' + POODLLFILENAME); + }, + + + /** + * Inserts the url/link onto the page + * @method _getDialogueContent + * @private + */ + _doInsert: function (e) { + e.preventDefault(); + this.getDialogue({ + focusAfterHide: null + }).hide(); + + var thefilename = document.getElementById(this._getFilenameControlName()); + //if no file is there to insert, don't do it + if (!thefilename.value) { + return; + } + + var thefilename = thefilename.value; + var wwwroot = M.cfg.wwwroot; + var mediahtml = ''; + + // It will store in mdl_question with the "@@PLUGINFILE@@/myfile.mp3" for the filepath. + var filesrc = wwwroot + '/draftfile.php/' + this._usercontextid + '/user/draft/' + this._itemid + '/' + thefilename; + + //if this is an image, insert the image + if (this._currentrecorder === 'snapshot' || this._currentrecorder === 'whiteboard') { + template = Y.Handlebars.compile(IMAGETEMPLATE); + mediahtml = template({ + url: filesrc, + alt: thefilename + }); + //otherwise insert the link + } else { + mediahtml = '' + thefilename + ''; + } + + this.editor.focus(); + this.get('host').insertContentAtFocusPoint(mediahtml); + this.markUpdated(); + + }, + + /** + * Called by PoodLL recorders directly to update filename field on page + * @method updatefilename + * @public + */ + updatefilename: function (args) { + //record the url on the html page + //var filenamecontrol = document.getElementById(args[3]); + var filenamecontrol = document.getElementById(this._getFilenameControlName()); + if (filenamecontrol === null) { + filenamecontrol = parent.document.getElementById(args[3]); + } + if (filenamecontrol) { + filenamecontrol.value = args[2]; + //var insertbutton = document.getElementById('insert'); + this._form.one('.' + CSS.INPUTSUBMIT).disabled = false; + //insertbutton.disabled = false; + } + + //console.log("just updated: " + args[3] + ' with ' + args[2]); + }, + + + /** + * Display the widgets dialog + * + * @method _displayDialogue + * @private + */ + _displayWidgetsDialogue: function (e, clickedicon) { + e.preventDefault(); + var width = 400; + + + var dialogue = this.getDialogue({ + headerContent: M.util.get_string('dialogtitle', COMPONENTNAME), + width: width + 'px', + focusAfterHide: clickedicon + }); + //dialog doesn't detect changes in width without this + //if you reuse the dialog, this seems necessary + if (dialogue.width !== width + 'px') { + dialogue.set('width', width + 'px'); + } + + //create content container + var bodycontent = Y.Node.create('
'); + + //create and append header + var template = Y.Handlebars.compile(BUTTONSHEADERTEMPLATE), + content = Y.Node.create(template({ + headertext: M.util.get_string('chooseinsert', COMPONENTNAME) + })); + bodycontent.append(content); + + //get button nodes + var buttons = this._getButtonsForNames(clickedicon); + + + Y.Array.each(buttons, function (button) { + //loop start bodycontent.append(button); - //loop end - }, bodycontent); - - - //set to bodycontent - dialogue.set('bodyContent', bodycontent); - dialogue.show(); - this.markUpdated(); - }, - - /** - * Display the chosen widgets template form - * - * @method _showTemplateForm - * @private - */ - _showTemplateForm: function(e,templateindex) { - e.preventDefault(); - var width=400; - - - var dialogue = this.getDialogue({ - headerContent: M.util.get_string('dialogtitle', COMPONENTNAME), - width: width + 'px' - }); - //dialog doesn't detect changes in width without this - //if you reuse the dialog, this seems necessary - if(dialogue.width !== width + 'px'){ - dialogue.set('width',width+'px'); - } + //loop end + }, bodycontent); + - //get fields , 1 per variable - var fields = this._getTemplateFields(templateindex); - var instructions = this.get('instructions')[templateindex]; + //set to bodycontent + dialogue.set('bodyContent', bodycontent); + dialogue.show(); + this.markUpdated(); + }, + + /** + * Display the chosen widgets template form + * + * @method _showTemplateForm + * @private + */ + _showTemplateForm: function (e, templateindex) { + e.preventDefault(); + var width = 400; + + + var dialogue = this.getDialogue({ + headerContent: M.util.get_string('dialogtitle', COMPONENTNAME), + width: width + 'px' + }); + //dialog doesn't detect changes in width without this + //if you reuse the dialog, this seems necessary + if (dialogue.width !== width + 'px') { + dialogue.set('width', width + 'px'); + } + + //get fields , 1 per variable + var fields = this._getTemplateFields(templateindex); + var instructions = this.get('instructions')[templateindex]; instructions = decodeURIComponent(instructions); - - //get header node. It will be different if we have no fields - if(fields && fields.length>0){ - var useheadertext = M.util.get_string('fieldsheader', COMPONENTNAME); - }else{ - var useheadertext = M.util.get_string('nofieldsheader', COMPONENTNAME); - } - var template = Y.Handlebars.compile(FIELDSHEADERTEMPLATE), - content = Y.Node.create(template({ - key: this.get('keys')[templateindex], - headertext: useheadertext, - instructions: instructions - })); - var header = content; - - //set container for our nodes (header, fields, buttons) - var bodycontent = Y.Node.create('
'); - - //add our header - bodycontent.append(header); - - //add fields - Y.Array.each(fields, function(field) { - //loop start + + //get header node. It will be different if we have no fields + if (fields && fields.length > 0) { + var useheadertext = M.util.get_string('fieldsheader', COMPONENTNAME); + } else { + var useheadertext = M.util.get_string('nofieldsheader', COMPONENTNAME); + } + var template = Y.Handlebars.compile(FIELDSHEADERTEMPLATE), + content = Y.Node.create(template({ + key: this.get('keys')[templateindex], + headertext: useheadertext, + instructions: instructions + })); + var header = content; + + //set container for our nodes (header, fields, buttons) + var bodycontent = Y.Node.create('
'); + + //add our header + bodycontent.append(header); + + //add fields + Y.Array.each(fields, function (field) { + //loop start bodycontent.append(field); - //loop end - }, bodycontent); - - //add submit button - var submitbuttons = this._getSubmitButtons(templateindex); - bodycontent.append(submitbuttons) - - //set to bodycontent - dialogue.set('bodyContent', bodycontent); - dialogue.show(); - this.markUpdated(); - }, - - /** - * Return the widget dialogue content for the tool, attaching any required - * events. - * - * @method _getSubmitButtons - * @return {Node} The content to place in the dialogue. - * @private - */ - _getSubmitButtons: function(templateindex) { - - var template = Y.Handlebars.compile(SUBMITTEMPLATE), - - content = Y.Node.create(template({ - elementid: this.get('host').get('elementid'), - inserttext: M.util.get_string('insert', COMPONENTNAME) - })); - - content.one('.' + CSS.INPUTSUBMIT).on('click', this._doWidgetsInsert, this, templateindex); - return content; - }, - - - /** - * Return a field (yui node) for each variable in the template - * - * @method _getTemplateFields - * @return {Node} The content to place in the dialogue. - * @private - */ - _getTemplateFields: function(templateindex) { - - var allcontent=[]; - var thekey=this.get('keys')[templateindex]; - var thevariables=this.get('variables')[templateindex]; - var thedefaults=this.get('defaults')[templateindex]; - - //defaults array - //var defaultsarray=this._getDefArray(thedefaults); - var defaultsarray=thedefaults; - - Y.Array.each(thevariables, function(thevariable, currentindex) { - //loop start - if((thevariable in defaultsarray) && defaultsarray[thevariable].indexOf('|')>-1){ - - var containertemplate = Y.Handlebars.compile(SELECTCONTAINERTEMPLATE), - content = Y.Node.create(containertemplate({ - elementid: this.get('host').get('elementid'), - variable: thevariable, - defaultvalue: defaultsarray[thevariable], - variableindex: currentindex - })); - - var selecttemplate = Y.Handlebars.compile(SELECTTEMPLATE), - selectbox = Y.Node.create(selecttemplate({ - variable: thevariable, - defaultvalue: defaultsarray[thevariable], - variableindex: currentindex - })); - - var opts = defaultsarray[thevariable].split('|'); - var htmloptions=""; - var opttemplate = Y.Handlebars.compile(OPTIONTEMPLATE); - Y.Array.each(opts, function(opt, optindex) { - var optcontent = Y.Node.create(opttemplate({ - option: opt - })); - selectbox.appendChild(optcontent); - }); - content.appendChild(selectbox); - - }else{ - - var template = Y.Handlebars.compile(FIELDTEMPLATE), - content = Y.Node.create(template({ - elementid: this.get('host').get('elementid'), - variable: thevariable, - defaultvalue: defaultsarray[thevariable], - variableindex: currentindex - })); - } - - - allcontent.push(content); - //loop end - }, this); - - - return allcontent; - }, - - - /** - * Return the dialogue content for the tool, attaching any required - * events. - * - * @method _getButtonsForNames - * @return {Node} The content to place in the dialogue. - * @private - */ - _getButtonsForNames: function(clickedicon) { - - var allcontent=[]; - Y.Array.each(this.get('names'), function(thename, currentindex) { - //loop start - var template = Y.Handlebars.compile(BUTTONTEMPLATE), - content = Y.Node.create(template({ - elementid: this.get('host').get('elementid'), - name: thename, - templateindex: currentindex - })); - this._form = content; - content.one('.' + CSS.NAMEBUTTON + '_' + currentindex).on('click', this._showTemplateForm, this,currentindex); - allcontent.push(content); - //loop end - }, this); - - return allcontent; - }, - - _getDefArray: function(thedefaults){ - //defaults array - var defaultsarray=[]; - var defaultstemparray = thedefaults.match(/([^=,]*)=("[^"]*"|[^,"]*)/g);//thedefaults.split(','); - Y.Array.each(defaultstemparray, function(defset){ - //loop start - var defsetarray = defset.split('='); - if(defsetarray && defsetarray.length>1){ - defaultsarray[defsetarray[0]] = defsetarray[1].replace(/"/g,''); - } - //loop end - }, this); - return defaultsarray; - - }, + //loop end + }, bodycontent); + + //add submit button + var submitbuttons = this._getSubmitButtons(templateindex); + bodycontent.append(submitbuttons) + + //set to bodycontent + dialogue.set('bodyContent', bodycontent); + dialogue.show(); + this.markUpdated(); + }, + + /** + * Return the widget dialogue content for the tool, attaching any required + * events. + * + * @method _getSubmitButtons + * @return {Node} The content to place in the dialogue. + * @private + */ + _getSubmitButtons: function (templateindex) { + + var template = Y.Handlebars.compile(SUBMITTEMPLATE), + + content = Y.Node.create(template({ + elementid: this.get('host').get('elementid'), + inserttext: M.util.get_string('insert', COMPONENTNAME) + })); + + content.one('.' + CSS.INPUTSUBMIT).on('click', this._doWidgetsInsert, this, templateindex); + return content; + }, + + + /** + * Return a field (yui node) for each variable in the template + * + * @method _getTemplateFields + * @return {Node} The content to place in the dialogue. + * @private + */ + _getTemplateFields: function (templateindex) { + + var allcontent = []; + var thekey = this.get('keys')[templateindex]; + var thevariables = this.get('variables')[templateindex]; + var thedefaults = this.get('defaults')[templateindex]; + + //defaults array + //var defaultsarray=this._getDefArray(thedefaults); + var defaultsarray = thedefaults; + + Y.Array.each(thevariables, function (thevariable, currentindex) { + //loop start + if ((thevariable in defaultsarray) && defaultsarray[thevariable].indexOf('|') > -1) { + + var containertemplate = Y.Handlebars.compile(SELECTCONTAINERTEMPLATE), + content = Y.Node.create(containertemplate({ + elementid: this.get('host').get('elementid'), + variable: thevariable, + defaultvalue: defaultsarray[thevariable], + variableindex: currentindex + })); + + var selecttemplate = Y.Handlebars.compile(SELECTTEMPLATE), + selectbox = Y.Node.create(selecttemplate({ + variable: thevariable, + defaultvalue: defaultsarray[thevariable], + variableindex: currentindex + })); + + var opts = defaultsarray[thevariable].split('|'); + var htmloptions = ""; + var opttemplate = Y.Handlebars.compile(OPTIONTEMPLATE); + Y.Array.each(opts, function (opt, optindex) { + var optcontent = Y.Node.create(opttemplate({ + option: opt + })); + selectbox.appendChild(optcontent); + }); + content.appendChild(selectbox); + + } else { + + var template = Y.Handlebars.compile(FIELDTEMPLATE), + content = Y.Node.create(template({ + elementid: this.get('host').get('elementid'), + variable: thevariable, + defaultvalue: defaultsarray[thevariable], + variableindex: currentindex + })); + } + + + allcontent.push(content); + //loop end + }, this); + + + return allcontent; + }, + + + /** + * Return the dialogue content for the tool, attaching any required + * events. + * + * @method _getButtonsForNames + * @return {Node} The content to place in the dialogue. + * @private + */ + _getButtonsForNames: function (clickedicon) { + + var allcontent = []; + Y.Array.each(this.get('names'), function (thename, currentindex) { + //loop start + var template = Y.Handlebars.compile(BUTTONTEMPLATE), + content = Y.Node.create(template({ + elementid: this.get('host').get('elementid'), + name: thename, + templateindex: currentindex + })); + this._form = content; + content.one('.' + CSS.NAMEBUTTON + '_' + currentindex).on('click', this._showTemplateForm, this, currentindex); + allcontent.push(content); + //loop end + }, this); + + return allcontent; + }, + + _getDefArray: function (thedefaults) { + //defaults array + var defaultsarray = []; + var defaultstemparray = thedefaults.match(/([^=,]*)=("[^"]*"|[^,"]*)/g);//thedefaults.split(','); + Y.Array.each(defaultstemparray, function (defset) { + //loop start + var defsetarray = defset.split('='); + if (defsetarray && defsetarray.length > 1) { + defaultsarray[defsetarray[0]] = defsetarray[1].replace(/"/g, ''); + } + //loop end + }, this); + return defaultsarray; + + }, + + /** + * Inserts the users input onto the page + * @method _getDialogueContent + * @private + */ + _doWidgetsInsert: function (e, templateindex) { + e.preventDefault(); + this.getDialogue({ + focusAfterHide: null + }).hide(); + + var retstring = "{POODLL:type="; + var thekey = this.get('keys')[templateindex]; + var thevariables = this.get('variables')[templateindex]; + var thedefaults = this.get('defaults')[templateindex]; + var theend = this.get('ends')[templateindex]; + var defaultsarray = thedefaults; + + //add key to return string + retstring += '"' + thekey + '"'; + + //add variables to return string + Y.Array.each(thevariables, function (variable, currentindex) { + //loop start + var thefield = Y.one('.' + CSS.TEMPLATEVARIABLE + '_' + currentindex); + var thevalue = thefield.get('value'); + if (thevalue && thevalue != defaultsarray[variable]) { + retstring += ',' + variable + '="' + thevalue + '"'; + } + //loop end + }, this); + + //close out return string + retstring += "}"; + + //add an end tag, if we need to + if (theend) { + retstring += '
{POODLL:type="' + thekey + '_end"}'; + } + + this.editor.focus(); + this.get('host').insertContentAtFocusPoint(retstring); + this.markUpdated(); - /** - * Inserts the users input onto the page - * @method _getDialogueContent - * @private - */ - _doWidgetsInsert : function(e,templateindex){ - e.preventDefault(); - this.getDialogue({ - focusAfterHide: null - }).hide(); - - var retstring = "{POODLL:type="; - var thekey = this.get('keys')[templateindex]; - var thevariables=this.get('variables')[templateindex]; - var thedefaults=this.get('defaults')[templateindex]; - var theend=this.get('ends')[templateindex]; - var defaultsarray=thedefaults; - - //add key to return string - retstring += '"' + thekey + '"'; - - //add variables to return string - Y.Array.each(thevariables, function(variable, currentindex) { - //loop start - var thefield = Y.one('.' + CSS.TEMPLATEVARIABLE + '_' + currentindex); - var thevalue = thefield.get('value'); - if(thevalue && thevalue!=defaultsarray[variable]){ - retstring += ',' + variable + '="' + thevalue + '"'; - } - //loop end - }, this); - - //close out return string - retstring += "}"; - - //add an end tag, if we need to - if(theend){ - retstring += '
{POODLL:type="' + thekey + '_end"}'; } - this.editor.focus(); - this.get('host').insertContentAtFocusPoint(retstring); - this.markUpdated(); - - } - -}, {ATTRS: { - names: { - value: null - }, - - keys: { - value: null - }, - - variables: { - value: null - }, - - defaults: { - value: null - } - , - instructions: { - value: null - }, - customicon: { - value: null - }, - ends: { - value: null - } - } -}); + }, { + ATTRS: { + names: { + value: null + }, + + keys: { + value: null + }, + + variables: { + value: null + }, + + defaults: { + value: null + } + , + instructions: { + value: null + }, + customicon: { + value: null + }, + ends: { + value: null + } + } + }); }, '@VERSION@', {"requires": ["moodle-editor_atto-plugin"]}); diff --git a/yui/src/button/js/button.js b/yui/src/button/js/button.js index 7c3818d..d97a509 100644 --- a/yui/src/button/js/button.js +++ b/yui/src/button/js/button.js @@ -36,62 +36,60 @@ var POODLLFILENAME = 'poodllfilename'; var LOGNAME = 'atto_poodll'; - var CSS = { - INPUTSUBMIT: 'atto_media_urlentrysubmit', - INPUTCANCEL: 'atto_media_urlentrycancel', - NAMEBUTTON: 'atto_poodll_templatebutton', - HEADERTEXT: 'atto_poodll_headertext', - INSTRUCTIONSTEXT: 'atto_poodll_instructionstext', - TEMPLATEVARIABLE: 'atto_poodll_templatevariable' - }; + INPUTSUBMIT: 'atto_media_urlentrysubmit', + INPUTCANCEL: 'atto_media_urlentrycancel', + NAMEBUTTON: 'atto_poodll_templatebutton', + HEADERTEXT: 'atto_poodll_headertext', + INSTRUCTIONSTEXT: 'atto_poodll_instructionstext', + TEMPLATEVARIABLE: 'atto_poodll_templatevariable' +}; var TEMPLATE = '' + - '
' + - '
' + - '' + - '' + + '' + + '
' + + '' + + '' + '
' + - ''; + ''; var IMAGETEMPLATE = '' + '{{alt}}'; var FIELDSHEADERTEMPLATE = '' + - '
' + - '

{{headertext}} {{key}}

' + - '
{{instructions}}
' + - '
'; + '
' + + '

{{headertext}} {{key}}

' + + '
{{instructions}}
' + + '
'; var BUTTONSHEADERTEMPLATE = '' + - '
' + - '

{{headertext}}

' + - '
'; - + '
' + + '

{{headertext}}

' + + '
'; + var BUTTONTEMPLATE = '' + - '
' + - '' + - '
'; - + '
' + + '' + + '
'; + var FIELDTEMPLATE = '' + - '
{{variable}}' + - ' ' + - '
'; + '
{{variable}}' + + ' ' + + '
'; var SELECTCONTAINERTEMPLATE = '' + - '
{{variable}}
'; - + '
{{variable}}
'; + var SELECTTEMPLATE = '' + - ''; + ''; -var OPTIONTEMPLATE ='' + - ''; +var OPTIONTEMPLATE = '' + + ''; var SUBMITTEMPLATE = '' + - '
' + - '
' + - '' + + '' + + '
' + + '' + '
' + - ''; - + ''; Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.EditorPlugin, [], { @@ -121,107 +119,109 @@ Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.Ed _modulecontextid: null, _usewhiteboard: null, - initializer: function(config) { - this._usercontextid = config.usercontextid; - this._coursecontextid = config.coursecontextid; - this._usewhiteboard = config.usewhiteboard; - + initializer: function (config) { + this._usercontextid = config.usercontextid; + this._coursecontextid = config.coursecontextid; + this._usewhiteboard = config.usewhiteboard; + var host = this.get('host'); var options = host.get('filepickeroptions'); if (options.image && options.image.itemid) { - this._itemid = options.image.itemid; + this._itemid = options.image.itemid; if (options.image.context && options.image.context.id) { - this._modulecontextid = options.image.context.id; + this._modulecontextid = options.image.context.id; } } else { Y.log('Plugin PoodLL Anywhere not available because itemid is missing.', - 'warn', LOGNAME); + 'warn', LOGNAME); return; } - + //if we don't have the capability, or no file uploads allowed, give up. - if(config.disabled){ - return; + if (config.disabled) { + return; } - - - var recorders = new Array('audiomp3','video', 'whiteboard','snapshot','widgets'); - for (var therecorder = 0; therecorder < recorders.length; therecorder++) { - // Add the poodll button first (if we are supposed to) - if(config.hasOwnProperty(recorders[therecorder])){ - this.addButton({ - icon: recorders[therecorder], - iconComponent: 'atto_poodll', - title: recorders[therecorder] + '_desc', - buttonName: recorders[therecorder], - callback: this._displayDialogue, - callbackArgs: recorders[therecorder] - }); - } + + + var recorders = new Array('audiomp3', 'video', 'whiteboard', 'snapshot', 'widgets'); + for (var therecorder = 0; therecorder < recorders.length; therecorder++) { + // Add the poodll button first (if we are supposed to) + if (config.hasOwnProperty(recorders[therecorder])) { + this.addButton({ + icon: recorders[therecorder], + iconComponent: 'atto_poodll', + title: recorders[therecorder] + '_desc', + buttonName: recorders[therecorder], + callback: this._displayDialogue, + callbackArgs: recorders[therecorder] + }); + } } - - + + }, - - /** + + /** * Display the PoodLL Recorder files. * * @method _displayDialogue * @private */ - _displayDialogue: function(e, therecorder) { - e.preventDefault(); - this._currentrecorder = therecorder; - - if(therecorder=='widgets'){ - this._displayWidgetsDialogue(e,therecorder); - return; - } - - var width=400; - var height=260; - switch(therecorder){ - case 'audiomp3': - width=390; - height=300; + _displayDialogue: function (e, therecorder) { + e.preventDefault(); + this._currentrecorder = therecorder; + + if (therecorder == 'widgets') { + this._displayWidgetsDialogue(e, therecorder); + return; + } + + var width = 400; + var height = 260; + switch (therecorder) { + case 'audiomp3': + width = 390; + height = 300; + break; + case 'video': + case 'snapshot': + width = 360; + height = 450; break; - case 'video': - case 'snapshot':width=360; - height=450; - break; - case 'whiteboard': width=680; - height=540; - break; - } - - //the dialogue widths are a bit bogus + case 'whiteboard': + width = 680; + height = 540; + break; + } + + //the dialogue widths are a bit bogus var dialogue = this.getDialogue({ headerContent: M.util.get_string('dialogtitle', COMPONENTNAME), width: width + 'px', focusAfterHide: therecorder }); - if(dialogue.width != width + 'px'){ - dialogue.set('width',width + 30 +'px'); + if (dialogue.width != width + 'px') { + dialogue.set('width', width + 30 + 'px'); } var iframeid = 'atto_poodll_dialog_iframe_' + new Date().getTime(); //var iframe = Y.Node.create(''); - // var iframe = Y.Node.create(''); - var iframe = Y.Node.create(''); - + // var iframe = Y.Node.create(''); + var iframe = Y.Node.create(''); + iframe.setStyles({ border: 'none', overflow: 'hidden' }); - //set attributes on the iframe + //set attributes on the iframe iframe.setAttribute('src', this._getIframeURL(therecorder, iframeid)); iframe.setAttribute('scrolling', 'no'); - + //append buttons to iframe var buttonform = this._getFormContent(); - - var bodycontent = Y.Node.create('
'); + + var bodycontent = Y.Node.create('
'); bodycontent.append(iframe).append(buttonform); //set to bodycontent @@ -230,21 +230,21 @@ Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.Ed this.markUpdated(); }, - /** + /** * Returns the URL to the file manager. * * @param _getIframeURL * @return {String} URL * @private */ - _getIframeURL: function(therecorder, iframeid) { - return M.cfg.wwwroot + '/lib/editor/atto/plugins/poodll/dialog/poodll.php?' + - 'itemid='+ this._itemid + '&recorder=' + therecorder + '&usewhiteboard=' + this._usewhiteboard + - '&iframeid=' + iframeid + '&coursecontextid=' + this._coursecontextid + '&modulecontextid=' + this._modulecontextid + - '&updatecontrol=' + this._getFilenameControlName(); + _getIframeURL: function (therecorder, iframeid) { + return M.cfg.wwwroot + '/lib/editor/atto/plugins/poodll/dialog/poodll.php?' + + 'itemid=' + this._itemid + '&recorder=' + therecorder + '&usewhiteboard=' + this._usewhiteboard + + '&iframeid=' + iframeid + '&coursecontextid=' + this._coursecontextid + '&modulecontextid=' + this._modulecontextid + + '&updatecontrol=' + this._getFilenameControlName(); }, - - /** + + /** * Return the dialogue content for the tool, attaching any required * events. * @@ -252,7 +252,7 @@ Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.Ed * @return {Node} The content to place in the dialogue. * @private */ - _getFormContent: function() { + _getFormContent: function () { var template = Y.Handlebars.compile(TEMPLATE), content = Y.Node.create(template({ elementid: this.get('host').get('elementid'), @@ -266,92 +266,94 @@ Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.Ed return content; }, - - /** + + /** * Get the id of the filename control where poodll stores filename * * @method _getFilenameControlName * @return {String} the name/id of the filename form field * @private */ - _getFilenameControlName: function(){ - return(this.get('host').get('elementid') + '_' + POODLLFILENAME); - }, - - - /** + _getFilenameControlName: function () { + return (this.get('host').get('elementid') + '_' + POODLLFILENAME); + }, + + + /** * Inserts the url/link onto the page * @method _getDialogueContent * @private */ - _doInsert : function(e){ - e.preventDefault(); - this.getDialogue({ + _doInsert: function (e) { + e.preventDefault(); + this.getDialogue({ focusAfterHide: null }).hide(); - + var thefilename = document.getElementById(this._getFilenameControlName()); //if no file is there to insert, don't do it - if(!thefilename.value){ - Y.log('No filename control or value could be found.','warn', LOGNAME); - return; + if (!thefilename.value) { + Y.log('No filename control or value could be found.', 'warn', LOGNAME); + return; } - var thefilename = thefilename.value; - var wwwroot = M.cfg.wwwroot; - var mediahtml=''; - - // It will store in mdl_question with the "@@PLUGINFILE@@/myfile.mp3" for the filepath. - var filesrc =wwwroot+'/draftfile.php/'+ this._usercontextid +'/user/draft/'+this._itemid+'/'+thefilename; + var thefilename = thefilename.value; + var wwwroot = M.cfg.wwwroot; + var mediahtml = ''; + + // It will store in mdl_question with the "@@PLUGINFILE@@/myfile.mp3" for the filepath. + var filesrc = wwwroot + '/draftfile.php/' + this._usercontextid + '/user/draft/' + this._itemid + '/' + thefilename; - //if this is an image, insert the image - if(this._currentrecorder==='snapshot' ||this._currentrecorder==='whiteboard'){ - template = Y.Handlebars.compile(IMAGETEMPLATE); + //if this is an image, insert the image + if (this._currentrecorder === 'snapshot' || this._currentrecorder === 'whiteboard') { + template = Y.Handlebars.compile(IMAGETEMPLATE); mediahtml = template({ url: filesrc, alt: thefilename - }); - //otherwise insert the link - }else{ - mediahtml = ''+thefilename+''; - } - - this.editor.focus(); - this.get('host').insertContentAtFocusPoint(mediahtml); - this.markUpdated(); - - }, - - /** + }); + //otherwise insert the link + } else { + mediahtml = '' + thefilename + ''; + } + + this.editor.focus(); + this.get('host').insertContentAtFocusPoint(mediahtml); + this.markUpdated(); + + }, + + /** * Called by PoodLL recorders directly to update filename field on page * @method updatefilename * @public */ - updatefilename : function(args) { - //record the url on the html page - //var filenamecontrol = document.getElementById(args[3]); - var filenamecontrol = document.getElementById(this._getFilenameControlName()); - if(filenamecontrol===null){ filenamecontrol = parent.document.getElementById(args[3]);} - if(filenamecontrol){ - filenamecontrol.value = args[2]; - //var insertbutton = document.getElementById('insert'); - this._form.one('.' + CSS.INPUTSUBMIT).disabled=false; - //insertbutton.disabled = false; - } - - //console.log("just updated: " + args[3] + ' with ' + args[2]); - }, - - - /** + updatefilename: function (args) { + //record the url on the html page + //var filenamecontrol = document.getElementById(args[3]); + var filenamecontrol = document.getElementById(this._getFilenameControlName()); + if (filenamecontrol === null) { + filenamecontrol = parent.document.getElementById(args[3]); + } + if (filenamecontrol) { + filenamecontrol.value = args[2]; + //var insertbutton = document.getElementById('insert'); + this._form.one('.' + CSS.INPUTSUBMIT).disabled = false; + //insertbutton.disabled = false; + } + + //console.log("just updated: " + args[3] + ' with ' + args[2]); + }, + + + /** * Display the widgets dialog * * @method _displayDialogue * @private */ - _displayWidgetsDialogue: function(e, clickedicon) { + _displayWidgetsDialogue: function (e, clickedicon) { e.preventDefault(); - var width=400; + var width = 400; var dialogue = this.getDialogue({ @@ -359,32 +361,32 @@ Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.Ed width: width + 'px', focusAfterHide: clickedicon }); - //dialog doesn't detect changes in width without this - //if you reuse the dialog, this seems necessary - if(dialogue.width !== width + 'px'){ - dialogue.set('width',width+'px'); + //dialog doesn't detect changes in width without this + //if you reuse the dialog, this seems necessary + if (dialogue.width !== width + 'px') { + dialogue.set('width', width + 'px'); } - + //create content container - var bodycontent = Y.Node.create('
'); - + var bodycontent = Y.Node.create('
'); + //create and append header var template = Y.Handlebars.compile(BUTTONSHEADERTEMPLATE), - content = Y.Node.create(template({ + content = Y.Node.create(template({ headertext: M.util.get_string('chooseinsert', COMPONENTNAME) })); - bodycontent.append(content); + bodycontent.append(content); //get button nodes var buttons = this._getButtonsForNames(clickedicon); - - Y.Array.each(buttons, function(button) { + + Y.Array.each(buttons, function (button) { //loop start - bodycontent.append(button); + bodycontent.append(button); //loop end }, bodycontent); - + //set to bodycontent dialogue.set('bodyContent', bodycontent); @@ -392,62 +394,62 @@ Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.Ed this.markUpdated(); }, - /** + /** * Display the chosen widgets template form * * @method _showTemplateForm * @private */ - _showTemplateForm: function(e,templateindex) { + _showTemplateForm: function (e, templateindex) { e.preventDefault(); - var width=400; + var width = 400; + - var dialogue = this.getDialogue({ headerContent: M.util.get_string('dialogtitle', COMPONENTNAME), width: width + 'px' }); - //dialog doesn't detect changes in width without this - //if you reuse the dialog, this seems necessary - if(dialogue.width !== width + 'px'){ - dialogue.set('width',width+'px'); + //dialog doesn't detect changes in width without this + //if you reuse the dialog, this seems necessary + if (dialogue.width !== width + 'px') { + dialogue.set('width', width + 'px'); } //get fields , 1 per variable var fields = this._getTemplateFields(templateindex); var instructions = this.get('instructions')[templateindex]; - instructions = decodeURIComponent(instructions); - - //get header node. It will be different if we have no fields - if(fields && fields.length>0){ - var useheadertext = M.util.get_string('fieldsheader', COMPONENTNAME); - }else{ - var useheadertext = M.util.get_string('nofieldsheader', COMPONENTNAME); - } - var template = Y.Handlebars.compile(FIELDSHEADERTEMPLATE), - content = Y.Node.create(template({ + instructions = decodeURIComponent(instructions); + + //get header node. It will be different if we have no fields + if (fields && fields.length > 0) { + var useheadertext = M.util.get_string('fieldsheader', COMPONENTNAME); + } else { + var useheadertext = M.util.get_string('nofieldsheader', COMPONENTNAME); + } + var template = Y.Handlebars.compile(FIELDSHEADERTEMPLATE), + content = Y.Node.create(template({ key: this.get('keys')[templateindex], headertext: useheadertext, instructions: instructions })); var header = content; - - //set container for our nodes (header, fields, buttons) - var bodycontent = Y.Node.create('
'); - + + //set container for our nodes (header, fields, buttons) + var bodycontent = Y.Node.create('
'); + //add our header - bodycontent.append(header); - + bodycontent.append(header); + //add fields - Y.Array.each(fields, function(field) { + Y.Array.each(fields, function (field) { //loop start - bodycontent.append(field); + bodycontent.append(field); //loop end }, bodycontent); - - //add submit button - var submitbuttons = this._getSubmitButtons(templateindex); - bodycontent.append(submitbuttons) + + //add submit button + var submitbuttons = this._getSubmitButtons(templateindex); + bodycontent.append(submitbuttons) //set to bodycontent dialogue.set('bodyContent', bodycontent); @@ -455,7 +457,7 @@ Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.Ed this.markUpdated(); }, - /** + /** * Return the widget dialogue content for the tool, attaching any required * events. * @@ -463,80 +465,80 @@ Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.Ed * @return {Node} The content to place in the dialogue. * @private */ - _getSubmitButtons: function(templateindex) { - + _getSubmitButtons: function (templateindex) { + var template = Y.Handlebars.compile(SUBMITTEMPLATE), - + content = Y.Node.create(template({ elementid: this.get('host').get('elementid'), - inserttext: M.util.get_string('insert', COMPONENTNAME) + inserttext: M.util.get_string('insert', COMPONENTNAME) })); - - content.one('.' + CSS.INPUTSUBMIT).on('click', this._doWidgetsInsert, this, templateindex); + + content.one('.' + CSS.INPUTSUBMIT).on('click', this._doWidgetsInsert, this, templateindex); return content; }, - /** + /** * Return a field (yui node) for each variable in the template * * @method _getTemplateFields * @return {Node} The content to place in the dialogue. * @private */ - _getTemplateFields: function(templateindex) { - - var allcontent=[]; - var thekey=this.get('keys')[templateindex]; - var thevariables=this.get('variables')[templateindex]; - var thedefaults=this.get('defaults')[templateindex]; - - //defaults array - //var defaultsarray=this._getDefArray(thedefaults); - var defaultsarray=thedefaults; - - Y.Array.each(thevariables, function(thevariable, currentindex) { + _getTemplateFields: function (templateindex) { + + var allcontent = []; + var thekey = this.get('keys')[templateindex]; + var thevariables = this.get('variables')[templateindex]; + var thedefaults = this.get('defaults')[templateindex]; + + //defaults array + //var defaultsarray=this._getDefArray(thedefaults); + var defaultsarray = thedefaults; + + Y.Array.each(thevariables, function (thevariable, currentindex) { //loop start - if((thevariable in defaultsarray) && defaultsarray[thevariable].indexOf('|')>-1){ - - var containertemplate = Y.Handlebars.compile(SELECTCONTAINERTEMPLATE), - content = Y.Node.create(containertemplate({ - elementid: this.get('host').get('elementid'), - variable: thevariable, - defaultvalue: defaultsarray[thevariable], - variableindex: currentindex - })); - - var selecttemplate = Y.Handlebars.compile(SELECTTEMPLATE), - selectbox = Y.Node.create(selecttemplate({ - variable: thevariable, - defaultvalue: defaultsarray[thevariable], - variableindex: currentindex - })); - - var opts = defaultsarray[thevariable].split('|'); - var htmloptions=""; - var opttemplate = Y.Handlebars.compile(OPTIONTEMPLATE); - Y.Array.each(opts, function(opt, optindex) { - var optcontent = Y.Node.create(opttemplate({ - option: opt - })); - selectbox.appendChild(optcontent); - }); - content.appendChild(selectbox); - - }else{ - - var template = Y.Handlebars.compile(FIELDTEMPLATE), - content = Y.Node.create(template({ - elementid: this.get('host').get('elementid'), - variable: thevariable, - defaultvalue: defaultsarray[thevariable], - variableindex: currentindex - })); - } - - + if ((thevariable in defaultsarray) && defaultsarray[thevariable].indexOf('|') > -1) { + + var containertemplate = Y.Handlebars.compile(SELECTCONTAINERTEMPLATE), + content = Y.Node.create(containertemplate({ + elementid: this.get('host').get('elementid'), + variable: thevariable, + defaultvalue: defaultsarray[thevariable], + variableindex: currentindex + })); + + var selecttemplate = Y.Handlebars.compile(SELECTTEMPLATE), + selectbox = Y.Node.create(selecttemplate({ + variable: thevariable, + defaultvalue: defaultsarray[thevariable], + variableindex: currentindex + })); + + var opts = defaultsarray[thevariable].split('|'); + var htmloptions = ""; + var opttemplate = Y.Handlebars.compile(OPTIONTEMPLATE); + Y.Array.each(opts, function (opt, optindex) { + var optcontent = Y.Node.create(opttemplate({ + option: opt + })); + selectbox.appendChild(optcontent); + }); + content.appendChild(selectbox); + + } else { + + var template = Y.Handlebars.compile(FIELDTEMPLATE), + content = Y.Node.create(template({ + elementid: this.get('host').get('elementid'), + variable: thevariable, + defaultvalue: defaultsarray[thevariable], + variableindex: currentindex + })); + } + + allcontent.push(content); //loop end }, this); @@ -546,7 +548,7 @@ Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.Ed }, - /** + /** * Return the dialogue content for the tool, attaching any required * events. * @@ -554,40 +556,40 @@ Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.Ed * @return {Node} The content to place in the dialogue. * @private */ - _getButtonsForNames: function(clickedicon) { - - var allcontent=[]; - Y.Array.each(this.get('names'), function(thename, currentindex) { + _getButtonsForNames: function (clickedicon) { + + var allcontent = []; + Y.Array.each(this.get('names'), function (thename, currentindex) { //loop start - var template = Y.Handlebars.compile(BUTTONTEMPLATE), - content = Y.Node.create(template({ - elementid: this.get('host').get('elementid'), - name: thename, - templateindex: currentindex - })); + var template = Y.Handlebars.compile(BUTTONTEMPLATE), + content = Y.Node.create(template({ + elementid: this.get('host').get('elementid'), + name: thename, + templateindex: currentindex + })); this._form = content; - content.one('.' + CSS.NAMEBUTTON + '_' + currentindex).on('click', this._showTemplateForm, this,currentindex); + content.one('.' + CSS.NAMEBUTTON + '_' + currentindex).on('click', this._showTemplateForm, this, currentindex); allcontent.push(content); //loop end }, this); return allcontent; }, - - _getDefArray: function(thedefaults){ - //defaults array - var defaultsarray=[]; - var defaultstemparray = thedefaults.match(/([^=,]*)=("[^"]*"|[^,"]*)/g);//thedefaults.split(','); - Y.Array.each(defaultstemparray, function(defset){ - //loop start - var defsetarray = defset.split('='); - if(defsetarray && defsetarray.length>1){ - defaultsarray[defsetarray[0]] = defsetarray[1].replace(/"/g,''); - } - //loop end + + _getDefArray: function (thedefaults) { + //defaults array + var defaultsarray = []; + var defaultstemparray = thedefaults.match(/([^=,]*)=("[^"]*"|[^,"]*)/g);//thedefaults.split(','); + Y.Array.each(defaultstemparray, function (defset) { + //loop start + var defsetarray = defset.split('='); + if (defsetarray && defsetarray.length > 1) { + defaultsarray[defsetarray[0]] = defsetarray[1].replace(/"/g, ''); + } + //loop end }, this); return defaultsarray; - + }, /** @@ -595,72 +597,73 @@ Y.namespace('M.atto_poodll').Button = Y.Base.create('button', Y.M.editor_atto.Ed * @method _getDialogueContent * @private */ - _doWidgetsInsert : function(e,templateindex){ + _doWidgetsInsert: function (e, templateindex) { e.preventDefault(); this.getDialogue({ focusAfterHide: null }).hide(); - + var retstring = "{POODLL:type="; var thekey = this.get('keys')[templateindex]; - var thevariables=this.get('variables')[templateindex]; - var thedefaults=this.get('defaults')[templateindex]; - var theend=this.get('ends')[templateindex]; - var defaultsarray=thedefaults; - + var thevariables = this.get('variables')[templateindex]; + var thedefaults = this.get('defaults')[templateindex]; + var theend = this.get('ends')[templateindex]; + var defaultsarray = thedefaults; + //add key to return string retstring += '"' + thekey + '"'; - + //add variables to return string - Y.Array.each(thevariables, function(variable, currentindex) { - //loop start - var thefield = Y.one('.' + CSS.TEMPLATEVARIABLE + '_' + currentindex); - var thevalue = thefield.get('value'); - if(thevalue && thevalue!=defaultsarray[variable]){ - retstring += ',' + variable + '="' + thevalue + '"'; - } - //loop end + Y.Array.each(thevariables, function (variable, currentindex) { + //loop start + var thefield = Y.one('.' + CSS.TEMPLATEVARIABLE + '_' + currentindex); + var thevalue = thefield.get('value'); + if (thevalue && thevalue != defaultsarray[variable]) { + retstring += ',' + variable + '="' + thevalue + '"'; + } + //loop end }, this); - + //close out return string retstring += "}"; - + //add an end tag, if we need to - if(theend){ - retstring += '
{POODLL:type="' + thekey + '_end"}'; + if (theend) { + retstring += '
{POODLL:type="' + thekey + '_end"}'; } this.editor.focus(); this.get('host').insertContentAtFocusPoint(retstring); this.markUpdated(); - } - -}, {ATTRS: { - names: { - value: null - }, - - keys: { - value: null - }, - - variables: { - value: null - }, - - defaults: { - value: null - } - , - instructions: { - value: null - }, - customicon: { - value: null - }, - ends: { - value: null - } + } + +}, { + ATTRS: { + names: { + value: null + }, + + keys: { + value: null + }, + + variables: { + value: null + }, + + defaults: { + value: null + } + , + instructions: { + value: null + }, + customicon: { + value: null + }, + ends: { + value: null + } } }); diff --git a/yui/src/button/meta/button.json b/yui/src/button/meta/button.json index 13709fc..51bf95b 100644 --- a/yui/src/button/meta/button.json +++ b/yui/src/button/meta/button.json @@ -1,7 +1,7 @@ { - "moodle-atto_poodll-button": { - "requires": [ - "moodle-editor_atto-plugin" - ] - } + "moodle-atto_poodll-button": { + "requires": [ + "moodle-editor_atto-plugin" + ] + } }