মিডিয়াউইকি:Gadget-wkdesigner.js
লক্ষ্য করুন: প্রকাশ করার পর, পরিবর্তনগুলো দেখতে আপনাকে আপনার ব্রাউজারের ক্যাশে পরিষ্কার করার প্রয়োজন হতে পারে।
- ফায়ারফক্স / সাফারি: পুনরায় লোড-এ ক্লিক করার সময় শিফট টিপে ধরে রাখুন, অথবা হয় Ctrl-F5 বা Ctrl-R টিপুন (ম্যাকে ⌘-R টিপুন)
- গুগল ক্রোম: Ctrl-Shift-R (ম্যাকে ⌘-Shift-R) টিপুন
- ইন্টারনেট এক্সপ্লোরার / এজ: Ctrl ধরে রাখা অবস্থায় Refresh-এ ক্লিক করুন, অথবা Ctrl-F5 টিপুন
- অপেরা: Ctrl-F5 টিপুন।
//Visual Book designer (vbd) class <source lang="javascript">
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('{{User:Whiteknight/SavedOutlineStart}}');
var end = text.indexOf('{{User:Whiteknight/SavedOutlineEnd}}');
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)) {
$(vbd.initialize);
} else {
$(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("[[") + 2);
var end = 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('{{User:Whiteknight/SavedOutlineStart}}');
var end = text.indexOf('{{User:Whiteknight/SavedOutlineEnd}}');
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 += "[[" + book + "/Resources|Resources]] - " +
"[[" + book + "/Licensing|Licensing]] - " +
"[[Talk:" + book + "|Discuss]]";
}
return text + "}}";
}
//
//class constructor for BookPage
function BookPage(name) {
if(name.match(/\s$/)) name = name.substring(0, name.length - 1);
this.pagename = name;
this.headings = new Array();
this.subpages = new Array();
this.formspan = wk.makeElement('div');
this.parent = null; //subpage parent, null if root
this.parent2 = null; //heading parent, null if not in a heading.
this.pagetext = ""; //initial text of a page
this.comments = ""; //comment text which is in the outline only
this.collapse = vbd.defaultcollapse; //flag to collapse part of the tree
this.inherittext = vbd.defaultinherit; //flag to inherit text from parent
this.box = null;
}
//add a new heading to the page
BookPage.prototype.addHeading = function(heading) {
heading.parent = this;
this.headings.push(heading);
}
//add a new subpage to the page
BookPage.prototype.addSubpage = function(subpage) {
subpage.parent = this;
this.subpages.push(subpage);
}
//create a special node for a page that is to be created but does not appear in the outline
BookPage.prototype.makeSpecialPageNode = function(name) {
// Create a node that thinks it's a subpage, but isn't included in the list of subpages of the parent.
var node = new BookPage(name);
node.parent = this;
node.formspan = null;
return node;
}
//Show a little animation when things are happening behind the scenes
BookPage.prototype.makeLoadingNotice = function(text) {
this.formspan.innerHTML = "<img src=\"//upload.wikimedia.org/wikipedia/commons/4/42/Loading.gif\"> <big>" + text + "...</big>"
}
//make an editor, according to the users preferences
BookPage.prototype.makeEditInterface = function(page, deftext, defsummary) {
if(vbd.useexternaledit) wk.showEditWindowExternal(page, deftext, defsummary);
else {
var self = this;
this.makeLoadingNotice("Loading");
wk.loadEditPage(page, function (xml) {
wk.showEditWindowSmall(xml, self.formspan, deftext, defsummary);
self.closeButton();
});
}
}
//create the part of the outline for the page text and comments
BookPage.prototype.getTextNode = function () {
var self = this;
var div = wk.makeElement('small', null,
((this.pagetext.length == 0)?('[click here to edit page text]'):(this.pagetext)));
div.innerHTML = div.innerHTML + ((this.inherittext && !this.isRoot())?(' (inherited)'):(""))
var cmts = wk.makeElement('small', {style:'color: #666666'},
((this.comments.length == 0)?('[click here to edit comments]'):(this.comments)));
div.onclick = function() {
var edit = wk.makeElement('textarea', {rows:10});
edit.value = self.pagetext;
self.formspan.innerHTML = 'Enter some text for the page:';
self.formspan.appendChild(edit);
if(!self.isRoot()) {
var inherit = wk.makeElement('input', {type:"checkbox"});
inherit.checked = self.inherittext;
wk.appendChildren(self.formspan, [inherit, 'inherit text from parent?']);
}
self.formspan.appendChild(wk.makeButton('', 'Save', function() {
if(!self.isRoot()) self.inherittext = inherit.checked;
self.pagetext = edit.value;
if(self.pagetext.match(/^\s*$/)) self.pagetext = "";
self.formspan.innerHTML = "";
vbd.visual();
}));
self.closeButton();
edit.focus();
}
div.style.cursor = "pointer";
cmts.onclick = function() {
var edit = wk.makeElement('textarea', {rows:10});
edit.value = self.comments;
self.formspan.innerHTML = 'Enter some comments:';
self.formspan.appendChild(edit);
self.formspan.appendChild(wk.makeButton('', 'Save', function() {
self.comments = edit.value;
if(self.comments.match(/^\s*$/)) self.comments = "";
self.formspan.innerHTML = "";
vbd.visual();
}));
self.closeButton();
edit.focus();
}
cmts.style.cursor = "pointer";
return wk.makeElement('table', {width:"100%", style:"background-color: transparent"}, [
wk.makeElement('td', {width:"50%", style:"padding-left: 2em;"}, div),
wk.makeElement('td', {style:"padding-left: 2em;"}, cmts)
]);
}
//remove a subpage
BookPage.prototype.removeSubpage = function(subpage) {
for(var i = 0; i < this.subpages.length; i++) {
if(this.subpages[i] != subpage) continue;
this.subpages.splice(i, 1);
return;
}
}
//remove a heading
BookPage.prototype.removeHeading = function(heading) {
for(var i = 0; i < this.headings.length; i++) {
if(this.headings[i] != heading) continue;
this.headings.splice(i, 1);
return;
}
}
//create a link to modify the list of headings.
BookPage.prototype.makeHeadingsLink = function () {
var link = wk.makeElement('a', null, ['Headings']);
var self = this;
link.onclick = function() {
var text = "";
for(var i = 0; i < self.headings.length; i++) {
text = text + self.headings[i].label + "\n";
}
var old = vbd.CopyArray(self.headings);
var edit = wk.makeElement('textarea', {rows:10, cols:50});
edit.value = text;
self.formspan.innerHTML = "";
self.formspan.appendChild(document.createTextNode(
'Enter the names of all headings, one per line'));
self.formspan.appendChild(edit);
self.formspan.appendChild(wk.makeButton('', 'Save', function() {
self.headings.length = 0;
var pages = edit.value.split("\n");
for(var i = 0; i < pages.length; i++) {
if(pages[i].match(/^\s*$/)) continue;
var stat = vbd.FindHeadNameInArray(old, pages[i]);
if(stat != -1) {
self.addHeading(old[stat]);
} else {
self.addHeading(new PageHeading(vbd.forceFirstCaps(pages[i])));
}
}
self.formspan.innerHTML = "";
vbd.visual();
}));
self.closeButton();
edit.focus();
}
return(link);
}
//create a link to add a new subpage
BookPage.prototype.makeSubpagesAddLink = function () {
var link = wk.makeElement('a', null, [" [ + ]"]);
var self = this;
link.onclick = function () {
self.addSubpage(new BookPage(vbd.defpagename + " " + vbd.newpagecnt));
vbd.newpagecnt++;
vbd.visual();
}
return link;
}
//create a link to add a new heading
BookPage.prototype.makeHeadingsAddLink = function () {
var link = wk.makeElement('a', null, [" [ + ]"]);
var self = this;
link.onclick = function () {
self.addHeading(new PageHeading(vbd.defheadname + " " + vbd.newheadcnt));
vbd.newheadcnt++;
vbd.visual();
}
return link;
}
//make a list to modify the list of subpages
BookPage.prototype.makeSubpagesLink = function () {
var link = wk.makeElement('a', null, ['Subpages']);
var self = this;
link.onclick = function() {
var text = "";
for(var i = 0; i < self.subpages.length; i++) {
text = text + self.subpages[i].pagename + "\n";
}
var old = vbd.CopyArray(self.subpages);
var edit = wk.makeElement('textarea', {rows:10, cols:50});
edit.value = text;
self.formspan.innerHTML = "";
self.formspan.appendChild(document.createTextNode('Enter subpages, one per line'));
self.formspan.appendChild(edit);
self.formspan.appendChild(wk.makeButton('', 'Save', function() {
self.subpages.length = 0;
var pages = edit.value.split("\n");
for(var i = 0; i < pages.length; i++) {
if(pages[i].match(/^\s*$/)) continue;
var stat = vbd.FindPageNameInArray(old, pages[i]);
if(stat != -1) self.addSubpage(old[stat]);
else self.addSubpage(new BookPage(vbd.forceFirstCaps(pages[i])));
}
self.formspan.innerHTML = "";
vbd.visual();
}));
self.closeButton();
edit.focus();
}
return(link);
}
//display the title of the page
BookPage.prototype.getTitleNode = function () {
var self = this;
var container = wk.makeElement('span');
var collapse = wk.makeElement('small', null,
((this.collapse == 0)?('[-] '):('[+] ')));
collapse.style.cursor = "pointer";
collapse.onclick = function () {
self.collapse = (self.collapse == 1)?(0):(1);
vbd.visual();
}
var span = wk.makeElement('big', {style:"font-weight: bold;"}, this.pagename);
span.style.cursor = "pointer";
span.onclick = function() {
var edit = wk.makeElement('input', {type:'text', value:(self.pagename), size:50});
self.formspan.innerHTML = "";
wk.appendChildren(self.formspan, ['Enter the new name: ', edit, wk.makeButton('', 'Rename', function() {
self.formspan.innerHTML = "Renaming...";
var pagename = vbd.forceCaps(edit.value, self.isRoot());
if(self.isRoot()) wk.loadWikiText(pagename, function (text) {
if(text.length != 0) self.formspan.innerHTML = "<b>Warning:</b> " + pagename + " already exists. Check it before saving over it.";
else self.formspan.innerHTML = "";
});
else self.formspan.innerHTML = "";
self.pagename = pagename.replace("\n", "");
vbd.visual();
})]);
if(!self.isRoot()) self.formspan.appendChild(wk.makeButton('', 'Delete', function () {
if(confirm("delete page '" + self.pagename + "'?")) {
if(self.parent2 == null) self.parent.removeSubpage(self);
else self.parent2.removeSubpage(self);
vbd.visual();
}
}));
self.closeButton();
}
if(this.subpages.length != 0 || this.headings.length != 0) container.appendChild(collapse);
container.appendChild(span);
return(container);
}
//functions for dealing with recursion
BookPage.prototype.isRoot = function () {
return (this.parent == null)?(1):(0);
}
BookPage.prototype.getFullName = function() {
if(this.isRoot()) return this.pagename;
return this.parent.getFullName() + "/" + this.pagename;
}
BookPage.prototype.getDepth = function() {
if(this.isRoot()) return 0;
return this.parent.getDepth() + 1;
}
BookPage.prototype.getBookName = function () {
if(this.isRoot()) return this.pagename;
return this.parent.getBookName();
}
//make wikitext of a page, using nested asterisks, as required
BookPage.prototype.makeWikitextLinkStars = function (parent) {
var depth = this.getDepth() - ((parent != null)?(parent.getDepth()):(0));
var stars = "";
for(var i = 0; i < depth; i++) {
stars = stars + "*";
}
var text = stars + "[[" + this.getFullName() + "|" + this.pagename + "]]\n";
text = text.replace(/\n/g, "") + "\n";
for(var i = 0; i < this.subpages.length; i++) {
text += this.subpages[i].makeWikitextLinkStars(parent);
}
for(var i = 0; i < this.headings.length; i++) {
text += this.headings[i].makeWikitextLinkStars(parent);
}
return text;
}
//make links for a subpage, as formattined for a template
BookPage.prototype.makeTemplateLinks = function () {
var text = "[[" + this.getFullName() + "|" + this.pagename + "]] - ";
for(var i = 0; i < this.subpages.length; i++) {
text += this.subpages[i].makeTemplateLinks() + " - ";
}
for(var i = 0; i < this.headings.length; i++) {
text += this.headings[i].makeTemplateLinks();
}
return text;
}
//make a link for a page without nested asterisks
BookPage.prototype.makeWikitextLink = function () {
return "*[[" + this.getFullName() + "|" + this.pagename + "]]";
}
BookPage.prototype.getPageText = function() {
if(!this.inherittext || this.isRoot()) return this.pagetext;
return this.parent.getPageText() + "\n" + this.pagetext;
}
//make the wikitext of an entire page
BookPage.prototype.makeWikitextPage = function () {
var text = "{{" + this.getBookName() + "/Page}}\n\n";
for(var i = 0; i < this.subpages.length; i++) {
text = text + this.subpages[i].makeWikitextLinkStars(this);
}
text += this.getPageText() + "\n";
for(var i = 0; i < this.headings.length; i++) {
text = text + this.headings[i].makeWikitext(this) + "\n";
}
text = text + "[[Category:" + this.getBookName() + "]]\n";
return text;
}
//make the wikitext for the special root page
BookPage.prototype.makeWikitextRoot = function () {
var text = "{{New book}}\n{{" + this.pagename + "/Page}}\n" +
"{{Reading level|" + vbd.readingLevels[vbd.readingLevel] + "}}\n\n";
text += "== Preface ==\n" + this.pagetext + "\n";
text += "== Table of Contents ==\n\n";
if(vbd.useintroduction) text += "*[[" + this.pagename + "/Introduction|Introduction]]\n";
for(var i = 0; i < this.subpages.length; i++) {
text += this.subpages[i].makeWikitextLinkStars();
}
text += "\n";
for(var i = 0; i < this.headings.length; i++) {
text += this.headings[i].makeWikitext() + "\n";
}
text += "\n== Resources and Licensing ==\n\n";
if(vbd.useresources) text += "*[[" + this.pagename + "/Resources|Resources]]\n";
if(vbd.uselicensing) text += "*[[" + this.pagename + "/Licensing|Licensing]]\n";
text += "\n[[Category:" + this.getBookName() + "]]\n";
text += "{{Subject";
for(var i = 0; i < vbd.subjects.length; i++) {
text += "|" + vbd.subjects[i];
}
text += "}}\n{{Alphabetical|" + this.pagename.substr(0, 1) + "}}\n";
return text;
}
//make the print version text of the root page
BookPage.prototype.makePrintVersionRoot = function() {
var text = "{{Print version notice}}\n" +
"__NOTOC__ __NOEDITSECTION__\n" +
"<br style=\"page-break-after: always\">\n" +
"{{:" + this.getBookName() + "/Cover}}\n" +
"<br style=\"page-break-after: always\">\n\n";
if(vbd.useintroduction) text += "{{Print chapter heading|Introduction}}\n";
for(var x = 0; x < this.subpages.length; x++) {
text += this.subpages[x].makePrintVersionText();
}
for(var x = 0; x < this.headings.length; x++) {
text += this.headings[x].makePrintVersionText();
}
text = text + "{{Print unit page|Resources and Licensing}}\n\n";
if(vbd.useresources) text += "{{Print chapter heading|Resources}}\n"
if(vbd.uselicensing) text += "{{Print chapter heading|Licensing}}\n";
text += "\n== License: GFDL ==\n\n{{:GFDL}}\n\n";
return text;
}
//make the print version text of a subpage
BookPage.prototype.makePrintVersionText = function () {
return "{{Print chapter heading|" + this.pagename + "}}\n" +
"{{:" + this.getFullName() + "}}\n\n";
}
//make the wikitext for any page
BookPage.prototype.makeWikitextAll = function() {
if(this.isRoot()) return this.makeWikitextRoot();
return this.makeWikitextPage();
}
//make a link to view the wikitext of the current page
BookPage.prototype.makeDisplayLink = function () {
var link = wk.makeElement('a', null, ['Wikitext']);
var self = this;
link.onclick = function() {
self.formspan.innerHTML = "<pre>" + self.makeWikitextAll() + "</pre>";
self.closeButton();
}
return(link);
}
//make the collection text of a page
BookPage.prototype.makeCollectionText = function (subt) {
var text = "";
if(this.isRoot()) {
if(subt == null || subt == "") subt = "A Book from English Wikibooks";
text = "== " + this.pagename + " ==\n=== " + subt + " ===\n";
if(vbd.usecollectionpreface) text += ":[[Wikibooks:Collections Preface]]\n";
if(vbd.useintroduction) text += ":[[" + this.pagename + "/Introduction|Introduction]]\n";
}
else text = ":[[" + this.getFullName() + "|" + this.pagename + "]]\n";
for(var i = 0; i < this.subpages.length; i++) {
text = text + this.subpages[i].makeCollectionText();
}
for(var i = 0; i < this.headings.length; i++) {
text = text + this.headings[i].makeCollectionText();
}
if(this.isRoot()) {
text += "\n;Resources and Licensing\n";
if(vbd.useresources) text += ":[[" + this.pagename + "/Resources|Resources]]\n";
if(vbd.uselicensing) text += ":[[" + this.pagename + "/Licensing|Licensing]]\n";
text += "\n[[Category:Collections]]\n";
}
return text;
}
//make a button to close an open formspan
BookPage.prototype.closeButton = function () {
var self = this;
this.formspan.appendChild(wk.makeButton('', 'Close', function() {
self.formspan.innerHTML = "";
}));
}
//add all subpages of the current page to list
BookPage.prototype.listAllSubpages = function(list) {
if(this.subpages.length) {
for(var i = this.subpages.length - 1; i >= 0; i--) {
list = this.subpages[i].listAllSubpages(list);
list.push(this.subpages[i]);
}
}
if(this.headings.length) {
for(var i = this.headings.length - 1; i >= 0; i--) {
list = this.headings[i].listAllSubpages(list);
}
}
return list;
}
//a link to create the book using AJAXy magic
BookPage.prototype.makeAutomateLink = function () {
var automate = wk.makeElement('a', null, ['Create']);
var self = this;
automate.onclick = function() {
if(!wk.testUserPermissions("administrator")) {
self.formspan.innerHTML = "<b>ERROR:</b> You must be an administrator to use this feature.";
return;
}
wk.loadWikiText(self.pagename, function (text) {
if(text.length != 0) self.formspan.innerHTML = "<b>ERROR:</b> The page " + self.pagename + " already exists. "
+ "This function cannot be used to overwrite existing pages.";
else {
var list = self.listAllSubpages(new Array());
if(vbd.useintroduction) list.push(self.makeSpecialPageNode("Introduction"));
if(vbd.useresources) list.push(self.makeSpecialPageNode("Resources"));
if(vbd.uselicensing) list.push(self.makeSpecialPageNode("Licensing"));
if(confirm("WARNING: This operation will automatically create " + (list.length + 1) + " pages. " +
"You are responsible for any edits made by this tool, and any pages that it creates. " +
"Do you want to continue?")) self.automaticCreation(list);
}
});
}
return automate;
}
//create a page using AJAXy magic
BookPage.prototype.automaticCreation = function(list) {
if(this.formspan) this.makeLoadingNotice("Creating");
else wk.appendChildren(this.parent.formspan, [wk.makeElement('br'), "Creating " + this.pagename + "..."]);
var text = this.makeWikitextAll();
var self = this;
wk.postEdit(this.getFullName(), text, "Automatic page creation", {callback: function() {
if(self.formspan) {
self.formspan.innerHTML = "<big>Done.</big> — ";
self.formspan.appendChild(wk.wikiLink(self.getFullName(), "View"));
} else {
wk.appendChildren(vbd.pageTree.formspan, ["Done. - ", wk.wikiLink(self.getFullName(), "View")]);
}
if(list.length) {
var next = list.pop();
next.automaticCreation(list);
}
}});
}
//make a link to edit the text of the page
BookPage.prototype.makeEditLink = function () {
var link = wk.makeElement('a', null, ['Edit']);
var self = this;
link.onclick = function() {
self.makeEditInterface(self.getFullName(), self.makeWikitextAll(), self.pagename + ": Created by Whiteknight's Visual Book Designer");
}
return(link);
}
//prepare the text to save a subpage from the outline.
// XXX: Eventually, should probably save the structures directly in JSON for easy loading.
BookPage.prototype.makeSaveText = function () {
var depth = this.getDepth();
var stars = "";
for(var i = 0; i < depth; i++) {
stars = stars + "*";
}
var text = stars + this.pagename + "\n";
if(this.pagetext.length != 0) {
var pagetext = this.pagetext;
pagetext.replace(/\n/g, "\n&");
text += "&" + this.pagetext + "\n";
}
if(this.comments.length != 0) {
var comments = this.comments;
comments.replace(/\n/g, "\n%");
text += "%" + this.comments + "\n";
}
for(var i = 0; i < this.subpages.length; i++)
{
text += this.subpages[i].makeSaveText();
}
for(var i = 0; i < this.headings.length; i++) {
text += this.headings[i].makeSaveText();
}
return text;
}
//make a link to save the outline
BookPage.prototype.makeSaveLink = function () {
var link = wk.makeElement('a', null, ['Save']);
var self = this;
link.onclick = function() {
var page = "User:" + mw.config.get('wgUserName') + "/" + self.pagename;
var edit = wk.makeElement('input', {type:'text', value:page, size:50});
self.formspan.innerHTML = 'Enter the page name to save at: ';
self.formspan.appendChild(edit);
self.formspan.appendChild(wk.makeButton('', 'Save', function() {
self.makeEditInterface(edit.value, function(t) {
return vbd.killOldSaves(t) + "{{User:Whiteknight/SavedOutlineStart|" + wk.getDate() + "}}\n\n" +
self.makeSaveText() + "\n\n{{User:Whiteknight/SavedOutlineEnd}}\n";
}, self.pagename + ": Saving Visual Book Designer Outline");
}));
self.closeButton();
edit.focus();
}
return(link);
}
//make a link to load a saved outline
BookPage.prototype.makeLoadLink = function () {
var link = wk.makeElement('a', null, ['Load']);
var self = this;
link.onclick = function() {
var page = "User:" + mw.config.get('wgUserName') + "/" + self.pagename;
var edit = wk.makeElement('input', {type:'text', value:page, size:50});
wk.appendChildren(self.formspan, ['Enter the page name to load from: ', edit, wk.makeButton('', 'Load', function() {
page = edit.value;
self.makeLoadingNotice("Loading");
wk.loadWikiText(page, function (text) {
var start = text.indexOf('{{User:Whiteknight/SavedOutlineStart}}');
var end = text.indexOf('{{User:Whiteknight/SavedOutlineEnd}}');
if(start == -1 || end == -1) {
self.formspan.innerHTML = "";
self.formspan.appendChild(wk.makeElement('font', {color:'#FF0000'}, [
'Cannot load outline from ' + page
]));
self.closeButton();
} else vbd.loadNodeTree(text.substring(start + 38, end));
});
})]);
self.closeButton();
edit.focus();
}
return(link);
}
//make a link to load the TOC from an existing book
BookPage.prototype.makeLoadTOCLink = function () {
var link = wk.makeElement('a', null, ['Load TOC']);
var self = this;
link.onclick = function() {
var page = self.pagename;
var edit = wk.makeElement('input', {type:'text', value:page, size:50});
self.formspan.innerHTML = 'Enter the name of the book to load: ';
self.formspan.appendChild(edit);
self.formspan.appendChild(wk.makeButton('', 'Load', function() {
page = edit.value;
wk.loadWikiText(page, function (text) {
vbd.loadNodeTreeTOC(text, page);
});
}));
self.closeButton();
edit.focus();
}
return(link);
}
BookPage.prototype.makeSaveCollectionLink = function (key) {
var link = wk.makeElement('a', null, ['Save']);
var self = this;
link.onclick = function() {
var page = "";
if(key == "personal") page = "User:" + mw.config.get('wgUserName') + "/Collections/" + self.pagename;
else page = "Wikibooks:Collections/" + self.pagename;
var subt = wk.makeElement('input', {type:'text', size:50});
var edit = wk.makeElement('input', {type:'text', value:page, size:50});
self.formspan.innerHTML = "";
wk.appendChildren(self.formspan, ["Enter a subtitle for the book: ", subt,
wk.makeElement('br'),
'Enter the ' + key + ' collection name to save at: ', edit]);
self.formspan.appendChild(wk.makeButton('', 'Save', function() {
self.makeEditInterface(edit.value, self.makeCollectionText(subt.value), ": Saving " + key + " collection");
}));
self.closeButton();
edit.focus();
}
return(link);
}
BookPage.prototype.makeLoadCollectionLink = function (type) {
var link = wk.makeElement('a', null, ['Load']);
var self = this;
link.onclick = function() {
var page = "";
if(type == 'personal') page = "User:" + mw.config.get('wgUserName') + "/Collections/";
else page = "Wikibooks:Collections/";
var edit = wk.makeElement('input', {type:'text', size:50});
self.formspan.innerHTML = "";
wk.appendChildren(self.formspan, ["Enter the name of the " + type + " collection to load: ", edit,
wk.makeButton('', 'Load', function () {
wk.loadWikiText(page + edit.value, function (text) {
vbd.loadNodeTreeCollection(text, page);
});
})
]);
}
return link;
}
//make the text for a heading template
BookPage.prototype.makeTemplate = function () {
var self = this;
self.makeEditInterface("Template:" + this.pagename + "/Page", vbd.makeTemplateText(), self.pagename + ": Creating page head template");
}
BookPage.prototype.makeFileLink = function() {
var self = this;
var disp = wk.makeElement('a', null, ['View']);
disp.onclick = function () {
self.formspan.innerHTML = "<b>Warning:</b> Print versions are deprecated. Please use <b>Collections</b> instead.<br>" +
"<pre>" + self.makePrintVersionRoot().replace(/</g, "<") + "</pre>";
self.closeButton();
}
var saveprint = wk.makeElement('a', null, ['Save']);
saveprint.onclick = function() {
self.makeEditInterface(self.getFullName() + "/Print Version", self.makePrintVersionRoot(),
self.pagename + ": Print version created by Whiteknight's Visual Book Designer");
}
var link = wk.makeElement('a', null, ['File']);
var self = this;
link.onclick = function () {
self.formspan.innerHTML = "";
//vbd.createDropMenu(self.formspan, [
wk.appendChildren(self.formspan, [
"Select whether you want to load or save this outline:", wk.makeElement('br'),
'Saved Outlines: ', self.makeSaveLink(), ' - ', self.makeLoadLink(), wk.makeElement('br'),
'Personal Collection: ', self.makeSaveCollectionLink('personal'), ' - ', self.makeLoadCollectionLink('personal'), wk.makeElement('br'),
'Public Collection: ', self.makeSaveCollectionLink('community'), ' - ', self.makeLoadCollectionLink('community'), wk.makeElement('br'),
'Existing Books: ', self.makeLoadTOCLink(), ' - ', self.makeAutomateLink(), wk.makeElement('br'),
'Print versions: ', disp, ' - ', saveprint, wk.makeElement('br'),
]);
self.closeButton();
}
return link;
}
//make additional links for the main page
BookPage.prototype.makeRootMenu = function() {
if(!this.isRoot()) { return document.createTextNode(' - '); }
var box = wk.makeElement('span', null, [" - "]);
var nav = wk.makeElement('a', null, ['Templates']);
var self = this;
nav.onclick = function () {
self.formspan.innerHTML = '';
var temps = wk.makeElement('select', {size:"1"});
for(var i = 0; i < vbd.templates.length; i++) {
temps.appendChild(wk.makeElement("option", {value:i}, vbd.templates[i][3]));
}
temps.onchange = function () { vbd.template = temps.selectedIndex; }
temps.selectedIndex = vbd.template;
var select = wk.makeElement('select', {size:"1"});
for(var i = 0; i < vbd.readingLevels.length; i++) {
select.appendChild(wk.makeElement("option", {value:i}, vbd.readingLevels[i]));
}
select.selectedIndex = vbd.readingLevel;
select.onchange = function () { vbd.readingLevel = select.selectedIndex; }
wk.appendChildren(self.formspan, [wk.makeElement('br'),
"Select a page navigation template (",
wk.wikiLink("User:Whiteknight/Book_Foundry#Header_Templates", "Help"), "): ",
temps, wk.makeButton('WKVBDMakeTemplate', 'Make Template', function () { self.makeTemplate() }), wk.makeElement('br'),
"Select the book ", wk.wikiLink("Wikibooks:Reading Levels", "reading level"), ": ", select]);
if(typeof cg == 'object') {
var topics = cg.makeSubjectSelect(10, true);
cg.setSelected(vbd.subjects);
topics.onchange = function () {
vbd.subjects.length = 0;
vbd.subjects = cg.returnAllSelected();
}
wk.appendChildren(self.formspan, [wk.makeElement('br'), 'Select major subjects for your book. ',
'Hold ctrl to select multiple entries.', wk.makeElement('br'), topics, wk.makeElement('br')]);
}
self.closeButton();
}
var options = wk.makeElement('a', null, ['Options']);
options.onclick = function () {
self.formspan.innerHTML = "";
wk.appendChildren(self.formspan, [
vbd.makeOptionsCheckbox("defaultinherit"), "inherit page text by default", wk.makeElement('br'),
vbd.makeOptionsCheckbox("defaultcollapse"), "collapse nodes by default", wk.makeElement('br'),
vbd.makeOptionsCheckbox("useresources"), "add a resources page by default", wk.makeElement('br'),
vbd.makeOptionsCheckbox("uselicensing"), "add a licensing page by default", wk.makeElement('br'),
vbd.makeOptionsCheckbox("useintroduction"), "add an introduction page by default", wk.makeElement('br'),
vbd.makeOptionsCheckbox("usecollectionpreface"), "add [[Wikibooks:Collections Preface]] to Collections by default", wk.makeElement('br'),
vbd.makeOptionsCheckbox("commentsaspages"), "use page comments to create talk pages", wk.makeElement('br'),
vbd.makeOptionsCheckbox("useexternaledit"), "make edits in an external tab or window", wk.makeElement('br')
]);
self.closeButton();
}
var clear = wk.makeElement('a', null, ['Clear']);
clear.onclick = function () {
if(!confirm('Clear this outline? You will lose any unsaved work.')) return;
vbd.clear();
self.formspan.innerHTML = "outline cleared";
vbd.visual();
}
wk.appendChildren(box, [
nav, ' - ',
this.makeFileLink(), ' - ',
options, ' - ',
clear, ' - ',
wk.makeElement('small', null, [" (Version " + vbd.version + ")"]),
wk.makeElement('br')
]);
return box;
}
//make a subpage node in the outline
BookPage.prototype.makeNode = function() {
this.box = wk.makeElement('div', null, [
this.getTitleNode(),
this.makeRootMenu(),
wk.makeElement('small', null, [
this.makeHeadingsLink(), this.makeHeadingsAddLink(), " - ",
this.makeSubpagesLink(), this.makeSubpagesAddLink(), " - ",
this.makeDisplayLink(), " - ",
this.makeEditLink()
])
]);
this.box.style.position = "relative";
this.box.appendChild(wk.makeElement('br'));
this.box.appendChild(this.getTextNode());
this.box.appendChild(this.formspan);
this.box.style.padding = "5px";
this.box.style.marginBottom = "1em";
var container = wk.makeElement('div');
container.style.marginLeft = "2em";
if(this.collapse == 0) {
for(var i = 0; i < this.subpages.length; i++) {
if(this.subpages[i] == null) continue;
var node = this.subpages[i].makeNode();
container.appendChild(node);
}
for(var i = 0; i < this.headings.length; i++) {
container.appendChild(this.headings[i].makeNode());
container.appendChild(wk.makeElement('br'));
}
}
container.style.borderLeft = "1px dashed #000000";
container.style.borderBottom = "1px dashed #000000";
this.box.appendChild(container);
var self = this;
//
return(this.box);
}
function PageHeading(name) {
if(name.match(/\s$/)) name = name.substring(0, name.length - 1);
this.label = name;
this.subpages = new Array();
this.text = "";
this.formspan = wk.makeElement('div');
this.parent = null;
this.pagetext = "";
this.comments = "";
this.collapse = 0;
this.box = null;
}
PageHeading.prototype.getTextNode = function () {
var self = this;
var div = wk.makeElement('small', {style: "padding-left: 2em;"},
((this.pagetext.length == 0)?('[click here to edit heading text]'):(this.pagetext)));
div.onclick = function() {
var edit = wk.makeElement('textarea', {rows:10});
edit.value = self.pagetext;
self.formspan.innerHTML = "";
self.formspan.appendChild(document.createTextNode('Enter some text for the page:'));
self.formspan.appendChild(edit);
self.formspan.appendChild(wk.makeButton('', 'Save', function() {
self.pagetext = edit.value;
if(self.pagetext.match(/^\s*$/)) self.pagetext = "";
self.formspan.innerHTML = "";
vbd.visual();
}));
self.closeButton();
edit.focus();
}
div.style.cursor = "pointer";
return div;
}
//make a link to modify the list of subpages
PageHeading.prototype.makeSubpagesLinks = function () {
var link = wk.makeElement('a', null, ['Subpages']);
var self = this;
link.onclick = function() {
var text = "";
for(var i = 0; i < self.subpages.length; i++) {
text = text + self.subpages[i].pagename + "\n";
}
var old = vbd.CopyArray(self.subpages);
var edit = wk.makeElement('textarea', {rows:10, cols:50});
edit.value = text;
self.formspan.innerHTML = "";
self.formspan.appendChild(document.createTextNode(
'Enter the names of all subpages, one per line'));
self.formspan.appendChild(edit);
self.formspan.appendChild(wk.makeButton('', 'Save', function() {
self.subpages.length = 0;
var pages = edit.value.split("\n");
for(var i = 0; i < pages.length; i++) {
if(pages[i].match(/^\s*$/)) continue;
var stat = vbd.FindPageNameInArray(old, pages[i]);
if(stat != -1) self.addSubpage(old[stat]);
else self.addSubpage(new BookPage(vbd.forceFirstCaps(pages[i])));
}
self.formspan.innerHTML = "";
vbd.visual();
}));
self.closeButton();
edit.focus();
}
var add = wk.makeElement('a', null, [' [ + ]']);
add.onclick = function() {
self.addSubpage(new BookPage(vbd.defpagename + " " + vbd.newpagecnt));
vbd.newpagecnt++;
vbd.visual();
}
return [link, add];
}
//the name of the heading
PageHeading.prototype.getTitleNode = function () {
var container = wk.makeElement('span');
var collapse = wk.makeElement('small', null,
((this.collapse == 0)?('[-] '):('[+] ')));
var span = wk.makeElement('big', null, this.label);
span.style.cursor = "pointer";
var self = this;
collapse.onclick = function () {
self.collapse = (self.collapse == 1)?(0):(1);
vbd.visual();
}
span.onclick = function() {
var edit = wk.makeElement('input', {type:'text', value:(self.label), size:50});
self.formspan.innerHTML = "";
self.formspan.appendChild(document.createTextNode('Enter the new name: '));
self.formspan.appendChild(edit);
self.formspan.appendChild(wk.makeButton('', 'Rename', function() {
self.formspan.innerHTML = "Renaming...";
var pagename = vbd.forceFirstCaps(edit.value);
self.label = pagename.replace("\n", "");
self.formspan.innerHTML = "";
vbd.visual();
}));
self.formspan.appendChild(wk.makeButton('', 'Delete', function () {
if(confirm("delete heading '" + self.label + "'?")) {
self.parent.removeHeading(self);
vbd.visual();
}
}));
self.closeButton();
edit.focus();
}
if(this.subpages.length != 0) container.appendChild(collapse);
container.appendChild(span);
return(container);
}
//get the depth of the page the heading is on
PageHeading.prototype.getDepth = function () {
return this.parent.getDepth();
}
//make wikitext of pages under a heading, but not of the heading itself
PageHeading.prototype.makeWikitextLinkStars = function (parent) {
var text = "";
for(var i = 0; i < this.subpages.length; i++) {
text = text + this.subpages[i].makeWikitextLinkStars(parent);
}
return text;
}
//make the links for the pages under a heading, as formatted for a template
PageHeading.prototype.makeTemplateLinks = function () {
var text = "";
for(var i = 0; i < this.subpages.length; i++) {
text = text + this.subpages[i].makeTemplateLinks();
}
return text;
}
//create a list of all subpages of the given heading and append them to list
PageHeading.prototype.listAllSubpages = function(list) {
if(this.subpages.length) {
for(var i = this.subpages.length - 1; i >= 0; i--) {
list = this.subpages[i].listAllSubpages(list);
list.push(this.subpages[i]);
}
}
return list;
}
//make the wikitext for a heading
PageHeading.prototype.makeWikitext = function () {
var text = "";
if(this.parent.isRoot()) text = "=== " + this.label + " ===\n\n";
else text = "== " + this.label + " ==\n\n";
text += this.pagetext + "\n";
for(var i = 0; i < this.subpages.length; i++) {
text = text + this.subpages[i].makeWikitextLinkStars(this);
}
return text;
}
//create the print version text for this heading
PageHeading.prototype.makePrintVersionText = function () {
var text = "{{Print unit page|" + this.label + "|" + this.pagetext + "}}\n\n";
for(var x = 0; x < this.subpages.length; x++) {
text = text + this.subpages[x].makePrintVersionText();
}
return text;
}
//make the collection text for this heading
PageHeading.prototype.makeCollectionText = function () {
var text = ";" + this.label + "\n";
for(var i = 0; i < this.subpages.length; i++) {
text = text + this.subpages[i].makeCollectionText();
}
return text;
}
//create a close button
PageHeading.prototype.closeButton = function () {
var self = this;
this.formspan.appendChild(wk.makeButton('', 'Close', function() {
self.formspan.innerHTML = "";
}));
}
//prepare the text to save a heading from the outline
PageHeading.prototype.makeSaveText = function () {
var depth = this.getDepth();
var text = "";
for(var i = 0; i < depth; i++) {
text += "=";
}
text += "=" + this.label + "\n";
if(this.pagetext.length != 0) {
var pagetext = this.pagetext;
pagetext.replace(/\n/g, "\n&");
text += "&" + pagetext + "\n";
}
if(this.comments.length != 0) {
var comments = this.comments;
comments.replace(/\n/g, "\n%");
text += "%" + comments + "\n";
}
for(var i = 0; i < this.subpages.length; i++) {
text += this.subpages[i].makeSaveText();
}
return text;
}
//make a heading node in the outline
PageHeading.prototype.makeNode = function () {
this.box = wk.makeElement('div', null, [
this.getTitleNode(), " - ",
wk.makeElement('small', null, this.makeSubpagesLinks()),
wk.makeElement('br'),
this.getTextNode(),
this.formspan
]);
this.box.style.position = "relative";
this.box.style.padding = "5px";
var container = wk.makeElement('div');
container.style.marginLeft = "2em";
if(this.collapse == 0) {
for(var i = 0; i < this.subpages.length; i++) {
if(this.subpages[i] == null) continue;
var node = this.subpages[i].makeNode();
container.appendChild(node);
}
}
container.style.borderBottom = "1px dashed #AAAAAA";
container.style.borderLeft = "1px dashed #AAAAAA";
this.box.appendChild(container);
var self = this;
//
return this.box;
}
//add a subpage to this heading
PageHeading.prototype.addSubpage = function (subpage) {
subpage.parent = this.parent;
subpage.parent2 = this;
this.subpages.push(subpage);
}
//add a new heading to the parent of this (headings cannot contain headings)
PageHeading.prototype.addHeading = function (heading) {
heading.parent = this.parent;
this.parent.headings.push(heading);
}
//remove a subpage from this heading
PageHeading.prototype.removeSubpage = function(subpage) {
for(var i = 0; i < this.subpages.length; i++) {
if(this.subpages[i] != subpage) continue;
this.subpages.splice(i, 1);
return;
}
}
// </source>