User:Whiteknight/designer3.js

//Visual Book designer (vbd) class var vbd = { // Version numbers _require: 2.81, version: 3.73, bookpageversion: 0.00, pageheadversion: 0.00,

// default name of all new books: pageTree: null, defName: 'New Book', defpagename: 'New Page', defheadname: 'New Heading', newpagecnt: 1, newheadcnt: 1,

//div IDs where the gadget is inserted into the page formspan: "WKVBDSpan", statspan: "WKVBDStatSpan",

// Navigation templates and configuration parameters templates: new Array(   ["Simple Header",    0, 0, "Simple header"],    ["Page Nav Header",  1, 0, "Header with forward/back links"],    ["Page Nav Header2", 1, 0, "Header with forward/back links (2)"],    ["Page List Header", 0, 1, "Header with page list"],    ["Page List Nav",    1, 1, "Header with page list and forward/back links"]  ), template: 0,

// Reading levels readingLevels: new Array(   'Pre-Reader',     'Beginner',     'Intermediate',     'Advanced',     'Professional'  ), readingLevel: 2,

// Prerequisite and corequisite books prerequisites: new Array, corequisites: new Array,

// Subjects for categorization subjects: new Array,

// whether to include certain special pages in the book by default useresources:   false, uselicensing:   false, useintroduction: false, usecollectionpreface: true,

// other options defaultinherit: false, defaultcollapse: false, commentsaspages: false, useexternaledit: false, // Drag-n-drop values lastClicked: null, offsetX: 0, offsetY: 0, startX: 0, startY: 0, box: null };

//Basic array management functions vbd.CopyArray = function(array) { return array.slice(0); } vbd.FindPageNameInArray = function (array, name) { for(var i = 0; i < array.length; i++) { if(array[i].pagename == name) return i; } return -1; } vbd.FindHeadNameInArray = function(array, name) { for(var i = 0; i < array.length; i++) { if(array[i].label == name) return i; } return -1; }

//Make a checkbox that corresponds to a boolean flag in vbd vbd.makeOptionsCheckbox = function (field) { var cbox = wk.makeElement('input', {type: "checkbox"}); cbox.checked = vbd[field]; cbox.onclick = function { vbd[field] = cbox.checked; } return cbox; }

//Initialization functions. If the wk object is not found, the noinit method is called. Otherwise, the //initialize method is called to start the gadget. vbd.noinit = function { wk.spanText(vbd.formspan, "Cannot load VBD. WKGadgetsCore is missing or is wrong version. "   + "Please install WKGadgetsCore, or update it to version " + vbd._require + "."); } vbd.initialize = function { vbd.pageTree = new BookPage(vbd.defName); vbd.status = wk.spanEditor(vbd.statspan); vbd.status("Use the outline tool below to create a new book"); var query = wk.getQueryHash; if(typeof query["book"] == "undefined") { vbd.visual; return; } vbd.status("Loading the outline for " + query["book"] + "..."); wk.loadWikiText(query["book"], function (text) {    var start = text.indexOf();    var end = text.indexOf();    if(start == -1 || end == -1) {      vbd.visual;      return;    }    vbd.loadNodeTree(text.substring(start + 38, end));    vbd.status("Use the outline tool below to create a new book");  }); } if(typeof wk == 'object' && wk.testVersion(vbd._require)) { addOnloadHook(vbd.initialize); } else { addOnloadHook(vbd.noinit); }

//rebuild the outline vbd.visual = function { vbd.box = wk.spanText(vbd.formspan, ""); if(vbd.box == null) return; vbd.box.appendChild(vbd.pageTree.makeNode); }

//Clear the outline completely and create a new one vbd.clear = function { vbd.pageTree = new BookPage(vbd.defName); vbd.subjects = new Array; vbd.readingLevel = 2; vbd.newpagecnt = 1; vbd.newheadcnt = 1; vbd.visual; }

//Load a saved outline from a save page vbd.loadNodeTree = function (text) { vbd.clear; var lastn = 0; var last = new Array; last[0] = vbd.pageTree; var lines = text.split("\n"); for(i = 0; i < lines.length; i++) { lines[i] = lines[i].replace(/^[ \t]+/, ""); lines[i] = lines[i].replace(/[ \t]+$/, ""); lines[i] = lines[i].replace(/\r\n/g, ""); if(lines[i] == "") continue; if(lines[i].match(/^=/)) { //heading var levels = lines[i].match(/^=+/); var n = levels[0].length; var k = n - 1; var head = new PageHeading(lines[i].substr(n)); last[k].addHeading(head); last[k] = head; lastn = k;   } else if(lines[i].match(/^\*+/)) { //subpage var stars = lines[i].match(/^\*+/); var n = stars[0].length; var k = n - 1; if(last[k] == null) { k = 0; } last[n] = new BookPage(lines[i].substr(n)); last[k].addSubpage(last[n]); lastn = n;   } else if(lines[i].match(/^&/)) { //pagetext last[lastn].pagetext += lines[i].substr(1); } else if(lines[i].match(/^%/)) { //comment last[lastn].comments += lines[i].substr(1); } else { //main title vbd.pageTree.pagename = lines[i]; lastn = 0; } }  vbd.pageTree.formspan.innerHTML = ""; vbd.visual; vbd.pageTree.formspan.appendChild(document.createTextNode( 'Successfully loaded saved outline' )); }

//Try to load in a saved collection vbd.loadNodeTreeCollection = function(text) { vbd.clear; var last = vbd.pageTree; var lines = text.split("\n"); for(var i = 0; i < lines.length; i++) { if(lines[i].match(/^===/) || lines[i].match(/\[\[category:/i)) { continue; } else if(lines[i].match(/^==.+==/)) { vbd.pageTree.pagename = vbd.extractHeadingName(lines[i]); } else if(lines[i].match(/^;/)) { var head = new PageHeading(lines[i].substring(1)); last.addHeading(head); last = head; } else if(lines[i].match(/^:\[\[/)) { if(lines[i].match(/Resources/)) { vbd.useresources = true; continue; } if(lines[i].match(/Licensing/)) { vbd.uselicensing = true; continue; } if(lines[i].match(/Wikibooks:/)) { vbd.usecollectionpreface = true; continue; } var page = new BookPage(vbd.extractLinkPageName(lines[i], vbd.pageTree.pagename)); last.addSubpage(page); } }  vbd.visual; vbd.pageTree.formspan.innerHTML = 'Successfully loaded collection!'; }

//take the wikitext of an arbitrary page and try to load a reasonable outline from it. vbd.loadNodeTreeTOC = function (text, title) { vbd.clear; var lastn = 0; var last = new Array; last[0] = vbd.pageTree; vbd.pageTree.pagename = title; var lines = text.split("\n"); for(i = 0; i < lines.length; i++) { lines[i] = lines[i].replace(/^[ \t]+/, ""); lines[i] = lines[i].replace(/[ \t]+$/, ""); lines[i] = lines[i].replace(/\r\n/g, ""); if(lines[i] == "") continue; if(lines[i].match(/^===.+===/)) { //heading var head = new PageHeading(vbd.extractHeadingName(lines[i])); last[0].addHeading(head); last[0] = head; } else if(lines[i].match(/^[\*\#]*\s*\[\[.+\]\]/)) { //subpage if(lines[i].match(/Resources/)) { vbd.useresources = true; continue; } if(lines[i].match(/Licensing/)) { vbd.uselicensing = true; continue; } if(lines[i].match(/Category:/i)) continue; var stars = lines[i].match(/^[\*\#]*/); var n = stars[0].length; if(n == 0) n = 1; var k = n - 1; if(last[k] == null) { k = 0; } last[n] = new BookPage(vbd.extractLinkPageName(lines[i], title)); last[k].addSubpage(last[n]); lastn = n;   } } vbd.pageTree.formspan.innerHTML = ""; vbd.visual; vbd.pageTree.formspan.appendChild(document.createTextNode( 'Successfully loaded outline from ' + title + ' TOC!' )); }

//try to get the name of a level-3 heading vbd.extractHeadingName = function(line) { line = line.substring(3); line = line.substring(0, line.indexOf("===")); return line; }

//Try to get the page name from a link. Very limited ability to deal with relative links vbd.extractLinkPageName = function(line, title) { line = line.substring(line.indexOf(""); if(end == -1) {    end = line.indexOf(""); } line = line.substring(0, end) if(line.charAt(line.length - 1) == '/') line = line.substring(0, line.length - 1); if(line.charAt(0) == '/') line = title + line; for(end = line.indexOf("/") ; end != -1; end = line.indexOf("/")) { line = line.substring(end + 1); } return line; }

//when saving an outline, find and remove an old save, if one is located on the page. vbd.killOldSaves = function(text) { var start = text.indexOf(''); var end = text.indexOf(''); if(start == -1 || end == -1) return text; //no previous save var prefix = text.slice(0, start); var suffix = text.slice(end + 36); return prefix + suffix; }

//force a page name to use appropriate capitalization vbd.forceCaps = function(title, isRoot) { if(isRoot) return vbd.forceTitleCaps(title); else return vbd.forceFirstCaps(title); }

//determines if the word needs to be capitalized. Returns 1 if it should be, 0 otherwise. vbd.isRealWord = function (word) { var preps = new Array('the', 'in', 'of', 'for', 'to', 'is', 'a', 'an'); for(var i = 0; i < preps.length; i++) { if(word == preps[i]) return 0; } return 1; }

//book names are forced to title caps vbd.forceTitleCaps = function(title) { title.replace("_", " "); var words = title.split(" "); for(var i = 0; i < words.length; i++) { if(words[i].length > 3 || i == 0 || vbd.isRealWord(words[i])) words[i] = words[i].charAt(0).toUpperCase + words[i].slice(1); } title = words.join(" "); return title; }

//page names are forced to have the first letter capitalized, but are not forced to have title-caps vbd.forceFirstCaps = function(title) { title.replace("_", " "); return title.charAt(0).toUpperCase + title.slice(1); }

//Create the wikitext of the selected navigation template vbd.makeTemplateText = function { var template = vbd.templates[vbd.template]; var book = vbd.pageTree.pagename; var text = "{"+"{subst:User:Whiteknight/" + template[0] + "|" + ((template[1])?("book="):("")) + book; if(template[2] == 1) { text += "|" + ((template[1] == 1)?("list="):("")) + vbd.pageTree.makeTemplateLinks; text += "Resources - " + "Licensing - " + "Discuss"; } return text + "}}"; }

//

// XXX: Drop-down menu utilities. These aren't implemented yet.

//vbd.createDropMenu = function(parent, children) { // var menu = wk.makeElement('div', {style:"position:absolute; top: 0px; left: 0px; z-index: 10; background-color: white;"}); // wk.appendChildren(menu, children); // menu.onmouseout = function { //   parent.removeChild(menu); // } //  parent.appendChild(menu); //}

// XXX: Drag'n'Drop utilities. These aren't implemented yet.

//document.addEventListener("mouseup", function(event) { // if(vbd.lastClicked && //    event.eventPhase == Event.BUBBLING_PHASE && //    event.currentTarget == event.target) { //    vbd.lastClicked.box.style.border = "none"; //    vbd.lastClicked = null; //  } //}, false);

//vbd.extractNumber = function(value) { // var n = parseInt(value); // return n == null || isNaN(n) ? 0 : n; //}

//vbd.moveMouse = function(e) { // vbd.lastClicked.box.style.left = (vbd.offsetX + e.clientX - vbd.startX) + 'px'; // vbd.lastClicked.box.style.top = (vbd.offsetY + e.clientY - vbd.startY) + 'px'; // vbd.status("x:" + vbd.lastClicked.box.style.left + " y: " + vbd.lastClicked.box.style.top); //}

//