మీడియావికీ:BookMaker.js
గమనిక: భద్రపరచిన తర్వాత, మార్పులను చూడాలంటే మీ విహారిణి కోశాన్ని తీసేయాల్సిరావచ్చు.
- ఫైర్ఫాక్స్ / సఫారి: Shift మీటని నొక్కిపట్టి Reloadని నొక్కండి లేదా Ctrl-F5 గానీ Ctrl-R (మాకింటోషులో ⌘-Shift-R) గానీ నొక్కండి
- గూగుల్ క్రోమ్: Ctrl-Shift-R (మాక్ లో ⌘-Shift-R) నొక్కండి
- ఇంటర్నెట్ ఎక్ప్లోరర్/ఎడ్జి: Ctrl ను నొక్కిపట్టి Refresh నొక్కండి లేదా Ctrl-F5 నొక్కండి.
- ఒపేరా:* Ctrl-F5 నొక్కండి.
/***********************************************************************
* bookMaker.js
*
* A tool to create page lists for use in creating books for export
* The book lists are compatible with PediaPress and WSexport and are
* designed to be more flexible and suitable for the Wikisource content
* than the PediaPress extension.
*
* This script is loaded by [[MediaWiki:Gadget-BookMakerLoader.js]]
* on demand to reduce network load if the tool isn't used
*
*
* Maintainer: Inductiveload
*
* V 0.1 2012-04-20 - Initial release
* 2012-06-07 - Fixed various bugs, add "use title as name"
* button. Add a delay to the name-existance code to
* prevent excessive queries.
* 2012-06-09 - Many small tweaks, now stores and loads pending
* pages too, add add page from input
* 2012-06-17 - More tweaks, fix formatting issues (use tables)
* Add QR code, break out some interface messages,
* Use strict enabled.
* 2012-10-29 - Update url of EPUB to labs (from TS) in 2 places
*
**********************************************************************/
(function () {
"use strict";
window.BookMaker.prototype.initialise = function () {
this.bookdata = {};
this.initialised = true;
this.bookTemplateName = 'saved book 2';
this.helpLocation = 'Help:Gadget-BookMaker';
this.localstorage_minimised_name = 'wikisource_bookmakerminimised';
this.central_bookstore = 'Wikisource:Books/';
this.user_bookstore = 'User:' + mw.config.get('wgUserName') + '/Books/';
this.qrGenerator = 'http://toolserver.org/~inductiveload/wmf-qrcode/wmfqr.php';
this.imgs = {
'x_red': '//upload.wikimedia.org/wikipedia/commons/e/e9/Silk_cross.png',
'tag_off': '//upload.wikimedia.org/wikipedia/commons/8/8c/Tag_grey.png',
'tag_on': '//upload.wikimedia.org/wikipedia/commons/d/dd/Tag_red.png',
'go_to_page': '//upload.wikimedia.org/wikipedia/commons/9/92/Book_next.png',
'editBook': '//upload.wikimedia.org/wikipedia/commons/6/69/Book_edit.png'
};
this.exportURLs = {'EPUB with images': '//tools.wmflabs.org/wsexport/tool/book.php?lang=en&page=$1&format=epub'.replace('$1', mw.config.get('wgPageName')),
'EPUB without images': '//tools.wmflabs.org/wsexport/tool/book.php?images=false&lang=en&page=$1&format=epub'.replace('$1', mw.config.get('wgPageName')),
'This page': window.location
};
//messages
this.msg = {
'yourShelf': 'Your bookshelf',
'startBookMaker': 'Edit with BookMaker',
'creation_summary': 'Creating book with the Book Maker tool.',
'addPages': 'Add pages',
'closeWarning': 'If you close the Book Maker, you will lose any unsaved data.',
'areYouSure': 'Are you sure?',
'closePortlet': 'Close book creator',
'closeButton': 'Close',
'minimise': 'Minimise',
'maximise': 'Maximise',
'help': 'Help',
'save': 'Save book',
'saveHint': 'Save this book to the title selected above.',
'enterBookLocation': 'Enter the location of the book you want to load',
'getQRCodes': 'Scan the relevant QR code below with your mobile device to get a direct link to the book',
'qrCodeTitle': 'QR codes',
'chooseLocation': 'Choose the location to save your book',
'bookPagePrefix': 'Book page prefix',
'useThisPagesTitle': "Use this page's title",
'clearAll': 'Clear all',
'pendingTitle': 'Pending pages',
'existingTitle': 'Pages in book',
'getThisPage': 'This page',
'getThisPageLinks': 'From links on this page',
'getThisPageSubpages': 'From subpages of this page',
'getSavedVersion': 'From saved version of this book',
'getSavedOther': 'From a saved book',
'getOtherPage': 'Another page',
'getCategory': 'From a category',
'manualMetadata': 'Manual metadata',
'useThisPagesMetadata': "Use this page's metadata",
'metadataTitle': 'Title',
'metadataAuthor': 'Author',
'metadataTranslator': 'Translator',
'metadataDate': 'Date',
'replaceAppend': 'Replace or append to the current pending pages in BookMaker?',
'replaceAppendTitle': 'Replace or append?',
'enterCategory': 'Enter the category you want to add page from',
'noCategoryPagesFound': 'No members of that category found, please check your spelling and try again',
'category': 'Category',
'noPageFound': 'No page found, please check your spelling and try again',
'enterPage': 'Enter the location of the page you want to add',
'loadPageTitle': 'Load an existing page',
'bookNotLoaded': 'The book at $1 could not be loaded',
'bookNotLoadedTitle': 'Book not loaded',
'missingMetadata': 'There is missing metadata (such as title and author) attached to this book. You can add metadata by clicking a "tag" icon on a page to use that page as a source, or by filling it in manually. Continue, or cancel and add some?',
'emptyBook': 'There are no pages in the book. Please add some before trying to save',
'emptyBookTitle': 'Book is empty!'
};
this.add_styles_to_page();
};
window.BookMaker.prototype.add_styles_to_page = function () {
$('<style type="text/css" />').appendTo('head')
.append('\
.ui-dialog {position: fixed;}\
#bookmaker { position:relative; background-color:#E0E9EA; border:1px solid #294584; padding:2em; margin-bottom:1em; }\
book_editor {clear:both;}\
#book_nameselection td {vertical-align:top; padding-right:1em;}\
#book_input_bookname {width:100%}\
#book_displaycontrols { position:absolute; right:5px; top:5px; }\
#book_pagelist { margin:auto; height:100%; clear:both;}\
#book_pagemanip {width:6em; float:left; margin-top:2em; text-align:center}\
.book_inputpagemanip { width:4em;}\
#book_pagelist_table {width:100%;}\
.book_pagelist_container {width:50%; vertical-align:top;}\
.book_pagelist { list-style:none; background-color:white; border:1px solid #444444; margin-left:0; width:100%; min-height:5em; max-height:40em; overflow-y:scroll;}\
.book_pagelist_title {font-weight:bold;}\
.book_pagelist_title > .book_clearall {float:right; color:red; cursor:pointer;}\
.book_displaycontrol { float:right; cursor:pointer; margin-right:10px; top:5px}\
#book_metadatafields {text-align:right; float:left;}\
.book_manualmetadata {width:25em}\
#book_commitcontrols {clear:both;}\
.book_pageitem {list-style-type:none; cursor:pointer;}\
.book_pageitem.book_mainitemsel {font-weight:bold;}\
.pageitem_sel { background-color:#DDDDDD;}\
.pageitem_sel_delete { background-color:#FF86A2;}\
#book_pagelistexist .book_tagmainitem { display:auto;}\
#book_pagelistpending .book_tagmainitem { display:none;}\
.book_updated {border:1px solid #00FF00 !important;}\
.book_pageitemtitle {padding-left:0.5em; }\
.qr_code_container {overflow-y:scroll !important; max-height:400px;}\
');
};
window.BookMaker.prototype.close_bookmaker = function () {
//Close the bookmaker and remove all data
var myself = this;
var dialog = $('<div>')
.html(myself.msg.closeWarning)
.dialog({
title: myself.msg.areYouSure,
modal: true,
buttons: {
"Cancel": function () {
$(this).dialog("close");
},
"Close": function () {
$(this).dialog("close");
localStorage.removeItem(myself.localstorage_name);
$('#bookmaker').remove();
myself.wantToStart = false;
myself.add_create_book_link();
}
}
});
};
window.BookMaker.prototype.toggle_mimimise_bookmaker = function () {
this.minimised = !this.minimised;
this.minimised?this.minimise():this.maximise();
};
window.BookMaker.prototype.minimise = function () {
$('#book_nameselection,#book_editor').css('display', 'none');
$('#book_minimisebutton').text(this.msg.maximise);
localStorage.setItem(this.localstorage_minimised_name, '1'); //ls stores strings
};
window.BookMaker.prototype.maximise = function () {
$('#book_nameselection,#book_editor').css('display', '');
$('#book_minimisebutton').text(this.msg.minimise);
localStorage.setItem(this.localstorage_minimised_name, '0');
};
window.BookMaker.prototype.start_bookmaker = function () {
var myself = this;
if ($('#bookmaker').length > 0) { return; }
if (!this.initialised) {
this.initialise(); //set up constants
}
$('#' + this.portletID + ' > a').text(this.msg.closePortlet).parent().off('click').click(function () {
myself.close_bookmaker();
});
this.bookmaker = $('<div>', {id: "bookmaker"});
var prefixinput = $('<td><span>' + this.msg.bookPagePrefix + ':</span><br>\
<input type="radio" class="book_namecontrol" id="book_bookdir_user" name="book-prefix" value="' + this.user_bookstore + '" checked="checked"/>' + this.generate_prefix_link(this.user_bookstore)[0].outerHTML + '<br />\
<input type="radio" class="book_namecontrol" id="book_bookdir_central" name="book-prefix" value="' + this.central_bookstore + '" />' + this.generate_prefix_link(this.central_bookstore)[0].outerHTML + '\
</td>');
var namecontrol = $('<input>', {
'type': 'text',
'class': 'book_namecontrol',
'id': 'book_input_bookname',
'name': 'book_input_bookname',
'value': this.guess_title_from_page()
});
var usetitleasname = $('<input>', {
'type': 'button',
'id': 'book_usetitleasname',
'value': this.msg.useThisPagesTitle
}).click(function () {
namecontrol.val(myself.guess_title_from_page());
myself.set_book_name();
});
var nameinput = $('<td>').append('<span>' + this.msg.chooseLocation + ':</span>', '<br>', namecontrol, '<br>', usetitleasname);
var booknamenotice = $('<td id="book_namenotice">\
<div style="float:left; padding-right:3em">Editing book: <a id="book_fullocation" href="#"><span id="book_bookdirectory"></span><span id="book_bookname"></span></a></div>\
</td>');
var booknameselection = $('<table>', {id:"book_nameselection"}).append($('<tr>').append(prefixinput, nameinput, booknamenotice));
this.book_editor = $('<div>', {id:"book_editor"});
var get_pages_buttons = $('<hr><div id="book_getpages">\
<table><tr>\
<td style="width:7em;">\
' + this.msg.addPages + '\
</td><td> \
<input type="button" class="book_addpagebutton" id="input_addthispage" name="input_addthispage" value="' + this.msg.getThisPage + '" onclick="BookMakerInstance.add_this_page()" />\
<input type="button" class="book_addpagebutton" id="input_getfromcurrentpage" name="input_getfromcurrentpage" value="' + this.msg.getThisPageLinks + '" onclick="BookMakerInstance.get_pages_from_current()" />\
<input type="button" class="book_addpagebutton" id="input_getfromsubpages" name="input_getfromsubpages" value="' + this.msg.getThisPageSubpages + '" onclick="BookMakerInstance.get_pages_from_subpage()" />\
<input type="button" class="book_addpagebutton" id="input_getfromsaved" name="input_getfromsaved" value="' + this.msg.getSavedVersion + '" onclick="BookMakerInstance.get_pages_from_saved_book()" />\
<input type="button" class="book_addpagebutton" id="input_getfromexisting" name="input_getfromexisting" value="' + this.msg.getSavedOther + '..." onclick="BookMakerInstance.get_pages_from_existing_book()" />\
<input type="button" class="book_addpagebutton" id="input_getfrominput" name="input_getfrominput" value="' + this.msg.getOtherPage + '..." onclick="BookMakerInstance.get_page_from_input()" />\
<input type="button" class="book_addpagebutton" id="input_getfromcategory" name="input_getfromcategory" value="' + this.msg.getCategory + '..." onclick="BookMakerInstance.get_page_from_category()" />\
</td></tr></table></div>');
var metadata_area = $('<div id="book_metadatainput"><hr><div style="float:left;">\
' + this.msg.manualMetadata +': \
<input type="checkbox" id="input_manualmetadata" name="input_manualmetadata" value="" onclick="BookMakerInstance.select_metadata_mode()" /><br>\
<input type="button" id="input_metadatafromthispage" name="input_metadatafromthispage" disabled=disabled value="' + this.msg.useThisPagesMetadata +'" onclick="BookMakerInstance.get_metadata_from_this_page()" />\
</div><div id="book_metadatafields">\
' + this.msg.metadataTitle +':\
<input class="book_manualmetadata" type="text" id="input_metadatatitle" name="input_metadatatitle" value="" disabled /><br>\
' + this.msg.metadataAuthor +':\
<input class="book_manualmetadata" type="text" id="input_metadataauthor" name="input_metadataauthor" value="" disabled /><br>\
' + this.msg.metadataTranslator +':\
<input class="book_manualmetadata" type="text" id="input_metadatatranslator" name="input_metadatatranslator" value="" disabled /><br>\
' + this.msg.metadataDate +':\
<input class="book_manualmetadata" type="text" id="input_metadatadate" name="input_metadatadate" value="" disabled /><br>\
<div></div>');
var pages_pending = $('<td class="book_pagelist_container"><div class="book_pagelist_title">' + this.msg.pendingTitle +': <span class="book_clearall" onclick="BookMakerInstance.clear_list(\'book_pagelistpending\')">[' + this.msg.clearAll + ']</span></div><ul id="book_pagelistpending" class="book_pagelist"></ul></td>');
var pages_exist = $('<td class="book_pagelist_container"><div class="book_pagelist_title"">' + this.msg.existingTitle +': <span class="book_clearall" onclick="BookMakerInstance.clear_list(\'book_pagelistexist\')">[' + this.msg.clearAll + ']</span></div><ul id="book_pagelistexist" class="book_pagelist"></ul></td>');
var pages_manipulation = $('<td id="book_pagemanip" >\
<input type="button" class="book_inputpagemanip" id="input_move_right_all" name="input_move_right_all" value=">>" onclick="BookMakerInstance.move_page(\'right_all\')" />\
<input type="button" class="book_inputpagemanip" id="input_move_left_all" name="input_move_left_all" value="<<" onclick="BookMakerInstance.move_page(\'left_all\')" />\
</td>');
var commit_controls = $('<div id="book_commitcontrols"><hr>\
<input type="button" id="book_commitbook" name="book_commitbook" value="' + this.msg.save +'" title="' + this.msg.saveHint + '" onclick="BookMakerInstance.save_book()" />\
</div>');
var page_list_table = $('<table>', {id: "book_pagelist_table"}).append($('<tr>').append(pages_pending, pages_manipulation, pages_exist));
var page_list = $('<div style="clear:both;">').append('<hr>', page_list_table);
this.book_editor.append(get_pages_buttons, metadata_area, page_list, commit_controls);
var closeButton = $('<a>', {'class': "book_displaycontrol", id: "book_closebutton", text: this.msg.closeButton}).click(function () {
myself.close_bookmaker();
});
var minimiseButton = $('<a>', {'class': "book_displaycontrol", id: "book_minimisebutton", text: this.msg.minimise}).click(function () {
myself.toggle_mimimise_bookmaker();
});
var helpButton = $('<a>', {'class': "book_displaycontrol", id: "book_minimisebutton", text: this.msg.help,
href: mw.config.get('wgArticlePath').replace('$1', this.helpLocation)});
var displayControls = $('<div>', {id: "book_displaycontrols"}).append(closeButton, minimiseButton, helpButton);
$('#bodyContent').prepend(this.bookmaker.append(displayControls, booknameselection, this.book_editor));
$("#book_pagelistpending, #book_pagelistexist").sortable({
connectWith: ".book_pagelist",
change: function (e) {
myself.accept_page();
},
receive: function (e) {
myself.accept_page();
} //have to have both, otherwise lists tags aren't updated when move to other list
});
$('.book_manualmetadata,#input_manualmetadata').css({
'padding-right': '1em'
}).change(function () {
myself.store_book();
});
$('.book_namecontrol').on('input keyup', function () {
var $this = $(this);
var delay = 1000; // 2 seconds delay after last input
clearTimeout($this.data('timer'));
$this.data('timer', setTimeout(function () {
$this.removeData('timer');
myself.set_book_name();
}, delay));
});
//load minimisation state
if (this.localstorage_minimised_name in localStorage){
this.minimised = (localStorage.getItem(this.localstorage_minimised_name) === '1');
} else {
this.minimised = false;
}
if (this.minimised){
this.minimise();
}
if ($('#' + this.bookTemplateID).length > 0) {
this.load_existing_book(mw.config.get('wgPageName'));
} else {
this.retrieve_book();
}
//scroll to panel
$('html,body').stop().animate({scrollTop: $('#bookmaker').position().top + mw.util.$content.position().top}, 500);
};
window.BookMaker.prototype.guess_title_from_page = function () {
//strip bookstore prefixes
if (mw.config.get('wgPageName').indexOf(this.user_bookstore) == [0]) {
var title = mw.config.get('wgPageName').replace(this.user_bookstore, '');
} else if (mw.config.get('wgPageName').indexOf(this.central_bookstore) == [0]) {
var title = mw.config.get('wgPageName').replace(this.central_bookstore, '');
} else {
var title = mw.config.get('wgTitle');
}
title = title.replace(/_/g, ' ');
return title;
};
window.BookMaker.prototype.set_book_name = function (use_stored_name) {
var directory, name;
if (use_stored_name) {
//set radio buttons to match data
if ($('#book_bookdirectory').text() == $('#book_bookdir_user').val()) {
$('#book_bookdir_user').prop('checked', true);
} else {
$('#book_bookdir_central').prop('checked', true);
}
$('#book_input_bookname').val($('#book_bookname').text().replace(/_/g, ' '));
directory = $('#book_bookdirectory').text();
name = $('#book_bookname').text();
} else { //get data from the user fields
directory = $('input:radio[name=book-prefix]:checked').val().replace(/_/g, ' ');
name = $('#book_input_bookname').val().replace(/_/g, ' ');
if (name) {
$('#book_bookdirectory').text(directory);
$('#book_bookname').text(name);
}
}
if (!use_stored_name) {
this.store_book();
}
var update_bookname_link = function (exists) {
if (exists) {
$('#book_fullocation').removeClass('new');
$('#input_getfromsaved').prop('disabled', false);
} else {
$('#book_fullocation').addClass('new');
$('#input_getfromsaved').prop('disabled', true);
}
};
this.check_title_exists(directory + name, update_bookname_link);
};
window.BookMaker.prototype.check_title_exists = function (title, callback) {
if (!title){
callback(false);
}
//check if a page exists, executing callback with the result,
var myself = this;
//set the link location
$('#book_fullocation').attr('href', mw.config.get('wgArticlePath').replace('$1', title));
var query = mw.config.get('wgServer') + wgScriptPath + '/api.php?action=query&prop=info|revisions&intoken=edit&titles=' + title + '&format=json';
$.ajax({
url: query,
success: function (data) {
var pageID;
var pages = data['query']['pages'];
for (var idloop in pages) {
pageID = idloop;
break;
}
var exists = (pageID > 0);
var edittoken = pages[pageID]['edittoken'];
var currtimestamp = pages[pageID]['starttimestamp'];
var timestamp = null;
var user = null;
if (exists) {
timestamp = new Date(pages[pageID]['revisions'][0]['timestamp']);
user = pages[pageID]['revisions'][0]['user'];
}
callback(exists, edittoken, timestamp, user, currtimestamp);
}
});
};
window.BookMaker.prototype.create_pageitem = function (title, highlight) {
var myself = this;
//don't add if we already have the title
if ($('.book_pageitemtitle').filter(function () {
return ($(this).text() == title);
}).length) {
return null;
}
var page = $('<li class="book_pageitem"></li>');
var delete_icon = $('<img class="book_deleteitem" src="' + this.imgs['x_red'] + '"/>').click(function (e) {
if ($(this).parents('#book_pagelistpending').length > 0) {
$(this).parent().remove();
} else if ($(this).parents('#book_pagelistexist').length > 0) {
$('#book_pagelistpending').append($(this).parent());
}
myself.store_book();
});
var tag_icon = $('<img class="book_tagmainitem" src="' + this.imgs['tag_off'] + '"/>').click(function (e) {
var was_selected = $(this).parent().hasClass('book_mainitemsel');
$('.book_tagmainitem').attr('src', myself.imgs['tag_off']).parent().removeClass('book_mainitemsel');
if (!was_selected) {
$(this).attr('src', myself.imgs['tag_on']).parent().addClass('book_mainitemsel');
$('#input_manualmetadata').prop('checked', false);
myself.select_metadata_mode();
}
myself.accept_page();
});
var go_icon = $('<img class="book_gotoitempage" src="' + this.imgs['go_to_page'] + '"/>').click(function (e) {
var url = $(this).siblings('.book_pageitemtitle').text();
if (url) {
window.open(mw.config.get('wgArticlePath').replace('$1', url), "_blank");
}
});
var span = $('<span class="book_pageitemtitle">' + title + '</span>').mouseover(function (e) {
if (e.ctrlKey) {
$(this).parent().addClass('pageitem_sel_delete');
} else {
$(this).parent().addClass('pageitem_sel');
}
}).mouseleave(function (e) {
$(this).parent().removeClass('pageitem_sel pageitem_sel_delete');
}).mouseup(function (e) {
$(this).parent().removeClass('pageitem_sel pageitem_sel_delete');
}).mousedown(function (e) {
if (e.ctrlKey) {
$(this).parent().remove();
}
}).click(function (e) {
$(this).parent().addClass('pageitem_sel');
}).dblclick(function (e) {
if ($(this).parents('#book_pagelistpending').length > 0) {
$('#book_pagelistexist').append($(this).parent());
} else if ($(this).parents('#book_pagelistexist').length > 0) {
$('#book_pagelistpending').append($(this).parent());
}
myself.accept_page();
$(this).parent().removeClass('pageitem_sel pageitem_sel_delete');
});
$(document).keyup(function (e) {
if (e.ctrlKey) {
$('.pageitem_sel_delete').removeClass('pageitem_sel_delete');
}
}).keydown(function (e) {
if (e.ctrlKey) {
$('.pageitem_sel').addClass('pageitem_sel_delete');
}
});
page.append(delete_icon, go_icon, tag_icon, span);
if (highlight) {
page.addClass('book_mainitemsel').find('.book_tagmainitem').attr('src', myself.imgs['tag_on']);
}
return page;
};
window.BookMaker.prototype.accept_page = function () {
//called when the lists are modified
this.store_book();
};
window.BookMaker.prototype.move_page = function (dir) {
if (dir == 'right_all') {
$('#book_pagelistexist').append($('#book_pagelistpending .book_pageitem'));
} else if (dir == 'left_all') {
$('#book_pagelistpending').append($('#book_pagelistexist .book_pageitem'));
$('.book_mainitemsel .book_tagmainitem').attr('src', this.imgs['tag_on']);
}
this.accept_page();
};
window.BookMaker.prototype.get_pages_from_subpage = function (prefix) {
var title, i,
myself = this;
myself.add_page(mw.config.get('wgTitle'));
$.ajax({
url: mw.util.wikiScript('api'),
data: {
format: 'json',
action: 'query',
list: 'allpages',
apprefix: mw.config.get('wgPageName'),
apnamespace: 0,
apfilterredir: 'nonredirects',
aplimit: 500
},
success: function (data) {
for (i in data.query.allpages) {
title = data.query.allpages[i].title;
if (title) {
myself.add_page(title);
}
}
},
});
};
window.BookMaker.prototype.get_page_from_input = function (failedTitle) {
//prompt for a page title to load
var myself = this;
var input = $('<input>', {'style':"width:100%", 'type':"text", 'value':failedTitle});
var prompt = failedTitle?this.msg.noPageFound:this.msg.enterPage;
var title;
var dialog = $('<div>')
.append(prompt + ':','<br>', input)
.dialog({
modal: true,
title: this.msg.loadPageTitle,
buttons: {
"OK": function () {
$(this).dialog("close");
if (input.val() != '') {
title = input.val();
myself.check_title_exists(title, function (exists) {
if (exists) {
myself.add_page(title);
} else {
myself.get_page_from_input(title); //try again
}
});
}
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
};
window.BookMaker.prototype.get_page_from_category = function (failedTitle) {
//prompt for a page title to load
var myself = this;
var input = $('<input>', {'type':"text", 'value':failedTitle});
var prompt = failedTitle?this.msg.noCategoryPagesFound:this.msg.enterCategory;
var category;
var dialog = $('<div>')
.append(prompt + ':','<br>', this.msg.category + ': ', input)
.dialog({
modal: true,
title: "Load pages from a category",
buttons: {
"OK": function () {
$(this).dialog("close");
if (input.val() != '') {
category = input.val();
$.ajax({
url: mw.util.wikiScript('api'),
data: {
format: 'json',
action: 'query',
list: 'categorymembers',
cmtitle: 'Category:' + category,
cmlimit: 500
},
dataType: 'json',
success: function (data) {
if ( data && data.query && data.query.categorymembers ) {
var cm = data.query.categorymembers;
if (cm.length == 0) {
myself.get_page_from_category(category); //try again
return;
}
for (var i=0; i<cm.length; i++) {
if (cm[i].ns == 0 || cm.ns == 2) { //main or user space
myself.add_page(cm[i].title);
}
}
}
}
});
}
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
};
window.BookMaker.prototype.add_this_page = function () {
this.add_page(mw.config.get('wgTitle'));
};
window.BookMaker.prototype.add_page = function (title) {
var page = this.append_pageitem(title, 'book_pagelistpending');
if (page) { //store if we added anything
this.store_book();
}
};
window.BookMaker.prototype.load_existing_book = function (pageTitle) {
var myself = this;
//if there are no existing pages, just add them
if ($('#book_pagelistpending .book_pageitem').length === 0 && $('#book_pagelistexist .book_pageitem').length === 0) {
myself.load_existing_book2(pageTitle, true);
return;
}
//otherwise prompt for replace/append
var dialog = $('<div>', {text: this.msg.replaceAppend}).dialog({
title: this.msg.replaceAppendTitle,
modal: true,
buttons: {
"Replace": function () {
$(this).dialog("close");
myself.load_existing_book2(pageTitle, true);
},
"Append": function () {
$(this).dialog("close");
myself.load_existing_book2(pageTitle, false);
}
}
});
};
window.BookMaker.prototype.load_existing_book2 = function (pageTitle, replace) {
var myself = this,
title, msg;
$.ajax({
url: mw.util.wikiScript('index'),
//cache: false,
data: {
action: 'raw',
title: pageTitle,
},
success: function (data) {
myself.set_book_name(); //initialise book name
myself.add_pages_from_wikitext(data, replace);
},
error: function (jqXHR, textStatus, errorThrown) {
msg = this.msg.bookNotLoaded.replace('$1', '<a href="' + mw.config.get('wgArticlePath').replace('$1', pageTitle) + '">' + pageTitle + '</a>');
title = this.msg.bookNotLoadedTitle;
$.alert(msg + '.', title);
},
});
};
//parse wikitext to load an existing book
window.BookMaker.prototype.add_pages_from_wikitext = function (bookWikitext, replace) {
var pagePattern = /[\*:]\s*\[\[([^\]\|]+)\|?.*]\]\s*/,
lines = bookWikitext.split('\n'),
match, i;
if (replace) {
this.clear_list('book_pagelistpending');
}
//check lines for interesting things
for (i = 0; i < lines.length; i++) {
match = pagePattern.exec(lines[i]);
if (match != null) {
this.add_page(match[1]);
}
}
};
window.BookMaker.prototype.get_pages_from_existing_book = function () {
//prompt for a book title to load
var myself = this;
var input = $('<input style="width:100%" type="text" value="' + this.central_bookstore + '"/>');
var dialog = $('<div>').append(this.msg.enterBookLocation + ':', '<br>', input)
.dialog({
modal: true,
title: "Load an existing book",
buttons: {
"OK": function () {
$(this).dialog("close");
if (input.val() != '') {
myself.load_existing_book(input.val());
}
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
};
window.BookMaker.prototype.get_pages_from_saved_book = function () {
//load from an already saved book
this.load_existing_book(this.bookdata.directory + this.bookdata.bookname);
};
window.BookMaker.prototype.append_pageitem = function (title, destid, highlight) {
var pageitem = this.create_pageitem(title, highlight); //add current page
$('#' + destid).append(pageitem);
return pageitem;
};
window.BookMaker.prototype.get_pages_from_current = function () {
var myself = this;
myself.add_page(mw.config.get('wgTitle'));
$('.mw-content-ltr a').each(function (index) {
var title = $(this).attr('title');
//reject external, no ns0, no-exported and header/footers
if (title == undefined || title.match(/^(Help|Author|User|Index|Portal|Wikisource|Template|Category|Page|Special|File)(_talk)?:/i) || $(this).is('.image, .extiw, .internal') || $(this).parents('.ws-noexport, #footertemplate, #headertemplate').length) {
return true;
}
myself.add_page(title);
});
};
window.BookMaker.prototype.clear_list = function (id) {
$('#' + id).empty();
};
window.BookMaker.prototype.select_metadata_mode = function () {
if ($('#input_manualmetadata:checked').length > 0) {
$('.book_manualmetadata, #input_metadatafromthispage').prop('disabled', false);
$('.book_mainitemsel .book_tagmainitem').attr('src', this.imgs['tag_off']).parent().removeClass('book_mainitemsel');
} else {
$('.book_manualmetadata, #input_metadatafromthispage').prop('disabled', true);
}
};
window.BookMaker.prototype.get_metadata_from_this_page = function () {
$('#input_metadatatitle').val($('#ws-title').text());
$('#input_metadatadate').val($('#ws-year').text());
$('#input_metadataauthor').val($('#ws-author').text());
$('#input_metadatatranslator').val($('#ws-translator').text());
this.store_book();
};
window.BookMaker.prototype.store_book = function () {
var myself = this;
this.bookdata = {
'directory': '',
'bookname': '',
'title': '',
'author': '',
'translator': '',
'date': '',
'pagelist': [],
'pendinglist': [],
'manual_metadata': false,
'metadata_source': ''
};
$('#book_pagelistexist .book_pageitemtitle').each(function () {
var title = $(this).text();
if (title) {
myself.bookdata['pagelist'].push(title);
}
});
$('#book_pagelistpending .book_pageitemtitle').each(function () {
var title = $(this).text();
if (title) {
myself.bookdata['pendinglist'].push(title);
}
});
this.bookdata['directory'] = $('#book_bookdirectory').text();
this.bookdata['bookname'] = $('#book_bookname').text();
if ($('#input_manualmetadata:checked').length > 0) {
this.bookdata['manual_metadata'] = true;
this.bookdata['title'] = $('#input_metadatatitle').val();
this.bookdata['author'] = $('#input_metadataauthor').val();
this.bookdata['translator'] = $('#input_metadatatranslator').val();
this.bookdata['date'] = $('#input_metadatadate').val();
} else {
this.bookdata['manual_metadata'] = false;
}
if ($('.book_mainitemsel').length > 0) {
this.bookdata['metadata_source'] = $('.book_mainitemsel').parent().find('.book_mainitemsel').text();
}
localStorage.setItem(this.localstorage_name, JSON.stringify(this.bookdata));
$('#bookmaker').addClass('book_updated');
setTimeout(function () {
$('#bookmaker').removeClass('book_updated');
}, 600);
};
window.BookMaker.prototype.retrieve_book = function () {
if (!(this.localstorage_name in localStorage)) {
this.set_book_name(); //initialise book name
}
this.bookdata = JSON.parse(localStorage[this.localstorage_name]);
$('#book_bookname').text(this.bookdata['bookname']);
$('#book_bookdirectory').text(this.bookdata['directory']);
this.set_book_name(true);
if (this.bookdata['manual_metadata']) {
$('#input_manualmetadata').prop('checked', true);
this.select_metadata_mode();
$('#input_metadatatitle').val(this.bookdata['title']);
$('#input_metadataauthor').val(this.bookdata['author']);
$('#input_metadatatranslator').val(this.bookdata['translator']);
$('#input_metadatadate').val(this.bookdata['date']);
$('#input_metadatafromthispage').prop('disabled', false);
} else {
$('#input_manualmetadata').prop('checked', false);
}
this.restore_pages(this.bookdata['pagelist'], 'book_pagelistexist');
this.restore_pages(this.bookdata['pendinglist'], 'book_pagelistpending');
};
window.BookMaker.prototype.restore_pages = function (pagelist, dest) {
var i, text;
for (i in pagelist) {
text = pagelist[i];
if (text) {
this.append_pageitem(text, dest, this.bookdata['metadata_source'] == text);
this.accept_page();
}
}
};
window.BookMaker.prototype.save_book = function () {
if (!('pagelist' in this.bookdata)) {
return;
}
if ($('#book_pagelistexist .book_pageitem').length === 0) {
$.alert(this.msg.emptyBook + '.', this.msg.emptyBookTitle);
return;
}
var myself = this;
if ((this.bookdata['manual_metadata'] && (!this.bookdata['title'] || !this.bookdata['author'])) || (!this.bookdata['manual_metadata'] && !this.bookdata['metadata_source'])) {
var dialog = $('<div>').html(this.msg.missingMetadata).dialog({
title: "Missing metadata!",
modal: true,
buttons: {
"Continue": function () {
$(this).dialog("close");
myself.save_book2();
},
"Stop and add metadata": function () {
$(this).dialog("close");
}
}
});
} else {
myself.save_book2();
}
};
window.BookMaker.prototype.save_book2 = function () {
var myself = this;
//callback for confirming potential save
var confirm_save = function (exists, edittoken, timestamp, user, currtimestamp) {
if (exists) {
var edittimestring = timestamp.toUTCString();
var now = new Date();
var timeago = myself.format_time_span(now - timestamp);
var dialog = $('<div></div>').html("A book exists in this location. The last revision was " + timeago + " ago, by " + user + ". Is it OK to overwrite it?").dialog({
title: "Book exists!",
modal: true,
buttons: {
"Overwrite": function () {
$(this).dialog("close");
myself.save_book_execute(edittoken);
},
"Stop": function () {
$(this).dialog("close");
}
}
});
} else {
myself.save_book_execute(edittoken);
}
};
var savelocation = this.bookdata['directory'] + this.bookdata['bookname'];
this.check_title_exists(savelocation, confirm_save);
};
window.BookMaker.prototype.format_time_span = function (ms) {
//return a string of the approximate length of time
var s = Math.floor(ms / 1000),
mi = Math.floor(s / 60),
h = Math.floor(mi / 60),
d = Math.floor(h / 24),
m = Math.floor(d / 30),
y = Math.floor(d / 365);
var span = ((y === 0) ? '' : (y + ' year' + ((y > 1) ? 's' : '')))
+ ((m === 0 || y > 2) ? '' : (((y === 0) ? '' : ', ') + m % 12 + ' month' + ((m > 1) ? 's' : '')))
+ ((d === 0 || y > 0) ? '' : (((m + y === 0) ? '' : ', ') + d % 30 + ' day' + ((d > 1) ? 's' : '')))
+ ((h === 0 || d > 3) ? '' : (((m + y + d === 0) ? '' : ', ') + h % 24 + ' hour' + ((h > 1) ? 's' : '')))
+ ((mi === 0 || h > 3) ? '' : (((m + y + d + h === 0) ? '' : ', ') + mi % 60 + ' minute' + ((mi > 1) ? 's' : '')))
+ ((s === 0 || mi > 5) ? '' : (((m + y + d + h + mi === 0) ? '' : ', ') + s % 60 + ' second' + ((s > 1) ? 's' : '')));
return span;
};
window.BookMaker.prototype.save_book_execute = function (edittoken) {
var i, wikitext = '{{' + this.bookTemplateName;
if (this.bookdata['manual_metadata']) {
wikitext += '\n | title = ' + this.bookdata['title'];
wikitext += '\n | author = ' + this.bookdata['author'];
wikitext += '\n | translator = ' + this.bookdata['translator'];
wikitext += '\n | year = ' + this.bookdata['date'] + '';
} else if (this.bookdata['metadata_source']) {
wikitext += '\n | metadata = ' + this.bookdata['metadata_source'] + '';
}
wikitext += '\n | contents = \n';
for (i in this.bookdata['pagelist']) {
var pagename = this.bookdata['pagelist'][i];
wikitext += ': [[' + pagename + '|' + pagename.split('/').pop() + ']]\n';
}
wikitext += '}}\n\n';
var savelocation = this.bookdata['directory'] + this.bookdata['bookname'];
this.edit_page(savelocation, wikitext, edittoken);
};
window.BookMaker.prototype.edit_page = function (pagetitle, content, editToken) {
$.ajax({
url: mw.util.wikiScript('api'),
data: {
format: 'json',
action: 'edit',
title: pagetitle,
summary: this.msg['creation_summary'],
text: content,
token: editToken
},
dataType: 'json',
type: 'POST',
success: function (data) {
if (data && data.edit && data.edit.result == 'Success') {
window.location.href = mw.config.get('wgArticlePath').replace('$1', pagetitle); // load page if edit was successful
} else if (data && data.error) {
$.alert('Error: API returned error code "' + data.error.code + '": ' + data.error.info);
} else {
$.alert('Error: Unknown result from API.');
}
},
error: function (xhr) {
$.alert('Error: Request failed.');
}
});
};
window.BookMaker.prototype.construct_qr_url = function (data) {
return this.qrGenerator + '?data=' + encodeURIComponent(data);
};
window.BookMaker.prototype.recentre_dialog = function () {
$(".ui-dialog-content").dialog("option", "position", "center");
};
window.BookMaker.prototype.show_qr_codes = function () {
var dialog = $('<div class="qr_code_container">').append(this.msg.getQRCodes, '<br>');
var table = $('<table>');
var imgLink, url;
for (url in this.exportURLs) {
table.append('<tr><td>' + url + '</td><td><img src="' + this.construct_qr_url(this.exportURLs[url]) + '"/></td></tr>');
}
dialog.append(table).dialog({
modal: true,
title: this.msg.qrCodeTitle,
resizable: false,
close: function (event, ui) {
$(this).remove();
},
});
$(".qr_code_container img").load(this.recentre_dialog);
};
window.BookMaker.prototype.process_saved_book_template = function () {
//add functionality to the saved book template
var myself = this;
//replace the bookmaker link
$('#open_bookmaker_link').append('[ ', $('<img>', {src:this.imgs.editBook}), ' ',
$('<a>', {id: 'open_bookmaker_link', href: '', text: this.msg.startBookMaker}).click( function (e) {
e.preventDefault();
myself.start_bookmaker();
}), ' ]');
//linkify the user bookshelf link placeholder
if (mw.config.get('wgUserName') !== null) {
$('#wikisource_userbookshelf_link').append('[ ', this.generate_prefix_link(myself.user_bookstore, this.msg.yourShelf), ' ]').after('<br>');
}
//linkify the QR code link
$('#book_get_qr_codes a').replaceWith($('<a>', {href: '', text: $('#book_get_qr_codes a').text()}).click( function (e) {
myself.show_qr_codes();
e.preventDefault();
}));
};
window.BookMakerInstance.initialise();
//check if we could be in a book namespace
if ($.inArray(mw.config.get('wgNamespaceNumber'), [0, 2]) > -1) { //only trigger in sensible namespaces: main, book, user
if (($('#' + window.BookMakerInstance.bookTemplateID).length > 0) //we are looking at a book list
|| $.inArray(mw.config.get('wgNamespaceNumber'), [0]) > -1) { //main namespace, we could make a book
window.BookMakerInstance.process_saved_book_template();
mw.loader.using(['jquery.ui'], function () {
//add a simple alert method
//http://coding.abel.nu/2012/01/jquery-ui-replacement-for-alert/
$.extend({
alert: function (message, title) {
$('<div>').dialog({
buttons: {
"OK": function () {
$(this).dialog("close");
}
},
close: function (event, ui) {
$(this).remove();
},
resizable: false,
title: title,
modal: true
}).html(message);
}
});
$(window).resize(window.BookMakerInstance.recentre_dialog);
$(document).triggerHandler('scriptLoaded', ['BookMaker', window.BookMakerInstance]);
});
}
}
}()); //END IIFE