#69. Add basic License support.
[booki.git] / site_media / js / editor.js
blob63136e3435e05d1722c73670b8ab4ac21f7249f9
1 $(function() {
2 /*
3 * todo:
4 * - should send projectid and bookid and not their full names
7 * */
9 function unescapeHtml (val) {
10 return val.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
12 /* booki.chat */
14 jQuery.namespace('jQuery.booki.chat');
16 jQuery.booki.chat = function() {
17 var element = null;
18 var element2 = null;
20 function showJoined(notice) {
21 $('.content', element).append('<p><span class="icon">JOINED</span> '+notice+'</p>');
22 $('.content', element2).append('<p><span class="icon">JOINED</span> '+notice+'</p>');
25 function showInfo(notice) {
26 $('.content', element).append('<p><span class="info">INFO</span> '+notice+'</p>');
27 // $('.content', element2).append('<p><span class="icon">JOINED</span> '+notice+'</p>');
31 function formatMessage(from, message) {
32 return $("<p><b>"+from+"</b>: "+message+"</p>");
35 function showMessage(from, message) {
36 $(".content", element).append(formatMessage(from, message));
37 $(".content", element2).append(formatMessage(from, message));
40 $(".content", element).attr({ scrollTop: $(".content", element).attr("scrollHeight") });
41 $(".content", element2).attr({ scrollTop: $(".content", element2).attr("scrollHeight") });
45 function initUI() {
46 element2.html($('<form onsubmit="javascript: return false;"><div class="content" style="margin-bottom: 5px; width: 500px; height: 400px; border: 1px solid gray; padding: 5px"></div><input type="text" style="width: 500px;"/></form>').submit(function() { var s = $("INPUT", element2).val(); $("INPUT", element2).attr("value", "");
47 showMessage($.booki.username, s);
48 $.booki.sendToChannel("/chat/"+$.booki.currentProjectID+"/"+$.booki.currentBookID+"/", {"command": "message_send", "message": s}, function() {} );
50 }));
52 element.html($('<form onsubmit="javascript: return false;"><div class="content" style="margin-bottom: 5px; width: 200px; height: 400px; border: 1px solid black; padding: 5px"></div><input type="text" style="width: 200px;"/></form>').submit(function() { var s = $("INPUT", element).val(); $("INPUT", element).attr("value", "");
53 showMessage($.booki.username, s);
54 $.booki.sendToChannel("/chat/"+$.booki.currentProjectID+"/"+$.booki.currentBookID+"/", {"command": "message_send", "message": s}, function() {} );
56 }));
60 return {
61 'initChat': function(elem, elem2) {
62 element = elem;
63 element2 = elem2;
64 initUI();
66 jQuery.booki.subscribeToChannel("/chat/"+$.booki.currentProjectID+"/"+$.booki.currentBookID+"/", function(message) {
67 if(message.command == "user_joined") {
68 showJoined(message.user_joined);
71 if(message.command == "message_info") {
72 showInfo(message.message);
76 if(message.command == "message_received") {
77 showMessage(message.from, message.message);
79 });
83 }();
84 /* booki.editor */
86 jQuery.namespace('jQuery.booki.editor');
88 jQuery.booki.editor = function() {
90 /* status */
91 var statuses = null;
92 var attachments = null;
93 var splitChapters = null;
94 var currentlyEditing = null;
96 function getStatusDescription(statusID) {
97 var r = $.grep(statuses, function(v, i) {
99 return v[0] == statusID;
102 if(r && r.length > 0)
103 return r[0][1];
105 return null;
109 /* TOC */
111 function createChapter(vals) {
112 var options = {
113 id: null,
114 title: '',
115 isChapter: true,
116 isLocked: false,
117 status: null
120 $.extend(options, vals);
122 return options;
125 function TOC(containerName) {
126 this.containerName = containerName;
127 this.items = new Array();
131 $.extend(TOC.prototype, {
132 'addItem': function(item) {
133 this.items.push(item);
136 'delItemById': function(id) {
137 for(var i = 0; i < this.items.length; i++) {
138 if(this.items[i].id == id) {
139 return this.items.splice(i, 1);
144 'getItemById': function(id) {
145 for(var i = 0; i < this.items.length; i++) {
146 if(this.items[i].id == id) {
147 return this.items[i];
151 return null;
154 'update': function(order) {
155 var newOrder = new Array();
157 for(var i = 0; i < order.length; i++) {
158 var item = this.getItemById(order[i])
159 newOrder.push(item);
161 this.items = newOrder;
164 'draw': function() {
165 var $this = this;
167 $($this.containerName).empty();
168 $.each(this.items, function(i, v) {
169 if(v.isChapter)
170 makeChapterLine(v.id, v.title, getStatusDescription(v.status)).appendTo($this.containerName);
171 else
172 makeSectionLine(v.id, v.title).appendTo($this.containerName);
177 'redraw': function() {
178 var $this = this;
179 var chldrn = $($this.containerName).contents().clone(true);
181 $($this.containerName).empty();
183 $.each(this.items, function(i, v) {
184 for(var n = 0; n < chldrn.length; n++) {
185 if( $(chldrn[n]).attr("id") == "item_"+v.id) {
186 $(chldrn[n]).appendTo($this.containerName);
187 break;
193 'refresh': function() {
194 // should update status and other things also
195 $.each(this.items, function(i, v) {
196 $("#item_"+v.id+" .title").html(v.title);
197 $("#item_"+v.id+" .status").html(getStatusDescription(v.status));
205 var toc = new TOC("#chapterslist");
206 var holdChapters = new TOC("#holdchapterslist");
209 function getChapter(chapterID) {
210 var chap = toc.getItemById(chapterID);
211 if(!chap)
212 chap = holdChapters.getItemById(chapterID);
213 return chap;
216 var _isEditingSmall = false;
219 function makeSectionLine(chapterID, name) {
220 return $('<li class="ui-state-default" id="item_'+chapterID+'" style="background-color: #a0a0a0; color: white; background-image: none"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span><div class="cont"><table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td width="70%"><div class="title" style="float: left">'+name+'</div></td><td width="10%"><td width="20%"><div class="extra" style="float: right; font-size: 6pt; clear: right"></div></td></tr></table></div></li>');
223 function makeChapterLine(chapterID, name, status) {
224 return $('<li class="ui-state-default" id="item_'+chapterID+'"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span><div class="cont"><table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td width="70%"><div class="title" style="float: left">'+name+'</div></td><td width="10%"><a href="javascript:void(0)" onclick="$.booki.editor.editChapter('+chapterID+')" style="font-size: 12px">EDIT</a><td width="20%"><div class="status" style="float:right; font-size: 6pt"><a href="javascript:void(0)" onclick="$.booki.editor.editStatusForChapter('+chapterID+')">'+status+'</a></div><div class="extra" style="float: right; font-size: 6pt; clear: right"></div></td></tr></table></div></li>').dblclick(function() {
225 if(_isEditingSmall) return;
226 _isEditingSmall = true;
228 $.booki.ui.notify("Sending data...");
229 $.booki.sendToCurrentBook({"command": "chapter_status", "status": "rename", "chapterID": chapterID}, function() {$.booki.ui.notify("")} );
231 var s = $(".title", $(this)).text();
232 var $this = $(this);
234 $(".cont", $(this)).html('<form style="font-size:12px; white-space: nowrap"></form>');
236 // Make it look nicer and look on the width of input box
237 // also use white-space: nowrap
240 $("FORM", $(this)).append($('<input type="text" style="width: 70%" value="'+s+'" >'));
241 $("FORM", $(this)).append($('<a href="#">SAVE</a>').click(function() {
243 var newName = $("INPUT", $this).val();
244 _isEditingSmall = false; $.booki.ui.notify("Sending data...");
245 $.booki.sendToCurrentBook({"command": "chapter_rename", "chapterID": chapterID, "chapter": newName}, function() {
246 $.booki.ui.notify("");
248 $("#item_"+chapterID).replaceWith(makeChapterLine(chapterID, newName, status));
250 }));
251 $("FORM", $(this)).append($('<span> </span>').html());
252 $("FORM", $(this)).append($('<a href="#">CANCEL</a>').click(function() {
253 _isEditingSmall = false; $.booki.ui.notify("Sending data...");
254 $.booki.sendToCurrentBook({"command": "chapter_status", "status": "normal", "chapterID": chapterID}, function() {$.booki.ui.notify("")} );
256 // this is not god. should get info from toc
257 var ch = getChapter(chapterID);
258 $("#item_"+chapterID).replaceWith(makeChapterLine(chapterID, ch.title, getStatusDescription(ch.status))); }));
262 function closeEditor() {
263 $("#editor").fadeOut("slow",
264 function() {
265 $("#editor").css("display", "none");
266 $("#container").hide().css("display", "block");
270 return {
271 editStatusForChapter: function(chapterID) {
272 var selopts = '<select><option value="-1" style="font-weight: bold; color: black">Cancel</option><option value="-1" style="font-weight: bold; color: black">--------</option>';
273 var chap = getChapter(chapterID);
275 $.each(statuses, function(i, v) {
276 selopts += '<option value="'+v[0]+'"';
277 if(v[0] == chap.status)
278 selopts += ' selected="selected" ';
279 selopts += '">'+v[1]+'</option>';
281 selopts += '</select>';
283 var s = $(selopts);
285 $("#item_"+chapterID+" .status").html(s.change(function() {
286 var chap = getChapter(chapterID);
287 if(parseInt($(this).val()) != -1)
288 chap.status = parseInt($(this).val());
290 $("#item_"+chapterID+" .status").html('<a href="javascript:void(0)" onclick="$.booki.editor.editStatusForChapter('+chapterID+')">'+getStatusDescription(chap.status)+'</a>');
292 }).wrap("<form></form>"));
295 reloadAttachments: function(func) {
296 $.booki.debug.debug("[reloadAttachments]");
298 $.booki.sendToCurrentBook({"command": "attachments_list"}, function(data) {
299 attachments = data.attachments;
300 $.booki.editor.drawAttachments();
301 func();
305 editChapter: function(chapterID) {
306 $.booki.ui.notify("Loading chapter data...");
307 $.booki.sendToChannel("/booki/book/"+$.booki.currentProjectID+"/"+$.booki.currentBookID+"/",
308 {"command": "get_chapter", "chapterID": chapterID}, function(data) {
309 $.booki.ui.notify();
310 $("#container").fadeOut("slow", function() {
312 $("#container").css("display", "none");
313 $("#editor").css("display", "block").fadeIn("slow");
315 /* xinha */
316 xinha_init();
318 function _tryAgain() {
319 var edi = xinha_editors.myTextArea;
320 if(edi) {
321 edi.whenDocReady(function() {
322 edi.setEditorContent(data.content);
324 } else {
325 setTimeout(_tryAgain, 500);
329 if(!xinha_editors.myTextArea) {
330 setTimeout(_tryAgain, 500);
331 } else {
332 _tryAgain();
337 var edi = xinha_editors.myTextArea;
338 if(edi)
339 edi.setEditorContent(data.content);
341 /* $("#editor INPUT[name=title]").attr("value", data.title); */
343 $("#editor INPUT[name=chapter_id]").attr("value", chapterID);
344 $("#editor INPUT[name=save]").unbind('click').click(function() {
345 currentlyEditing = chapterID;
346 var edi = xinha_editors["myTextArea"];
347 var content = edi.getEditorContent();
349 var c = content.substring(0);
350 var chapters_n = 0;
351 var currentPos = 0;
353 while(chapters_n < 10) {
354 var n1 = content.indexOf("</H1>", currentPos);
355 var n2 = content.indexOf("</h1>", currentPos);
356 var n = -1;
358 if(n2 != -1 ) {
359 if (n1 > n2)
360 n = n2;
361 else
362 if(n1 != -1)
363 n = n1;
364 else n = n2;
366 if(n == -1 && n1 == -1) {
367 break;
368 } else {
369 if(n == -1)
370 n = n1;
372 currentPos = n;
373 chapters_n += 1;
379 var r = new RegExp("<h1>([^\<]+)</h1>", "ig");
380 var chapters_n = 0;
382 var c = content.substring(0);
384 while(true) {
385 $.booki.debug.debug("#"+unescapeHtml(c)+"#");
386 m = r.exec(c);
387 if(m) {
388 $.booki.debug.debug("m je pun");
389 chapters_n += 1;
390 $.booki.debug.debug("last index je ");
391 $.booki.debug.debug(r.lastIndex);
392 $.booki.debug.debug(m.length);
394 c = c.substring(r.lastIndex-m[0].length);
395 } else {
396 $.booki.debug.debug("m je prazan");
397 break;
401 $.booki.debug.debug(chapters_n);
404 if(chapters_n > 1) {
405 $("#spalatodialog").dialog("open");
406 } else {
407 $.booki.ui.notify("Sending data...");
409 $.booki.sendToCurrentBook({"command": "chapter_save", "chapterID": chapterID, "content": content}, function() {$.booki.ui.notify(); closeEditor(); } );
414 $("#editor INPUT[class=cancel]").unbind('click').click(function() {
415 $.booki.sendToCurrentBook({"command": "chapter_status", "status": "normal", "chapterID": chapterID});
416 closeEditor();
417 });
425 _initUI: function() {
426 $("#tabs").tabs();
427 $('#tabs').bind('tabsselect', function(event, ui) {});
429 /* $("#accordion").accordion({ header: "h3" }); */
430 $("#chapterslist, #holdchapterslist").sortable({'connectWith': ['.connectedSortable'], 'dropOnEmpty': true, 'stop': function(event, ui) {
432 var result = $('#chapterslist').sortable('toArray');
433 var holdResult = $('#holdchapterslist').sortable('toArray');
435 // too much copy+paste here. should organise it in better way.
437 if(toc.items.length > result.length) {
438 for(var i = 0; i < toc.items.length; i++) {
439 var wasFound = false;
440 for(var n = 0; n < result.length; n++) {
441 if(toc.items[i].id == result[n].substr(5)) {
442 wasFound = true;
446 if(!wasFound) {
447 var itm = toc.getItemById(toc.items[i].id);
448 if((""+itm.id).substring(0,1) != 's') {
449 holdChapters.addItem(itm);
450 } else {
451 $("#item_"+toc.items[i].id).remove();
453 $.booki.debug.debug(itm.id);
454 toc.delItemById(toc.items[i].id);
456 $.booki.ui.info("#container .middleinfo", "Removing chapter from Table of Contents.");
457 $.booki.ui.notify("Sending data...");
458 $.booki.sendToCurrentBook({"command": "chapters_changed",
459 "chapters": result,
460 "hold": holdResult,
461 "kind": "remove",
462 "chapter_id": itm.id},
463 function() {$.booki.ui.notify()} );
465 break;
468 } else if(toc.items.length < result.length) {
469 for(var i = 0; i < holdChapters.items.length; i++) {
470 var wasFound = false;
471 for(var n = 0; n < holdResult.length; n++) {
472 if(holdChapters.items[i].id == holdResult[n].substr(5)) {
473 wasFound = true;
477 if(!wasFound) {
478 var itm = holdChapters.getItemById(holdChapters.items[i].id);
479 toc.addItem(itm);
480 holdChapters.delItemById(itm.id);
482 $.booki.ui.info("#container .middleinfo", "Adding chapter to Table of Contents.");
483 $.booki.ui.notify("Sending data...");
484 $.booki.sendToCurrentBook({"command": "chapters_changed",
485 "chapters": result,
486 "hold": holdResult,
487 "kind": "add",
488 "chapter_id": itm.id},
489 function() {$.booki.ui.notify()} );
490 break;
494 } else if (toc.items.length == result.length) {
495 $.booki.ui.info("#container .middleinfo", "Reordering the chapters...");
496 $.booki.ui.notify("Sending data...");
497 $.booki.sendToCurrentBook({"command": "chapters_changed",
498 "chapters": result,
499 "hold": holdResult,
500 "kind": "order",
501 "chapter_id": null
503 function() {$.booki.ui.notify()} );
506 $.booki.sendToCurrentBook({"command": "chapters_changed", "chapters": result}, function() {$.booki.ui.notify()} );
509 }, 'placeholder': 'ui-state-highlight', 'scroll': true}).disableSelection();
512 $.booki.chat.initChat($("#chat"), $("#chat2"));
514 $("#tabpublish BUTTON").click(function() {
515 $("#tabpublish .info").html('<div style="padding-top: 20px; padding-bottom: 20px;">"'+$.booki.currentBook+'" is being sent to Objavi (the publishing engine for Booki), converted to an .epub, and uploaded to Archive.org.</div>');
516 $("#tabpublish BUTTON").attr("disabled", "disabled");
518 $("#tabpublish .info").append('<div id="progressbar" style="width: 400px;"></div>');
520 var currentProgress = 0;
522 $("#progressbar").progressbar({
523 value: currentProgress
527 function _incrementProgress() {
528 if(currentProgress == -1) return;
529 if(currentProgress > 100) currentProgress = 100;
531 currentProgress += 10;
533 $("#progressbar").progressbar('value', currentProgress);
534 setTimeout(function() { _incrementProgress();}, 1000);
537 _incrementProgress();
539 $.booki.sendToCurrentBook({"command": "publish_book"},
540 function(data) {
541 currentProgress = -1;
542 $("#tabpublish BUTTON").removeAttr("disabled");
544 $("#tabpublish .info").html('<div style="padding-top: 20px; padding-bottom: 10px"><a href="'+data.dta+'" target="_new">'+data.dta+'</a></div>');
545 $("#tabpublish .info").append('<p>Your epub has been sent to Archive.org. It will appear at the following URL in a few minutes.</p>');
546 $("#tabpublish .info").append('<p><a href="'+data.dtas3+'" target="_new">'+data.dtas3+'</a></p>');
548 $.booki.debug.debug(data.dtaall);
549 $.booki.ui.notify();
550 } );
553 // init upload dialog
555 $.booki.editor.upload.init(function(){
556 return attachments } );
558 // spalato dialog
560 $("#spalatodialog").dialog({
561 bgiframe: true,
562 autoOpen: false,
563 height: 400,
564 width: 700,
565 modal: true,
566 buttons: {
567 'Split into chapters and save changes': function() {
568 var $dialog = $(this);
569 $.booki.debug.debug(splitChapters);
570 $.booki.sendToCurrentBook({"command": "chapter_split", "chapterID": currentlyEditing, "chapters": splitChapters}, function() {$dialog.dialog('close'); $.booki.ui.notify(); closeEditor(); } );
573 'Continue editing': function() {
574 $(this).dialog('close');
578 open: function(event,ui) {
580 var edi = xinha_editors["myTextArea"];
581 var content = edi.getEditorContent();
583 var endSplitting = false;
585 var n = 0;
587 $("#spalatodialog .chapters").empty();
588 $("#spalatodialog .content").empty();
590 splitChapters = new Array();
591 var chapName = '';
592 var chapContent = '';
594 while(!endSplitting) {
595 var r = new RegExp("<h1>([^<]+)</h1>", "igm");
596 var m = r.exec(content);
598 if(m != null) {
599 if(n == 0) {
600 if(r.lastIndex-m[0].length > 1) {
601 $("#spalatodialog .chapters").append('<li><a class="chapter" href="javascript:void(0)" title="0">Unknown chapter</a></li>');
602 var chap = content.substring(0, r.lastIndex-m[0].length);
603 $("#spalatodialog .content").append('<div style="display: none" class="chapter0">'+chap+'</div>');
604 splitChapters.push(["Unknown chapter", chap]);
606 n += 1;
608 $("#spalatodialog .chapters").append('<li><a class="chapter" href="javascript:void(0)" title="'+n+'">'+m[1]+'</a></li>');
609 chapName = m[1];
611 } else {
612 $("#spalatodialog .chapters").append('<li><a class="chapter" href="javascript:void(0)" title="'+n+'">'+m[1]+'</a></li>');
613 chapName = m[1];
615 if(n > 0) {
616 var chap = content.substring(0, r.lastIndex-m[0].length);
617 $("#spalatodialog .content").append('<div style="display: none" class="chapter'+(n-1)+'">'+chap+'</div>');
618 chapContent = chap;
622 if(splitChapters.length > 0) {
623 if(splitChapters[splitChapters.length-1][0] != "Unknown chapter")
624 splitChapters[splitChapters.length-1][1] = chapContent;
625 splitChapters.push([chapName, ""]);
626 } else {
627 splitChapters.push([chapName, ""]);
631 n += 1;
632 content = content.substring(r.lastIndex);
633 } else {
634 endSplitting = true;
638 splitChapters[splitChapters.length-1][1] = content;
639 $("#spalatodialog .content").append('<div style="display: none" class="chapter'+(n-1)+'">'+content+'</div>');
640 $("#spalatodialog DIV.chapter0").css("display", "block");
642 $("#spalatodialog A.chapter").click(function() {
643 var chap_n = $(this).attr("title");
644 $("#spalatodialog .content > DIV").css("display", "none");
645 $("#spalatodialog DIV.chapter"+chap_n).css("display", "block");
650 close: function() {
659 drawAttachments: function() {
661 function _getDimension(dim) {
662 if(dim) {
663 return dim[0]+'x'+dim[1];
666 return '';
669 function _getSize(size) {
670 return (size/1024).toFixed(2)+' Kb';
673 $("#tabattachments .files").empty().append('<tr><td width="5%"></td><td align="left"><b>filename</b></td><td align="left"><b>dimension</b></td><td align="right" width="10%"><b>size</b></td></tr>');
675 $.each(attachments, function(i, elem) {
676 $("#tabattachments .files").append('<tr class="line"><td><input type="checkbox"></td><td><a class="file" href="javascript:void(0)" alt="'+elem["name"]+'">'+elem["name"]+'</a></td><td>'+_getDimension(elem["dimension"])+'</td><td align="right"><nobr>'+_getSize(elem.size)+'</nobr></td></tr>');
679 $("#tabattachments .line").hover(function() {
680 $(this).css("background-color", "#f0f0f0");
682 function() {
683 $(this).css("background-color", "white");
687 $("#tabattachments .file").click(function() {
688 var imageName = $(this).attr("alt");
689 if(imageName.match(/.+\.jpg$/gi)) {
690 $("#attachmentpreview").html('<img src="../_utils/thumbnail/'+imageName+'"><br/><br/><a style="font-size: 10px" href="../static/'+imageName+'" target="_new">Open in new window</a>');
696 _loadInitialData : function() {
697 $.booki.ui.notify("Loading...");
699 jQuery.booki.sendToCurrentBook({"command": "init_editor"},
701 function(data) {
702 $.booki.ui.notify("");
704 $.booki.licenses = data.licenses;
706 statuses = data.statuses;
708 $.each(data.metadata, function(i, elem) {
709 $("#tabinfo .metadata").append('<tr><td valign="top"><b>'+elem.name+':</b></td><td valign="top"> '+elem.value+'</td></tr>');
712 $.each(data.chapters, function(i, elem) {
713 toc.addItem(createChapter({id: elem[0], title: elem[1], isChapter: elem[3] == 1, status: elem[4]}));
716 $.each(data.hold, function(i, elem) {
717 holdChapters.addItem(createChapter({id: elem[0], title: elem[1], isChapter: elem[3] == 1, status: elem[4]}));
721 toc.draw();
722 holdChapters.draw();
724 attachments = data.attachments;
725 $.booki.editor.drawAttachments();
727 $.each(data.users, function(i, elem) {
728 $("#users").append(elem+"<br/>");
735 /* initialize editor */
737 initEditor: function() {
739 jQuery.booki.subscribeToChannel("/booki/book/"+$.booki.currentProjectID+"/"+$.booki.currentBookID+"/", function(message) {
741 // ERROR
742 // this does not work when you change chapter status very fast
743 if(message.command == "chapter_status") {
744 if(message.status == "rename" || message.status == "edit") {
745 // $("#item_"+message.chapterID).css("color", "red");
746 $(".extra", $("#item_"+message.chapterID)).html('<div style="padding: 3px; background-color: red; color: white">'+message.username+'</div>');
749 if(message.status == "normal") {
750 //$("#item_"+message.chapterID).css("color", "gray");
751 $(".extra", $("#item_"+message.chapterID)).html("");
755 if(message.command == "chapters_changed") {
756 if(message.kind == "remove") {
758 var itm = toc.getItemById(message.chapter_id);
760 if((""+message.chapter_id).substring(0,1) != 's')
761 holdChapters.addItem(itm);
763 toc.delItemById(message.chapter_id);
765 toc.update(message.ids);
766 holdChapters.update(message.hold_ids);
768 toc.draw();
769 holdChapters.draw();
771 $.booki.ui.info("#container .middleinfo", "Removing chapter from Table of Contents.");
772 } else {
773 if(message.kind == "add") {
774 var itm = holdChapters.getItemById(message.chapter_id);
775 toc.addItem(itm);
776 holdChapters.delItemById(message.chapter_id);
778 toc.update(message.ids);
779 holdChapters.update(message.hold_ids);
781 toc.draw();
782 holdChapters.draw();
784 $.booki.ui.info("#container .middleinfo", "Adding chapter to Table of Contents.");
785 } else {
786 $.booki.ui.info("#container .middleinfo", "Reordering the chapters...");
788 toc.update(message.ids);
789 holdChapters.update(message.hold_ids);
790 toc.redraw();
791 holdChapters.redraw();
796 if(message.command == "chapter_create") {
797 // this also only works for the TOC
798 if(message.chapter[3] == 1) {
799 holdChapters.addItem(createChapter({id: message.chapter[0], title: message.chapter[1], isChapter: true, status: message.chapter[4]}));
800 var v = holdChapters.getItemById(message.chapter[0]);
801 makeChapterLine(v.id, v.title, getStatusDescription(v.status)).appendTo("#holdchapterslist");
802 } else {
803 toc.addItem(createChapter({id: message.chapter[0], title: message.chapter[1], isChapter: false}));
804 var v = toc.getItemById(message.chapter[0]);
805 makeSectionLine(v.id, v.title).appendTo("#chapterslist");
809 if(message.command == "chapter_rename") {
810 $.booki.debug.debug("[chapter_rename]");
811 var item = toc.getItemById(message.chapterID);
812 if(!item)
813 item = holdChapters.getItemById(message.chapterID);
814 item.title = message.chapter;
815 toc.refresh();
816 holdChapters.refresh();
819 if(message.command == "chapters_list") {
820 $("#chapterslist").empty();
821 $.each(message.chapters, function(i, elem) {
822 // should be makeSectionLine also
823 makeChapterLine(elem[0], elem[1], 0).prependTo("#chapterslist");
827 if(message.command == "chapter_split") {
828 toc.items = new Array();
829 holdChapters.items = new Array();
831 $.each(message.chapters, function(i, elem) {
832 toc.addItem(createChapter({id: elem[0], title: elem[1], isChapter: elem[3] == 1, status: elem[4]}));
835 $.each(message.hold, function(i, elem) {
836 holdChapters.addItem(createChapter({id: elem[0], title: elem[1], isChapter: elem[3] == 1, status: elem[4]}));
841 toc.draw();
842 holdChapters.draw();
848 $.booki.editor._initUI();
849 $.booki.editor._loadInitialData();
852 }();
856 /* booki.editor.upload */
858 jQuery.namespace('jQuery.booki.editor.upload');
860 jQuery.booki.editor.upload = function() {
861 var selectedFile = null;
862 var editor = null;
863 var f = null;
864 var n = 1;
865 var hasChanged = false;
867 return {
868 setEditor: function(edit) {
869 editor = edit;
872 showFiles: function(func) {
873 $("#insertattachment .files").empty();
875 $("#insertattachment .files").append('<tr><td><b>name</b></td><td><b>size</b></td><td><b>image size</b></td><td><b>date modified</b></td></tr>');
877 $.each(func(), function(i, att) {
878 $("#insertattachment .files").append('<tr><td><a class="file" href="javascript:void(0)" alt="'+att.name+'">'+att.name+'</a></td><td>'+att.size+'</td><td></td><td></td></tr>');
881 $("#insertattachment A.file").click(function() {
882 var fileName = $(this).attr("alt");
883 selectedFile = fileName;
884 $("#insertattachment .previewattachment").html('<img src="../_utils/thumbnail/'+fileName+'">');
889 showUpload: function() {
890 var onChanged = function() {
891 $("#insertattachment .listing").slideUp(2000);
893 var entry = $(this).parent().attr("class");
895 if(!hasChanged) {
896 $("#insertattachment .uploadsubmit").append('<input type="submit" value="Upload"/>');
897 $("#insertattachment .uploadattachment").css("height", "250px");
900 var licenses = '';
902 $.each($.booki.licenses, function(i, v) {
903 licenses += '<option value="'+v[0]+'">'+v[1]+'</option>';
904 });
907 $("#insertattachment .uploadattachment ."+entry).append('<br><table border="0"><tr><td>Rights holder:</td><td> <input name="rights'+n+'" type="text" size="30"/></td></tr><tr><td>License:</td><td><select name="license'+n+'" >'+licenses+'</select></td></tr></table>');
909 $('#insertattachment .'+entry+' OPTION[value="Unknown"]').attr('selected', 'selected');
911 $("#insertattachment .uploadattachment").append('<div style="border-top: 1px solid gray; padding-top: 5px; padding-bottom: 5px" class="entry'+n+'"><input type="file" name="entry'+n+'"></div>');
913 $("#insertattachment INPUT[type='file'][name='entry"+n+"']").change(onChanged);
916 $("#insertattachment .uploadattachment").attr({ scrollTop: $("#insertattachment .uploadattachment").attr("scrollHeight") });
917 n += 1;
918 hasChanged = true;
922 $("#insertattachment .uploadsubmit").empty();
924 $("#insertattachment .uploadattachment").empty();
925 $("#insertattachment .uploadattachment").css("height", "40px");
927 $("#insertattachment .uploadattachment").append('<div style="border-top: 1px solid #c0c0c0; padding-bottom: 5px" class="entry0"><input type="file" name="entry0"></div>');
928 $("#insertattachment INPUT[type='file'][name='entry0']").change(onChanged);
931 redrawFiles: function() {
932 n = 1;
933 hasChanged = false;
934 $.booki.editor.upload.showFiles(f);
935 $.booki.editor.upload.showUpload();
939 init: function(func) {
940 f = func;
941 $("#insertattachment").dialog({
942 bgiframe: true,
943 autoOpen: false,
944 height: 400,
945 width: 700,
946 modal: true,
947 buttons: {
948 'Insert image': function() {
949 if(selectedFile) {
950 editor.insertHTML('<img src="../static/'+selectedFile+'"/>');
951 $(this).dialog('close');
954 'Cancel': function() {
955 $(this).dialog('close');
958 open: function(event,ui) {
959 hasChanged = false;
960 n = 1;
962 $.booki.editor.upload.showUpload();
963 $.booki.editor.upload.showFiles(func);
966 close: function() {
973 }();