4 * - should send projectid and bookid and not their full names
12 jQuery
.namespace('jQuery.booki.chat');
14 jQuery
.booki
.chat = function() {
18 function showJoined(notice
) {
19 $('.content', element
).append('<p><span class="icon">JOINED</span> '+notice
+'</p>');
20 $('.content', element2
).append('<p><span class="icon">JOINED</span> '+notice
+'</p>');
23 function formatMessage(from, message
) {
24 return $("<p><b>"+from+"</b>: "+message
+"</p>");
27 function showMessage(from, message
) {
28 $(".content", element
).append(formatMessage(from, message
));
29 $(".content", element2
).append(formatMessage(from, message
));
32 $(".content", element
).attr({ scrollTop
: $(".content", element
).attr("scrollHeight") });
33 $(".content", element2
).attr({ scrollTop
: $(".content", element2
).attr("scrollHeight") });
38 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", "");
39 showMessage($.booki
.username
, s
);
40 $.booki
.sendToChannel("/chat/"+$.booki
.currentProjectID
+"/"+$.booki
.currentBookID
+"/", {"command": "message_send", "message": s
}, function() {} );
44 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", "");
45 showMessage($.booki
.username
, s
);
46 $.booki
.sendToChannel("/chat/"+$.booki
.currentProjectID
+"/"+$.booki
.currentBookID
+"/", {"command": "message_send", "message": s
}, function() {} );
53 'initChat': function(elem
, elem2
) {
58 jQuery
.booki
.subscribeToChannel("/chat/"+$.booki
.currentProjectID
+"/"+$.booki
.currentBookID
+"/", function(message
) {
59 if(message
.command
== "user_joined") {
60 showJoined(message
.user_joined
);
63 if(message
.command
== "message_received") {
64 showMessage(message
.from, message
.message
);
73 jQuery
.namespace('jQuery.booki.editor');
75 jQuery
.booki
.editor = function() {
79 var attachments
= null;
81 function getStatusDescription(statusID
) {
82 var r
= $.grep(statuses
, function(v
, i
) {
84 return v
[0] == statusID
;
96 function createChapter(vals
) {
105 $.extend(options
, vals
);
110 function TOC(containerName
) {
111 this.containerName
= containerName
;
112 this.items
= new Array();
116 $.extend(TOC
.prototype, {
117 'addItem': function(item
) {
118 this.items
.push(item
);
121 'delItemById': function(id
) {
122 for(var i
= 0; i
< this.items
.length
; i
++) {
123 if(this.items
[i
].id
== id
) {
124 return this.items
.splice(i
, 1);
129 'getItemById': function(id
) {
130 for(var i
= 0; i
< this.items
.length
; i
++) {
131 if(this.items
[i
].id
== id
) {
132 return this.items
[i
];
139 'update': function(order
) {
140 var newOrder
= new Array();
142 for(var i
= 0; i
< order
.length
; i
++) {
143 var item
= this.getItemById(order
[i
])
146 this.items
= newOrder
;
152 $($this.containerName
).empty();
153 $.each(this.items
, function(i
, v
) {
155 makeChapterLine(v
.id
, v
.title
, getStatusDescription(v
.status
)).appendTo($this.containerName
);
157 makeSectionLine(v
.id
, v
.title
).appendTo($this.containerName
);
162 'redraw': function() {
164 var chldrn
= $($this.containerName
).contents().clone(true);
166 $($this.containerName
).empty();
168 $.each(this.items
, function(i
, v
) {
169 for(var n
= 0; n
< chldrn
.length
; n
++) {
170 if( $(chldrn
[n
]).attr("id") == "item_"+v
.id
) {
171 $(chldrn
[n
]).appendTo($this.containerName
);
178 'refresh': function() {
179 // should update status and other things also
180 $.each(this.items
, function(i
, v
) {
181 $("#item_"+v
.id
+" .title").html(v
.title
);
182 $("#item_"+v
.id
+" .status").html(getStatusDescription(v
.status
));
190 var toc
= new TOC("#chapterslist");
191 var holdChapters
= new TOC("#holdchapterslist");
194 function getChapter(chapterID
) {
195 var chap
= toc
.getItemById(chapterID
);
197 chap
= holdChapters
.getItemById(chapterID
);
201 var _isEditingSmall
= false;
204 function makeSectionLine(chapterID
, name
) {
205 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>');
208 function makeChapterLine(chapterID
, name
, status
) {
209 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() {
210 if(_isEditingSmall
) return;
211 _isEditingSmall
= true;
213 $.booki
.ui
.notify("Sending data...");
214 $.booki
.sendToCurrentBook({"command": "chapter_status", "status": "rename", "chapterID": chapterID
}, function() {$.booki
.ui
.notify("")} );
216 var s
= $(".title", $(this)).text();
219 $(".cont", $(this)).html('<form style="font-size:12px; white-space: nowrap"></form>');
221 // Make it look nicer and look on the width of input box
222 // also use white-space: nowrap
225 $("FORM", $(this)).append($('<input type="text" style="width: 70%" value="'+s
+'" >'));
226 $("FORM", $(this)).append($('<a href="#">SAVE</a>').click(function() {
228 var newName
= $("INPUT", $this).val();
229 _isEditingSmall
= false; $.booki
.ui
.notify("Sending data...");
230 $.booki
.sendToCurrentBook({"command": "chapter_rename", "chapterID": chapterID
, "chapter": newName
}, function() {
231 $.booki
.ui
.notify("");
233 $("#item_"+chapterID
).replaceWith(makeChapterLine(chapterID
, newName
, status
));
236 $("FORM", $(this)).append($('<span> </span>').html());
237 $("FORM", $(this)).append($('<a href="#">CANCEL</a>').click(function() {
238 _isEditingSmall
= false; $.booki
.ui
.notify("Sending data...");
239 $.booki
.sendToCurrentBook({"command": "chapter_status", "status": "normal", "chapterID": chapterID
}, function() {$.booki
.ui
.notify("")} );
241 // this is not god. should get info from toc
242 var ch
= getChapter(chapterID
);
243 $("#item_"+chapterID
).replaceWith(makeChapterLine(chapterID
, ch
.title
, getStatusDescription(ch
.status
))); }));
247 function closeEditor() {
248 $("#editor").fadeOut("slow",
250 $("#editor").css("display", "none");
251 $("#container").hide().css("display", "block");
256 editStatusForChapter: function(chapterID
) {
257 var selopts
= '<select><option value="-1" style="font-weight: bold; color: black">Cancel</option><option value="-1" style="font-weight: bold; color: black">--------</option>';
258 var chap
= getChapter(chapterID
);
260 $.each(statuses
, function(i
, v
) {
261 selopts
+= '<option value="'+v
[0]+'"';
262 if(v
[0] == chap
.status
)
263 selopts
+= ' selected="selected" ';
264 selopts
+= '">'+v
[1]+'</option>';
266 selopts
+= '</select>';
270 $("#item_"+chapterID
+" .status").html(s
.change(function() {
271 var chap
= getChapter(chapterID
);
272 if(parseInt($(this).val()) != -1)
273 chap
.status
= parseInt($(this).val());
275 $("#item_"+chapterID
+" .status").html('<a href="javascript:void(0)" onclick="$.booki.editor.editStatusForChapter('+chapterID
+')">'+getStatusDescription(chap
.status
)+'</a>');
277 }).wrap("<form></form>"));
280 editChapter: function(chapterID
) {
281 $.booki
.ui
.notify("Loading chapter data...");
282 $.booki
.sendToChannel("/booki/book/"+$.booki
.currentProjectID
+"/"+$.booki
.currentBookID
+"/",
283 {"command": "get_chapter", "chapterID": chapterID
}, function(data
) {
285 $("#container").fadeOut("slow", function() {
287 $("#container").css("display", "none");
288 $("#editor").css("display", "block").fadeIn("slow");
293 function _tryAgain() {
294 var edi
= xinha_editors
.myTextArea
;
296 edi
.whenDocReady(function() {
297 edi
.setEditorContent(data
.content
);
300 setTimeout(_tryAgain
, 500);
304 if(!xinha_editors
.myTextArea
) {
305 setTimeout(_tryAgain
, 500);
312 var edi = xinha_editors.myTextArea;
314 edi.setEditorContent(data.content);
316 /* $("#editor INPUT[name=title]").attr("value", data.title); */
318 $("#editor INPUT[name=chapter_id]").attr("value", chapterID
);
319 $("#editor INPUT[name=save]").unbind('click').click(function() {
320 var edi
= xinha_editors
["myTextArea"];
321 var content
= edi
.getEditorContent();
323 var r
= new RegExp("<h1>([^<]+)</h1>", "ig");
326 var c
= content
.substring(0);
332 c
= c
.substring(r
.lastIndex
-m
[0].length
);
339 $("#spalatodialog").dialog("open");
341 $.booki
.ui
.notify("Sending data...");
343 $.booki
.sendToCurrentBook({"command": "chapter_save", "chapterID": chapterID
, "content": content
}, function() {$.booki
.ui
.notify(); closeEditor(); } );
348 $("#editor INPUT[class=cancel]").unbind('click').click(function() {
349 $.booki
.sendToCurrentBook({"command": "chapter_status", "status": "normal", "chapterID": chapterID
});
359 _initUI: function() {
361 $('#tabs').bind('tabsselect', function(event
, ui
) {});
363 /* $("#accordion").accordion({ header: "h3" }); */
364 $("#chapterslist, #holdchapterslist").sortable({'connectWith': ['.connectedSortable'], 'dropOnEmpty': true, 'stop': function(event
, ui
) {
366 var result
= $('#chapterslist').sortable('toArray');
367 var holdResult
= $('#holdchapterslist').sortable('toArray');
369 // too much copy+paste here. should organise it in better way.
371 if(toc
.items
.length
> result
.length
) {
372 for(var i
= 0; i
< toc
.items
.length
; i
++) {
373 var wasFound
= false;
374 for(var n
= 0; n
< result
.length
; n
++) {
375 if(toc
.items
[i
].id
== result
[n
].substr(5)) {
381 var itm
= toc
.getItemById(toc
.items
[i
].id
);
382 if((""+itm
.id
).substring(0,1) != 's') {
383 holdChapters
.addItem(itm
);
385 $("#item_"+toc
.items
[i
].id
).remove();
387 $.booki
.debug
.debug(itm
.id
);
388 toc
.delItemById(toc
.items
[i
].id
);
390 $.booki
.ui
.info("#container .middleinfo", "Removing chapter from Table of Contents.");
391 $.booki
.ui
.notify("Sending data...");
392 $.booki
.sendToCurrentBook({"command": "chapters_changed",
396 "chapter_id": itm
.id
},
397 function() {$.booki
.ui
.notify()} );
402 } else if(toc
.items
.length
< result
.length
) {
403 for(var i
= 0; i
< holdChapters
.items
.length
; i
++) {
404 var wasFound
= false;
405 for(var n
= 0; n
< holdResult
.length
; n
++) {
406 if(holdChapters
.items
[i
].id
== holdResult
[n
].substr(5)) {
412 var itm
= holdChapters
.getItemById(holdChapters
.items
[i
].id
);
414 holdChapters
.delItemById(itm
.id
);
416 $.booki
.ui
.info("#container .middleinfo", "Adding chapter to Table of Contents.");
417 $.booki
.ui
.notify("Sending data...");
418 $.booki
.sendToCurrentBook({"command": "chapters_changed",
422 "chapter_id": itm
.id
},
423 function() {$.booki
.ui
.notify()} );
428 } else if (toc
.items
.length
== result
.length
) {
429 $.booki
.ui
.info("#container .middleinfo", "Reordering the chapters...");
430 $.booki
.ui
.notify("Sending data...");
431 $.booki
.sendToCurrentBook({"command": "chapters_changed",
437 function() {$.booki
.ui
.notify()} );
440 $.booki.sendToCurrentBook({"command": "chapters_changed", "chapters": result}, function() {$.booki.ui.notify()} );
443 }, 'placeholder': 'ui-state-highlight', 'scroll': true}).disableSelection();
446 $.booki
.chat
.initChat($("#chat"), $("#chat2"));
448 $("#tabpublish BUTTON").click(function() {
449 $.booki
.sendToCurrentBook({"command": "publish_book"},
451 $("#tabpublish .info").html("<p>Book is being send to objavi.flossmanuals.net. Soon it will be converted to .epub.</p>");
458 // initialize dialogs
459 $("#insertattachment").dialog({
466 'Insert image': function() {
468 $(this).dialog('close');
470 'Cancel': function() {
471 $(this).dialog('close');
474 open: function(event
,ui
) {
475 $("#insertattachment .files").empty();
476 $("#insertattachment .files").append('<tr><td><b>name</b></td><td><b>size</b></td></tr>');
478 $.each(attachments
, function(i
, att
) {
479 $("#insertattachment .files").append('<tr><td><a class="file" href="javascript:void(0)" alt="'+att
.name
+'">'+att
.name
+'</a></td><td>'+att
.size
+'</td></tr>');
482 $("#insertattachment A.file").click(function() {
483 var fileName
= $(this).attr("alt");
484 $("#insertattachment .previewattachment").html('<img src="../_utils/thumbnail/'+fileName
+'">');
496 $("#spalatodialog").dialog({
503 'Split into chapters and save changes': function() {
505 $(this).dialog('close');
508 /* 'Cancel': function() {
509 $(this).dialog('close');
511 'Continue editing': function() {
512 $(this).dialog('close');
516 open: function(event
,ui
) {
518 var edi
= xinha_editors
["myTextArea"];
519 var content
= edi
.getEditorContent();
521 var endSplitting
= false;
525 $("#spalatodialog .chapters").empty();
526 $("#spalatodialog .content").empty();
528 while(!endSplitting
) {
529 var r
= new RegExp("<h1>([^<]+)</h1>", "ig");
530 var m
= r
.exec(content
);
534 if(r
.lastIndex
-m
[0].length
> 1) {
535 $("#spalatodialog .chapters").append('<li><a class="chapter" href="javascript:void(0)" title="0">Unknown chapter</a></li>');
536 var chap
= content
.substring(0, r
.lastIndex
-m
[0].length
);
537 $("#spalatodialog .content").append('<div style="display: none" class="chapter0">'+chap
+'</div>');
541 $("#spalatodialog .chapters").append('<li><a class="chapter" href="javascript:void(0)" title="'+n
+'">'+m
[1]+'</a></li>');
544 $("#spalatodialog .chapters").append('<li><a class="chapter" href="javascript:void(0)" title="'+n
+'">'+m
[1]+'</a></li>');
547 var chap
= content
.substring(0, r
.lastIndex
-m
[0].length
);
548 $("#spalatodialog .content").append('<div style="display: none" class="chapter'+(n
-1)+'">'+chap
+'</div>');
553 content
= content
.substring(r
.lastIndex
);
559 $("#spalatodialog .content").append('<div style="display: none" class="chapter'+(n
-1)+'">'+content
+'</div>');
562 $("#spalatodialog A.chapter").click(function() {
563 var chap_n
= $(this).attr("title");
564 $("#spalatodialog .content > DIV").css("display", "none");
565 $("#spalatodialog DIV.chapter"+chap_n
).css("display", "block");
579 _loadInitialData : function() {
580 $.booki
.ui
.notify("Loading...");
582 jQuery
.booki
.sendToCurrentBook({"command": "init_editor"},
585 $.booki
.ui
.notify("");
587 statuses
= data
.statuses
;
589 $.each(data
.metadata
, function(i
, elem
) {
590 $("#tabinfo .metadata").append('<tr><td valign="top"><b>'+elem
.name
+':</b></td><td valign="top"> '+elem
.value
+'</td></tr>');
593 $.each(data
.chapters
, function(i
, elem
) {
594 toc
.addItem(createChapter({id
: elem
[0], title
: elem
[1], isChapter
: elem
[3] == 1, status
: elem
[4]}));
597 $.each(data
.hold
, function(i
, elem
) {
598 holdChapters
.addItem(createChapter({id
: elem
[0], title
: elem
[1], isChapter
: elem
[3] == 1, status
: elem
[4]}));
606 attachments
= data
.attachments
;
608 /* this should not be here */
610 function _getDimension(dim
) {
612 return dim
[0]+'x'+dim
[1];
618 function _getSize(size
) {
619 return (size
/1024).toFixed(2)+' Kb';
622 $.each(data
.attachments
, function(i
, elem
) {
623 $("#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>');
625 /* $("#tabattachments .files").append('<tr><td><input type="checkbox"></td><td><a class="file" href="../static/'+elem["name"]+'" target="_new">'+elem["name"]+'</a></td><td align="right"> '+elem.size+'</td></tr>'); */
630 $("#tabattachments .line").hover(function() {
631 $(this).css("background-color", "#f0f0f0");
634 $(this).css("background-color", "white");
638 $("#tabattachments .file").click(function() {
639 var imageName = $(this).attr("alt");
640 if(imageName.match(/.+\.jpg$/gi)) {
641 $("#attachmentpreview").html('<img src="../_utils/thumbnail/'+imageName+'"><br/><br/><a style="font-size: 10px" href="../static/'+imageName+'" target="_new">Open in new window</a>');
647 $.each(data.users, function(i, elem) {
648 $("#users").append(elem+"<br/>");
655 /* initialize editor */
657 initEditor: function() {
659 jQuery
.booki
.subscribeToChannel("/booki/book/"+$.booki
.currentProjectID
+"/"+$.booki
.currentBookID
+"/", function(message
) {
662 // this does not work when you change chapter status very fast
663 if(message
.command
== "chapter_status") {
664 if(message
.status
== "rename" || message
.status
== "edit") {
665 // $("#item_"+message.chapterID).css("color", "red");
666 $(".extra", $("#item_"+message
.chapterID
)).html('<div style="padding: 3px; background-color: red; color: white">'+message
.username
+'</div>');
669 if(message
.status
== "normal") {
670 //$("#item_"+message.chapterID).css("color", "gray");
671 $(".extra", $("#item_"+message
.chapterID
)).html("");
675 if(message
.command
== "chapters_changed") {
676 if(message
.kind
== "remove") {
678 var itm
= toc
.getItemById(message
.chapter_id
);
680 if((""+message
.chapter_id
).substring(0,1) != 's')
681 holdChapters
.addItem(itm
);
683 toc
.delItemById(message
.chapter_id
);
685 toc
.update(message
.ids
);
686 holdChapters
.update(message
.hold_ids
);
691 $.booki
.ui
.info("#container .middleinfo", "Removing chapter from Table of Contents.");
693 if(message
.kind
== "add") {
694 var itm
= holdChapters
.getItemById(message
.chapter_id
);
696 holdChapters
.delItemById(message
.chapter_id
);
698 toc
.update(message
.ids
);
699 holdChapters
.update(message
.hold_ids
);
704 $.booki
.ui
.info("#container .middleinfo", "Adding chapter to Table of Contents.");
706 $.booki
.ui
.info("#container .middleinfo", "Reordering the chapters...");
708 toc
.update(message
.ids
);
709 holdChapters
.update(message
.hold_ids
);
711 holdChapters
.redraw();
716 if(message
.command
== "chapter_create") {
717 // this also only works for the TOC
718 if(message
.chapter
[3] == 1) {
719 holdChapters
.addItem(createChapter({id
: message
.chapter
[0], title
: message
.chapter
[1], isChapter
: true, status
: message
.chapter
[4]}));
720 var v
= holdChapters
.getItemById(message
.chapter
[0]);
721 makeChapterLine(v
.id
, v
.title
, getStatusDescription(v
.status
)).appendTo("#holdchapterslist");
723 toc
.addItem(createChapter({id
: message
.chapter
[0], title
: message
.chapter
[1], isChapter
: false}));
724 var v
= toc
.getItemById(message
.chapter
[0]);
725 makeSectionLine(v
.id
, v
.title
).appendTo("#chapterslist");
729 if(message
.command
== "chapter_rename") {
730 $.booki
.debug
.debug("[chapter_rename]");
731 var item
= toc
.getItemById(message
.chapterID
);
733 item
= holdChapters
.getItemById(message
.chapterID
);
734 item
.title
= message
.chapter
;
736 holdChapters
.refresh();
739 if(message
.command
== "chapters_list") {
740 $("#chapterslist").empty();
741 $.each(message
.chapters
, function(i
, elem
) {
742 // should be makeSectionLine also
743 makeChapterLine(elem
[0], elem
[1], 0).prependTo("#chapterslist");
750 $.booki
.editor
._initUI();
751 $.booki
.editor
._loadInitialData();