Diff for /loncom/homework/structuretags.pm between versions 1.494 and 1.497.2.3

version 1.494, 2011/07/28 02:53:38 version 1.497.2.3, 2011/12/12 12:07:45
Line 172  function setmode(form,probmode) { Line 172  function setmode(form,probmode) {
 ENDSCRIPT  ENDSCRIPT
 }  }
   
 sub file_delchk_js {  
     my $delfilewarn = &mt('You have indicated you wish to remove some files previously included in your submission.').'\\n'.  
                       &mt('Continue submission with these files removed?');  
     return <<"ENDSCRIPT";  
 <script type="text/javascript">  
 // <![CDATA[  
 function file_deletion_check(formname,uploadid) {  
     var elemnum = formname.elements.length;  
     if (elemnum == 0) {  
         return true;  
     }  
     var alluploads = new Array();  
     if ((uploadid != '') && (uploadid != undefined)) {  
         alluploads.push(uploadid);  
     } else {  
         var uploadstr = /^HWFILE.+\$/;  
         for (var i=0; i<formname.elements.length; i++) {  
             var id = formname.elements[i].id;  
             if (id != '') {  
                 if (uploadstr.test(id)) {  
                     if (formname.elements[i].type == 'file') {  
                         alluploads.push(id);  
                     }  
                 }  
             }  
         }  
     }  
     for (var i=0; i<alluploads.length; i++) {  
         var delstr = new RegExp('^'+alluploads[i]+'_\\\\d+_delete\$');  
         var delboxes = new Array();  
         for (var j=0; j<formname.elements.length; j++) {  
             var id = formname.elements[j].id;  
             if (id != '') {  
                 if (delstr.test(id)) {  
                     if (formname.elements[j].type == 'checkbox') {  
                         if (formname.elements[j].checked) {  
                             delboxes.push(id);  
                         }  
                     }  
                 }  
             }  
         }  
         if (delboxes.length > 0) {  
             if (!confirm("$delfilewarn")) {  
                 for (var j=0; j<delboxes.length; j++) {  
                     formname.elements[delboxes[j]].checked = false;  
                 }  
                 return false;  
             }  
         }  
     }  
     return true;  
 }  
 // ]]>  
 </script>  
 ENDSCRIPT  
 }  
   
 sub file_overwritechk_js {  
     my $overwritewarn = &mt('File(s) you uploaded for your submission will overwrite existing file(s) submitted for this item').'\\n'.  
                       &mt('Continue submission and overwrite the file(s)?');  
     return <<"ENDSCRIPT";  
 <script type="text/javascript">  
 // <![CDATA[  
 function file_overwrite_check(formname,path,multiresp) {  
     var elemnum = formname.elements.length;  
     if (elemnum == 0) {  
         return true;  
     }  
     var alluploads = new Array();  
     var uploaded = new Array();  
     var uploadstr = /^HWFILE.+\$/;  
     var fnametrim = /[^\\/\\\\]+\$/;  
     for (var i=0; i<formname.elements.length; i++) {  
         var id = formname.elements[i].id;  
         if (id != '') {  
             if (uploadstr.test(id)) {  
                 if (formname.elements[i].type == 'file') {  
                     alluploads.push(id);  
                     if ((formname.elements[i].value != undefined) &&  
                         (formname.elements[i].value != '')) {  
                         uploaded.push(id);  
                     }  
                 }  
             }  
         }  
     }  
     for (var i=0; i<alluploads.length; i++) {  
         var delstr = new RegExp("^"+alluploads[i]+"_\\\\d+_delete\$");  
         var delboxes = new Array();  
         for (var j=0; j<formname.elements.length; j++) {  
             var id = formname.elements[j].id;  
             if (id != '') {  
                 if (delstr.test(id)) {  
                     if (formname.elements[j].type == 'checkbox') {  
                         delboxes.push(id);  
                     }  
                 }  
             }  
         }  
         var overwrites = new Array();  
         if (delboxes.length > 0) {  
             if ((formname.elements[alluploads[i]].value != undefined) &&  
                 (formname.elements[alluploads[i]].value != '')) {  
                 var filepath = formname.elements[alluploads[i]].value;  
                 var newfilename = fnametrim.exec(filepath);  
                 if (newfilename != null) {  
                     var filename = String(newfilename);  
                     var nospaces = filename.replace(/\\s+/g,'_');  
                     var nospecials = nospaces.replace(/[^\\/\\w\\.\\-]/g,'');  
                     var cleanfilename = nospecials.replace(/\\.(\\d+\\.)/g,"_\$1");  
                     if (cleanfilename != '') {  
                         var fullpath = path+"/"+cleanfilename;  
                         if (multiresp == 1) {  
                             var partid = String(alluploads[i]);  
                             var subdir = partid.replace(/^HWFILE/,'');  
                             if (subdir != "" && subdir != undefined) {  
                                 fullpath = path+"/"+subdir+"/"+cleanfilename;  
                             }  
                         }  
                         for (var k=0; k<delboxes.length; k++) {  
                             if (fullpath == formname.elements[delboxes[k]].value) {  
                                 var id = formname.elements[delboxes[k]].id;  
                                 if (id != '') {  
                                     if (!formname.elements[delboxes[k]].checked) {  
                                         overwrites.push(id);  
                                     }  
                                 }  
                             }  
                         }  
                     }  
                 }  
             }  
             if (overwrites.length > 0) {  
                 if (confirm("$overwritewarn")) {  
                     var delcheck = file_deletion_check(formname,alluploads[i]);  
                     if (delcheck == false) {  
                         return false;  
                     }  
                 } else {  
                     for (var n=0; n<overwrites.length; n++) {  
                         formname.elements[overwrites[n]].value = "";  
                     }  
                     return false;  
                 }  
             } else {  
                 var delcheck = file_deletion_check(formname);  
                 if (delcheck == false) {  
                     return false;  
                 }  
             }  
         }  
     }  
     return true;  
 }  
 // ]]>  
 </script>  
 ENDSCRIPT  
 }  
   
 sub page_start {  sub page_start {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$name,      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$name,
  $extra_head)=@_;   $extra_head)=@_;
Line 358  sub page_start { Line 198  sub page_start {
     }      }
     my $is_task = ($env{'request.uri'} =~ /\.task$/);      my $is_task = ($env{'request.uri'} =~ /\.task$/);
     my $needs_upload;      my $needs_upload;
       my ($symb)= &Apache::lonnet::whichuser();
       my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb);
     if ($is_task) {      if ($is_task) {
         $extra_head .= &file_delchk_js();          $extra_head .= &Apache::lonhtmlcommon::file_submissionchk_js();
     } else {      } else {
         if (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.uploadedfiletypes") ne '') {          if (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.uploadedfiletypes") ne '') {
             $needs_upload = 1;              unless ($env{'request.state'} eq 'construct') {
                   my $navmap = Apache::lonnavmaps::navmap->new();
                   if (ref($navmap)) {
                       my $mapres = $navmap->getResourceByUrl($map);
                       my $is_page;
                       if (ref($mapres)) {
                           $is_page = $mapres->is_page();
                       }
                       unless ($is_page) {
                           $needs_upload = 1;
                       }
                   }
               }
         } else {          } else {
             unless ($env{'request.state'} eq 'construct') {              unless ($env{'request.state'} eq 'construct') {
                 my ($symb)= &Apache::lonnet::whichuser();  
                 my $navmap = Apache::lonnavmaps::navmap->new();                  my $navmap = Apache::lonnavmaps::navmap->new();
                 if (ref($navmap)) {                  if (ref($navmap)) {
                     my $res = $navmap->getBySymb($symb);                      my $mapres = $navmap->getResourceByUrl($map);
                     if (ref($res)) {                      my $is_page;
                         my $partlist = $res->parts();                      if (ref($mapres)) {
                         if (ref($partlist) eq 'ARRAY') {                          $is_page = $mapres->is_page();
                             foreach my $part (@{$partlist}) {                      }
                                 my @types = $res->responseType($part);                      unless ($is_page) {
                                 my @ids = $res->responseIds($part);                          my $res = $navmap->getBySymb($symb);
                                 for (my $i=0; $i < scalar(@ids); $i++) {                          if (ref($res)) {
                                     if ($types[$i] eq 'essay') {                              my $partlist = $res->parts();
                                         my $partid = $part.'_'.$ids[$i];                              if (ref($partlist) eq 'ARRAY') {
                                         if (&Apache::lonnet::EXT("resource.$partid.uploadedfiletypes") ne '') {                                  foreach my $part (@{$partlist}) {
                                             $needs_upload = 1;                                      my @types = $res->responseType($part);
                                             last;                                      my @ids = $res->responseIds($part);
                                       for (my $i=0; $i < scalar(@ids); $i++) {
                                           if ($types[$i] eq 'essay') {
                                               my $partid = $part.'_'.$ids[$i];
                                               if (&Apache::lonnet::EXT("resource.$partid.uploadedfiletypes") ne '') {
                                                   $needs_upload = 1;
                                                   last;
                                               }
                                         }                                          }
                                     }                                      }
                                 }                                  }
                             }                              } 
                         }                           }
                     }                      }
                 }                  }
             }              }
         }          }
     }          if ($needs_upload) {
     if ($needs_upload) {              $extra_head .= &Apache::lonhtmlcommon::file_submissionchk_js();
         $extra_head .= &file_overwritechk_js()."\n".          }
                        &file_delchk_js();  
     }      }
   
     my %body_args;      my %body_args;
Line 424  sub page_start { Line 283  sub page_start {
         &Apache::lonhtmlcommon::clear_breadcrumbs();          &Apache::lonhtmlcommon::clear_breadcrumbs();
         &Apache::lonhtmlcommon::add_breadcrumb({          &Apache::lonhtmlcommon::add_breadcrumb({
             'text'  => 'Construction Space',              'text'  => 'Construction Space',
             'href'  => &Apache::loncommon::authorspace(),              'href'  => &Apache::loncommon::authorspace($env{'request.uri'}),
         });          });
         # breadcrumbs (and tools) will be created           # breadcrumbs (and tools) will be created 
         # in start_page->bodytag->innerregister          # in start_page->bodytag->innerregister
Line 489  sub page_start { Line 348  sub page_start {
         my ($symb,$courseid,$udom,$uname)=&Apache::lonnet::whichuser();          my ($symb,$courseid,$udom,$uname)=&Apache::lonnet::whichuser();
         my ($path,$multiresp) =           my ($path,$multiresp) = 
             &Apache::loncommon::get_turnedin_filepath($symb,$uname,$udom);              &Apache::loncommon::get_turnedin_filepath($symb,$uname,$udom);
         if ($is_task) {          if (($is_task) || ($needs_upload)) {
             $form_tag_start .= ' onsubmit="return file_deletion_check(this);"';              $form_tag_start .= ' onsubmit="return file_submission_check(this,'."'$path','$multiresp'".');"';
         } elsif ($needs_upload) {  
             $form_tag_start .= ' onsubmit="return file_overwrite_check(this,'."'$path','$multiresp'".');"';  
         }          }
  $form_tag_start.='>'."\n";   $form_tag_start.='>'."\n";
   
Line 1682  sub end_block { Line 1539  sub end_block {
     }      }
     return $result;      return $result;
 }  }
   #
   #  <languageblock [include='lang1,lang2...'] [exclude='lang1,lang2...']>
   #  ...
   #  </languageblock>
   #
   #   This declares the intent to provide content that can be rendered in the
   #   set of languages in the include specificatino but not in the exclude
   #   specification.  If a currently preferred language is in the include list
   #   the content in the <languageblock>...</languageblock> is rendered
   #   If the currently preferred language is in the exclude list,
   #   the content in the <languageblock>..></languageblock is not rendered.
   #
   #   Pathalogical case handling:
   #     - Include specified, without the preferred language but exclude  specified
   #       also without the preferred langauge results in rendering the block.
   #     - Exclude specified without include and excluden not containing a 
   #       preferred language renders the block.
   #     - Include and exclude both specifying the preferred language does not
   #       render the block.
   #     - If neither include/exclude is specified, the block gets rendered.
   #
   #  This tag has no effect when target is in {edit, modified}
   #
 sub start_languageblock {  sub start_languageblock {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
   
     my $result;      my $result = '';
   
     if ($target eq 'web' || $target eq 'grade'   || $target eq 'answer' ||      if ($target eq 'web' || $target eq 'grade'   || $target eq 'answer' ||
  $target eq 'tex' || $target eq 'analyze' || $target eq 'webgrade') {   $target eq 'tex' || $target eq 'analyze' || $target eq 'webgrade') {
  my $include = $token->[2]->{'include'};   my $include = $token->[2]->{'include'};
  my $exclude = $token->[2]->{'exclude'};   my $exclude = $token->[2]->{'exclude'};
         my @preferred_languages=&Apache::lonlocal::preferred_languages();          my @preferred_languages=&Apache::lonlocal::preferred_languages();
 # This should not even happen, since we should at least have the server language  
         if (!$preferred_languages[0]) { $preferred_languages[0]='en'; }          # This should not even happen, since we should at least have the server language
 # Now loop over all languages in order of preference  
           if (!$preferred_languages[0]) { 
       $preferred_languages[0]='en'; 
    }
   
           # Now loop over all languages in order of preference
   
         foreach my $preferred_language (@preferred_languages) {          foreach my $preferred_language (@preferred_languages) {
 # If the languageblock has no arguments, show the contents  
            $result=1;      # If neither include/nor exlude is present the block is going
       # to get rendered.
   
              my $render=1;
            my $found=0;             my $found=0;
 # Do we have an include argument?             
      #  If include is specified,  don't render the block
      #  unless the preferred language is included in the set.
   
    if ($include) {     if ($include) {
 # If include is specified, by default, don't render the block                $render=0;
               $result=0;  
               foreach my $included_language (split(/\,/,$include)) {                foreach my $included_language (split(/\,/,$include)) {
 # ... but if my preferred language is included, render it  
                  if ($included_language eq $preferred_language) {                   if ($included_language eq $preferred_language) {
                     $result=1;                       $render=1; 
                     $found=1;                       $found=1; 
       last; # Only need to find the first.
                  }                   }
               }                }
    }     }
 # Do we have an exclude argument?             # Do we have an exclude argument?
      # If so, and one of the languages matches a preferred language
      # inhibit rendering the block.  Note that in the pathalogical case the
      # author has specified a preferred language in both the include and exclude
      # attribte exclude is preferred.  
   
            if ($exclude) {             if ($exclude) {
               $result=1;                $render=1;
               foreach my $excluded_language (split(/\,/,$exclude)) {                foreach my $excluded_language (split(/\,/,$exclude)) {
                  if ($excluded_language eq $preferred_language) {                   if ($excluded_language eq $preferred_language) {
                     $result=0;                      $render=0;
                     $found=1;                      $found=1;
       last; # Only need to find the first.
                  }                   }
               }                }
    }     }
            if ($found) { last; }             if ($found) { 
          last; # Done on any match of include or exclude.
      }
         }          }
  if ( ! $result ) {   # If $render not true skip the entire block until </languageblock>
    #
   
    if ( ! $render ) {
     my $skip=&Apache::lonxml::get_all_text("/languageblock",$parser,      my $skip=&Apache::lonxml::get_all_text("/languageblock",$parser,
    $style);     $style);
     &Apache::lonxml::debug("skipping ahead :$skip: $$parser[-1]");      &Apache::lonxml::debug("skipping ahead :$skip: $$parser[-1]");
  }   }
  $result='';   # If $render is true, we've not skipped the contents of the <languageglock>
    # and the normal loncapa processing flow will render it as a matter of course.
   
     } elsif ($target eq 'edit') {      } elsif ($target eq 'edit') {
  $result .=&Apache::edit::tag_start($target,$token);   $result .=&Apache::edit::tag_start($target,$token);
  $result .=&Apache::edit::text_arg(&mt('Include Language:'),'include',   $result .=&Apache::edit::text_arg(&mt('Include Language:'),'include',
Line 1754  sub end_languageblock { Line 1657  sub end_languageblock {
     }      }
     return $result;      return $result;
 }  }
   #  languagblock specific tags:
 {  {
     my %available_texts;      # For chunks of a resource that has translations, this hash contains
       # the translations available indexed by language name.
       #
   
       my %available_texts;       
   
       # <translated> starts a block of a resource that has multiple translations.
       # See the <lang> tag as well.
       # When </translated> is encountered if there is a translation for the 
       # currently preferred language, that is rendered inthe web/tex/webgrade
       # targets.  Otherwise, the default text is rendered.
       #
       # Note that <lang> is only registered for the duration of the 
       #  <translated>...</translated> block 
       #
       # Pathalogical case handling:
       #   - If there is no <lang> that specifies a 'default' and there is no
       #     translation that matches a preferred language, nothing is rendered.
       #   - Nested <translated>...</translated> might be linguistically supported by
       #     XML due to the stack nature of tag registration(?) however the rendered
       #     output will be incorrect because there is only one %available_texts
       #     has and end_translated clears it.
       #   - Material outside of a <lang>...</lang> block within the
       #     <translated>...<translated> block won't render either e.g.:
       #    <translated>
       #      The following will be in your preferred langauge:
       #      <lang which='en'>
       #         This section in english
       #      </lang>
       #      <lang which='sgeiso'>
       #         Hier es ist auf Deutsch.
       #      </lang>
       #      <lang which='sfriso'>
       #         En Francais
       #      </lang>
       #    </translated>
       #
       #    The introductory text prior to the first <lang> tag is not rendered.
       #
     sub start_translated {      sub start_translated {
  my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  &Apache::lonxml::register('Apache::structuretags',('lang'));   &Apache::lonxml::register('Apache::structuretags',('lang'));
Line 1782  sub end_languageblock { Line 1723  sub end_languageblock {
  return $result;   return $result;
     }      }
   
       # <lang [which='language-name'] [other='lang1,lang2...']>  
       #  Specifies that the block contained within it is a translation 
       #  for a specific language specified by the 'which' attribute. The
       #   'other' attribute can be used by itself or in conjunction with
       #   which to specify this tag _may_ be used as a translation for some
       #   list of languages. e.g.:  <lang which='senisoUS' other='senisoCA,senisoAU,seniso'>
       #   specifying that the block provides a translation for US (primary)
       #   Canadian, Australian and UK Englush.
       #   
       # Comment: this seems a bit silly why not just support a list of languages
       #           e.g. <lang which='l1,l2...'> and ditch the other attribute?
       #
       #  Effect:
       #    The material within the <lang>..</lang> block is stored in the
       #    specified set of $available_texts hash entries, the appropriate one
       #    is selected at </translated> time.
       #
       #  Pathalogical case handling:
       #    If a language occurs multiple times within a <translated> block,
       #    only the last one is rendered e.g.:
       #
       #    <translated>
       #       <lang which='senisoUS', other='senisoCA,senisoAU,seniso'>
       #          Red green color blindness is quite common affecting about 7.8% of 
       #          the male population, but onloy about .65% of the female population.
       #       </lang>
       #          Red green colour blindness is quite common affecting about 7.8% of 
       #          the male population, but onloy about .65% of the female population.
       #       <lang which='seniso', other='senisoCA,senisoAU'>
       #     </translated>
       #
       #    renders the correct spelling of color (colour) for people who have specified
       #    a preferred language that is one of the British Commonwealth languages
       #    even though those are also listed as valid selections for the US english
       #    <lang> block.
       #
     sub start_lang {      sub start_lang {
  my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;   my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;
  if ($target eq 'web' || $target eq 'grade'   || $target eq 'answer' ||   if ($target eq 'web' || $target eq 'grade'   || $target eq 'answer' ||
Line 1813  sub end_languageblock { Line 1789  sub end_languageblock {
  }   }
  return '';   return '';
     }      }
 }  } # end langauge block specific tags.
   
   
 sub start_instructorcomment {  sub start_instructorcomment {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;      my ($target,$token,$tagstack,$parstack,$parser,$safeeval,$style)=@_;

Removed from v.1.494  
changed lines
  Added in v.1.497.2.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>