var DOKU_BASE = '/';var DOKU_TPL = '/lib/tpl/vector/';var DOKU_COOKIE_PARAM = {"path":"\/","secure":true};Object.defineProperty(window, 'DOKU_UHN', { get: function() {console.warn('Using DOKU_UHN is deprecated. Please use JSINFO.useHeadingNavigation instead');return JSINFO.useHeadingNavigation; } });Object.defineProperty(window, 'DOKU_UHC', { get: function() {console.warn('Using DOKU_UHC is deprecated. Please use JSINFO.useHeadingContent instead');return JSINFO.useHeadingContent; } });LANG = {"search_toggle_tools":"Toggle Search Tools","willexpire":"Your lock for editing this page is about to expire in a minute.\\nTo avoid conflicts use the preview button to reset the locktimer.","notsavedyet":"Unsaved changes will be lost.","searchmedia":"Search for files","keepopen":"Keep window open on selection","hidedetails":"Hide Details","mediatitle":"Link settings","mediadisplay":"Link type","mediaalign":"Alignment","mediasize":"Image size","mediatarget":"Link target","mediaclose":"Close","mediainsert":"Insert","mediadisplayimg":"Show the image.","mediadisplaylnk":"Show only the link.","mediasmall":"Small version","mediamedium":"Medium version","medialarge":"Large version","mediaoriginal":"Original version","medialnk":"Link to detail page","mediadirect":"Direct link to original","medianolnk":"No link","medianolink":"Do not link the image","medialeft":"Align the image on the left.","mediaright":"Align the image on the right.","mediacenter":"Align the image in the middle.","medianoalign":"Use no align.","nosmblinks":"Linking to Windows shares only works in Microsoft Internet Explorer.\\nYou still can copy and paste the link.","linkwiz":"Link Wizard","linkto":"Link to:","del_confirm":"Really delete selected item(s)?","restore_confirm":"Really restore this version?","media_diff":"View differences:","media_diff_both":"Side by Side","media_diff_opacity":"Shine-through","media_diff_portions":"Swipe","media_select":"Select files\u2026","media_upload_btn":"Upload","media_done_btn":"Done","media_drop":"Drop files here to upload","media_cancel":"remove","media_overwrt":"Overwrite existing files","data_insecure":"WARNING: It seems your data directory is not properly secured. Please read about Web Access Security in DokuWiki<\/a>.","plugins":{"bookcreator":{"include":"Add to selection","remove":"Remove page from selection","sortable":"Drag and drop to sort\/remove\/add pages","showpage":"Show page","confirmdel":"Do you really want to delete this selection from the archive?","confirmload":"Do you really want to load this selection, replacing any pages already selected?","btn_addtobook":"Add to book","btn_removetobook":"Remove from book","namespace_picker":"Namespace picker","select_namespace":"Select Namespace:","added_pages":"These pages have been added:","no_pages_selected":"None. \n(Is the namespace empty?)\n","select":"Select","cancel":"Cancel","add_subns_too":"Add pages in sub-namespaces too?"},"extension":{"reallydel":"Really uninstall this extension?","display_viewoptions":"View Options:","display_enabled":"enabled","display_disabled":"disabled","display_updatable":"updatable"},"logviewer":{"filter":"Filter Loglines:"},"searchindex":{"indexing":"Indexed:","done":"Finished indexing.","pages":"%d pages found.","clearing":"Clearing index...","finding":"Finding pages...","notindexed":"Skipped: Up-to-date","indexed":"Updated"},"styling":{"loader":"Preview is loading...
if this does not goes away, your values may be faulty","popup":"Open as a popup"},"vshare":{"button":"Insert video from video sharing sites","prompt":"Please paste the full URL to the video page here:","notfound":"Sorry, this URL wasn't recognized.\nPlease refer to the documentation on how to insert the correct syntax manually.","click":"Click to load this video. Your IP address and possibly other data will be transferred to %s."}}}; var toolbar = [{"type":"format","title":"Bold Text","icon":"bold.png","key":"b","open":"**","close":"**","block":false},{"type":"format","title":"Italic Text","icon":"italic.png","key":"i","open":"\/\/","close":"\/\/","block":false},{"type":"format","title":"Underlined Text","icon":"underline.png","key":"u","open":"__","close":"__","block":false},{"type":"format","title":"Monospaced Text","icon":"mono.png","key":"m","open":"''","close":"''","block":false},{"type":"format","title":"Strike-through Text","icon":"strike.png","key":"d","open":"","close":"<\/del>","block":false},{"type":"autohead","title":"Same Level Headline","icon":"hequal.png","key":"8","text":"Headline","mod":0,"block":true},{"type":"autohead","title":"Lower Headline","icon":"hminus.png","key":"9","text":"Headline","mod":1,"block":true},{"type":"autohead","title":"Higher Headline","icon":"hplus.png","key":"0","text":"Headline","mod":-1,"block":true},{"type":"picker","title":"Select Headline","icon":"h.png","class":"pk_hl","list":[{"type":"format","title":"Level 1 Headline","icon":"h1.png","key":"1","open":"====== ","close":" ======\\n"},{"type":"format","title":"Level 2 Headline","icon":"h2.png","key":"2","open":"===== ","close":" =====\\n"},{"type":"format","title":"Level 3 Headline","icon":"h3.png","key":"3","open":"==== ","close":" ====\\n"},{"type":"format","title":"Level 4 Headline","icon":"h4.png","key":"4","open":"=== ","close":" ===\\n"},{"type":"format","title":"Level 5 Headline","icon":"h5.png","key":"5","open":"== ","close":" ==\\n"}],"block":true},{"type":"linkwiz","title":"Internal Link","icon":"link.png","key":"l","open":"[[","close":"]]","block":false},{"type":"format","title":"External Link","icon":"linkextern.png","open":"[[","close":"]]","sample":"http:\/\/example.com|External Link","block":false},{"type":"formatln","title":"Ordered List Item","icon":"ol.png","open":" - ","close":"","key":"-","block":true},{"type":"formatln","title":"Unordered List Item","icon":"ul.png","open":" * ","close":"","key":".","block":true},{"type":"insert","title":"Horizontal Rule","icon":"hr.png","insert":"\\n----\\n","block":true},{"type":"mediapopup","title":"Add Images and other files (opens in a new window)","icon":"image.png","url":"lib\/exe\/mediamanager.php?ns=","name":"mediaselect","options":"width=750,height=500,left=20,top=20,scrollbars=yes,resizable=yes","block":false},{"type":"picker","title":"Smileys","icon":"smiley.png","list":{"8-)":"cool.svg","8-O":"eek.svg","8-o":"eek.svg",":-(":"sad.svg",":-)":"smile.svg","=)":"smile2.svg",":-\/":"doubt.svg",":-\\":"doubt2.svg",":-?":"confused.svg",":-D":"biggrin.svg",":-P":"razz.svg",":-o":"surprised.svg",":-O":"surprised.svg",":-x":"silenced.svg",":-X":"silenced.svg",":-|":"neutral.svg",";-)":"wink.svg","m(":"facepalm.svg","^_^":"fun.svg",":?:":"question.svg",":!:":"exclaim.svg","LOL":"lol.svg","FIXME":"fixme.svg","DELETEME":"deleteme.svg"},"icobase":"smileys","block":false},{"type":"picker","title":"Special Chars","icon":"chars.png","list":["\u00c0","\u00e0","\u00c1","\u00e1","\u00c2","\u00e2","\u00c3","\u00e3","\u00c4","\u00e4","\u01cd","\u01ce","\u0102","\u0103","\u00c5","\u00e5","\u0100","\u0101","\u0104","\u0105","\u00c6","\u00e6","\u0106","\u0107","\u00c7","\u00e7","\u010c","\u010d","\u0108","\u0109","\u010a","\u010b","\u00d0","\u0111","\u00f0","\u010e","\u010f","\u00c8","\u00e8","\u00c9","\u00e9","\u00ca","\u00ea","\u00cb","\u00eb","\u011a","\u011b","\u0112","\u0113","\u0116","\u0117","\u0118","\u0119","\u0122","\u0123","\u011c","\u011d","\u011e","\u011f","\u0120","\u0121","\u0124","\u0125","\u00cc","\u00ec","\u00cd","\u00ed","\u00ce","\u00ee","\u00cf","\u00ef","\u01cf","\u01d0","\u012a","\u012b","\u0130","\u0131","\u012e","\u012f","\u0134","\u0135","\u0136","\u0137","\u0139","\u013a","\u013b","\u013c","\u013d","\u013e","\u0141","\u0142","\u013f","\u0140","\u0143","\u0144","\u00d1","\u00f1","\u0145","\u0146","\u0147","\u0148","\u00d2","\u00f2","\u00d3","\u00f3","\u00d4","\u00f4","\u00d5","\u00f5","\u00d6","\u00f6","\u01d1","\u01d2","\u014c","\u014d","\u0150","\u0151","\u0152","\u0153","\u00d8","\u00f8","\u0154","\u0155","\u0156","\u0157","\u0158","\u0159","\u015a","\u015b","\u015e","\u015f","\u0160","\u0161","\u015c","\u015d","\u0162","\u0163","\u0164","\u0165","\u00d9","\u00f9","\u00da","\u00fa","\u00db","\u00fb","\u00dc","\u00fc","\u01d3","\u01d4","\u016c","\u016d","\u016a","\u016b","\u016e","\u016f","\u01d6","\u01d8","\u01da","\u01dc","\u0172","\u0173","\u0170","\u0171","\u0174","\u0175","\u00dd","\u00fd","\u0178","\u00ff","\u0176","\u0177","\u0179","\u017a","\u017d","\u017e","\u017b","\u017c","\u00de","\u00fe","\u00df","\u0126","\u0127","\u00bf","\u00a1","\u00a2","\u00a3","\u00a4","\u00a5","\u20ac","\u00a6","\u00a7","\u00aa","\u00ac","\u00af","\u00b0","\u00b1","\u00f7","\u2030","\u00bc","\u00bd","\u00be","\u00b9","\u00b2","\u00b3","\u00b5","\u00b6","\u2020","\u2021","\u00b7","\u2022","\u00ba","\u2200","\u2202","\u2203","\u018f","\u0259","\u2205","\u2207","\u2208","\u2209","\u220b","\u220f","\u2211","\u203e","\u2212","\u2217","\u00d7","\u2044","\u221a","\u221d","\u221e","\u2220","\u2227","\u2228","\u2229","\u222a","\u222b","\u2234","\u223c","\u2245","\u2248","\u2260","\u2261","\u2264","\u2265","\u2282","\u2283","\u2284","\u2286","\u2287","\u2295","\u2297","\u22a5","\u22c5","\u25ca","\u2118","\u2111","\u211c","\u2135","\u2660","\u2663","\u2665","\u2666","\u03b1","\u03b2","\u0393","\u03b3","\u0394","\u03b4","\u03b5","\u03b6","\u03b7","\u0398","\u03b8","\u03b9","\u03ba","\u039b","\u03bb","\u03bc","\u039e","\u03be","\u03a0","\u03c0","\u03c1","\u03a3","\u03c3","\u03a4","\u03c4","\u03c5","\u03a6","\u03c6","\u03c7","\u03a8","\u03c8","\u03a9","\u03c9","\u2605","\u2606","\u260e","\u261a","\u261b","\u261c","\u261d","\u261e","\u261f","\u2639","\u263a","\u2714","\u2718","\u201e","\u201c","\u201d","\u201a","\u2018","\u2019","\u00ab","\u00bb","\u2039","\u203a","\u2014","\u2013","\u2026","\u2190","\u2191","\u2192","\u2193","\u2194","\u21d0","\u21d1","\u21d2","\u21d3","\u21d4","\u00a9","\u2122","\u00ae","\u2032","\u2033","[","]","{","}","~","(",")","%","\u00a7","$","#","|","@"],"block":false},{"type":"signature","title":"Insert Signature","icon":"sig.png","key":"y","block":false},{"type":"format","title":"Mark text as key press","icon":"..\/..\/plugins\/keyboard\/keyboard.png","open":"","close":"<\/key>"},{"type":"picker","title":"Notes","icon":"..\/..\/plugins\/note\/images\/note_picker.png","list":[{"type":"format","title":"Note","icon":"..\/..\/plugins\/note\/images\/tb_note.png","open":"","close":"<\/note>"},{"type":"format","title":"Tip","icon":"..\/..\/plugins\/note\/images\/tb_tip.png","open":"","close":"<\/note>"},{"type":"format","title":"Important","icon":"..\/..\/plugins\/note\/images\/tb_important.png","open":"","close":"<\/note>"},{"type":"format","title":"Warning","icon":"..\/..\/plugins\/note\/images\/tb_warning.png","open":"","close":"<\/note>"}]},{"type":"picker","title":"Wrap Plugin","icon":"..\/..\/plugins\/wrap\/images\/toolbar\/picker.png","list":[{"type":"format","title":"columns","icon":"..\/..\/plugins\/wrap\/images\/toolbar\/column.png","open":"\\n\\n","close":"\\n<\/WRAP>\\n\\n\\n\\n<\/WRAP>\\n<\/WRAP>\\n"},{"type":"format","title":"simple centered box","icon":"..\/..\/plugins\/wrap\/images\/toolbar\/box.png","open":"\\n","close":"\\n<\/WRAP>\\n"},{"type":"format","title":"info box","icon":"..\/..\/plugins\/wrap\/images\/note\/16\/info.png","open":"\\n","close":"\\n<\/WRAP>\\n"},{"type":"format","title":"tip box","icon":"..\/..\/plugins\/wrap\/images\/note\/16\/tip.png","open":"\\n","close":"\\n<\/WRAP>\\n"},{"type":"format","title":"important box","icon":"..\/..\/plugins\/wrap\/images\/note\/16\/important.png","open":"\\n","close":"\\n<\/WRAP>\\n"},{"type":"format","title":"alert box","icon":"..\/..\/plugins\/wrap\/images\/note\/16\/alert.png","open":"\\n","close":"\\n<\/WRAP>\\n"},{"type":"format","title":"help box","icon":"..\/..\/plugins\/wrap\/images\/note\/16\/help.png","open":"\\n","close":"\\n<\/WRAP>\\n"},{"type":"format","title":"download box","icon":"..\/..\/plugins\/wrap\/images\/note\/16\/download.png","open":"\\n","close":"\\n<\/WRAP>\\n"},{"type":"format","title":"todo box","icon":"..\/..\/plugins\/wrap\/images\/note\/16\/todo.png","open":"\\n","close":"\\n<\/WRAP>\\n"},{"type":"insert","title":"clear floats","icon":"..\/..\/plugins\/wrap\/images\/toolbar\/clear.png","insert":"\\n"},{"type":"format","title":"especially emphasised","icon":"..\/..\/plugins\/wrap\/images\/toolbar\/em.png","open":"","close":"<\/wrap>"},{"type":"format","title":"highlighted","icon":"..\/..\/plugins\/wrap\/images\/toolbar\/hi.png","open":"","close":"<\/wrap>"},{"type":"format","title":"less significant","icon":"..\/..\/plugins\/wrap\/images\/toolbar\/lo.png","open":"","close":"<\/wrap>"}]}]; /* XXXXXXXXXX begin of lib/scripts/jquery/jquery.cookie.js XXXXXXXXXX */ /*! * jQuery Cookie Plugin v1.4.1 * https://github.com/carhartl/jquery-cookie * * Copyright 2013 Klaus Hartl * Released under the MIT license */ (function (factory) { if (typeof define === 'function' && define.amd) { // AMD define(['jquery'], factory); } else if (typeof exports === 'object') { // CommonJS factory(require('jquery')); } else { // Browser globals factory(jQuery); } }(function ($) { var pluses = /\+/g; function encode(s) { return config.raw ? s : encodeURIComponent(s); } function decode(s) { return config.raw ? s : decodeURIComponent(s); } function stringifyCookieValue(value) { return encode(config.json ? JSON.stringify(value) : String(value)); } function parseCookieValue(s) { if (s.indexOf('"') === 0) { // This is a quoted cookie as according to RFC2068, unescape... s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\'); } try { // Replace server-side written pluses with spaces. // If we can't decode the cookie, ignore it, it's unusable. // If we can't parse the cookie, ignore it, it's unusable. s = decodeURIComponent(s.replace(pluses, ' ')); return config.json ? JSON.parse(s) : s; } catch(e) {} } function read(s, converter) { var value = config.raw ? s : parseCookieValue(s); return $.isFunction(converter) ? converter(value) : value; } var config = $.cookie = function (key, value, options) { // Write if (value !== undefined && !$.isFunction(value)) { options = $.extend({}, config.defaults, options); if (typeof options.expires === 'number') { var days = options.expires, t = options.expires = new Date(); t.setTime(+t + days * 864e+5); } return (document.cookie = [ encode(key), '=', stringifyCookieValue(value), options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE options.path ? '; path=' + options.path : '', options.domain ? '; domain=' + options.domain : '', options.secure ? '; secure' : '' ].join('')); } // Read var result = key ? undefined : {}; // To prevent the for loop in the first place assign an empty array // in case there are no cookies at all. Also prevents odd result when // calling $.cookie(). var cookies = document.cookie ? document.cookie.split('; ') : []; for (var i = 0, l = cookies.length; i < l; i++) { var parts = cookies[i].split('='); var name = decode(parts.shift()); var cookie = parts.join('='); if (key && key === name) { // If second argument (value) is a function it's a converter... result = read(cookie, value); break; } // Prevent storing a cookie that we couldn't decode. if (!key && (cookie = read(cookie)) !== undefined) { result[name] = cookie; } } return result; }; config.defaults = {}; $.removeCookie = function (key, options) { if ($.cookie(key) === undefined) { return false; } // Must not alter options, thus extending a fresh object... $.cookie(key, '', $.extend({}, options, { expires: -1 })); return !$.cookie(key); }; })); /* XXXXXXXXXX end of lib/scripts/jquery/jquery.cookie.js XXXXXXXXXX */ /* XXXXXXXXXX begin of lib/scripts/fileuploader.js XXXXXXXXXX */ /** * http://github.com/valums/file-uploader * * Multiple file upload component with progress-bar, drag-and-drop. * © 2010 Andrew Valums ( andrew(at)valums.com ) * * Licensed under GNU GPL 2 or later and GNU LGPL 2 or later, see license.txt. */ // // Helper functions // var qq = qq || {}; /** * Adds all missing properties from second obj to first obj */ qq.extend = function(first, second){ for (var prop in second){ first[prop] = second[prop]; } }; /** * Searches for a given element in the array, returns -1 if it is not present. * @param {Number} [from] The index at which to begin the search */ qq.indexOf = function(arr, elt, from){ if (arr.indexOf) return arr.indexOf(elt, from); from = from || 0; var len = arr.length; if (from < 0) from += len; for (; from < len; from++){ if (from in arr && arr[from] === elt){ return from; } } return -1; }; qq.getUniqueId = (function(){ var id = 0; return function(){ return id++; }; })(); // // Events qq.attach = function(element, type, fn){ if (element.addEventListener){ element.addEventListener(type, fn, false); } else if (element.attachEvent){ element.attachEvent('on' + type, fn); } }; qq.detach = function(element, type, fn){ if (element.removeEventListener){ element.removeEventListener(type, fn, false); } else if (element.attachEvent){ element.detachEvent('on' + type, fn); } }; qq.preventDefault = function(e){ if (e.preventDefault){ e.preventDefault(); } else{ e.returnValue = false; } }; // // Node manipulations /** * Insert node a before node b. */ qq.insertBefore = function(a, b){ b.parentNode.insertBefore(a, b); }; qq.remove = function(element){ element.parentNode.removeChild(element); }; qq.contains = function(parent, descendant){ // compareposition returns false in this case if (parent == descendant) return true; if (parent.contains){ return parent.contains(descendant); } else { return !!(descendant.compareDocumentPosition(parent) & 8); } }; /** * Creates and returns element from html string * Uses innerHTML to create an element */ qq.toElement = (function(){ var div = document.createElement('div'); return function(html){ div.innerHTML = html; var element = div.firstChild; div.removeChild(element); return element; }; })(); // // Node properties and attributes /** * Sets styles for an element. * Fixes opacity in IE6-8. */ qq.css = function(element, styles){ if (styles.opacity != null){ if (typeof element.style.opacity != 'string' && typeof(element.filters) != 'undefined'){ styles.filter = 'alpha(opacity=' + Math.round(100 * styles.opacity) + ')'; } } qq.extend(element.style, styles); }; qq.hasClass = function(element, name){ var re = new RegExp('(^| )' + name + '( |$)'); return re.test(element.className); }; qq.addClass = function(element, name){ if (!qq.hasClass(element, name)){ element.className += ' ' + name; } }; qq.removeClass = function(element, name){ var re = new RegExp('(^| )' + name + '( |$)'); element.className = element.className.replace(re, ' ').replace(/^\s+|\s+$/g, ""); }; qq.setText = function(element, text){ element.innerText = text; element.textContent = text; }; // // Selecting elements qq.children = function(element){ var children = [], child = element.firstChild; while (child){ if (child.nodeType == 1){ children.push(child); } child = child.nextSibling; } return children; }; qq.getByClass = function(element, className){ if (element.querySelectorAll){ return element.querySelectorAll('.' + className); } var result = []; var candidates = element.getElementsByTagName("*"); var len = candidates.length; for (var i = 0; i < len; i++){ if (qq.hasClass(candidates[i], className)){ result.push(candidates[i]); } } return result; }; /** * obj2url() takes a json-object as argument and generates * a querystring. pretty much like jQuery.param() * * how to use: * * `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');` * * will result in: * * `http://any.url/upload?otherParam=value&a=b&c=d` * * @param Object JSON-Object * @param String current querystring-part * @return String encoded querystring */ qq.obj2url = function(obj, temp, prefixDone){ var uristrings = [], prefix = '&', add = function(nextObj, i){ var nextTemp = temp ? (/\[\]$/.test(temp)) // prevent double-encoding ? temp : temp+'['+i+']' : i; if ((nextTemp != 'undefined') && (i != 'undefined')) { uristrings.push( (typeof nextObj === 'object') ? qq.obj2url(nextObj, nextTemp, true) : (Object.prototype.toString.call(nextObj) === '[object Function]') ? encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj()) : encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj) ); } }; if (!prefixDone && temp) { prefix = (/\?/.test(temp)) ? (/\?$/.test(temp)) ? '' : '&' : '?'; uristrings.push(temp); uristrings.push(qq.obj2url(obj)); } else if ((Object.prototype.toString.call(obj) === '[object Array]') && (typeof obj != 'undefined') ) { // we wont use a for-in-loop on an array (performance) for (var i = 0, len = obj.length; i < len; ++i){ add(obj[i], i); } } else if ((typeof obj != 'undefined') && (obj !== null) && (typeof obj === "object")){ // for anything else but a scalar, we will use for-in-loop for (var i in obj){ if(obj.hasOwnProperty(i) && typeof obj[i] != 'function') { add(obj[i], i); } } } else { uristrings.push(encodeURIComponent(temp) + '=' + encodeURIComponent(obj)); } return uristrings.join(prefix) .replace(/^&/, '') .replace(/%20/g, '+'); }; // // // Uploader Classes // // var qq = qq || {}; /** * Creates upload button, validates upload, but doesn't create file list or dd. */ qq.FileUploaderBasic = function(o){ this._options = { // set to true to see the server response debug: false, action: '/server/upload', params: {}, button: null, multiple: true, maxConnections: 3, // validation allowedExtensions: [], sizeLimit: 0, minSizeLimit: 0, // events // return false to cancel submit onSubmit: function(id, fileName){}, onProgress: function(id, fileName, loaded, total){}, onComplete: function(id, fileName, responseJSON){}, onCancel: function(id, fileName){}, // messages messages: { typeError: "{file} has invalid extension. Only {extensions} are allowed.", sizeError: "{file} is too large, maximum file size is {sizeLimit}.", minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.", emptyError: "{file} is empty, please select files again without it.", onLeave: "The files are being uploaded, if you leave now the upload will be cancelled." }, showMessage: function(message){ alert(message); } }; qq.extend(this._options, o); // number of files being uploaded this._filesInProgress = 0; this._handler = this._createUploadHandler(); if (this._options.button){ this._button = this._createUploadButton(this._options.button); } this._preventLeaveInProgress(); }; qq.FileUploaderBasic.prototype = { setParams: function(params){ this._options.params = params; }, getInProgress: function(){ return this._filesInProgress; }, _createUploadButton: function(element){ var self = this; return new qq.UploadButton({ element: element, multiple: this._options.multiple && qq.UploadHandlerXhr.isSupported(), onChange: function(input){ self._onInputChange(input); } }); }, _createUploadHandler: function(){ var self = this, handlerClass; if(qq.UploadHandlerXhr.isSupported()){ handlerClass = 'UploadHandlerXhr'; } else { handlerClass = 'UploadHandlerForm'; } var handler = new qq[handlerClass]({ debug: this._options.debug, action: this._options.action, maxConnections: this._options.maxConnections, onProgress: function(id, fileName, loaded, total){ self._onProgress(id, fileName, loaded, total); self._options.onProgress(id, fileName, loaded, total); }, onComplete: function(id, fileName, result){ self._onComplete(id, fileName, result); self._options.onComplete(id, fileName, result); }, onCancel: function(id, fileName){ self._onCancel(id, fileName); self._options.onCancel(id, fileName); } }); return handler; }, _preventLeaveInProgress: function(){ var self = this; qq.attach(window, 'beforeunload', function(e){ if (!self._filesInProgress){return;} var e = e || window.event; // for ie, ff e.returnValue = self._options.messages.onLeave; // for webkit return self._options.messages.onLeave; }); }, _onSubmit: function(id, fileName){ this._filesInProgress++; }, _onProgress: function(id, fileName, loaded, total){ }, _onComplete: function(id, fileName, result){ this._filesInProgress--; if (result.error){ this._options.showMessage(result.error); } }, _onCancel: function(id, fileName){ this._filesInProgress--; }, _onInputChange: function(input){ if (this._handler instanceof qq.UploadHandlerXhr){ this._uploadFileList(input.files); } else { if (this._validateFile(input)){ this._uploadFile(input); } } this._button.reset(); }, _uploadFileList: function(files){ for (var i=0; i this._options.sizeLimit){ this._error('sizeError', name); return false; } else if (size && size < this._options.minSizeLimit){ this._error('minSizeError', name); return false; } return true; }, _error: function(code, fileName){ var message = this._options.messages[code]; function r(name, replacement){ message = message.replace(name, replacement); } r('{file}', this._formatFileName(fileName)); r('{extensions}', this._options.allowedExtensions.join(', ')); r('{sizeLimit}', this._formatSize(this._options.sizeLimit)); r('{minSizeLimit}', this._formatSize(this._options.minSizeLimit)); this._options.showMessage(message); }, _formatFileName: function(name){ if (name.length > 33){ name = name.slice(0, 19) + '...' + name.slice(-13); } return name; }, _isAllowedExtension: function(fileName){ var ext = (-1 !== fileName.indexOf('.')) ? fileName.replace(/.*[.]/, '').toLowerCase() : ''; var allowed = this._options.allowedExtensions; if (!allowed.length){return true;} for (var i=0; i 99); return Math.max(bytes, 0.1).toFixed(1) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i]; } }; /** * Class that creates upload widget with drag-and-drop and file list * @inherits qq.FileUploaderBasic */ qq.FileUploader = function(o){ // call parent constructor qq.FileUploaderBasic.apply(this, arguments); // additional options qq.extend(this._options, { element: null, // if set, will be used instead of qq-upload-list in template listElement: null, template: '
' + '
Drop files here to upload
' + '
Upload a file
' + '
    ' + '
    ', // template for one item in file list fileTemplate: '
  • ' + '' + '' + '' + 'Cancel' + 'Failed' + '
  • ', classes: { // used to get elements from templates button: 'qq-upload-button', drop: 'qq-upload-drop-area', dropActive: 'qq-upload-drop-area-active', list: 'qq-upload-list', file: 'qq-upload-file', spinner: 'qq-upload-spinner', size: 'qq-upload-size', cancel: 'qq-upload-cancel', // added to list item when upload completes // used in css to hide progress spinner success: 'qq-upload-success', fail: 'qq-upload-fail' } }); // overwrite options with user supplied qq.extend(this._options, o); this._element = this._options.element; this._element.innerHTML = this._options.template; this._listElement = this._options.listElement || this._find(this._element, 'list'); this._classes = this._options.classes; this._button = this._createUploadButton(this._find(this._element, 'button')); this._bindCancelEvent(); this._setupDragDrop(); }; // inherit from Basic Uploader qq.extend(qq.FileUploader.prototype, qq.FileUploaderBasic.prototype); qq.extend(qq.FileUploader.prototype, { /** * Gets one of the elements listed in this._options.classes **/ _find: function(parent, type){ var element = qq.getByClass(parent, this._options.classes[type])[0]; if (!element){ throw new Error('element not found ' + type); } return element; }, _setupDragDrop: function(){ var self = this, dropArea = this._find(this._element, 'drop'); var dz = new qq.UploadDropZone({ element: dropArea, onEnter: function(e){ qq.addClass(dropArea, self._classes.dropActive); e.stopPropagation(); }, onLeave: function(e){ e.stopPropagation(); }, onLeaveNotDescendants: function(e){ qq.removeClass(dropArea, self._classes.dropActive); }, onDrop: function(e){ dropArea.style.display = 'none'; qq.removeClass(dropArea, self._classes.dropActive); self._uploadFileList(e.dataTransfer.files); } }); dropArea.style.display = 'none'; qq.attach(document, 'dragenter', function(e){ if (!dz._isValidFileDrag(e)) return; dropArea.style.display = 'block'; }); qq.attach(document, 'dragleave', function(e){ if (!dz._isValidFileDrag(e)) return; var relatedTarget = document.elementFromPoint(e.clientX, e.clientY); // only fire when leaving document out if ( ! relatedTarget || relatedTarget.nodeName == "HTML"){ dropArea.style.display = 'none'; } }); }, _onSubmit: function(id, fileName){ qq.FileUploaderBasic.prototype._onSubmit.apply(this, arguments); this._addToList(id, fileName); }, _onProgress: function(id, fileName, loaded, total){ qq.FileUploaderBasic.prototype._onProgress.apply(this, arguments); var item = this._getItemByFileId(id); var size = this._find(item, 'size'); size.style.display = 'inline'; var text; if (loaded != total){ text = Math.round(loaded / total * 100) + '% from ' + this._formatSize(total); } else { text = this._formatSize(total); } qq.setText(size, text); }, _onComplete: function(id, fileName, result){ qq.FileUploaderBasic.prototype._onComplete.apply(this, arguments); // mark completed var item = this._getItemByFileId(id); qq.remove(this._find(item, 'cancel')); qq.remove(this._find(item, 'spinner')); if (result.success){ qq.addClass(item, this._classes.success); } else { qq.addClass(item, this._classes.fail); } }, _addToList: function(id, fileName){ var item = qq.toElement(this._options.fileTemplate); item.qqFileId = id; var fileElement = this._find(item, 'file'); qq.setText(fileElement, this._formatFileName(fileName)); this._find(item, 'size').style.display = 'none'; this._listElement.appendChild(item); }, _getItemByFileId: function(id){ var item = this._listElement.firstChild; // there can't be txt nodes in dynamically created list // and we can use nextSibling while (item){ if (item.qqFileId == id) return item; item = item.nextSibling; } }, /** * delegate click event for cancel link **/ _bindCancelEvent: function(){ var self = this, list = this._listElement; qq.attach(list, 'click', function(e){ e = e || window.event; var target = e.target || e.srcElement; if (qq.hasClass(target, self._classes.cancel)){ qq.preventDefault(e); var item = target.parentNode; self._handler.cancel(item.qqFileId); qq.remove(item); } }); } }); qq.UploadDropZone = function(o){ this._options = { element: null, onEnter: function(e){}, onLeave: function(e){}, // is not fired when leaving element by hovering descendants onLeaveNotDescendants: function(e){}, onDrop: function(e){} }; qq.extend(this._options, o); this._element = this._options.element; this._disableDropOutside(); this._attachEvents(); }; qq.UploadDropZone.prototype = { _disableDropOutside: function(e){ // run only once for all instances if (!qq.UploadDropZone.dropOutsideDisabled ){ qq.attach(document, 'dragover', function(e){ if (e.dataTransfer){ e.dataTransfer.dropEffect = 'none'; e.preventDefault(); } }); qq.UploadDropZone.dropOutsideDisabled = true; } }, _attachEvents: function(){ var self = this; qq.attach(self._element, 'dragover', function(e){ if (!self._isValidFileDrag(e)) return; var effect = e.dataTransfer.effectAllowed; if (effect == 'move' || effect == 'linkMove'){ e.dataTransfer.dropEffect = 'move'; // for FF (only move allowed) } else { e.dataTransfer.dropEffect = 'copy'; // for Chrome } e.stopPropagation(); e.preventDefault(); }); qq.attach(self._element, 'dragenter', function(e){ if (!self._isValidFileDrag(e)) return; self._options.onEnter(e); }); qq.attach(self._element, 'dragleave', function(e){ if (!self._isValidFileDrag(e)) return; self._options.onLeave(e); var relatedTarget = document.elementFromPoint(e.clientX, e.clientY); // do not fire when moving a mouse over a descendant if (qq.contains(this, relatedTarget)) return; self._options.onLeaveNotDescendants(e); }); qq.attach(self._element, 'drop', function(e){ if (!self._isValidFileDrag(e)) return; e.preventDefault(); self._options.onDrop(e); }); }, _isValidFileDrag: function(e){ var dt = e.dataTransfer, // do not check dt.types.contains in webkit, because it crashes safari 4 isWebkit = navigator.userAgent.indexOf("AppleWebKit") > -1; // dt.effectAllowed is none in Safari 5 // dt.types.contains check is for firefox return dt && dt.effectAllowed != 'none' && (dt.files || (!isWebkit && dt.types.contains && dt.types.contains('Files'))); } }; qq.UploadButton = function(o){ this._options = { element: null, // if set to true adds multiple attribute to file input multiple: false, // name attribute of file input name: 'file', onChange: function(input){}, hoverClass: 'qq-upload-button-hover', focusClass: 'qq-upload-button-focus' }; qq.extend(this._options, o); this._element = this._options.element; // make button suitable container for input qq.css(this._element, { position: 'relative', overflow: 'hidden', // Make sure browse button is in the right side // in Internet Explorer direction: 'ltr' }); this._input = this._createInput(); }; qq.UploadButton.prototype = { /* returns file input element */ getInput: function(){ return this._input; }, /* cleans/recreates the file input */ reset: function(){ if (this._input.parentNode){ qq.remove(this._input); } qq.removeClass(this._element, this._options.focusClass); this._input = this._createInput(); }, _createInput: function(){ var input = document.createElement("input"); if (this._options.multiple){ input.setAttribute("multiple", "multiple"); } input.setAttribute("type", "file"); input.setAttribute("name", this._options.name); qq.css(input, { position: 'absolute', // in Opera only 'browse' button // is clickable and it is located at // the right side of the input right: 0, top: 0, fontFamily: 'Arial', // 4 persons reported this, the max values that worked for them were 243, 236, 236, 118 fontSize: '118px', margin: 0, padding: 0, cursor: 'pointer', opacity: 0 }); this._element.appendChild(input); var self = this; qq.attach(input, 'change', function(){ self._options.onChange(input); }); qq.attach(input, 'mouseover', function(){ qq.addClass(self._element, self._options.hoverClass); }); qq.attach(input, 'mouseout', function(){ qq.removeClass(self._element, self._options.hoverClass); }); qq.attach(input, 'focus', function(){ qq.addClass(self._element, self._options.focusClass); }); qq.attach(input, 'blur', function(){ qq.removeClass(self._element, self._options.focusClass); }); // IE and Opera, unfortunately have 2 tab stops on file input // which is unacceptable in our case, disable keyboard access if (window.attachEvent){ // it is IE or Opera input.setAttribute('tabIndex', "-1"); } return input; } }; /** * Class for uploading files, uploading itself is handled by child classes */ qq.UploadHandlerAbstract = function(o){ this._options = { debug: false, action: '/upload.php', // maximum number of concurrent uploads maxConnections: 999, onProgress: function(id, fileName, loaded, total){}, onComplete: function(id, fileName, response){}, onCancel: function(id, fileName){} }; qq.extend(this._options, o); this._queue = []; // params for files in queue this._params = []; }; qq.UploadHandlerAbstract.prototype = { log: function(str){ if (this._options.debug && window.console) console.log('[uploader] ' + str); }, /** * Adds file or file input to the queue * @returns id **/ add: function(file){}, /** * Sends the file identified by id and additional query params to the server */ upload: function(id, params){ var len = this._queue.push(id); var copy = {}; qq.extend(copy, params); this._params[id] = copy; // if too many active uploads, wait... if (len <= this._options.maxConnections){ this._upload(id, this._params[id]); } }, /** * Cancels file upload by id */ cancel: function(id){ this._cancel(id); this._dequeue(id); }, /** * Cancells all uploads */ cancelAll: function(){ for (var i=0; i= max && i < max){ var nextId = this._queue[max-1]; this._upload(nextId, this._params[nextId]); } } }; /** * Class for uploading files using form and iframe * @inherits qq.UploadHandlerAbstract */ qq.UploadHandlerForm = function(o){ qq.UploadHandlerAbstract.apply(this, arguments); this._inputs = {}; }; // @inherits qq.UploadHandlerAbstract qq.extend(qq.UploadHandlerForm.prototype, qq.UploadHandlerAbstract.prototype); qq.extend(qq.UploadHandlerForm.prototype, { add: function(fileInput){ fileInput.setAttribute('name', 'qqfile'); var id = 'qq-upload-handler-iframe' + qq.getUniqueId(); this._inputs[id] = fileInput; // remove file input from DOM if (fileInput.parentNode){ qq.remove(fileInput); } return id; }, getName: function(id){ // get input value and remove path to normalize return this._inputs[id].value.replace(/.*(\/|\\)/, ""); }, _cancel: function(id){ this._options.onCancel(id, this.getName(id)); delete this._inputs[id]; var iframe = document.getElementById(id); if (iframe){ // to cancel request set src to something else // we use src="javascript:false;" because it doesn't // trigger ie6 prompt on https iframe.setAttribute('src', 'javascript:false;'); qq.remove(iframe); } }, _upload: function(id, params){ var input = this._inputs[id]; if (!input){ throw new Error('file with passed id was not added, or already uploaded or cancelled'); } var fileName = this.getName(id); var iframe = this._createIframe(id); var form = this._createForm(iframe, params); form.appendChild(input); var self = this; this._attachLoadEvent(iframe, function(){ self.log('iframe loaded'); var response = self._getIframeContentJSON(iframe); self._options.onComplete(id, fileName, response); self._dequeue(id); delete self._inputs[id]; // timeout added to fix busy state in FF3.6 setTimeout(function(){ qq.remove(iframe); }, 1); }); form.submit(); qq.remove(form); return id; }, _attachLoadEvent: function(iframe, callback){ qq.attach(iframe, 'load', function(){ // when we remove iframe from dom // the request stops, but in IE load // event fires if (!iframe.parentNode){ return; } // fixing Opera 10.53 if (iframe.contentDocument && iframe.contentDocument.body && iframe.contentDocument.body.innerHTML == "false"){ // In Opera event is fired second time // when body.innerHTML changed from false // to server response approx. after 1 sec // when we upload file with iframe return; } callback(); }); }, /** * Returns json object received by iframe from server. */ _getIframeContentJSON: function(iframe){ // iframe.contentWindow.document - for IE<7 var doc = iframe.contentDocument ? iframe.contentDocument: iframe.contentWindow.document, response; this.log("converting iframe's innerHTML to JSON"); this.log("innerHTML = " + doc.body.innerHTML); try { response = eval("(" + doc.body.innerHTML + ")"); } catch(err){ response = {}; } return response; }, /** * Creates iframe with unique name */ _createIframe: function(id){ // We can't use following code as the name attribute // won't be properly registered in IE6, and new window // on form submit will open // var iframe = document.createElement('iframe'); // iframe.setAttribute('name', id); var iframe = qq.toElement('").appendTo("body"); formDoc = getiframeDocument($iframe); } formDoc.write("
    " + formInnerHtml + "
    " + settings.popupWindowTitle + ""); $form = $(formDoc).find('form'); } $form.submit(); } //check if the file download has completed every checkInterval ms setTimeout(checkFileDownloadComplete, settings.checkInterval); function checkFileDownloadComplete() { //has the cookie been written due to a file download occuring? var cookieValue = settings.cookieValue; if(typeof cookieValue == 'string') { cookieValue = cookieValue.toLowerCase(); } var lowerCaseCookie = settings.cookieName.toLowerCase() + "=" + cookieValue; if (document.cookie.toLowerCase().indexOf(lowerCaseCookie) > -1) { //execute specified callback internalCallbacks.onSuccess(fileUrl); //remove cookie var cookieData = settings.cookieName + "=; path=" + settings.cookiePath + "; expires=" + new Date(0).toUTCString() + ";"; if (settings.cookieDomain) cookieData += " domain=" + settings.cookieDomain + ";"; document.cookie = cookieData; //remove iframe cleanUp(false); return; } //has an error occured? //if neither containers exist below then the file download is occuring on the current window if (downloadWindow || $iframe) { //has an error occured? try { var formDoc = downloadWindow ? downloadWindow.document : getiframeDocument($iframe); if (formDoc && formDoc.body !== null && formDoc.body.innerHTML.length) { var isFailure = true; if ($form && $form.length) { var $contents = $(formDoc.body).contents().first(); try { if ($contents.length && $contents[0] === $form[0]) { isFailure = false; } } catch (e) { if (e && e.number == -2146828218) { // IE 8-10 throw a permission denied after the form reloads on the "$contents[0] === $form[0]" comparison isFailure = true; } else { throw e; } } } if (isFailure) { // IE 8-10 don't always have the full content available right away, they need a litle bit to finish setTimeout(function () { internalCallbacks.onFail(formDoc.body.innerHTML, fileUrl); cleanUp(true); }, 100); return; } } } catch (err) { //500 error less than IE9 internalCallbacks.onFail('', fileUrl, err); cleanUp(true); return; } } //keep checking... setTimeout(checkFileDownloadComplete, settings.checkInterval); } //gets an iframes document in a cross browser compatible manner function getiframeDocument($iframe) { var iframeDoc = $iframe[0].contentWindow || $iframe[0].contentDocument; if (iframeDoc.document) { iframeDoc = iframeDoc.document; } return iframeDoc; } function cleanUp(isFailure) { setTimeout(function() { if (downloadWindow) { if (isAndroid) { downloadWindow.close(); } if (isIos) { if (downloadWindow.focus) { downloadWindow.focus(); //ios safari bug doesn't allow a window to be closed unless it is focused if (isFailure) { downloadWindow.close(); } } } } //iframe cleanup appears to randomly cause the download to fail //not doing it seems better than failure... //if ($iframe) { // $iframe.remove(); //} }, 0); } function htmlSpecialCharsEntityEncode(str) { return str.replace(htmlSpecialCharsRegEx, function(match) { return '&' + htmlSpecialCharsPlaceHolders[match]; }); } var promise = deferred.promise(); promise.abort = function() { cleanUp(); $iframe.remove(); }; return promise; } }); })(jQuery, this); /** * The Namespace picker dialog * * Based on the code from "The Link Wizard"/linkwiz.js * from Andreas Gohr and Pierre Spring * * @author LarsDW223 */ var bc_nspicker = { $picker: null, $entry: null, result: null, timer: null, textArea: null, selected: null, selection: null, /** * Initialize the bc_nspicker by creating the needed HTML * and attaching the eventhandlers */ init: function ($editor) { "use strict"; // position relative to the text area var pos = $editor.position(); // create HTML Structure if (bc_nspicker.$picker) { return; } bc_nspicker.$picker = jQuery(document.createElement('div')) .dialog({ autoOpen: false, draggable: true, title: LANG.plugins.bookcreator.namespace_picker, resizable: false }) .html( '
    ' + LANG.plugins.bookcreator.select_namespace + ' ' + '' + '' + '
    ' + LANG.plugins.bookcreator.add_subns_too + '
    ' + '
    ' ) .parent() .attr('id', 'bc__nspicker') .css({ 'position': 'absolute', 'top': (pos.top + 20) + 'px', //overwritten later with position of Add Namespace button. 'left': (pos.left + 80) + 'px' }) .hide() .appendTo('.dokuwiki:first'); bc_nspicker.textArea = $editor[0]; bc_nspicker.result = jQuery('#bc__nspicker_result')[0]; // scrollview correction on arrow up/down gets easier jQuery(bc_nspicker.result).css('position', 'relative'); bc_nspicker.$entry = jQuery('#bc__nspicker_entry'); if (JSINFO.namespace) { bc_nspicker.$entry.val(JSINFO.namespace + ':'); } // attach event handlers jQuery('#bc__nspicker .ui-dialog-titlebar-close').on('click', bc_nspicker.hide); jQuery('#bc__nspicker_select').on('click', bc_nspicker.selectNamespace_exec); jQuery('#bc__nspicker_cancel').on('click', bc_nspicker.hide); bc_nspicker.$entry.keyup(bc_nspicker.onEntry); jQuery(bc_nspicker.result).on('click', 'a', bc_nspicker.onResultClick); }, /** * handle all keyup events in the entry field */ onEntry: function (e) { "use strict"; if (e.keyCode === 37 || e.keyCode === 39) { //left/right return true; //ignore } if (e.keyCode === 27) { //Escape bc_nspicker.hide(); e.preventDefault(); e.stopPropagation(); return false; } if (e.keyCode === 38) { //Up bc_nspicker.select(bc_nspicker.selected - 1); e.preventDefault(); e.stopPropagation(); return false; } if (e.keyCode === 40) { //Down bc_nspicker.select(bc_nspicker.selected + 1); e.preventDefault(); e.stopPropagation(); return false; } if (e.keyCode === 13) { //Enter if (bc_nspicker.selected > -1) { var $obj = bc_nspicker.$getResult(bc_nspicker.selected); if ($obj.length > 0) { bc_nspicker.resultClick($obj.find('a')[0]); } } else if (bc_nspicker.$entry.val()) { bc_nspicker.selectNamespace_exec(); } e.preventDefault(); e.stopPropagation(); return false; } bc_nspicker.autocomplete(); }, /** * Get one of the results by index * * @param num int result div to return * @returns jQuery object */ $getResult: function (num) { "use strict"; return jQuery(bc_nspicker.result).find('div').eq(num); }, /** * Select the given result */ select: function (num) { "use strict"; if (num < 0) { bc_nspicker.deselect(); return; } var $obj = bc_nspicker.$getResult(num); if ($obj.length === 0) { return; } bc_nspicker.deselect(); $obj.addClass('selected'); // make sure the item is viewable in the scroll view //getting child position within the parent var childPos = $obj.position().top; //getting difference between the childs top and parents viewable area var yDiff = childPos + $obj.outerHeight() - jQuery(bc_nspicker.result).innerHeight(); if (childPos < 0) { //if childPos is above viewable area (that's why it goes negative) jQuery(bc_nspicker.result)[0].scrollTop += childPos; } else if (yDiff > 0) { // if difference between childs top and parents viewable area is // greater than the height of a childDiv jQuery(bc_nspicker.result)[0].scrollTop += yDiff; } bc_nspicker.selected = num; }, /** * deselect a result if any is selected */ deselect: function () { "use strict"; if (bc_nspicker.selected > -1) { bc_nspicker.$getResult(bc_nspicker.selected).removeClass('selected'); } bc_nspicker.selected = -1; }, /** * Handle clicks in the result set an dispatch them to * resultClick() */ onResultClick: function (e) { "use strict"; if (!jQuery(this).is('a')) { return; } e.stopPropagation(); e.preventDefault(); bc_nspicker.resultClick(this); return false; }, /** * Handles the "click" on a given result anchor */ resultClick: function (a) { "use strict"; if (a.title === '' || a.title.substr(a.title.length - 1) === ':') { bc_nspicker.$entry.val(a.title); bc_nspicker.autocomplete_exec(); } }, /** * Start the page/namespace lookup timer * * Calls autocomplete_exec when the timer runs out */ autocomplete: function () { "use strict"; if (bc_nspicker.timer !== null) { window.clearTimeout(bc_nspicker.timer); bc_nspicker.timer = null; } bc_nspicker.timer = window.setTimeout(bc_nspicker.autocomplete_exec, 350); }, /** * Executes the AJAX call for the page/namespace lookup */ autocomplete_exec: function () { "use strict"; var $res = jQuery(bc_nspicker.result); bc_nspicker.deselect(); $res.html('') .load( DOKU_BASE + 'lib/exe/ajax.php', { call: 'linkwiz', q: bc_nspicker.$entry.val() } ); }, /** * Show the link wizard */ show: function () { "use strict"; bc_nspicker.selection = DWgetSelection(bc_nspicker.textArea); bc_nspicker.$picker.show(); bc_nspicker.$entry.focus(); bc_nspicker.autocomplete(); // Move the cursor to the end of the input var temp = bc_nspicker.$entry.val(); bc_nspicker.$entry.val(''); bc_nspicker.$entry.val(temp); }, /** * Hide the link wizard */ hide: function () { "use strict"; bc_nspicker.$picker.hide(); bc_nspicker.textArea.focus(); }, /** * Toggle the link wizard */ toggle: function () { "use strict"; if (bc_nspicker.$picker.css('display') === 'none') { bc_nspicker.show(); } else { bc_nspicker.hide(); } }, /** * Executes the AJAX call for the selected namespace lookup. * Parameter "ns" is the namespace to search through. Parameter * "r" specifies if the search should be recursive or not. */ selectNamespace_exec: function () { "use strict"; var $recursive = jQuery('#bc__nspicker_recursive'); jQuery.post( DOKU_BASE + 'lib/exe/ajax.php', { call: 'plugin_bookcreator_call', action: 'searchPages', ns: bc_nspicker.$entry.val(), r: $recursive.is(':checked'), sectok: jQuery('input[name="sectok"]').val() }, bc_nspicker.selectNamespace, 'json' ); }, /** * Select Namespace. * Add all pages in the selected Namespace to the book, show * window with added pages and then close/hide the Namespace * picker. */ selectNamespace: function (data) { "use strict"; var content; var pages; var name; // Go through the array of pages, add them and prepare // a message for the user pages = 0; content = LANG.plugins.bookcreator.added_pages + "\n\n"; if (data.hasOwnProperty('pages')) { jQuery(data.pages).each(function (index) { name = data.pages [index]; Bookcreator.selectedpages.addPage (name); content += name + "\n"; pages += 1; }); } if (pages === 0) { content += LANG.plugins.bookcreator.no_pages_selected + "\n"; } BookManager.updateListsFromStorage(); window.alert(content); bc_nspicker.hide(); } }; /** * Storage object for an array with a selection of pages * * @param key * @constructor */ function Storage(key) { this.localStorageKey = key; this._storage = []; } /** * Is pageid in stored selection * * @param {string} pageid * @returns {boolean} */ Storage.prototype.isSelected = function(pageid) { return this._storage.indexOf(pageid) !== -1; }; /** * Insert pageid at given position * * @param {string} pageid * @param {Number} position */ Storage.prototype.addPage = function(pageid, position) { if(typeof position === 'undefined') { this._storage.push(pageid); //add to the end } else { this._storage.splice(position, 0, pageid); } this._save(); }; /** * Move pageid inside selection to given position * * @param {string} pageid * @param {Number} position */ Storage.prototype.movePage = function(pageid, position) { if(!this._deletePage(pageid).length) return; this.addPage(pageid, position); }; /** * Delete pageid from selection * @param pageid */ Storage.prototype.deletePage = function(pageid) { this._deletePage(pageid); this._save(); }; /** * Delete given pageid from storage * * @param pageid * @returns {Array} empty or with deleted entry * @private */ Storage.prototype._deletePage = function(pageid) { let pos = this._storage.indexOf(pageid); if(pos === -1) return []; return this._storage.splice(pos, 1); }; /** * Empty the store */ Storage.prototype.clearAll = function() { this._storage = []; this._save(); }; /** * Returns array with pageids of selected books * * @returns {Array} */ Storage.prototype.getSelection = function() { return this._storage; }; /** * Set a new selection at once and save * * @param {Array} selection */ Storage.prototype.setSelection = function(selection) { this._storage = selection; this._save(); }; /** * Count number of selected pages * * @returns {Number} */ Storage.prototype.count = function() { return this._storage.length; }; /** * Save current selection in browser's localStorage * * @private */ Storage.prototype._save = function() { window.localStorage.setItem(this.localStorageKey, JSON.stringify(this._storage)); }; /** * Load selection from browser's localStorage */ Storage.prototype.load = function() { let source = window.localStorage.getItem(this.localStorageKey); try { this._storage = JSON.parse(source) || []; } catch (E) { this._storage = []; } }; /** * Storage object for an property in browser's localStorage * * @param key * @constructor */ function CachedProperty(key) { this.localStorageKey = key; } CachedProperty.prototype.set = function(value) { window.localStorage.setItem(this.localStorageKey, value); }; CachedProperty.prototype.get = function() { return window.localStorage.getItem(this.localStorageKey); }; /** * Performs bookcreator functionality at wiki pages */ let Bookcreator = { selectedpages: new Storage('bookcreator_selectedpages'), isCurrentPageSelected: false, /** * Handle click at page add/remove buttons */ clickAddRemoveButton: function(e) { e.preventDefault(); Bookcreator.toggleSelectionCurrentPage(); Bookcreator.updatePage(); }, /** * Sets up a storage change observer */ setupUpdateObserver: function() { jQuery(window).on('storage', function() { Bookcreator.init(); Bookcreator.updatePage(); }); //// handle cached navigation //if ('addEventListener' in window) { // window.addEventListener('pageshow', function(event) { // if (event.persisted) { // Bookcreator.load(); // } // }, false); //} }, /** * Initiate storage */ init: function() { this.selectedpages.load(); this.isCurrentPageSelected = this.selectedpages.isSelected(JSINFO.id); }, /** * Delete or add current page from selection */ toggleSelectionCurrentPage: function() { if(this.isCurrentPageSelected) { this.selectedpages.deletePage(JSINFO.id); } else { this.selectedpages.addPage(JSINFO.id); } this.isCurrentPageSelected = this.selectedpages.isSelected(JSINFO.id); }, /** * Update the interface to current selection */ updatePage: function() { //$addtobookBtn2 = jQuery('.plugin_bookcreator_addtobook,a.plugin_bookcreator_addtobook'), let $addtobookBtn = jQuery('.plugin_bookcreator__addtobook'), $bookbar = jQuery('.bookcreator__bookbar'); //pagetool add/remove button // /* TODO DEPRECATED 2017 */ // $addtobookBtn2.css( "display", "block"); // if ($addtobookBtn2.length) { //exists the addtobook link // var text = LANG.plugins.bookcreator['btn_' + (this.isCurrentPageSelected ? 'remove' : 'add') + 'tobook']; // // $addtobookBtn2 // .toggleClass('remove', this.isCurrentPageSelected) // .attr('title', text) // .children('span').html(text); // } //pagetool add/remove button if ($addtobookBtn.length) { //exists the addtobook item in pagetools? let text = LANG.plugins.bookcreator['btn_' + (this.isCurrentPageSelected ? 'remove' : 'add') + 'tobook']; let $a = $addtobookBtn.find('a') .toggleClass('remove', this.isCurrentPageSelected) .attr('title', text).trigger('blur'); let $span = $a.children('span'); if($span.length) { $span.html(text); } else { //e.g vector template does not use svg, so has no span $a.html(text); } // Workaround for Bootstrap3 Template uses instead of
  • jQuery('a.plugin_bookcreator__addtobook') .toggleClass('remove', this.isCurrentPageSelected) .attr('title', text).trigger('blur') .children('span').html(text); } //bookbar with add/remove button if(this.isBookbarVisible()) { jQuery("#bookcreator__add").toggle(!this.isCurrentPageSelected); jQuery("#bookcreator__remove").toggle(this.isCurrentPageSelected); jQuery("#bookcreator__pages").html(this.selectedpages.count()); } $bookbar.toggle(this.isBookbarVisible()) }, /** * Is bookbar visible * * @returns {boolean} */ isBookbarVisible: function() { if(!JSINFO.bookcreator.areToolsVisible) { //permissions, skip page return false; } return JSINFO.bookcreator.showBookbar === 'always' || JSINFO.bookcreator.showBookbar === 'noempty' && this.selectedpages.count() > 0; } }; let BookManager = { cache: {}, booktitle: new CachedProperty('bookcreator_booktitle'), deletedpages: new Storage('bookcreator_deletedpages'), init: function() { this.deletedpages.load(); Bookcreator.init(); }, setupUpdateObserver: function(){ jQuery(window).on('storage', function(event) { if(event.key === Bookcreator.selectedpages.localStorageKey) { BookManager.init(); BookManager.updateListsFromStorage(); } if(event.key === BookManager.booktitle.localStorageKey) { BookManager.fillTitle(); } }) }, /** * Retrieve missing pages and add to the page cache */ updateListsFromStorage: function() { //get selection changes let notcachedpages = jQuery(Bookcreator.selectedpages.getSelection()).not(Object.keys(this.cache)).get(); notcachedpages = notcachedpages.concat(jQuery(BookManager.deletedpages.getSelection()).not(Object.keys(this.cache)).get()); //add to list at page and to cache function processRetrievedPages(pages) { if(pages.hasOwnProperty('selection')) { jQuery.extend(BookManager.cache, pages.selection); BookManager.updateLists(); } } //retrieve data if(notcachedpages.length > 0) { jQuery.post( DOKU_BASE + 'lib/exe/ajax.php', { call: 'plugin_bookcreator_call', action: 'retrievePageinfo', selection: JSON.stringify(notcachedpages), sectok: jQuery('input[name="sectok"]').val() }, processRetrievedPages, 'json' ); } else { this.updateLists(); } }, /** * Use updated selected pages selection for updating deleted pages selection and gui */ updateLists: function() { let $ul_deleted = jQuery('ul.pagelist.deleted'), $ul_selected = jQuery('ul.pagelist.selected'), deletedpages = BookManager.deletedpages.getSelection(), selectedpages = Bookcreator.selectedpages.getSelection(); BookManager.refillList($ul_selected, selectedpages); //deleted pages selection could still contain re-added pages let filtereddeletedpages = jQuery(deletedpages).not(selectedpages).get(); BookManager.deletedpages.setSelection(filtereddeletedpages); BookManager.refillList($ul_deleted, filtereddeletedpages); }, /** * Empty the list in the gui and fill with pages from the stored selection * * @param {jQuery} $ul_selection the unordered list element, to fill with pages * @param {Array} selection array with the pageids of selected or deleted pages */ refillList: function($ul_selection, selection) { //just empty $ul_selection.empty(); //recreate li items let liopen1 = "
  • " + "" + '' + "" + '' + "  ", liclose = "
  • "; let i = 0, itemsToInsert = []; jQuery.each(selection, function(index, page){ if(BookManager.cache[page]) { itemsToInsert[i++] = liopen1; itemsToInsert[i++] = page; itemsToInsert[i++] = liopen2; itemsToInsert[i++] = BookManager.cache[page][0]; itemsToInsert[i++] = liopen3; itemsToInsert[i++] = BookManager.cache[page][1]; itemsToInsert[i++] = liclose; } else { console.log('Not in cache: ' + page); } }); //add to list $ul_selection.append(itemsToInsert.join('')); //update gui //jQuery('div.bookcreator__pagelist').find('ul.pagelist.selected,ul.pagelist.deleted').sortable('refresh'); $ul_selection.sortable('refresh'); }, /** * Returns pageids from selection which are not in list at page * * @param {string} selectionname * @returns {Array} */ getNotdisplayedPages: function(selectionname) { let sortedIDs, selection; sortedIDs = jQuery('div.bookcreator__pagelist').find('ul.pagelist.'+selectionname).sortable('toArray'); //remove 'pg__' sortedIDs = jQuery.map(sortedIDs, function(id){ return id.substr(4); }); if(selectionname === 'selected') { selection = Bookcreator.selectedpages.getSelection(); } else { selection = BookManager.deletedpages.getSelection(); } return jQuery(selection).not(sortedIDs).get(); }, /** * Move between selections * * @param {string} pageid * @param {boolean} isAddAction * @param {Number} position or skip */ toggleSelectedPage: function (pageid, isAddAction, position) { if (isAddAction) { Bookcreator.selectedpages.addPage(pageid, position); BookManager.deletedpages.deletePage(pageid); } else { Bookcreator.selectedpages.deletePage(pageid); BookManager.deletedpages.addPage(pageid, position); } }, /** * handler for move buttons on the list items */ movePage: function() { let $a = jQuery(this), $li = $a.parent(), pageid = $li.attr('id').substr(4); //true=add to selected list, false=remove from selected list let isAddAction = $li.parent().hasClass('deleted'); //move page to other list let listclass = isAddAction ? 'selected' : 'deleted'; $li.appendTo(jQuery('div.bookcreator__pagelist ul.pagelist.' + listclass)); BookManager.toggleSelectedPage(pageid, isAddAction); }, /** * List item is dropped in other pagelist * * @param event * @param ui */ receivedFromOtherSelection: function (event, ui) { let pageid = ui.item.attr('id').substr(4), isAddAction = ui.item.parent().hasClass('selected'), position = ui.item.index(); //store new status BookManager.toggleSelectedPage(pageid, isAddAction, position); }, /** * Store start position of moved list item * * @param event * @param ui */ startSort: function(event, ui) { ui.item.data("startindex", ui.item.index()); }, /** * Store whether list item is sorted within list, or from outside * * @param event * @param ui */ updateSort: function(event, ui) { isItemSortedWithinList = !ui.sender; }, /** * Handle sorting within list * * @param event * @param ui */ stopSort: function(event, ui) { let isAddAction = ui.item.parent().hasClass('selected'), pageid = ui.item.attr('id').substr(4), startindex = ui.item.data("startindex"), endindex = ui.item.index(); if(isItemSortedWithinList) { if(startindex !== endindex) { if(isAddAction) { Bookcreator.selectedpages.movePage(pageid, endindex); } else { BookManager.deletedpages.movePage(pageid, endindex); } } isItemSortedWithinList = false; } }, /** * click handler: Delete all selections of selected and deleted pages */ clearSelections: function() { BookManager.deletedpages.clearAll(); jQuery('ul.pagelist.deleted').empty(); Bookcreator.selectedpages.clearAll(); jQuery('ul.pagelist.selected').empty(); }, /** * click handler: load or delete saved selections */ handleSavedselectionAction: function() { let $this = jQuery(this), action = ($this.hasClass('delete') ? 'delete' : 'load'), pageid = $this.parent().data('pageId'); //confirm dialog let msg, comfirmed = false; if (action === "delete") { msg = LANG.plugins.bookcreator.confirmdel; } else { if (Bookcreator.selectedpages.count() === 0) { comfirmed = true; } msg = LANG.plugins.bookcreator.confirmload; } if (!comfirmed) { comfirmed = confirm(msg); } if (comfirmed) { function processResponse(data) { let $msg = $this.parent().parent().parent().find('.message'); //get $msg before deletion of the li elem //action: loadSavedSelection if (data.hasOwnProperty('selection')) { BookManager.clearSelections(); Bookcreator.selectedpages.setSelection(data.selection); BookManager.updateListsFromStorage(); jQuery('input[name="book_title"]').val(data.title).trigger('change'); } //action: deleteSavedSelection if (data.hasOwnProperty('deletedpage')) { jQuery('.bkctrsavsel__' + data.deletedpage).remove(); } BookManager.setMessage($msg, data); } jQuery.post( DOKU_BASE + 'lib/exe/ajax.php', { call: 'plugin_bookcreator_call', action: (action === 'load' ? 'loadSavedSelection' : 'deleteSavedSelection'), savedselectionname: pageid, sectok: jQuery('input[name="sectok"]').val() }, processResponse, 'json' ); } }, /** * Save selection at a wiki page */ saveSelection: function($this) { let $fieldset = $this.parent(), $title = $fieldset.find('input[name="bookcreator_title"]'), title = $title.val(); function processResponse(data) { if (data.hasOwnProperty('item')) { jQuery('.bookcreator__selections__list').find('ul').prepend(data.item); $title.val(''); } let $msg = $fieldset.find('.message'); BookManager.setMessage($msg, data); } jQuery.post( DOKU_BASE + 'lib/exe/ajax.php', { call: 'plugin_bookcreator_call', action: 'saveSelection', savedselectionname: title, selection: JSON.stringify(Bookcreator.selectedpages.getSelection()), sectok: jQuery('input[name="sectok"]').val() }, processResponse, 'json' ); }, /** * Show temporary the succes or error message * * @param {jQuery} $msg * @param {Object} data */ setMessage: function($msg, data) { let msg = false, state; function setMsg($msg, msg, state) { $msg.html(msg) .toggleClass('error', state === -1) .toggleClass('success', state === 1); } if(data.hasOwnProperty('error')) { msg = data.error; state = -1; } else if(data.hasOwnProperty('success')) { msg = data.success; state = 1; } if (msg) { setMsg($msg, msg, state); setTimeout(function () { setMsg($msg, '', 0); }, 1000 * 10); } }, /** * */ fillTitle: function() { let title = BookManager.booktitle.get(); jQuery('input[name="book_title"]').val(title); }, /** * Download the requested file * * @param event */ downloadSelection: function(event) { let $this = jQuery(this), do_action = $this.find('select[name="do"]').val(); if(do_action === 'export_html' || do_action === 'export_text') { //just extend the form $this.append( '' ); } else { //download in background and shows dialog let formdata = $this.serializeArray(); formdata.push({ name: 'selection', value: JSON.stringify(Bookcreator.selectedpages.getSelection()) }); let $preparingFileModal = jQuery("#preparing-file-modal"); $preparingFileModal.dialog({ modal: true }); jQuery.fileDownload( window.location.href, { successCallback: function (url) { $preparingFileModal.dialog('close'); }, failCallback: function (responseHtml, url) { $preparingFileModal.dialog('close'); jQuery("#error-modal") .dialog({ modal: true }) .find('.downloadresponse').html(responseHtml); }, httpMethod: "POST", data: formdata } ); event.preventDefault(); //otherwise a normal form submit would occur } }, htmlSpecialCharsEntityEncode: function (str) { let htmlSpecialCharsRegEx = /[<>&\r\n"']/gm; let htmlSpecialCharsPlaceHolders = { '<': 'lt;', '>': 'gt;', '&': 'amp;', '\r': "#13;", '\n': "#10;", '"': 'quot;', "'": '#39;' /*single quotes just to be safe, IE8 doesn't support ', so use ' instead */ }; return str.replace(htmlSpecialCharsRegEx, function(match) { return '&' + htmlSpecialCharsPlaceHolders[match]; }); } }; jQuery(function () { //Tools for selecting a page if(JSINFO.bookcreator.areToolsVisible) { Bookcreator.init(); Bookcreator.setupUpdateObserver(); //bookbar buttons jQuery('a.bookcreator__tglPgSelection').on('click', Bookcreator.clickAddRemoveButton); // //pagetool button TODO DEPRECATED 2017 // jQuery('.plugin_bookcreator_addtobook').click(Bookcreator.clickAddRemoveButton); //pagetool button jQuery('.plugin_bookcreator__addtobook').on('click', Bookcreator.clickAddRemoveButton); //gui Bookcreator.updatePage(); } else { //hide addtobook button from pagetool jQuery('.plugin_bookcreator__addtobook').hide(); } //bookmanager let $pagelist = jQuery('div.bookcreator__pagelist'); if ($pagelist.length) { BookManager.init(); //buttons at page lists $pagelist.find('ul') .on('click', 'a.action', BookManager.movePage); //sorting and drag-and-drop isItemSortedWithinList = false; //use in closure in stop and update handler $pagelist.find('ul.pagelist.selected,ul.pagelist.deleted') .sortable({ connectWith: "div.bookcreator__pagelist ul.pagelist", receive: BookManager.receivedFromOtherSelection, start: BookManager.startSort, stop: BookManager.stopSort, update: BookManager.updateSort, distance: 5 }); //clear selection button jQuery('form.clearactive button').on('click', function(event) { event.preventDefault(); BookManager.clearSelections(); }); //add namespace to selection button bc_nspicker.init(jQuery('.dokuwiki:first')); jQuery('form.selectnamespace button').on('click', function(event) { bc_nspicker.val = null; //place dialog near the button let offset = jQuery(this).offset(); let offsetparent = jQuery(this).parent().parent().offset(); bc_nspicker.$picker.css({ 'top': offset.top + 'px', 'left': offsetparent.left - 0 + 'px', }); bc_nspicker.toggle(); event.preventDefault(); return 'bc__nspicker'; }); BookManager.updateListsFromStorage(); BookManager.fillTitle(); BookManager.setupUpdateObserver(); //save selection jQuery('form.saveselection button').on('click', function(event) { event.preventDefault(); BookManager.saveSelection(jQuery(this)); }); jQuery('input[name="book_title"]').on('change', function() { let value = jQuery(this).val(); BookManager.booktitle.set(value); }); jQuery('form.downloadselection').on('submit', BookManager.downloadSelection); } //saved selection list jQuery('.bookcreator__selections__list').find('ul') .on('click', 'a.action', BookManager.handleSavedselectionAction); }); /* XXXXXXXXXX end of lib/plugins/bookcreator/script.js XXXXXXXXXX */ /* XXXXXXXXXX begin of lib/plugins/captcha/script.js XXXXXXXXXX */ jQuery(function () { var $wrap = jQuery('#plugin__captcha_wrapper'); if (!$wrap.length) return; /** * Autofill and hide the whole CAPTCHA stuff in the simple JS mode */ var $code = jQuery('#plugin__captcha_code'); if ($code.length) { var $box = $wrap.find('input[type=text]'); $box.first().val($code.text().replace(/([^A-Z])+/g, '')); $wrap.hide(); } /** * Add a HTML5 player for the audio version of the CAPTCHA */ var $audiolink = $wrap.find('a.audiolink'); if ($audiolink.length) { var audio = document.createElement('audio'); if (audio) { audio.src = $audiolink.attr('href'); $wrap.append(audio); $audiolink.click(function (e) { audio.play(); e.preventDefault(); e.stopPropagation(); }); } } }); /* XXXXXXXXXX end of lib/plugins/captcha/script.js XXXXXXXXXX */ /* XXXXXXXXXX begin of lib/plugins/epub/script.js XXXXXXXXXX */ function epub_show_throbber(user,client) { var dom = document.getElementById('epub_throbber'); if(!dom || !user || !epub_title) return; dom.style.display='block'; var params="user="+encodeURIComponent(user); params += "&location="+encodeURIComponent(window.location); params += "&title="+encodeURIComponent(epub_title); params+="&epub_ids="+epub_stringifyArray(epub_id); params+="&epub_titles="+epub_stringifyArray(epub_wikilink); if(client) { params += "&client="+encodeURIComponent(client); } if(book_id) { params+= "&book_page=" + encodeURIComponent(book_id); } jQuery.post( DOKU_BASE + 'lib/plugins/epub/scripts/ebook.php', params, function (data) { dom.innerHTML = '
    ' +decodeURIComponent(decodeURIComponent(data)) + '
    '; regex=/Ebook:\s+(:?epub.*?\.epub)/; result = regex.exec(dom.innerHTML); if(result) { var epub='http://'+ location.host + DOKU_BASE + 'lib/exe/fetch.php?media=' + result[1]; dom.innerHTML +='
    ' + result[1] +'
    '; } }, 'html' ); } function epub_stringifyArray(ar) { ar=ar.join(';;'); ar= ar.replace(/^;;/,""); ar= ar.replace(/;;$/,""); return encodeURIComponent(ar); } function epub_remove_creator(id) { var params="remove="+encodeURIComponent(id); jQuery.post( DOKU_BASE + 'lib/plugins/epub/scripts/update_files.php', params, function (data) { alert(data); }, 'html' ); } function _epub_show_throbber(user,client) { epub_show_throbber(user,client); var dom = document.getElementById('show_throbberbutton'); dom.style.display='none'; epub_check_progress(client,user); } function epub_check_progress(client,user) { var dom = document.getElementById('epub_progress'); var params="user="+encodeURIComponent(user); if(client) { params += "&client="+encodeURIComponent(client); } var secs = 0; var t =window.setInterval(function() { jQuery.post( DOKU_BASE + 'lib/plugins/epub/scripts/check_progess.php', params, function (data) { if(!data) window.clearInterval(t); secs++; dom.innerHTML = data + '[seconds: ' + secs*15 + ']'; }, 'html' ); }, 15000); } function epub_admin_confirm(which) { var f =document.epub_admin; var epubs = new Array(); var msg=""; for(var i=0; i < f.length; i++) { if(f[i].checked) { matches = f[i].name.match(/\[([a-z0-9]+)\]/); msg += f[i].value + "\n" ; } } var confirm_msg = "Please confirm that you want to delete the following cache entries"; if(which == 'media') { confirm_msg +=" and their ebooks"; } if(!confirm(confirm_msg + ":\n" + msg)) return false; return true; } /* XXXXXXXXXX end of lib/plugins/epub/script.js XXXXXXXXXX */ /* XXXXXXXXXX begin of lib/plugins/extension/script.js XXXXXXXXXX */ jQuery(function(){ var $extmgr = jQuery('#extension__manager'); /** * Confirm uninstalling */ $extmgr.find('button.uninstall').on('click', function(e){ if(!window.confirm(LANG.plugins.extension.reallydel)){ e.preventDefault(); return false; } return true; }); /** * very simple lightbox * @link http://webdesign.tutsplus.com/tutorials/htmlcss-tutorials/super-simple-lightbox-with-css-and-jquery/ */ $extmgr.find('a.extension_screenshot').on('click', function(e) { e.preventDefault(); //Get clicked link href var image_href = jQuery(this).attr("href"); // create lightbox if needed var $lightbox = jQuery('#plugin__extensionlightbox'); if(!$lightbox.length){ $lightbox = jQuery('

    Click to close

    ') .appendTo(jQuery('body')) .hide() .on('click', function(){ $lightbox.hide(); }); } // fill and show it $lightbox .show() .find('div').html(''); return false; }); /** * Enable/Disable extension via AJAX */ $extmgr.find('button.disable, button.enable').on('click', function (e) { e.preventDefault(); var $btn = jQuery(this); // get current state var extension = $btn.attr('name').split('[')[2]; extension = extension.substr(0, extension.length - 1); var act = ($btn.hasClass('disable')) ? 'disable' : 'enable'; // disable while we wait $btn.attr('disabled', 'disabled'); $btn.css('cursor', 'wait'); // execute jQuery.get( DOKU_BASE + 'lib/exe/ajax.php', { call: 'plugin_extension', ext: extension, act: act, sectok: $btn.parents('form').find('input[name=sectok]').val() }, function (data) { $btn.css('cursor', '') .removeAttr('disabled') .removeClass('disable') .removeClass('enable') .text(data.label) .addClass(data.reverse) .parents('li') .removeClass('disabled') .removeClass('enabled') .addClass(data.state); } ).fail(function() { $btn.css('cursor', '') .removeAttr('disabled'); }); }); /** * AJAX detail infos */ $extmgr.find('a.info').on('click', function(e){ e.preventDefault(); var $link = jQuery(this); var $details = $link.parent().find('dl.details'); if($details.length){ $link.toggleClass('close'); $details.toggle(); return; } $link.addClass('close'); jQuery.get( DOKU_BASE + 'lib/exe/ajax.php', { call: 'plugin_extension', ext: $link.data('extid'), act: 'info' }, function(data){ $link.parent().append(data); } ); }); /** Create section for enabling/disabling viewing options */ if ( $extmgr.find('.plugins, .templates').hasClass('active') ) { var $extlist = jQuery('#extension__list'); $extlist.addClass('hasDisplayOptions'); var $displayOpts = jQuery('

    ', { id: 'extension__viewoptions'} ).appendTo($extmgr.find( '.panelHeader' )); $displayOpts.append(LANG.plugins.extension.display_viewoptions); var displayOptionsHandler = function(){ $extlist.toggleClass( this.name ); DokuCookie.setValue('ext_'+this.name, $extlist.hasClass(this.name) ? '1' : '0'); }; jQuery(['enabled', 'disabled', 'updatable']).each(function(index, chkName){ var $label = jQuery( '' ) .appendTo($displayOpts); var $input = jQuery( '', { type: 'checkbox', name: chkName }) .on('change', displayOptionsHandler) .appendTo($label); var previous = DokuCookie.getValue('ext_'+chkName); if(typeof previous === "undefined" || previous == '1') { $input.trigger('click'); } jQuery( '' ) .append(' '+LANG.plugins.extension['display_'+chkName]) .appendTo($label); }); } }); /* XXXXXXXXXX end of lib/plugins/extension/script.js XXXXXXXXXX */ /* XXXXXXXXXX begin of lib/plugins/include/script.js XXXXXXXXXX */ /** * Javascript functionality for the include plugin */ /** * Highlight the included section when hovering over the appropriate include edit button * * @author Andreas Gohr * @author Michael Klier * @author Michael Hamann */ jQuery(function() { jQuery('.btn_incledit') .mouseover(function () { jQuery(this).closest('.plugin_include_content').addClass('section_highlight'); }) .mouseout(function () { jQuery('.section_highlight').removeClass('section_highlight'); }); }); // vim:ts=4:sw=4:et: /* XXXXXXXXXX end of lib/plugins/include/script.js XXXXXXXXXX */ /* XXXXXXXXXX begin of lib/plugins/logviewer/script.js XXXXXXXXXX */ /** * Scroll to the end of the log on load */ jQuery(function () { var $dl = jQuery('#plugin__logviewer').find('dl'); if (!$dl.length) return; $dl.animate({scrollTop: $dl.prop("scrollHeight")}, 500); var $filter = jQuery(''); $filter.on('keyup', function (e) { var re = new RegExp($filter.val(), 'i'); $dl.find('dt').each(function (idx, elem) { if (elem.innerText.match(re)) { jQuery(elem).removeClass('hidden'); } else { jQuery(elem).addClass('hidden'); } }); }); $dl.before($filter); $filter.wrap(''); $filter.before(LANG.plugins.logviewer.filter + ' '); }); /* XXXXXXXXXX end of lib/plugins/logviewer/script.js XXXXXXXXXX */ /* XXXXXXXXXX begin of lib/plugins/note/script.js XXXXXXXXXX */ /* Add Note buttons to the toolbar */ /* from http://wiki.splitbrain.org/wiki:tips:toolbarbutton */ /* Disabled because this does not allow to select a text and turn it into a note like the type:format does var notes_arr = new Array(); // key = insertion string , value = icon filename. notes_arr['\\n']='tb_note.png'; notes_arr['\\n']='tb_tip.png'; notes_arr['\\n']='tb_important.png'; notes_arr['\\n']='tb_warning.png'; toolbar[toolbar.length] = {"type":"picker", "title":"Notes", "icon":"../../plugins/note/images/tb_note.png", "key":"", "list": notes_arr, "icobase":"../plugins/note/images"}; */ if(toolbar){ toolbar[toolbar.length] = {"type":"format", "title":"note", "key":"", "icon":"../../plugins/note/images/tb_note.png", "open":"", "close":"" }; toolbar[toolbar.length] = {"type":"format", "title":"tip", "key":"", "icon":"../../plugins/note/images/tb_tip.png", "open":"", "close":"" }; toolbar[toolbar.length] = {"type":"format", "title":"important", "key":"", "icon":"../../plugins/note/images/tb_important.png", "open":"", "close":"" }; toolbar[toolbar.length] = {"type":"format", "title":"warning", "key":"", "icon":"../../plugins/note/images/tb_warning.png", "open":"", "close":"" }; } /* XXXXXXXXXX end of lib/plugins/note/script.js XXXXXXXXXX */ /* XXXXXXXXXX begin of lib/plugins/searchindex/script.js XXXXXXXXXX */ /** * Javascript for searchindex manager plugin * * @author Andreas Gohr * @author Symon Bent * Complete rewrite using jQuery and revealing module pattern * Separate update and rebuild options */ var plugin_searchindex = (function() { // public methods/properties var pub = {}; // private vars var pages = null, page = null, url = null, done = 1, count = 0, $msg = null, $buttons = null, lang = null; force = ''; /** * initialize everything */ pub.init = function() { $msg = jQuery('#plugin__searchindex_msg'); if( ! $msg) return; lang = LANG.plugins.searchindex; url = DOKU_BASE + 'lib/plugins/searchindex/ajax.php'; $buttons = jQuery('#plugin__searchindex_buttons'); // init interface events jQuery('#plugin__searchindex_update').click(pub.update); jQuery('#plugin__searchindex_rebuild').click(pub.rebuild); }; /** * Gives textual feedback */ var message = function(text) { if (text.charAt(0) !== '<') { text = '

    ' + text + '

    ' } $msg.html(text); }; /** * Starts the indexing of a page. */ var index = function() { if (page) { jQuery.post(url, 'call=indexpage&page=' + encodeURI(page) + '&force=' + force, function(response) { var wait = 250; // next page from queue page = pages.shift(); done++; var msg = (response !== 'true') ? lang.notindexed : lang.indexed; status = '

    ' + msg + '

    '; message('

    ' + lang.indexing + ' ' + done + '/' + count + '

    ' + page + '

    ' + status); // next index run window.setTimeout(index, wait); }); } else { finished(); } }; var finished = function() { // we're done throbber_off(); message(lang.done); window.setTimeout(function() { message(''); $buttons.show('slow'); }, 3000); }; /** * Cleans the index (ready for complete rebuild) */ var clear = function() { message(lang.clearing); jQuery.post(url, 'call=clearindex', function(response) { if (response !== 'true') { message(response); // retry window.setTimeout(clear,5000); } else { // start indexing force = 'true'; window.setTimeout(index,1000); } }); }; pub.rebuild = function() { pub.update(true); }; /** * Starts the index update */ pub.update = function(rebuild) { done = 1; rebuild = rebuild || false; $buttons.hide('slow'); throbber_on(); message(lang.finding); jQuery.post(url, 'call=pagelist', function(response) { if (response !== 'true') { pages = response.split("\n"); count = pages.length; message(lang.pages.replace(/%d/, pages.length)); // move the first page from the queue page = pages.shift(); // complete index rebuild? if (rebuild === true) { clear(); } else { force = ''; // just start indexing immediately window.setTimeout(index,1000); } } else { finished(); } }); }; /** * add a throbber image */ var throbber_on = function() { $msg.addClass('updating'); }; /** * Stop the throbber */ var throbber_off = function() { $msg.removeClass('updating'); }; // return only public methods/properties return pub; })(); jQuery(function() { plugin_searchindex.init(); }); /* XXXXXXXXXX end of lib/plugins/searchindex/script.js XXXXXXXXXX */ /* XXXXXXXXXX begin of lib/plugins/styling/script.js XXXXXXXXXX */ jQuery(function () { /** * Function to reload the preview styles in the main window * * @param {Window} target the main window */ function applyPreview(target) { // remove style var $style = target.jQuery('link[rel=stylesheet][href*="lib/exe/css.php"]'); $style.attr('href', ''); // append the loader screen var $loader = target.jQuery('#plugin__styling_loader'); if (!$loader.length) { $loader = target.jQuery('
    ' + LANG.plugins.styling.loader + '
    '); $loader.css({ 'position': 'absolute', 'width': '100%', 'height': '100%', 'top': 0, 'left': 0, 'z-index': 5000, 'background-color': '#fff', 'opacity': '0.7', 'color': '#000', 'font-size': '2.5em', 'text-align': 'center', 'line-height': 1.5, 'padding-top': '2em' }); target.jQuery('body').append($loader); } // load preview in main window (timeout works around chrome updating CSS weirdness) setTimeout(function () { var now = new Date().getTime(); $style.attr('href', DOKU_BASE + 'lib/exe/css.php?preview=1&tseed=' + now); }, 500); } var doreload = 1; var $styling_plugin = jQuery('#plugin__styling'); // if we are not on the plugin page (either main or popup) if (!$styling_plugin.length) { // handle the preview cookie if(DokuCookie.getValue('styling_plugin') == 1) { applyPreview(window); } return; // nothing more to do here } /* ---- from here on we're in the popup or admin page ---- */ // add button on main page if (!$styling_plugin.hasClass('ispopup')) { var $form = $styling_plugin.find('form.styling').first(); var $btn = jQuery(''); $form.prepend($btn); $btn.on('click', function (e) { var windowFeatures = "menubar=no,location=no,resizable=yes,scrollbars=yes,status=false,width=500,height=500"; window.open(DOKU_BASE + 'lib/plugins/styling/popup.php', 'styling_popup', windowFeatures); e.preventDefault(); e.stopPropagation(); }).wrap('

    '); return; // we exit here if this is not the popup } /* ---- from here on we're in the popup only ---- */ // reload the main page on close window.onunload = function(e) { if(doreload) { DokuCookie.setValue('styling_plugin', 0); if(window.opener) window.opener.document.location.reload(); } return null; }; // don't reload on our own buttons jQuery(':button').click(function(e){ doreload = false; }); // on first load apply preview if(window.opener) applyPreview(window.opener); // enable the preview cookie DokuCookie.setValue('styling_plugin', 1); }); /* XXXXXXXXXX end of lib/plugins/styling/script.js XXXXXXXXXX */ /* XXXXXXXXXX begin of lib/plugins/tag/script.js XXXXXXXXXX */ /** * For the searchtags syntax: make the checkboxes behave like radio buttons * so the user can't both include and exclude a tag */ jQuery(function() { jQuery('form.plugin__tag_search table input').change(function() { if (jQuery(this).attr('checked')) { // was this input checked? if (jQuery(this).parent().hasClass('minus')) { // find the other input in the same tr and uncheck it jQuery(this).closest('tr').find('.plus input').attr('checked', false); } else { jQuery(this).closest('tr').find('.minus input').attr('checked', false); } } }) }); /* XXXXXXXXXX end of lib/plugins/tag/script.js XXXXXXXXXX */ /* XXXXXXXXXX begin of lib/plugins/usermanager/script.js XXXXXXXXXX */ /** * Add JavaScript confirmation to the User Delete button */ jQuery(function(){ jQuery('#usrmgr__del').on('click', function(){ return confirm(LANG.del_confirm); }); }); /* XXXXXXXXXX end of lib/plugins/usermanager/script.js XXXXXXXXXX */ /* XXXXXXXXXX begin of lib/plugins/vshare/script.js XXXXXXXXXX */ /** * Append a toolbar button */ if (window.toolbar !== undefined) { toolbar[toolbar.length] = { "type": "pluginvshare", "title": LANG['plugins']['vshare']['button'], "icon": "../../plugins/vshare/button.png", "key": "" }; } /** * Try to determine the video service, extract the ID and insert * the correct syntax */ function tb_pluginvshare(btn, props, edid) { PluginVShare.edid = edid; PluginVShare.buildSyntax(); } const PluginVShare = { edid: null, /** * Ask for URL, extract data and create syntax */ buildSyntax: function () { const text = prompt(LANG['plugins']['vshare']['prompt']); if (!text) return; for (const [site, rex] of Object.entries(JSINFO.plugins.vshare)) { const RE = new RegExp(rex, 'i'); const match = text.match(RE); if (match) { const urlparam = ''; const videoid = match[1]; PluginVShare.insert(site, videoid, urlparam); return; } } alert(LANG['plugins']['vshare']['notfound']); }, /** * Insert the syntax in the editor * * @param {string} key * @param {string} videoid * @param {string} urlparam */ insert: function (key, videoid, urlparam) { const code = '{{' + key + '>' + videoid + '?' + urlparam + '}}'; insertAtCarret(PluginVShare.edid, code); }, /** * Allow loading videos on click */ attachGDPRHandler: function () { const $videos = jQuery('div.vshare'); // add click handler $videos.on('click', function () { // create an iframe and copy over the attributes const iframe = document.createElement('iframe'); let attr; let attributes = Array.prototype.slice.call(this.attributes); while(attr = attributes.pop()) { iframe.setAttribute(attr.nodeName, attr.nodeValue); } // replace the div with the iframe this.replaceWith(iframe); }); // add info text $videos.each(function (){ const $self = jQuery(this); const info = document.createElement('p'); info.innerText = LANG.plugins.vshare.click.replace('%s', $self.data('domain')); $self.append(info); }); } }; jQuery(function () { PluginVShare.attachGDPRHandler(); }); /* XXXXXXXXXX end of lib/plugins/vshare/script.js XXXXXXXXXX */ jQuery(function(){ dw_locktimer.init(840,1); });