/** * Javascript library for enableing a drag and drop upload to courses * * @package core * @subpackage course * @copyright 2012 Davo Smith * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ M.course_dndupload={Y:null,url:M.cfg.wwwroot+'/course/dndupload.php',maxbytes:0,courseid:null,handlers:null,entercount:0,currentsection:null,uploadqueue:null,uploaddialog:!1,lastselected:null,sectiontypename:'li',sectionclasses:['section','main'],pagecontentid:'page',modslistselector:'ul.section',init:function(Y,options){this.Y=Y;if(!this.browser_supported()){return} this.maxbytes=options.maxbytes;this.courseid=options.courseid;this.handlers=options.handlers;this.uploadqueue=new Array();this.lastselected=new Array();var sectionselector=this.sectiontypename+'.'+this.sectionclasses.join('.');var sections=this.Y.all(sectionselector);if(sections.isEmpty()){return} sections.each(function(el){this.add_preview_element(el);this.init_events(el)},this);if(options.showstatus){this.add_status_div()} var self=this;require(['core_courseformat/courseeditor','core_course/events'],function(Editor,CourseEvents){self.courseeditor=Editor.getCurrentCourseEditor();document.querySelector('#'+self.pagecontentid).addEventListener(CourseEvents.sectionRefreshed,self.sectionRefreshed.bind(self))});document.addEventListener('scroll',function(){sections.each(function(el){if(el.hasClass('dndupload-dropzone')){self.rePositionPreviewInfoElement(el)}},this)},!0)},sectionRefreshed:function(event){if(event.detail.newSectionElement===undefined){return} var element=this.Y.one(event.detail.newSectionElement);this.add_preview_element(element);this.init_events(element)},add_status_div:function(){var Y=this.Y,coursecontents=Y.one('#'+this.pagecontentid),div,handlefile=(this.handlers.filehandlers.length>0),handletext=!1,handlelink=!1,i=0,styletop,styletopunit;if(!coursecontents){return} div=Y.Node.create('
').setStyle('opacity','0.0');coursecontents.insert(div,0);for(i=0;i2){this.entercount=2;return!1}} this.showPreviewInfoElement(section);return!1},drag_leave:function(e){if(!this.check_drag(e)){return!1} this.entercount--;if(this.entercount==1){return!1} this.entercount=0;this.currentsection=null;this.hide_preview_element();return!1},drag_over:function(e){this.check_drag(e);return!1},drop:function(e){this.hide_preview_element();if(!(type=this.check_drag(e))){return!1} var section=this.get_section(e.currentTarget);var sectionnumber=this.get_section_number(section);if(type.type=='Files'){var files=e._event.dataTransfer.files;for(var i=0,f;f=files[i];i++){this.handle_file(f,section,sectionnumber)}}else{var contents=e._event.dataTransfer.getData(type.realtype);if(contents){this.handle_item(type,contents,section,sectionnumber)}} return!1},get_mods_element:function(section){var modsel=section.one(this.modslistselector);if(!modsel){modsel=document.createElement('ul');modsel.className='section img-text';var contentel=section.get('children').pop();var brel=contentel.get('children').pop();contentel.insertBefore(modsel,brel);modsel=this.Y.one(modsel)} return modsel},add_resource_element:function(name,section,module){var modsel=this.get_mods_element(section);var resel={parent:modsel,li:document.createElement('li'),div:document.createElement('div'),indentdiv:document.createElement('div'),a:document.createElement('a'),icon:document.createElement('img'),namespan:document.createElement('span'),groupingspan:document.createElement('span'),progressouter:document.createElement('span'),progress:document.createElement('span')};resel.li.className='activity '+module+' modtype_'+module;resel.indentdiv.className='mod-indent';resel.li.appendChild(resel.indentdiv);resel.div.className='activityinstance';resel.indentdiv.appendChild(resel.div);resel.a.href='#';resel.div.appendChild(resel.a);resel.icon.src=M.util.image_url('i/ajaxloader');resel.icon.className='activityicon iconlarge';resel.a.appendChild(resel.icon);resel.namespan.className='instancename';resel.namespan.innerHTML=name;resel.a.appendChild(resel.namespan);resel.groupingspan.className='groupinglabel';resel.div.appendChild(resel.groupingspan);resel.progressouter.className='dndupload-progress-outer';resel.progress.className='dndupload-progress-inner';resel.progress.innerHTML=' ';resel.progressouter.appendChild(resel.progress);resel.div.appendChild(resel.progressouter);modsel.insertBefore(resel.li,modsel.get('children').pop());return resel},hide_preview_element:function(){this.Y.all('.dndupload-preview-wrapper').addClass('dndupload-hidden');this.Y.all('.dndupload-over').removeClass('dndupload-over');this.Y.all('.dndupload-dropzone').removeClass('dndupload-dropzone')},show_preview_element:function(section,type){this.hide_preview_element();var preview=section.one('li.dndupload-preview').removeClass('dndupload-hidden');section.addClass('dndupload-over');var node=preview.one('span').getDOMNode();node.firstChild.nodeValue=type.addmessage},showPreviewInfoElement:function(section){this.hide_preview_element();section.one('.dndupload-preview-wrapper').removeClass('dndupload-hidden');section.addClass('dndupload-dropzone');this.rePositionPreviewInfoElement(section)},add_preview_element:function(section){const modsEl=this.get_mods_element(section);const overlay=document.createElement('div');overlay.className='dndupload-preview-overlay';modsEl.get('parentNode').appendChild(overlay);const preview={wrapper:document.createElement('div'),div:document.createElement('div'),iconSpan:document.createElement('span'),nameSpan:document.createElement('span')};preview.wrapper.className='dndupload-preview-wrapper dndupload-hidden';preview.wrapper.appendChild(preview.div);preview.div.className='dndupload-preview';preview.div.appendChild(document.createTextNode(' '));preview.iconSpan.className='fa fa-arrow-circle-o-down';preview.nameSpan.className='instancename';preview.nameSpan.innerHTML=M.util.get_string('addfilehere','moodle');preview.div.appendChild(preview.iconSpan);preview.div.appendChild(preview.nameSpan);modsEl.get('parentNode').appendChild(preview.wrapper)},rePositionPreviewInfoElement:function(section){const sectionElement=document.getElementById(section.get('id'));const rect=sectionElement.getBoundingClientRect();const sectionHeight=parseInt(window.getComputedStyle(sectionElement).height,10);const sectionOffset=rect.top;const preview=sectionElement.querySelector('.dndupload-preview-wrapper');const previewHeight=parseInt(window.getComputedStyle(preview).height,10)+(2*parseInt(window.getComputedStyle(preview).padding,10));let top,bottom;if(sectionOffset<0){if(sectionHeight+sectionOffset>=previewHeight){let offSetTop=0-sectionOffset;const navBar=document.querySelector('nav.navbar.fixed-top');if(navBar){offSetTop=offSetTop+navBar.offsetHeight} top=offSetTop+'px';bottom='unset'}else{top='unset';bottom=0}}else{top=0;bottom='unset'} preview.style.top=top preview.style.bottom=bottom},handle_file:function(file,section,sectionnumber){var handlers=new Array();var filehandlers=this.handlers.filehandlers;var extension='';var dotpos=file.name.lastIndexOf('.');if(dotpos!=-1){extension=file.name.substr(dotpos+1,file.name.length).toLowerCase()} for(var i=0;i';content+='
';for(var i=0;i';content+='
'} content+='
';var Y=this.Y;var self=this;var panel=new M.core.dialogue({bodyContent:content,width:'350px',modal:!0,visible:!1,render:!0,align:{node:null,points:[Y.WidgetPositionAlign.CC,Y.WidgetPositionAlign.CC]}});panel.show();panel.after("visibleChange",function(e){if(!panel.get('visible')){panel.destroy(!0);self.check_upload_queue()}});panel.addButton({label:M.util.get_string('upload','moodle'),action:function(e){e.preventDefault();var module=!1;var div=Y.one('#dndupload_handlers'+uploadid);div.all('input').each(function(input){if(input.get('checked')){module=input.get('value')}});if(!module){return} panel.hide();self.lastselected[extension]=module;self.upload_file(file,section,sectionnumber,module)},section:Y.WidgetStdMod.FOOTER});panel.addButton({label:M.util.get_string('cancel','moodle'),action:function(e){e.preventDefault();panel.hide()},section:Y.WidgetStdMod.FOOTER})},check_upload_queue:function(){this.uploaddialog=!1;if(this.uploadqueue.length==0){return} var details=this.uploadqueue.shift();if(details.isfile){this.file_handler_dialog(details.handlers,details.extension,details.file,details.section,details.sectionnumber)}else{this.handle_item(details.type,details.contents,details.section,details.sectionnumber)}},upload_file:function(file,section,sectionnumber,module){var xhr=new XMLHttpRequest();var self=this;if(this.maxbytes>0&&file.size>this.maxbytes){new M.core.alert({message:M.util.get_string('namedfiletoolarge','moodle',{filename:file.name})});return} var resel=this.add_resource_element(file.name,section,module);xhr.upload.addEventListener('progress',function(e){if(e.lengthComputable){var percentage=Math.round((e.loaded*100)/e.total);resel.progress.style.width=percentage+'%'}},!1);xhr.onreadystatechange=function(){if(xhr.readyState==1){this.originalUnloadEvent=window.onbeforeunload;require(['core_form/events'],function(FormEvent){FormEvent.notifyUploadStarted(section.get('id'))})} if(xhr.readyState==4){if(xhr.status==200){var result=JSON.parse(xhr.responseText);if(result){if(result.error==0){resel.li.outerHTML=result.fullcontent;if(self.Y.UA.gecko>0){resel.li.outerHTML=unescape(resel.li.outerHTML)} self.add_editing(result.elementid);self.courseeditor.dispatch('cmState',[result.cmid]);require(['core/event','jquery'],function(event,$){event.notifyFilterContentUpdated($(result.fullcontent))})}else{resel.parent.removeChild(resel.li);new M.core.alert({message:result.error})}}}else{new M.core.alert({message:M.util.get_string('servererror','moodle')})} require(['core_form/events'],function(FormEvent){FormEvent.notifyUploadCompleted(section.get('id'))})}};var formData=new FormData();try{formData.append('repo_upload_file',file)}catch(e){resel.parent.removeChild(resel.li);new M.core.alert({message:M.util.get_string('filereaderror','moodle',file.name)});return} formData.append('sesskey',M.cfg.sesskey);formData.append('course',this.courseid);formData.append('section',sectionnumber);formData.append('module',module);formData.append('type','Files');var reader=new FileReader();reader.onload=function(){xhr.open("POST",self.url,!0);xhr.send(formData)};reader.onerror=function(){resel.parent.removeChild(resel.li);new M.core.alert({message:M.util.get_string('filereaderror','moodle',file.name)})};if(file.size>0){reader.readAsText(file.slice(0,5))}else{reader.readAsText(file)}},handle_item:function(type,contents,section,sectionnumber){if(type.handlers.length==0){return} if(type.handlers.length==1&&type.handlers[0].noname){this.upload_item('',type.type,contents,section,sectionnumber,type.handlers[0].module);this.check_upload_queue();return} if(this.uploaddialog){var details=new Object();details.isfile=!1;details.type=type;details.contents=contents;details.section=section;details.setcionnumber=sectionnumber;this.uploadqueue.push(details);return} this.uploaddialog=!0;var timestamp=new Date().getTime();var uploadid=Math.round(Math.random()*100000)+'-'+timestamp;var nameid='dndupload_handler_name'+uploadid;var content='';if(type.handlers.length>1){content+='

'+type.handlermessage+'

';content+='
';var sel=type.handlers[0].module;for(var i=0;i';content+='
'} content+='
'} var disabled=(type.handlers[0].noname)?' disabled = "disabled" ':'';content+='';content+=' ';var Y=this.Y;var self=this;var panel=new M.core.dialogue({bodyContent:content,width:'350px',modal:!0,visible:!0,render:!0,align:{node:null,points:[Y.WidgetPositionAlign.CC,Y.WidgetPositionAlign.CC]}});panel.after("visibleChange",function(e){if(!panel.get('visible')){panel.destroy(!0);self.check_upload_queue()}});var namefield=Y.one('#'+nameid);var submit=function(e){e.preventDefault();var name=Y.Lang.trim(namefield.get('value'));var module=!1;var noname=!1;if(type.handlers.length>1){var div=Y.one('#dndupload_handlers'+uploadid);div.all('input').each(function(input){if(input.get('checked')){var idx=input.get('value');module=type.handlers[idx].module;noname=type.handlers[idx].noname}});if(!module){return}}else{module=type.handlers[0].module;noname=type.handlers[0].noname} if(name==''&&!noname){return} if(noname){name=''} panel.hide();self.upload_item(name,type.type,contents,section,sectionnumber,module)};panel.addButton({label:M.util.get_string('upload','moodle'),action:submit,section:Y.WidgetStdMod.FOOTER,name:'submit'});panel.addButton({label:M.util.get_string('cancel','moodle'),action:function(e){e.preventDefault();panel.hide()},section:Y.WidgetStdMod.FOOTER});var submitbutton=panel.getButton('submit').button;namefield.on('key',submit,'enter');namefield.after('keyup',function(){if(Y.Lang.trim(namefield.get('value'))==''){submitbutton.disable()}else{submitbutton.enable()}});for(i=0;i0){resel.li.outerHTML=unescape(resel.li.outerHTML)} self.add_editing(result.elementid);self.courseeditor.dispatch('cmState',[result.cmid])}else{resel.parent.removeChild(resel.li);require(['core_form/events'],function(FormEvent){FormEvent.notifyUploadCompleted(section.get('id'))});new M.core.alert({message:result.error})}}}else{require(['core_form/events'],function(FormEvent){FormEvent.notifyUploadCompleted(section.get('id'))});new M.core.alert({message:M.util.get_string('servererror','moodle')})} require(['core_form/events'],function(FormEvent){FormEvent.notifyUploadCompleted(section.get('id'))})}};var formData=new FormData();formData.append('contents',contents);formData.append('displayname',name);formData.append('sesskey',M.cfg.sesskey);formData.append('course',this.courseid);formData.append('section',sectionnumber);formData.append('type',type);formData.append('module',module);xhr.open("POST",this.url,!0);xhr.send(formData)},add_editing:function(elementid){var node=Y.one('#'+elementid);YUI().use('moodle-course-coursebase',function(Y){Y.log("Invoking setup_for_resource",'debug','coursedndupload');M.course.coursebase.invoke_function('setup_for_resource',node)});if(M.core.actionmenu&&M.core.actionmenu.newDOMNode){M.core.actionmenu.newDOMNode(node)}}}