Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 920 lines (768 sloc) 28.135 kb
f60c7ef DanBricklin Initial commit
authored
1 #!/usr/bin/perl
2
3 use strict;
4 use CGI qw(:standard);
5 use URI;
6 use HTTP::Daemon;
7 use HTTP::Status;
8 use HTTP::Response;
9 use Socket;
10 use CGI::Cookie;
11
12 use SocialCalcServersideUtilities;
13
14
15 my $datadir = "se2-data/";
16 my $versionstr = "2.01";
17 my $jsdir = "/sgi/scjstest/";
18
19 #
20 # This whole first section lets this code run either as a CGI script on a server
21 # or standalone on the desktop run from the Perl command line.
22 #
23 # The main processing starts with process_request.
24 #
25
26 if ($ENV{REQUEST_METHOD}) { # being run as a CGI on a server
27 print "Content-type: text/html\n\n";
28 my $q = new CGI;
29 print process_request($q);
30 exit;
31 }
32
33 # running locally - do mini-server
34
35 my $d = HTTP::Daemon->new (
36 LocalPort => 6557,
37 Reuse => 1);
38
39 if (!$d) {
40 print "simpleedit could not start on 127.0.0.1:6557\n";
41 exit;
42 }
43
44 print "simpleedit14\nAccess at: http://127.0.0.1:6557/\n";
45
46 while (my $c = $d->accept) {
47
48 # Make sure the request is from our machine
49
50 if ($c) {
51 my ($port, $host) = sockaddr_in(getpeername($c));
52 if ($host ne inet_aton("127.0.0.1")) {
53 $c->close; # no - ignore request completely
54 undef($c);
55 next;
56 }
57 }
58
59 # Process the request
60
61 while ((defined $c) && (my $r = $c->get_request)) {
62 if ($r->method eq 'POST' || $r->method eq 'GET') {
63 $c->force_last_request;
64 my $uri = $r->uri;
65 if ($uri =~ /favicon/) { # if this is a request for favicon.ico, ignore
66 $c->send_error(RC_NOT_FOUND);
67 next;
68 }
69 if ($uri =~ /\/quit$/) {
70 $c->send_file_response("quitmessage.html");
71 $c->close;
72 undef($c);
73 exit;
74 }
75 if ($uri =~ /\/([a-z\-0-9]+)\.(gif|js|css)$/) { # ok request
76 $uri = "$1.$2";
77 $uri = "images/$uri" if $2 eq "gif";
78 # if ($2 eq "js") {
79 # $res->content_type("text/html; charset=UTF-8");
80 # }
81 $c->send_file_response($uri);
82 next;
83 }
84
85 my $resp="";
86 if ($r->method eq 'POST') {
87 my $q = new CGI($r->content());
88 $resp = process_request($q)
89 }
90 else {
91 my $q = new CGI($r->uri->query());
92 $resp = process_request($q)
93 }
94 my $res = new HTTP::Response(200);
95 $res->content_type("text/html; charset=UTF-8");
96 $res->expires("-1d");
97 $res->content($resp);
98 $c->send_response($res);
99 }
100
101 else {
102 $c->send_error(RC_FORBIDDEN);
103 }
104 }
105
106 $c->close;
107 undef($c);
108 }
109
110 #
111 # Main routine starts here:
112 #
113
114 sub process_request {
115
116 my ($request) = @_;
117 my $q = new CGI($request);
118
119 my $response;
120
121 my ($statusmessage);
122
123 if ($q->param("loadsheet")) { # Ajax request: loadsheet=pagename.sheetname
124 my $fullsheetname = $q->param("loadsheet");
125 $fullsheetname =~ m/^(.*)\.(.*)$/;
126 my $pagename = $1;
127 my $sheetname = $2;
128 my $page = {};
129 load_page($q, $pagename, $page);
130 my $sheetstr = $page->{items}{$sheetname}{text};
131 my $htmlpos = index($sheetstr, "\nHTML:\n");
132 if ($htmlpos >= 0) {
133 $sheetstr = substr($sheetstr, 0, $htmlpos);
134 }
135 sleep 1;
136 return $sheetstr;
137 }
138
139 if ($q->param("wikitext")) { # Ajax request: wikitext=wikitext-url-encoded
140 my $wikitext = $q->param("wikitext");
141 $wikitext = expand_wikitext($wikitext);
142 sleep 1;
143 return $wikitext;
144 }
145
146 my $pagename = $q->param('pagename');
147
148 if ($q->param('newpage')) {
149 $pagename = $q->param('newpagename');
150 }
151
152 $pagename =~ s/[^a-zA-Z0-9_\-]*//g;
153 if (!$pagename) {
154 $pagename = "home";
155 $statusmessage .= "No pagename given - using '$pagename'<br>";
156 }
157
158 if ($q->param('savepageedit')) {
159 my $newstr;
160 $newstr = $q->param('pagetext');
161 if ($q->param('edittype') eq "clean") {
162 my $page = {};
163 load_page($q, $pagename, $page);
164 $newstr =~ s/^\[(spreadsheet|datatable|drawing)\:(.+?)\]/"[$1:$2:\n" . $page->{items}{$2}{text} . "\n:$1]"/gme;
165 }
166 open (PAGEFILEOUT, ">$datadir$pagename.page.txt");
167 print PAGEFILEOUT $newstr;
168 close PAGEFILEOUT;
169 $statusmessage .= "Saved updated page '$pagename'.<br>";
170 }
171
172 if ($q->param("editpage") || $q->param("editrawpage")) { # when one of the "editpage" buttons is pressed
173 return do_editpage($q, $pagename, $statusmessage);
174 }
175
176 foreach my $p ($q->param) { # go through all the parameters
177 if ($p =~ /^edit(spreadsheet|datatable):(.*)/) { # "editspreadsheet:sheetname" pressed
178 return start_editsheet($pagename, $2, $q, $statusmessage);
179 }
180 if ($p =~ /^editdrawing:(.*)/) { # "editdrawing:sheetname" pressed
181 return start_editdrawing($pagename, $1, $q, $statusmessage);
182 }
183 }
184
185 if ($q->param('savespreadsheet')) { # save the edited spreadsheet
186 my $page = {};
187 load_page($q, $pagename, $page);
188 my $pagestr = $page->{raw};
189 my $sheetname = $q->param('sheetname');
190 my $sheettype = $page->{items}{$sheetname}{type};
191
192 $pagestr =~ s/^\[$sheettype\:$sheetname:.*?\:$sheettype\]/"[$sheettype:$sheetname:\n" . $q->param('newstr') . "\n:$sheettype]"/sme;
193
194 open (PAGEFILEOUT, ">$datadir$pagename.page.txt");
195 print PAGEFILEOUT $pagestr;
196 close PAGEFILEOUT;
197 $statusmessage =
198 "Saved updated $sheettype '$sheetname' on page '$pagename'.<br>";
199 }
200
201 $response = do_displaypage($q, $pagename, $statusmessage); # Otherwise, display page
202
203 return $response;
204
205 }
206
207 #
208 # load_page($q, $pagename, \%page)
209 #
210 # Loads the specified page and puts the parts into %page:
211 #
212 # %page{raw} - raw page text
213 # %page{clean} - page text with embedded items' bodies removed
214 # %page{items}{name} - hash with embedded item "name"'s info
215 # %page{items}{name}{text} - text of embedded item's body
216 # %page{items}{name}{type} - type embedded item (e.g., "spreadsheet")
217 #
218
219 sub load_page {
220
221 my ($q, $pagename, $page) = @_;
222
223 $page->{bodies} = {};
224
225 open (PAGEFILEIN, "$datadir$pagename.page.txt");
226 my ($rawstr, $cleanstr);
227 while (my $line = <PAGEFILEIN>) {
228 $line =~ s/\r//g;
229 $rawstr .= $line;
230 if ($line =~ m/^\[(spreadsheet|datatable|drawing)\:(.*?)\:/) {
231 my $type = $1;
232 my $name = $2;
233 $page->{items}{$name} = {type => $type, text => ""};
234 my $itemstr;
235 while (my $sline = <PAGEFILEIN>) {
236 $sline =~ s/\r//g;
237 $rawstr .= $sline;
238 last if substr($sline, 0, length($type)+2) eq ":$type]";
239 $itemstr .= $sline;
240 }
241 $page->{items}{$name}{text} = $itemstr;
242 $cleanstr .= "[$type:$name]\n";
243 }
244 else {
245 $cleanstr .= $line;
246 }
247 }
248 close PAGEFILEIN;
249 $page->{raw} = $rawstr;
250 $page->{clean} = $cleanstr;
251
252 return;
253 }
254
255 #
256 # $response = do_displaypage($q, $pagename, $statusmessage) - Display page
257 #
258
259 sub do_displaypage {
260
261 my ($q, $pagename, $statusmessage) = @_;
262 my $response;
263
264 my $page = {};
265 load_page($q, $pagename, $page);
266
267 open (PAGEFILEIN, "$datadir$pagename.page.txt");
268 my $pagestr;
269 while (my $line = <PAGEFILEIN>) {
270 $line =~ s/\r//g;
271 if ($line =~ m/^\[(spreadsheet|datatable|drawing)\:(.*?)\:/) {
272 my $sheettype = $1;
273 my $sheetname = $2;
274 my $sheetstr;
275 while (my $sline = <PAGEFILEIN>) {
276 $sline =~ s/\r//g;
277 last if $sline =~ m/^:(spreadsheet|datatable|drawing)]/;
278 $sheetstr .= $sline;
279 }
280 my $htmlpos = index($sheetstr, "\nHTML:\n");
281 my $html="";
282 my $localhtml="";
283 if ($htmlpos >= 0) {
284 $html = substr($sheetstr, $htmlpos+7);
285 $sheetstr = substr($sheetstr, 0, $htmlpos);
286 my $sheet = CreateSheet();
287 my $parts = DecodeSpreadsheetSave($sheetstr);
288 ParseSheetSave($sheet, $parts->{sheet});
289 my $context = CreateRenderContext($sheet);
290 $localhtml = RenderSheet($context);
291 }
292 else {
293 $html = "Sheet goes here";
294 $localhtml = "Sheet goes here";
295 }
296 $sheetstr = special_chars($sheetstr);
297 $pagestr .= <<"EOF";
298 <textarea id="sheetdata-$sheetname" style="display:none;">$sheetstr</textarea>
299 <table cellspacing="0" cellpadding="0" width="100%">
300 <tr onmouseout="hide_buttons(!document.getElementById('showb').checked);"
301 onmouseover="hide_buttons(false);"><td valign="top" id="sheet-$sheetname">$localhtml</td>
302 <td class="hideable" width="5" style="visibility:hidden;border-top:1px solid #80A9F3;border-bottom:1px solid #80A9F3;padding:6px;">&nbsp;</td>
303 <td class="hideable" width="100" valign="middle" style="visibility:hidden;border-left:1px solid #80A9F3;padding:6px;">
304 <span style="font-size:smaller;">$sheettype:<br>$sheetname<br></span>
305 <input type="submit" name="edit$sheettype:$sheetname" value="Edit" style="font-size:smaller;">
306 </td></tr></table>
307 <script>
308 if("$sheettype"!="spreadsheet") show_$sheettype("$sheetname");
309 </script>
310 EOF
311 }
312 else {
313 $pagestr .= expand_wikitext($line);
314 }
315 }
316
317 close PAGEFILEIN;
318
319 $response = <<"EOF";
320 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
321 "http://www.w3.org/TR/html4/strict.dtd">
322 <html>
323 <head>
324 <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
325 <title>Simple Page Editor With Spreadsheets $versionstr</title>
326 <script type="text/javascript" src="${jsdir}socialcalcconstants.js"></script>
327 <script type="text/javascript" src="${jsdir}socialcalc-3.js"></script>
328 <script type="text/javascript" src="${jsdir}socialcalctableeditor.js"></script>
329 <script type="text/javascript" src="${jsdir}formatnumber2.js"></script>
330 <script type="text/javascript" src="${jsdir}formula1.js"></script>
331 <script type="text/javascript" src="${jsdir}drawlib3.js"></script>
332 <script>
333
334 function show_datatable(sheetname) {
335 var sheet = new SocialCalc.Sheet();
336 sheet.ParseSheetSave(document.getElementById("sheetdata-"+sheetname).value);
337 var context=new SocialCalc.RenderContext(sheet);
338 context.CalculateCellSkipData();
339 context.CalculateColWidthData();
340 context.showGrid=true;
341 context.showRCHeaders=true;
342 var teobj=new SocialCalc.TableEditor(context);
343 teobj.imageprefix="/sgi/scjstest/sc";
344 teobj.recalcFunction = null;
345 var sizes = SocialCalc.GetViewportInfo();
346 var teelement=teobj.CreateTableEditor(800, 300);
347 var teid=document.getElementById("sheet-"+sheetname);
348 teid.replaceChild(teelement, teid.firstChild);
349 teobj.SchedulePositionCalculations();
350 }
351
352 function show_drawing(sheetname) {
353 var teid=document.getElementById("sheet-"+sheetname);
354 var sheet = new SocialDraw.Sheet(teid, false, document.getElementById("sheetdata-"+sheetname).value);
355 sheet.Display();
356 }
357
358 function hide_buttons(hide) {
359 var val=hide ? 'hidden':'visible';
360 var tds = document.getElementsByTagName("td");
361 for (var i=0; i<tds.length; i++) {
362 if (tds[i].className=="hideable") tds[i].style.visibility=val;
363 }
364 }
365 </script>
366 <style>
367 body, td, input, texarea
368 {font-family:verdana,helvetica,sans-serif;font-size:small;}
369 </style>
370 </head>
371 <body>
372 <form action="" method="POST">
373 <div style="padding:6px;background-color:#80A9F3;">
374 <div style="font-weight:bold;color:white;">SIMPLE SYSTEM FOR EDITING PAGES WITH SPREADSHEETS AND MORE</div>
375 <div style="color:#FDD;font-weight:bold;">$statusmessage &nbsp;</div>
376 <table cellspacing="0" cellpadding="0" width="100%">
377 <tr>
378 <td>
379 Viewing page: <span style="font-style:italic;font-weight:bold;">$pagename</span>
380 &nbsp;<input type="submit" name="editpage" value="Edit This Page" style="font-size:smaller;">
381 </td>
382 <td align="right">
383 <input type="submit" name="editrawpage" value="Edit Raw Page" style="font-size:smaller;">
384 </td></tr></table>
385 </div>
386 <div style="border:6px solid #80A9F3;padding:0px 10px 10px 10px;">
387 <div style="padding-top:5px;">
388 <table cellpadding="0" cellspacing="0"><tr><td width="100%"></td><td valign="top">
389 <input id="showb" type="checkbox" value="1" onclick="hide_buttons(!this.checked);">
390 </td><td style="font-size:smaller;padding-left:4px;">Show&nbsp;item<br>edit&nbsp;buttons</td>
391 </tr></table>
392 </div>
393 $pagestr
394 </div>
395 <div style="padding:6px;background-color:#80A9F3;">
396 <div style="font-weight:bold;font-size:smaller;">Pages:</div>
397 <div style="font-size:smaller;">
398 EOF
399
400 my @pagefiles = glob("$datadir*.page.txt"); # Get list of all pages
401 for (my $pnum=0; $pnum <= $#pagefiles; $pnum++) {
402 $pagefiles[$pnum] =~ m/^(?:.*\/){0,1}(.*).page.txt$/;
403 $response .= ", " if $pnum!=0;
404 $response .= qq!<a href="?pagename=$1">$1</a>!;
405 }
406
407 $response .= <<"EOF";
408 </div>
409 <br>
410 <input type="hidden" name="pagename" value="$pagename">
411 </form>
412 <form action="" method="POST">
413 <input type="text" name="newpagename" value="">
414 <input type="submit" name="newpage" value="Create New Page">
415 </form>
416 </div>
417 <br>
418 </body>
419 </html>
420 EOF
421
422 return $response;
423 }
424
425
426 #
427 # do_editpage($q, $pagename, $statusmessage) - Show page editing display
428 #
429
430 sub do_editpage {
431
432 my ($q, $pagename, $statusmessage) = @_;
433 my $response;
434
435 my $page = {};
436 load_page($q, $pagename, $page);
437
438 my $edittype = $q->param("editpage") ? "clean" : "raw";
439
440 my $pagestr = special_chars($page->{$edittype});
441
442 $response = <<"EOF";
443 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
444 "http://www.w3.org/TR/html4/strict.dtd">
445 <html>
446 <head>
447 <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
448 <title>Simple Page Editor With Spreadsheets $versionstr</title>
449 <style>
450 body, td, input, texarea
451 {font-family:verdana,helvetica,sans-serif;font-size:small;}
452 </style>
453 </head>
454 <body>
455 <form name="f0" action="" method="POST">
456 <div style="padding:6px;background-color:#80A9F3;">
457 <div style="font-weight:bold;color:white;">SIMPLE SYSTEM FOR EDITING PAGES WITH SPREADSHEETS AND MORE</div>
458 <div style="color:#FDD;font-weight:bold;">$statusmessage &nbsp;</div>
459 <div style="margin-bottom:6px;">Editing page: <span style="font-style:italic;font-weight:bold;">$pagename</span></div>
460 <script>
461 function addss(sstype) {
462 var now = new Date();
463 var name = ""+now.getFullYear()+(now.getMonth()+101).toString().substr(1)+(now.getDate()+100).toString().substr(1)+
464 (now.getHours()+100).toString().substr(1)+(now.getMinutes()+100).toString().substr(1)+(now.getSeconds()+100).toString().substr(1);
465 var sname =
466 prompt("New "+sstype+" name (alphanumeric only, unique on page):", name);
467 if (!sname) return false;
468 sname = sname.replace(/[^a-zA-Z0-9]/g, "").toLowerCase();
469 if (!sname) return false;
470 document.f0.pagetext.value =
471 document.f0.pagetext.value + "\\n["+sstype+":" + sname +"]\\n";
472 return false;
473 }
474 </script>
475 <div style="margin-bottom:4px;">
476 <table cellspacing="0" cellpadding="0" width="100%">
477 <tr>
478 <td>
479 <input type="submit" name="savepageedit" value="Save">
480 <input type="hidden" name="edittype" value="$edittype">
481 <input type="submit" name="canceledit" value="Cancel">
482 </td>
483 <td align="right">
484 EOF
485
486 if ($edittype eq "clean") {
487 $response .= <<"EOF";
488 <input type="submit" value="Add Spreadsheet" onclick="return addss('spreadsheet');" style="font-size:smaller;">
489 <input type="submit" value="Add Data Table" onclick="return addss('datatable');" style="font-size:smaller;">
490 <input type="submit" value="Add Character Drawing" onclick="return addss('drawing');" style="font-size:smaller;">
491 EOF
492 }
493
494 $response .= <<"EOF";
495 </td></tr></table>
496 </div>
497 <textarea name="pagetext" rows="20" style="width:100%;">$pagestr</textarea>
498 <input type="hidden" name="pagename" value="$pagename">
499 </div>
500 </form>
501 </body>
502 </html>
503 EOF
504
505 return $response;
506 }
507
508 #
509 # start_editsheet($pagename, $sheetname, $q, $statusmessage)
510 # - render initial editing display
511 #
512
513 sub start_editsheet {
514
515 my ($pagename, $sheetname, $q, $statusmessage) = @_;
516
517 my ($response, $sheetstr);
518
519 my $page = {};
520 load_page($q, $pagename, $page);
521
522 $sheetstr = $page->{items}{$sheetname}{text};
523
524 my $htmlpos = index($sheetstr, "\nHTML:\n");
525 if ($htmlpos >= 0) {
526 $sheetstr = substr($sheetstr, 0, $htmlpos);
527 }
528
529 $response = <<"EOF"; # output page with edit JS code
530 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
531 <html>
532 <head>
533 <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
534 <title>Simple Page Editor With Spreadsheets $versionstr</title>
535 <script type="text/javascript" src="${jsdir}socialcalcconstants.js"></script>
536 <script type="text/javascript" src="${jsdir}socialcalc-3.js"></script>
537 <script type="text/javascript" src="${jsdir}socialcalctableeditor.js"></script>
538 <script type="text/javascript" src="${jsdir}formatnumber2.js"></script>
539 <script type="text/javascript" src="${jsdir}formula1.js"></script>
540 <script type="text/javascript" src="${jsdir}socialcalcspreadsheetcontrol.js"></script>
541 <style>
542 body, td, input, texarea
543 {font-family:verdana,helvetica,sans-serif;font-size:small;}
544 </style>
545 </head>
546 <body>
547 <form name="f0" action="" method="POST">
548 <div style="padding:6px;background-color:#80A9F3;">
549 <div style="font-weight:bold;color:white;">SIMPLE SYSTEM FOR EDITING PAGES WITH SPREADSHEETS AND MORE</div>
550 <div style="color:#FDD;font-weight:bold;">$statusmessage &nbsp;</div>
551 <div style="margin-bottom:6px;">Editing page: <span style="font-style:italic;font-weight:bold;">$pagename</span></div>
552 <input type="submit" name="savespreadsheet" value="Save" onclick="dosave();">
553 <input type="submit" name="cancelspreadsheet" value="Cancel">
554 <textarea name="savestr" id="sheetdata" style="display:none;">$sheetstr</textarea>
555 <input type="hidden" name="newstr" id="newdata" value="">
556 <input type="hidden" name="pagename" value="$pagename">
557 <input type="hidden" name="sheetname" value="$sheetname">
558 </div>
559 </form>
560 <div id="msg" style="position:absolute;right:15px;">
561 <input type="button" style="font-size:x-small;" value="Clear" onclick="addmsg('',true);"><br>
562 <input type="button" style="font-size:x-small;" value="ShowCols" onclick="showvalue();"><br>
563 <textarea id="msgtext" style="margin-top:10px;width:140px;height:500px;"></textarea>
564 </div>
565 <div id="tableeditor" style="margin:8px 170px 10px 0px;">editor goes here</div>
566 <script>
567
568 document.getElementById("msgtext").value = "";
569
570 function setmsg(msg) {document.getElementById("msg").innerHTML = msg;}
571 function addmsg(msg, clear) {
572 var msgtextid = document.getElementById("msgtext");
573 if (!msgtextid) {
574 document.getElementById("msg").innerHTML = '<textarea id="msgtext" cols="60" rows="5"></textarea>';
575 msgtextid = document.getElementById("msgtext");
576 }
577 if (clear) msgtextid.value = "";
578 if (msgtextid.value.length>0) msgtextid.value += "\\n";
579 msgtextid.value += msg;
580 }
581 var heights=[];
582 function showvalue() {
583 addmsg(spreadsheet.editor.colwidth, true);
584 }
585
586
587 // define functions
588
589 function loadsheet(sheetname) {
590 addmsg("loadsheet:"+sheetname);
591 return ajaxrequest("", "&loadsheet="+encodeURIComponent(sheetname));
592 }
593
594 SocialCalc.RecalcInfo.LoadSheet = loadsheet;
595
596 // function
597
598 var http_request;
599
600 function ajaxrequest(url, contents) {
601
602 http_request = null;
603
604 if (window.XMLHttpRequest) { // Mozilla, Safari,...
605 http_request = new XMLHttpRequest();
606 }
607 else if (window.ActiveXObject) { // IE
608 try {
609 http_request = new ActiveXObject("Msxml2.XMLHTTP");
610 }
611 catch (e) {
612 try {
613 http_request = new ActiveXObject("Microsoft.XMLHTTP");
614 }
615 catch (e) {}
616 }
617 }
618 if (!http_request) {
619 alert('Giving up :( Cannot create an XMLHTTP instance');
620 return false;
621 }
622
623 // Make the actual request
624
625 http_request.onreadystatechange = alertContents;
626 http_request.open('POST', document.URL, true); // async
627 http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
628 http_request.send(contents);
629
630 return true;
631
632 }
633
634 function alertContents() {
635
636 var loadedstr = "";
637
638 if (http_request.readyState == 4) {
639 addmsg("received:"+http_request.responseText.length+" chars");
640 try {
641 if (http_request.status == 200) {
642 loadedstr = http_request.responseText || "";
643 http_request = null;
644 }
645 else {
646 ;
647 }
648 }
649 catch (e) {
650 }
651 parts = spreadsheet.DecodeSpreadsheetSave(loadedstr);
652 if (parts) {
653 if (parts.sheet) {
654 SocialCalc.RecalcLoadedSheet(null, loadedstr.substring(parts.sheet.start, parts.sheet.end), true); // notify recalc loop
655 }
656 }
657 if (loadedstr=="") {
658 SocialCalc.RecalcLoadedSheet(null, "", true); // notify recalc loop that it's not available, but that we tried
659 }
660 }
661 }
662
663
664 function dosave() {
665 var sheetstr = spreadsheet.CreateSpreadsheetSave();
666 var htmlstr = spreadsheet.CreateSheetHTML();
667 document.getElementById("newdata").value = sheetstr + "\\nHTML:\\n" + htmlstr;
668 }
669
670 var http_request2;
671
672 function ajaxrequest2(url, contents) {
673
674 http_request2 = null;
675
676 if (window.XMLHttpRequest) { // Mozilla, Safari,...
677 http_request2 = new XMLHttpRequest();
678 }
679 else if (window.ActiveXObject) { // IE
680 try {
681 http_request2 = new ActiveXObject("Msxml2.XMLHTTP");
682 }
683 catch (e) {
684 try {
685 http_request2 = new ActiveXObject("Microsoft.XMLHTTP");
686 }
687 catch (e) {}
688 }
689 }
690 if (!http_request2) {
691 alert('Giving up :( Cannot create an XMLHTTP instance');
692 return false;
693 }
694
695 // Make the actual request
696
697 // http_request2.onreadystatechange = alertContents2;
698 http_request2.open('POST', document.URL, false); // sync
699 http_request2.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
700 http_request2.send(contents);
701
702 return http_request2.responseText || "";
703
704 }
705
706 function alertContents2() {
707
708 var loadedstr = "";
709 var parts;
710
711 if (http_request2.readyState == 4) {
712 try {
713 if (http_request.status == 200) {
714 loadedstr = http_request2.responseText || "";
715 http_request2 = null;
716 }
717 else {
718 ;
719 }
720 }
721 catch (e) {
722 }
723 parts = spreadsheet.DecodeSpreadsheetSave(loadedstr);
724 if (parts) {
725 if (parts.sheet) {
726 SocialCalc.RecalcLoadedSheet(null, loadedstr.substring(parts.sheet.start, parts.sheet.end), true); // notify recalc loop
727 }
728 }
729
730 }
731 }
732
733 // start everything
734
735 var spreadsheet = new SocialCalc.SpreadsheetControl();
736 spreadsheet.imagePrefix="/sgi/scjstest/images/";
737 spreadsheet.editor.imageprefix="/sgi/scjstest/images/sc";
738 spreadsheet.InitializeSpreadsheetControl("tableeditor", 0, 0, 0);
739
740 var savestr = document.getElementById("sheetdata").value;
741 var parts = spreadsheet.DecodeSpreadsheetSave(savestr);
742 if (parts) {
743 if (parts.sheet) {
744 spreadsheet.sheet.ResetSheet();
745 spreadsheet.ParseSheetSave(savestr.substring(parts.sheet.start, parts.sheet.end));
746 }
747 if (parts.edit) {
748 spreadsheet.editor.LoadEditorSettings(savestr.substring(parts.edit.start, parts.edit.end));
749 }
750 }
751 if (spreadsheet.editor.context.sheetobj.attribs.recalc=="off") {
752 spreadsheet.ExecuteCommand('redisplay', '');
753 }
754 else {
755 spreadsheet.ExecuteCommand('recalc', '');
756 }
757
758 </script>
759 </body>
760 </html>
761 EOF
762
763 return $response;
764
765 }
766
767
768 #
769 # start_editdrawing($pagename, $sheetname, $q, $statusmessage)
770 # - render initial editing display
771 #
772
773 sub start_editdrawing {
774
775 my ($pagename, $sheetname, $q, $statusmessage) = @_;
776
777 my ($response, $sheetstr);
778
779 my $page = {};
780 load_page($q, $pagename, $page);
781
782 $sheetstr = $page->{items}{$sheetname}{text};
783
784 $response = <<"EOF"; # output page with edit JS code
785 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
786 "http://www.w3.org/TR/html4/strict.dtd">
787 <html>
788 <head>
789 <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
790 <title>Simple Page Editor With Spreadsheets $versionstr</title>
791 <script type="text/javascript" src="${jsdir}socialcalc-3.js"></script>
792 <script type="text/javascript" src="${jsdir}drawlib3.js"></script>
793 <style>
794 body, td, input, texarea
795 {font-family:verdana,helvetica,sans-serif;font-size:small;}
796 </style>
797 </head>
798 <body>
799 <form name="f0" action="" method="POST">
800 <div style="padding:6px;background-color:#80A9F3;">
801 <div style="font-weight:bold;color:white;">SIMPLE SYSTEM FOR EDITING PAGES WITH SPREADSHEETS AND MORE</div>
802 <div style="color:#FDD;font-weight:bold;">$statusmessage &nbsp;</div>
803 <div style="margin-bottom:6px;">Editing page: <span style="font-style:italic;font-weight:bold;">$pagename</span></div>
804 <input type="submit" name="savespreadsheet" value="Save" onclick="dosave();">
805 <input type="submit" name="cancelspreadsheet" value="Cancel">
806 <textarea name="savestr" id="sheetdata" style="display:none;">$sheetstr</textarea>
807 <input type="hidden" name="newstr" id="newdata" value="">
808 <input type="hidden" name="pagename" value="$pagename">
809 <input type="hidden" name="sheetname" value="$sheetname">
810 </div>
811 </form>
812 <div id="drawingeditor" style="margin:8px 0px 10px 0px;"></div>
813 <script>
814 var de = document.getElementById("drawingeditor");
815 var sheet = new SocialDraw.Sheet(de, true, document.getElementById("sheetdata").value);
816 sheet.Display();
817
818 function dosave() {
819 document.getElementById("newdata").value = sheet.Save();
820 }
821
822 </script>
823 </body>
824 </html>
825 EOF
826
827 return $response;
828
829 }
830
831
832 # # # # # # # # # #
833 # special_chars($string)
834 #
835 # Returns $estring where &, <, >, " are HTML escaped
836 #
837
838 sub special_chars {
839 my $string = shift @_;
840
841 $string =~ s/&/&amp;/g;
842 $string =~ s/</&lt;/g;
843 $string =~ s/>/&gt;/g;
844 $string =~ s/"/&quot;/g;
845
846 return $string;
847 }
848
849
850 #
851 # decode_from_ajax($string) - Returns a string with
852 # \n, \b, and \c escaped to \n, \, and :
853 #
854
855 sub decode_from_ajax {
856 my $string = shift @_;
857
858 $string =~ s/\\n/\n/g;
859 $string =~ s/\\c/:/g;
860 $string =~ s/\\b/\\/g;
861
862 return $string;
863 }
864
865
866 #
867 # encode_for_ajax($string) - Returns a string with
868 # \n, \, :, and ]]> escaped to \n, \b, \c, and \e
869 #
870
871 sub encode_for_ajax {
872 my $string = shift @_;
873
874 $string =~ s/\\/\\b/g;
875 $string =~ s/\n/\\n/g;
876 $string =~ s/\r//g;
877 $string =~ s/:/\\c/g;
878 $string =~ s/]]>/\\e/g;
879
880 return $string;
881 }
882
883
884 #
885 # expand_wikitext($string) - Returns $string doing wiki-style formatting
886 #
887
888 sub expand_wikitext {
889 my $string = shift @_;
890
891 # Process forms that use URL encoding first
892
893 # [page:pagename text] to link to other pages on this site
894 $string =~ s!\[page:(.+?)\s+(.+?)?]!'{{lt}}a href={{quot}}?pagename=' .
895 $1 . "{{quot}}{{gt}}$2\{{lt}}/a{{gt}}"!xegs;
896
897 # [url:url text] to link to other pages on other sites
898 $string =~ s!\[url:(.+?)\s+(.+?)?]!'{{lt}}a href={{quot}}' .
899 $1 . "{{quot}} target={{quot}}_blank{{quot}}{{gt}}$2\{{lt}}/a{{gt}}"!xegs;
900
901 # Convert &, <, >, "
902
903 $string = special_chars($string);
904
905 $string =~ s/^\= (.*) \=$/<span style="font-size:150%;font-weight:bold;">$1<\/span>/gs;
906 $string =~ s/\n/<br>/g; # Line breaks are preserved
907 $string =~ s/('*)'''(.*?)'''/$1<b>$2<\/b>/gs; # Wiki-style bold/italics
908 $string =~ s/''(.*?)''/<i>$1<\/i>/gs;
909 $string =~ s/\{\{amp}}/&/gs; # {{amp}} for ampersand
910 $string =~ s/\{\{lt}}/</gs; # {{lt}} for less than
911 $string =~ s/\{\{gt}}/>/gs; # {{gt}} for greater than
912 $string =~ s/\{\{quot}}/"/gs; # {{quot}} for quote
913 $string =~ s/\{\{lbracket}}/[/gs; # {{lbracket}} for left bracket
914 $string =~ s/\{\{rbracket}}/]/gs; # {{rbracket}} for right bracket
915 $string =~ s/\{\{lbrace}}/{/gs; # {{lbrace}} for brace
916
917 return $string;
918 }
919
Something went wrong with that request. Please try again.