File:  [LON-CAPA] / loncom / homework / daxepage.pm
Revision 1.18: download - view: text, annotated - select for diffs
Fri Feb 21 06:09:37 2025 UTC (4 months, 1 week ago) by raeburn
Branches: MAIN
CVS tags: version_2_12_X, HEAD
- WCAG 2 compliance.
  - Replace layout table with divs in collapsible header above Daxe iframe.

    1: # The LearningOnline Network
    2: # Page with Daxe on the left side and the preview on the right side
    3: #
    4: # $Id: daxepage.pm,v 1.18 2025/02/21 06:09:37 raeburn Exp $
    5: #
    6: # Copyright Michigan State University Board of Trustees
    7: #
    8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    9: #
   10: # LON-CAPA is free software; you can redistribute it and/or modify
   11: # it under the terms of the GNU General Public License as published by
   12: # the Free Software Foundation; either version 2 of the License, or
   13: # (at your option) any later version.
   14: #
   15: # LON-CAPA is distributed in the hope that it will be useful,
   16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18: # GNU General Public License for more details.
   19: #
   20: # You should have received a copy of the GNU General Public License
   21: # along with LON-CAPA; if not, write to the Free Software
   22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23: #
   24: # /home/httpd/html/adm/gpl.txt
   25: #
   26: # http://www.lon-capa.org/
   27: #
   28: ###
   29: 
   30: package Apache::daxepage;
   31: use strict;
   32: 
   33: use Apache::loncommon();
   34: use Apache::lonnet();
   35: use Apache::lonhtmlcommon();
   36: use Apache::lonxml();
   37: use Apache::edit();
   38: use Apache::lonmenu();
   39: use Apache::lonlocal;
   40: use Apache::Constants qw(:common);
   41: use LONCAPA qw(:DEFAULT :match);
   42: use HTML::Entities();
   43: 
   44: sub handler {
   45:     my $request = shift;
   46:     my $uri = $request->uri;
   47:     $uri =~ s{^/daxepage}{};
   48:     &Apache::loncommon::content_type($request,'text/html');
   49:     my ($is_not_assess,$is_assess,$is_course_doc,$is_supp,$supp_path,$supp_title);
   50:     if ($uri =~/\.(xml|html|htm|xhtml|xhtm)$/) {
   51:         $is_not_assess = 1;
   52:         if ($Apache::lonnet::env{'request.course.id'}) {
   53:             my $cid = $Apache::lonnet::env{'request.course.id'};
   54:             my $cdom = $Apache::lonnet::env{'course.'.$cid.'.domain'};
   55:             my $cnum = $Apache::lonnet::env{'course.'.$cid.'.num'};
   56:             if ($uri =~ m{^/uploaded/\Q$cdom/$cnum\E/(docs|supplemental)/}) {
   57:                 if ($1 eq 'supplemental') {
   58:                     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
   59:                                                             ['folderpath','title']);
   60:                     $is_supp = 1;
   61:                     $supp_path = &escape(&HTML::Entities::decode($Apache::lonnet::env{'form.folderpath'}));
   62:                     $supp_title = &escape(&HTML::Entities::decode($Apache::lonnet::env{'form.title'}));
   63:                 }
   64:                 $is_course_doc = 1;
   65:                 $Apache::lonnet::env{'form.forceedit'} = 1;
   66:             }
   67:         }
   68:     } elsif ($uri =~ /$LONCAPA::assess_re/) {
   69:         unless ($uri =~ /\.form$/) {
   70:             $is_assess = 1;
   71:         }
   72:     }
   73:     unless ($is_not_assess || $is_assess) {
   74:         $request->status(406);
   75:         return OK;
   76:     }
   77:     my %editors = &Apache::loncommon::permitted_editors($uri);
   78:     unless ($editors{'daxe'}) {
   79:         my $msg = '<p class="LC_warning">'.
   80:                   &mt('Daxe editor is not enabled for this Authoring Space.').'</p>';
   81:         &do_redirect($request,$uri,$msg);
   82:         return OK;
   83:     }
   84:     if ($is_not_assess) {
   85:         delete($editors{'xml'});
   86:         $editors{'edit'} = 1;
   87:         $Apache::lonnet::env{'form.editmode'} = 'daxe';
   88:     } else {
   89:         $Apache::lonnet::env{'form.problemmode'} = 'daxe';
   90:     }
   91:     &Apache::lonhtmlcommon::clear_breadcrumbs();
   92:     my %lt = &Apache::lonlocal::texthash(
   93:                                           'noif' => 'No iframe support.',
   94:                                           'show' => 'Show content in pop-up window',
   95:                                           'save' => 'Save',
   96:                                           'text' => 'Text Editor',
   97:                                           'oeds' => 'other editors',
   98:                                           'othe' => 'other editor',
   99:                                           'edit' => 'Save and Edit',
  100:                                           'disc' => 'Discard and View',
  101:                                           'save' => 'Save and View',
  102:                                           'daxe' => 'Daxe Editor',
  103:                                         );
  104:     my $name = $uri;
  105:     $name =~ s/^.*\/([^\/]+)$/$1/;
  106:     my $lang = &Apache::lonlocal::current_language();
  107:     my $filearg = '/daxeopen'.$uri;
  108:     my $daxeurl = '/adm/daxe/daxe.html?config=config/loncapa_config.xml&save=/daxesave'.
  109:                   '&file='.$filearg;
  110:     my $headjs = &Apache::loncommon::iframe_wrapper_headjs().
  111:                  &listener_js($lang,$filearg,$is_assess).
  112:                  &toggle_LCmenus_js().&saveandview_js().
  113:                  &Apache::edit::js_change_detection();
  114: 
  115:     my ($clickexit,$clicksave,$clickedit);
  116:     if ($is_assess) {
  117:         $headjs .= &Apache::lonxml::setmode_javascript();
  118:         $clickexit = "javascript:setmode(this.form,'view');";
  119:     } else {
  120:         $headjs .= &Apache::lonxml::seteditor_javascript($is_course_doc,$is_supp,
  121:                                                          $supp_path,$supp_title);
  122:         $clickexit = "javascript:seteditmode(this.form,'view');";
  123:     }
  124:     $clicksave = "javascript:daxesave('exit');";
  125:     $clickedit = "javascript:daxesave();";
  126:     my $form_events = &Apache::edit::form_change_detection();
  127:     my $editheader = '<form '.$form_events.' method="post" name="daxeedit" action="'.$uri.'">';
  128:     if ($is_assess) {
  129:         $editheader .= '<input type="hidden" name="problemmode" value="daxe" />'."\n";
  130:     }
  131:     $editheader .= '<div class="LC_edit_problem_daxe_header">'."\n";
  132:     my $saveeditbutton = '<input type="button" name="submitmode" accesskey="s" value="'.$lt{'edit'}.
  133:                      '" onclick="'.$clickedit.'" />'."\n";
  134:     my $exitbutton = '<input type="button" name="submitmode" accesskey="d" value="'.$lt{'disc'}.
  135:                      '" onclick="'.$clickexit.'" />'."\n";
  136:     my $saveexitbutton = '<input type="button" name="submitmode" accesskey="v" value="'.$lt{'save'}.
  137:                      '" onclick="'.$clicksave.'" />'."\n";
  138:     $editheader .= '<div class="LC_landmark" style="clear:both;">'.
  139:                    '<div class="LC_floatleft LC_landmark" style="margin-top: 2px">'.$uri.'</div>'.
  140:                    '<div class="LC_floatright LC_landmark"><span class="LC_nobreak">'.
  141:                    $saveeditbutton.$saveexitbutton.$exitbutton.'</span>';
  142:     if ($editors{'edit'} || $editors{'xml'}) {
  143:         my $other = (($editors{'edit'} && $editors{'xml'})? $lt{'oeds'} : $lt{'othe'});
  144:         $editheader .= '&nbsp;&nbsp;|&nbsp;&nbsp;<span class="LC_nobreak">'.$other.':</span> '.
  145:                        '<span class="LC_nobreak">';
  146:         if ($is_not_assess) {
  147:             $editheader .= '<input type="hidden" name="editmode" value="daxe" />'."\n".
  148:                            '<input type="button" name="editordefault" value="'.$lt{'text'}.
  149:                            '" onclick="javascript:seteditmode(this.form,'."'edit'".');" />'."\n";
  150:         } else {
  151:             if ($editors{'edit'}) {
  152:                 $editheader .= '<input type="button" name="submitmode" accesskey="e" value="'.&mt('Edit').'" '.
  153:                                'onclick="javascript:setmode(this.form,'."'edit'".')" />'."\n";
  154:             }
  155:             if ($editors{'xml'}) {
  156:                 $editheader .= '<input type="button" name="submitmode" accesskey="x" value="'.&mt('EditXML').'" '.
  157:                                'onclick="javascript:setmode(this.form,'."'editxml'".')" />'."\n";
  158:             }
  159:         }
  160:         $editheader .= '</span>';
  161:     }
  162:     $editheader .= '</div></div>'.
  163:                    '<div class="LC_landmark" style="clear:both"></div>'.
  164:                    '</div></form>'."\n";
  165:     my $start_collapsed = &collapsible_std_LCmenus();
  166:     my $args = {
  167:                 'collapsible_header' => $editheader,
  168:                 'start_collapsed'    => $start_collapsed,
  169:                };
  170:     my $startpage = &Apache::loncommon::start_page('Daxe: '.$name,$headjs,$args).
  171:                     &Apache::lonmenu::constspaceform();
  172:     my $endpage = &Apache::loncommon::end_page();
  173: 
  174:     # javascript will position the iframe if window was resized (or zoomed)
  175:     my $script = &Apache::loncommon::iframe_wrapper_resizejs();
  176:     my $dest = &HTML::Entities::encode($daxeurl,'&<>"');
  177:     my $noiframe = &Apache::loncommon::modal_link($dest,$lt{'show'},500,400);
  178: 
  179:     $request->print(<<"ENDFRAME");
  180: $startpage
  181: $script
  182: <div class="LC_iframecontainer" style="padding-right: 5px" role="main">
  183: <h1 class="LC_visually_hidden">$lt{'daxe'}</h1>
  184: <iframe src="$dest" id="lcdiframe">$lt{'noif'} $noiframe</iframe>
  185: </div>
  186: $endpage
  187: ENDFRAME
  188:     return OK;
  189: }
  190: 
  191: sub listener_js {
  192:     my ($lang,$filearg,$is_assess) = @_;
  193:     return <<"ENDJS";
  194: <script type="text/javascript">
  195: //<![CDATA[
  196: 
  197: var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent";
  198: var eventer = window[eventMethod];
  199: var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message";
  200: 
  201: eventer(messageEvent,function(e) {
  202:     var reqdOrigin = window.location.protocol+'//'+window.location.hostname;
  203:     var is_assess = '$is_assess';
  204:     if (e.origin == reqdOrigin) {
  205:         if (e.data == '$filearg') {
  206:             if (is_assess) {
  207:                 setmode(document.daxeedit,'view');
  208:             } else {
  209:                 seteditmode(document.daxeedit,'view');
  210:             }
  211:         } else if ((e.data == 'userlclang') || (e.data == 'userlang')) {
  212:             window.myIframe = document.getElementById("lcdiframe").contentWindow;
  213:             window.myIframe.postMessage(e.data+':$lang',reqdOrigin);
  214:         }
  215:         return;
  216:     }
  217: },false);
  218: 
  219: //]]>
  220: </script>
  221: ENDJS
  222: 
  223: }
  224: 
  225: sub saveandview_js {
  226:     return <<"ENDJS";
  227: 
  228: <script type="text/javascript">
  229: //<![CDATA[
  230: 
  231: function daxesave(exit) {
  232:     window.myIframe = document.getElementById("lcdiframe").contentWindow;
  233:     window.myIframe.focus();
  234:     window.myIframe.savelcdoc(exit);
  235:     return;
  236: }
  237: 
  238: //]]>
  239: </script>
  240: ENDJS
  241: }
  242: 
  243: sub toggle_LCmenus_js {
  244:     my %lt = &Apache::lonlocal::texthash(
  245:                                          altc => 'menu state: collapsed',
  246:                                          alte => 'menu state: explanded',
  247:                                          ttlc => 'display standard menus',
  248:                                          ttle => 'hide standard menus',
  249:     );
  250:     return <<"ENDJS";
  251: <script type="text/javascript">
  252: //<![CDATA[
  253: \$(document).ready (function () {
  254:     \$(".LC_collapse_trigger").on("click", function (e) {
  255:         var id = this.id;
  256:         var \$content = \$(this).next (".LC_menus_content");
  257:         var expanded = \$content.hasClass ("shown");
  258:         if (expanded) {
  259:             \$content.removeClass ("shown");
  260:             \$content.addClass ("hidden");
  261:         } else {
  262:             \$content.removeClass ("hidden");
  263:             \$content.addClass ("shown");
  264:         }
  265: 
  266:         \$(this).find ("[aria-expanded]")
  267:         .attr ("aria-expanded", !expanded);
  268: 
  269:         \$(this).find ("[aria-pressed]")
  270:         .attr ("aria-pressed", !expanded);
  271: 
  272:         \$(this).find (".LC_collapsible_indicator").attr ({
  273:         "src":
  274:         (expanded)? "/res/adm/pages/collapsed.png" : "/res/adm/pages/expanded.png",
  275:         "alt":
  276:         (expanded)? "$lt{altc}" : "$lt{alte}",
  277:         "title":
  278:         (expanded)? "$lt{ttlc}" : "$lt{ttle}"
  279:         });
  280: 
  281:         \$(window).trigger('resize');
  282:         \$(this).focus ();
  283:     });
  284: 
  285:     \$("#LC_expandingContainer").attr ("aria-live", "off");
  286: });
  287: //]]>
  288: </script>
  289: ENDJS
  290: 
  291: }
  292: 
  293: sub do_redirect {
  294:     my ($request,$uri,$msg) = @_;
  295:     &Apache::lonhtmlcommon::clear_breadcrumbs();
  296:     $request->print(
  297:         &Apache::loncommon::start_page('Authoring Space',undef,
  298:                                        {'redirect'       => [2,$uri]}).
  299: 
  300:         '<div style="padding:0;clear:both;margin:0;border:0"></div>'."\n".
  301:         "$msg\n".
  302:         &Apache::loncommon::end_page());
  303:     return;
  304: }
  305: 
  306: sub collapsible_std_LCmenus {
  307:     my $daxecollapse = $Apache::lonnet::env{'environment.daxecollapse'};
  308:     unless ($daxecollapse) {
  309:         my %domdefs = &Apache::lonnet::get_domain_defaults($Apache::lonnet::env{'user.domain'});
  310:         if ($domdefs{'daxecollapse'}) {
  311:             $daxecollapse = 'yes';
  312:         }
  313:     }
  314:     if ($daxecollapse eq 'yes') {
  315:         return 1;
  316:     }
  317:     return;
  318: }
  319: 
  320: 1;
  321: __END__

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