source: main/trunk/greenstone3/web/interfaces/oran/js/documentmaker_scripts.js@ 25072

Last change on this file since 25072 was 25072, checked in by sjm84, 12 years ago

Added the ability to edit a document straight from the document view

  • Property svn:executable set to *
File size: 17.9 KB
Line 
1var _transactions = new Array();
2var _collectionsToBuild = new Array();
3var _allContents = new Array();
4var _idCounter = 0;
5var _indexCounter = 0;
6var _deletedSections = new Array();
7var _undoOperations = new Array();
8var _baseURL;
9var _statusBar;
10
11function init()
12{
13 de.init();
14 //Get all of the links on the page
15 var allLinks = document.getElementsByTagName("a");
16
17 //Work out which links are the actual document links
18 var docLinks = new Array();
19 for(var i = 0; i < allLinks.length; i++)
20 {
21 if(allLinks[i].getAttribute("class") && (hasClass(allLinks[i], "dbdoc")))
22 {
23 docLinks.push(allLinks[i]);
24 }
25 }
26
27 if(gs.cgiParams.docToEdit)
28 {
29 var content = document.getElementById("gs_content");
30 var newLink = document.createElement("A");
31 newLink.setAttribute("href", gs.xsltParams.library_name + "?a=d&c=" + gs.cgiParams.p_c + "&dt=hierarchy&ed=1&d=" + gs.cgiParams.docToEdit);
32 content.appendChild(newLink);
33 docLinks.push(newLink);
34 }
35
36 if(docLinks.length == 0)
37 {
38 document.getElementById("gs_content").innerHTML = "No documents in the Document Basket";
39 return;
40 }
41
42 //Create the top menu bar
43 var menuBar = createTopMenuBar();
44
45 //Add the menu bar to the page
46 var mainContentDiv = document.getElementById("gs_content");
47 mainContentDiv.appendChild(menuBar);
48
49 var dbDiv = document.createElement("DIV");
50 dbDiv.setAttribute("id", "dbDiv");
51 insertAfter(dbDiv, menuBar);
52
53 var statusDiv = document.createElement("DIV");
54 statusDiv.setAttribute("class", "statusBar");
55 insertAfter(statusDiv, menuBar);
56 _statusBar = new StatusBar(statusDiv);
57
58 //Request the html for each link's page
59 for(var i = 0; i < docLinks.length; i++)
60 {
61 var callback = {
62 success: addDocumentStructureToPage,
63 failure: function(data){/*alert("FAILED");*/}
64 }
65 callback.currentLink = docLinks[i];
66 YAHOO.util.Connect.asyncRequest("GET", docLinks[i].getAttribute("href").concat('&dmd=true&excerptid=gs-document-text&hhf=[{"name":"Cache-Control", "value":"no-cache"}]'), callback);
67 }
68
69 _baseURL = gs.xsltParams.library_name;
70}
71
72function addDocumentStructureToPage(data)
73{
74 //Get the HTML
75 var page = data.responseText;
76
77 //Add the HTML to the page inside an invisible div
78 var tempDiv = document.createElement("DIV");
79 tempDiv.innerHTML = page;
80 tempDiv.style.display = "none";
81 insertAfter(tempDiv, this.currentLink);
82
83 //Get the collection that this document belongs to
84 var collection = document.getElementById("gs-document-text").getAttribute("collection");
85
86 //Get the Document Basket div
87 var dbDiv = document.getElementById("dbDiv");
88
89 //Create the container list and add it to the Document Basket div
90 var containerUL = document.createElement("UL");
91 containerUL.setAttribute("class", "topLevel");
92 dbDiv.appendChild(containerUL);
93
94 //Get all of the headers in the page
95 var headers = getElementsByClassName("sectionTitle", tempDiv);
96
97 //Some necessary loop variables
98 var prevItem = null;
99 var prevDepth = 0;
100 var levelContainers = new Array();
101 levelContainers[0] = containerUL;
102
103 //Loop through all of the headers
104 for(var i = 0; i < headers.length; i++)
105 {
106 var currentHeader = headers[i];
107
108 //If the currentHeader is not a <td> element then we are not interested
109 if(currentHeader.nodeName.toLowerCase() != "td")
110 {
111 continue;
112 }
113
114 //Split the section ID on . to get its position in the document
115 var posArray = currentHeader.getAttribute("id").split(".");
116
117 //Save the document ID
118 var docID = posArray[0].substring(6);
119
120 //Save the depth of the section (top level is 0)
121 var depth = posArray.length - 1;
122
123 //Turn the position array into a string
124 var position = "";
125 for(var j = 1; j < posArray.length; j++)
126 {
127 if(j != 1)
128 {
129 position += ".";
130 }
131 position += posArray[j];
132 }
133
134 //Save the section number
135 var secID = currentHeader.getAttribute("id").substring("6");
136
137 //Get the text of the section
138 var currentText = document.getElementById("text" + secID);
139 var renderedDiv = createSectionTextDiv(currentText.innerHTML);
140
141 var newItem = document.createElement("LI");
142 new YAHOO.example.DDList(newItem);
143
144 var title = createSectionTitle(currentHeader.innerHTML);
145 newItem.sectionTitle = title;
146 newItem.appendChild(title);
147 newItem.setAttribute("class", depth == 0 ? "dragItem topLevel" : "dragItem");
148 newItem.textDiv = renderedDiv;
149 renderedDiv.parentItem = newItem;
150
151 var metadataTable = document.getElementById("meta" + secID);
152 renderedDiv.insertBefore(metadataTable, renderedDiv.firstChild);
153 addFunctionalityToTable(metadataTable);
154
155 if(depth > prevDepth)
156 {
157 var newContainer = document.createElement("UL");
158 new YAHOO.util.DDTarget(newContainer);
159 newContainer.setAttribute("class", "dragList");
160
161 prevItem.childList = newContainer;
162 prevItem.menu.newSectionLink.style.display = "none";
163 newContainer.parentItem = prevItem;
164 levelContainers[depth - 1].appendChild(newContainer);
165 levelContainers[depth] = newContainer;
166 }
167 prevDepth = depth;
168
169 levelContainers[depth].appendChild(newItem);
170 levelContainers[depth].appendChild(renderedDiv);
171
172 createSectionMenu(newItem);
173 setMouseOverAndOutFunctions(newItem);
174
175 //Set various section properties
176 //newItem.collection = collectionName;
177 newItem.documentID = docID;
178 newItem.position = position;
179 newItem.nodeID = secID;
180 newItem.dbID = _idCounter++;
181 newItem.index = newItem.dbID;
182 newItem.collection = collection;
183 newItem.parentList = levelContainers[depth];
184
185 prevItem = newItem;
186
187 //Insert the section into the list of sections
188 _allContents.push(newItem);
189 }
190
191 removeFromParent(this.currentLink);
192 updateFromTop();
193}
194
195function createSectionTextDiv(text)
196{
197 var renderedDiv = document.createElement("DIV");
198 renderedDiv.setAttribute("style", "display:none;");
199
200 var textDiv = document.createElement("DIV");
201 if(text && text.length > 0)
202 {
203 textDiv.innerHTML = text;
204 }
205 else
206 {
207 textDiv.innerHTML = "&nbsp;";
208 }
209 textDiv.setAttribute("class", "renderedText editable");
210
211 //This registering can cause a sizeable delay so we'll thread it (effectively) so the browser is not paused
212 setTimeout(function(){de.doc.registerEditSection(textDiv)}, 0);
213
214 renderedDiv.appendChild(textDiv);
215 textDiv.parentDiv = renderedDiv;
216
217 return renderedDiv;
218}
219
220function createNewDocumentArea()
221{
222 //Create the necessary elements
223 var topLevelUL = document.createElement("UL");
224 var topLevelLI = document.createElement("LI");
225 var contentUL = document.createElement("UL");
226
227 //Append the top-level list item to the top-level list
228 topLevelUL.appendChild(topLevelLI);
229 topLevelUL.setAttribute("class", "topLevel");
230
231 //Set up the top-level item
232 topLevelLI.setAttribute("class", "dragItem topLevel");
233 topLevelLI.childList = contentUL;
234 contentUL.parentItem = topLevelLI;
235
236 //Add a textDiv to the top-level item
237 var textDiv = createSectionTextDiv(null);
238 topLevelLI.textDiv = textDiv;
239 topLevelUL.appendChild(textDiv);
240
241 //Add a title to the top-level item
242 var title = createSectionTitle("UNTITLED DOCUMENT");
243 topLevelLI.appendChild(title);
244 topLevelLI.sectionTitle = title;
245
246 createSectionMenu(topLevelLI);
247 setMouseOverAndOutFunctions(topLevelLI);
248
249 //Set up the placeholder for the first section
250 contentUL.setAttribute("class", "dragList");
251 new YAHOO.util.DDTarget(contentUL);
252
253 //Create a placeholder and add it to first section
254 var placeHolder = createPlaceholder(null, contentUL, false);
255 contentUL.appendChild(placeHolder);
256
257 var dbDiv = document.getElementById("dbDiv");
258
259 //Add elements to the page
260 if(dbDiv.firstChild)
261 {
262 dbDiv.insertBefore(topLevelUL, dbDiv.firstChild);
263 }
264 else
265 {
266 dbDiv.appendChild(topLevelUL);
267 }
268 insertAfter(contentUL, topLevelLI.textDiv);
269
270 //Correct any issues
271 updateFromTop();
272}
273
274function createPlaceholder(parent, parentList, mouseEvents)
275{
276 //Create the place holder and assign its class
277 var placeHolder = document.createElement("LI");
278 placeHolder.setAttribute("class", "placeHolder");
279
280 //If a parent was given then we can assign the collection and nodeID
281 if(parent)
282 {
283 placeHolder.collection = parent.collection;
284 placeHolder.nodeID = parent.nodeID;
285 }
286
287 //If this is to be a plain placeholder then we don't want it to react to mouse events
288 if(mouseEvents)
289 {
290 placeHolder.isEmptyList = true;
291
292 //Create the delete section link
293 var deleteSectionLink = document.createElement("A");
294 deleteSectionLink.innerHTML = "delete section";
295 deleteSectionLink.setAttribute("href", "javascript:;");
296 deleteSectionLink.setAttribute("class", "menuLink");
297 deleteSectionLink.style.display = "none";
298
299 //Set the onclick behaviour of the delete link
300 deleteSectionLink.onclick = function()
301 {
302 //Delete the place holder
303 removeFromParent(placeHolder);
304
305 //If this is in a list then delete the list (as this will be the only thing in the list)
306 if(parentList)
307 {
308 var undo = new Array();
309
310 undo.op = "mva";
311 undo.srcElem = parentList;
312 undo.refElem = parent;
313 undo.removeTransaction = false;
314 _undoOperations.push(undo);
315
316 removeFromParent(parentList);
317 }
318
319 //Enable the "add sub-section" menu option in the parent
320 if(parent)
321 {
322 parent.menu.newSectionLink.style.display = "inline";
323 parent.childList = null;
324 }
325 }
326 placeHolder.appendChild(deleteSectionLink);
327
328 //Colour the list item and display the menu on mouse over
329 placeHolder.onmouseover = function(e)
330 {
331 deleteSectionLink.style.display = "inline";
332 this.style.background = "rgb(255, 200, 0)";
333 };
334 //Uncolour the list item and hide the menu on mouse out
335 placeHolder.onmouseout = function(e)
336 {
337 deleteSectionLink.style.display = "none";
338 this.style.background = "none";
339 };
340 }
341
342 var dragItem = new YAHOO.example.DDList(placeHolder);
343 dragItem.addInvalidHandleClass("placeHolder");
344 return placeHolder;
345}
346
347function duplicateSection(section)
348{
349 var newLI = document.createElement("LI");
350 newLI.setAttribute("class", "dragItem");
351 new YAHOO.example.DDList(newLI);
352
353 if(section.textDiv)
354 {
355 var textDiv = createSectionTextDiv(section.textDiv.innerHTML);
356 newLI.textDiv = textDiv;
357 }
358 newLI.collection = section.collectionName;
359
360 if(section.sectionTitle)
361 {
362 var title = createSectionTitle(section.sectionTitle.innerHTML);
363 newLI.sectionTitle = title;
364 newLI.appendChild(title);
365 }
366
367 createSectionMenu(newLI);
368 setMouseOverAndOutFunctions(newLI);
369 newLI.onmouseout();
370
371 if(section.childList)
372 {
373 insertAfter(newLI, section.childList);
374 }
375 else if(section.textDiv)
376 {
377 insertAfter(newLI, section.textDiv);
378 }
379 else
380 {
381 insertAfter(newLI, section);
382 }
383
384 if(newLI.textDiv)
385 {
386 insertAfter(newLI.textDiv, newLI);
387 }
388 return newLI;
389}
390
391function duplicateSectionChildrenRecursive(duplicate, original)
392{
393 if(!original.childList)
394 {
395 return;
396 }
397
398 var newUL = document.createElement("UL");
399 newUL.setAttribute("class", "dragList");
400 new YAHOO.util.DDTarget(newUL);
401 insertAfter(newUL, duplicate.textDiv);
402
403 var children = new Array();
404 var current = original.childList.firstChild;
405 while(current != null)
406 {
407 children.push(current);
408 current = current.nextSibling;
409 }
410
411 for(var i = 0; i < children.length; i++)
412 {
413 current = children[i];
414 if(current.nodeName.toLowerCase() == "li" && !hasClass(current, "placeHolder"))
415 {
416 var newSection = duplicateSection(current);
417 newUL.appendChild(newSection);
418 if(current.childList)
419 {
420 duplicateSectionChildrenRecursive(newSection, current);
421 }
422 }
423 }
424
425 duplicate.childList = newUL;
426 newUL.parentItem = duplicate.childList;
427
428 if(duplicate.menu)
429 {
430 duplicate.menu.newSectionLink.style.display = "none";
431 }
432}
433
434function deleteSection(section)
435{
436 var undo = new Array();
437 var prev = getPrevSiblingOfType(section, "li");
438 var next = getNextSiblingOfType(section, "li");
439 var parent = section.parentList;
440 if(prev)
441 {
442 undo.op = "mva";
443 undo.refElem = prev;
444 }
445 else if(next)
446 {
447 undo.op = "mvb";
448 undo.refElem = next;
449 }
450 else
451 {
452 undo.op = "mvi";
453 undo.refElem = parent;
454 }
455 undo.srcElem = section;
456 undo.removeTransaction = true;
457 _undoOperations.push(undo);
458
459 saveTransaction('{"operation":"delete", "collection":"' + section.collection + '", "oid":"' + section.nodeID + '"}');
460 addCollectionToBuild(section.collection);
461
462 _deletedSections.push(section);
463 if(section.textDiv)
464 {
465 removeFromParent(section.textDiv);
466 }
467 if(section.childList)
468 {
469 removeFromParent(section.childList);
470 }
471 removeFromParent(section);
472 updateFromTop();
473}
474
475function createBlankSection(parent)
476{
477 if(parent.childList)
478 {
479 return;
480 }
481
482 var newUL = document.createElement("UL");
483
484 newUL.setAttribute("class", "dragList emptyList");
485 new YAHOO.util.DDTarget(newUL);
486
487 insertAfter(newUL, parent.textDiv);
488 parent.childList = newUL;
489 newUL.parentItem = parent;
490
491 var menu = parent.menu;
492 menu.newSectionLink.style.display = "none";
493
494 var undo = new Array();
495 undo.op = "del";
496 undo.srcElem = newUL;
497 undo.removeTransaction = false;
498 _undoOperations.push(undo);
499}
500
501function createSectionMenu(section)
502{
503 var menuBar = document.createElement("SPAN");
504
505 //Separator
506 menuBar.appendChild(document.createTextNode(" "));
507
508 //"Edit" link
509 var toggleLink = document.createElement("A");
510 toggleLink.innerHTML = "edit";
511 toggleLink.setAttribute("class", "menuLink");
512 toggleLink.setAttribute("href", "javascript:;");
513 toggleLink.onclick = function(){toggleTextDiv(section);};
514 menuBar.appendChild(toggleLink);
515 menuBar.editTextLink = toggleLink;
516
517 //Separator
518 menuBar.appendChild(document.createTextNode(" "));
519
520 var newSectionLink = document.createElement("A");
521 newSectionLink.innerHTML = "add&nbsp;sub-section";
522 newSectionLink.setAttribute("class", "menuLink");
523 newSectionLink.setAttribute("href", "javascript:;");
524 newSectionLink.onclick = function()
525 {
526 createBlankSection(section);
527 updateFromTop();
528 };
529 menuBar.appendChild(newSectionLink);
530 menuBar.newSectionLink = newSectionLink;
531
532 //"New Section" link
533 if(section.childList)
534 {
535 newSectionLink.style.display = "none";
536 }
537
538 //Separator
539 menuBar.appendChild(document.createTextNode(" "));
540
541 //"Duplicate" link
542 var duplicateLink = document.createElement("A");
543 duplicateLink.innerHTML = "duplicate";
544 duplicateLink.setAttribute("class", "menuLink");
545 duplicateLink.setAttribute("href", "javascript:;");
546 duplicateLink.onclick = function()
547 {
548 var newSection = duplicateSection(section);
549 if(section.childList)
550 {
551 duplicateSectionChildrenRecursive(newSection, section);
552 }
553
554 var newNodeID = section.nodeID;
555 var lastDigit = parseInt(newNodeID.substring(newNodeID.lastIndexOf(".") + 1));
556 newNodeID = newNodeID.replace(/\.[^\.]*$/, "." + ++lastDigit);
557
558 var undo = new Array();
559 undo.op = "del";
560 undo.srcElem = section;
561 undo.removeTransaction = true;
562 _undoOperations.push(undo);
563
564 saveTransaction('{"operation":"duplicate", "subOperation":"insertBefore", "collection":"' + section.collection + '", "oid":"' + section.nodeID + '", "newCollection":"' + section.collection + '", "newOID":"' + newNodeID + '"}');
565 addCollectionToBuild(section.collection);
566
567 updateFromTop();
568 };
569 menuBar.appendChild(duplicateLink);
570 menuBar.duplicateLink = duplicateLink;
571
572 //Separator
573 menuBar.appendChild(document.createTextNode(" "));
574
575 //"Delete" link
576 var deleteLink = document.createElement("A");
577 deleteLink.innerHTML = "[X]";
578 deleteLink.setAttribute("class", "menuLink deleteLink");
579 deleteLink.setAttribute("href", "javascript:;");
580 deleteLink.onclick = function(){deleteSection(section)};
581 menuBar.appendChild(deleteLink);
582 menuBar.deleteLink = deleteLink;
583
584 menuBar.style.display = "none";
585 section.appendChild(menuBar);
586 section.menu = menuBar;
587}
588
589function updateRecursive(parent, currentDocument, currentPosition, level)
590{
591 if(level == 0)
592 {
593 _indexCounter = 0;
594 }
595
596 level++;
597 var current = parent.firstChild;
598 var posCount = 1;
599 var lastItem;
600 var liCount = 0;
601 while(current != null)
602 {
603 if(current.nodeName.toLowerCase() == "ul")
604 {
605 var pos = null;
606 if(level > 2)
607 {
608 if(!currentPosition)
609 {
610 pos = (posCount - 1);
611 }
612 else
613 {
614 pos = currentPosition + "." + (posCount - 1);
615 }
616 }
617
618 updateRecursive(current, currentDocument, pos, level);
619 }
620 else if (current.nodeName.toLowerCase() == "li" && hasClass(current, "dragItem") && !hasClass(current, "placeHolder"))
621 {
622 if(currentDocument == null && current.nodeID)
623 {
624 currentDocument = current.nodeID;
625 }
626
627 var pos;
628 if(!currentPosition)
629 {
630 pos = posCount;
631 }
632 else
633 {
634 pos = currentPosition + "." + posCount;
635 }
636
637 if(!hasClass(current, "topLevel"))
638 {
639 current.nodeID = currentDocument + "." + pos;
640 current.position = pos;
641 current.documentID = currentDocument;
642 }
643 posCount++;
644
645 current.index = _indexCounter++;
646 }
647 else if (hasClass(current, "placeHolder") && !current.isEmptyList)
648 {
649 var pos;
650 if(!currentPosition)
651 {
652 pos = posCount - 1;
653 }
654 else
655 {
656 pos = currentPosition + "." + posCount - 1;
657 }
658 current.nodeID = currentDocument + "." + pos;
659 }
660
661 if(current.nodeName.toLowerCase() == "li")
662 {
663 liCount++;
664 lastItem = current;
665 }
666
667 current = current.nextSibling;
668 }
669
670 if(level > 2)
671 {
672 //If the last section a this level has a child list then insert a blank placeholder after it so we can insert sections after the list
673 if(lastItem && lastItem.childList)
674 {
675 var placeHolder = createPlaceholder(lastItem, parent, false);
676 parent.appendChild(placeHolder);
677 }
678
679 //If this list is empty or has 1 placeholder child
680 if(liCount == 0 || (liCount == 1 && hasClass(lastItem, "placeHolder")))
681 {
682 //Give it the emptyList css class (if it does not already have it)
683 if(!parent.getAttribute("class") || parent.getAttribute("class").search("emptyList") == -1)
684 {
685 var newClass = parent.getAttribute("class") ? parent.getAttribute("class") + " emptyList" : "emptyList";
686 parent.setAttribute("class", newClass);
687 }
688
689 //If the list is empty then add a placeholder
690 if(liCount == 0)
691 {
692 var placeHolder = createPlaceholder(parent.previousSibling.previousSibling, parent, true); //Find a smarter way of doing this
693 parent.appendChild(placeHolder);
694 }
695 }
696 //Remove the empty list class if the list is no longer empty
697 else if(hasClass(parent, "emptyList"))
698 {
699 parent.setAttribute("class", parent.getAttribute("class").replace(/emptyList/g, ""));
700 }
701 }
702}
703
704YAHOO.util.Event.onDOMReady(init);
Note: See TracBrowser for help on using the repository browser.