Zum Inhalt springen

„Benutzer:Trigonomie/wikEdDiff.js“ – Versionsunterschied

aus Wikipedia, der freien Enzyklopädie
Inhalt gelöscht Inhalt hinzugefügt
Keine Bearbeitungszusammenfassung
aktuelle Version übernommen von https://en.wikipedia.org/w/index.php?title=User%3ACacycle%2FwikEdDiff.js&diff=629600284&oldid=629595952
 
Zeile 1: Zeile 1:
// Kopie von http://en.wikipedia.org/w/index.php?title=User:Cacycle/wikEdDiff.js&oldid=459677987
// Kopie von https://en.wikipedia.org/w/index.php?title=User%3ACacycle%2FwikEdDiff.js&diff=629600284&oldid=629595952
// zur Einbindung in meine monobook.js - Leider ist die aktuelle Version von [[en:user:Cacycle]] buggy für IE Nutzer, deshalb hier eine alte Version
// zur Einbindung in meine monobook.js - Leider ist die aktuelle Version von [[en:user:Cacycle]] buggy für IE Nutzer, deshalb hier eine alte Version
// 22. August 2012, Fix von Cacycle für IE übernommen
// 22. August 2012, Fix von Cacycle für IE übernommen
// 20. Oktober 2014 neue Version übernommen, alte funktionert nicht mehr
// <source lang="JavaScript">
// <syntaxhighlight lang="JavaScript">


// ==UserScript==
if (typeof(wikEd) == 'undefined') { window.wikEd = {}; }
// @name wikEdDiff

// version info
// @version 0.9.38
// @date October 14, 2014
wikEd.diffProgramVersion = '0.9.16b';
// @description improved diff with block move detection for comparing article versions
wikEd.diffProgramDate = 'August 06, 2012';
// @homepage https://en.wikipedia.org/wiki/User:Cacycle/wikEdDiff
// @source https://en.wikipedia.org/wiki/User:Cacycle/wikEdDiff.js
// @author Cacycle (https://en.wikipedia.org/wiki/User:Cacycle)
// @license released into the public domain
// @include /\b(action=submit|diff=)\b/
// @require https://en.wikipedia.org/w/index.php?title=User:Cacycle/diff.js&action=raw&ctype=text/javascript
// @grant GM_getValue
// @grant GM_xmlhttpRequest
// ==/UserScript==


/*
/*

== wikEdDiff ==

A user script that provides an improved and easier to read diff view for comparing article versions
on Wikipedia and other MediaWiki sites.


Features:
Features:
* Additions and deletions are highlighted by color in the same text
* Additions, deletions, and block moves are highlighted by color in the same text
* Block moves are detected and indicated by color
* Block moves and character differences are detected
* Unchanged regions of the text are omitted from the output
* Unchanged regions are omitted from the output
* Highly optimized for MediaWiki source texts
* Highly optimized for MediaWiki source texts
* Compatible with Greasemonkey


wikEdDiff uses the Cacycle diff.js routines [[en:User:Cacycle/diff]] and is also an integrated part of wikEd,
wikEdDiff uses the diff.js library (https://en.wikipedia.org/wiki/User:Cacycle/Cacycle/diff) and has been integrated
the full-featured JavaScript in-browser editor (http://en.wikipedia.org/wiki/User:Cacycle/wikEd)
into wikEd, a full-featured JavaScript in-browser editor (https://en.wikipedia.org/wiki/User:Cacycle/wikEd).
For installation details, please see https://en.wikipedia.org/wiki/User:Cacycle/wikEdDiff.


*/
Homepage: http://en.wikipedia.org/wiki/User:Cacycle/wikEdDiff
Author: Cacycle (http://en.wikipedia.org/wiki/User:Cacycle)
License: This code has been released into the public domain


// JSHint options
== Installation ==
/* jshint -W004, -W100, newcap: false, browser: true, jquery: true, sub: true, bitwise: true, curly: false, evil: true, forin: true, freeze: true, globalstrict: true, immed: true, latedef: true, loopfunc: true, quotmark: single, strict: true, undef: true */
/* global GM_getValue, GM_xmlhttpRequest, console */


// turn on ECMAScript 5 strict mode
* Copy the following short block of code to [[User:YOURUSERNAME/monobook.js]]
'use strict';
* Press SHIFT-Reload to update to the newest version
* PLEASE DO NOT COPY THE WHOLE PROGRAM
* See http://en.wikipedia.org/wiki/User:Cacycle/wikEdDiff for detailed instructions
* Users of wikEd do not have to install wikEdDiff


// define global objects
// ---- START INSTALLATION CODE ----
var wikEd; if ( wikEd === undefined ) { wikEd = {}; }

if ( wikEd.config === undefined ) { wikEd.config = {}; }
// install [[User:Cacycle/wikEdDiff]] enhanced diff view using ajax
var WikEdDiff;
document.write('<script type="text/javascript" src="'
var wikEdConfig;
+ 'http://en.wikipedia.org/w/index.php?title=User:Cacycle/wikEdDiff.js'
+ '&action=raw&ctype=text/javascript"></script>');

// ---- END INSTALLATION CODE ----

*/


if (typeof(wikEd.config) == 'undefined') { wikEd.config = {}; }


//
//
Zeile 57: Zeile 51:
//
//


wikEd.DiffInit = function() {
wikEd.DiffInit = function () {


//
//
Zeile 64: Zeile 58:


// wikEd code home base URL, also defined in wikEd.js
// wikEd code home base URL, also defined in wikEd.js
if (typeof(wikEd.config.homeBaseUrl) == 'undefined') { wikEd.config.homeBaseUrl = '//en.wikipedia.org/'; }
if ( wikEd.config.homeBaseUrl === undefined ) { wikEd.config.homeBaseUrl = '//en.wikipedia.org/'; }


// diff.js routines URL, also defined in wikEd.js
// diff library URL, also defined in wikEd.js
if (typeof(wikEd.config.diffScriptSrc) == 'undefined') { wikEd.config.diffScriptSrc = wikEd.config.homeBaseUrl + 'w/index.php?title=User:Cacycle/diff.js&action=raw&ctype=text/javascript'; }
if ( wikEd.config.diffScriptSrc === undefined ) { wikEd.config.diffScriptSrc = wikEd.config.homeBaseUrl + 'w/index.php?title=User:Cacycle/diff.js&action=raw&ctype=text/javascript'; }

// allow ajax requests from local copy for testing, also defined in wikEd.js
if (typeof(wikEd.config.allowLocalAjax) == 'undefined') { wikEd.config.allowLocalAjax = false; }


// wikEdDiff css rules
// wikEdDiff css rules
if (typeof(wikEd.config.diffCSS) == 'undefined') { wikEd.config.diffCSS = {}; }
if ( wikEd.config.diffCSS === undefined ) { wikEd.config.diffCSS = {}; }
wikEd.InitObject(wikEd.config.diffCSS, {
wikEd.InitObject( wikEd.config.diffCSS, {
'.wikEdDiffWrapper': 'margin: 0 0 1em 0;',
'.wikEdDiffWrapper': 'padding: 0.33em 0.5em;',
'.wikEdDiffButtonWrapper': 'text-align: center;',
'.wikEdDiffButtonWrapper': 'text-align: center;',
'.wikEdDiffButtonChecked':
'.wikEdDiffButton': 'padding: 0; margin: 0.2em 0 0.33em 0;',
'.wikEdDiffDiv': 'background: #faf8f6; padding: 0.5em; border: 1px solid; border-color: #808080;'
'padding: 0.1em 0.1em 0.2em; background: #c8c4c0; border: 1px solid; ' +
'border-color: #555 #e8e8e8 #e8e8e8 #555; border-radius: 0.25em; cursor: pointer;',
});
'.wikEdDiffButtonUnchecked':
'padding: 0.1em 0.1em 0.2em; background: #d8d4d0; border: 1px solid; ' +
'border-color: #f0f0f0 #666 #666 #f0f0f0; border-radius: 0.25em; cursor: pointer;',
'.wikEdDiffButtonPressed':
'padding: 0.1em 0.1em 0.2em; background: #c8c4c0; border: 1px solid; ' +
'border-color: #666 #f0f0f0 #f0f0f0 #666; border-radius: 0.25em; cursor: wait;',
'.wikEdDiffDiv': 'margin-top: 0.5em;',
'.wikEdDiffWorking':
'background: #fcfcfc; border: 1px #bbb solid; border-radius: 0.5em; line-height: 1.6; ' +
'box-shadow: 2px 2px 2px #ddd; padding: 0.5em; margin: 1em 0; text-align: center;'
} );


// use local copies of images for testing (set to true in local copy of edit page), also defined in wikEd.js
// use local copies of images for testing (set to true in local copy of edit page), also defined in wikEd.js
if (typeof(wikEd.config.localImages) == 'undefined') { wikEd.config.localImages = false; }
if ( wikEd.config.localImages === undefined ) { wikEd.config.localImages = false; }


// path to local images for testing, also defined in wikEd.js
// path to local wikEd images for testing, also defined in wikEd.js
if (typeof(wikEd.config.imagePathLocal) == 'undefined') { wikEd.config.imagePathLocal = 'file:///D:/wikEd/images/'; }
if ( wikEd.config.imagePathLocal === undefined ) { wikEd.config.imagePathLocal = 'file:///D:/wikEd/images/'; }


// path to images, also defined in wikEd.js
// path to wikEd images, also defined in wikEd.js
if (typeof(wikEd.config.imagePath) == 'undefined') { wikEd.config.imagePath = '/media/wikipedia/commons/'; }
if ( wikEd.config.imagePath === undefined ) { wikEd.config.imagePath = '/media/wikipedia/commons/'; }


// image filenames, also defined in wikEd.js
// wikEd image filenames, also defined in wikEd.js
if (typeof(wikEd.config.image) == 'undefined') { wikEd.config.image = {}; }
if ( wikEd.config.image === undefined ) { wikEd.config.image = {}; }
wikEd.InitImage(wikEd.config.image, {
wikEd.InitImage( wikEd.config.image, {
'wikEdDiff': 'c/c6/WikEdDiff.png'
'wikEdDiff': 'c/c6/WikEdDiff.png'
});
} );


// user readable texts, copy changes to http://en.wikipedia.org/wiki/User:Cacycle/wikEd_international_en.js, also defined in wikEd.js
// user readable texts, copy changes to http://en.wikipedia.org/wiki/User:Cacycle/wikEd_international_en.js, also defined in wikEd.js
if (typeof(wikEd.config.text) == 'undefined') { wikEd.config.text = {}; }
if ( wikEd.config.text === undefined ) { wikEd.config.text = {}; }
wikEd.InitObject(wikEd.config.text, {
wikEd.InitObject( wikEd.config.text, {
'wikEdDiffButtonImg alt': 'wikEdDiff',
'wikEdDiffButtonImg alt': 'wikEdDiff',
'wikEdDiffButton title': 'Show improved diff view',
'wikEdDiffButton title': 'Show improved diff view',
'wikEdDiffLoading': '...'
'wikEdDiffLoading': '...'
});
} );


// show complete unshortened article text for local diff, also defined in wikEd.js
// expiration time span for permanent cookies in seconds, also defined in wikEd.js
if (typeof(wikEd.config.fullDiff) == 'undefined') { wikEd.config.fullDiff = false; }
if ( wikEd.config.cookieExpireSec === undefined ) { wikEd.config.cookieExpireSec = 1 * 30 * 24 * 60 * 60; }


//
//
Zeile 119: Zeile 121:


// hash of loaded scripts, also defined in wikEd.js
// hash of loaded scripts, also defined in wikEd.js
if (typeof(wikEd.externalScripts) == 'undefined') { wikEd.externalScripts = null; }
if ( wikEd.externalScripts === undefined ) { wikEd.externalScripts = null; }
if (typeof(wikEd.diffPreset) == 'undefined') { wikEd.diffPreset = false; }
if ( wikEd.diffPreset === undefined ) { wikEd.diffPreset = false; }

// diff table element
wikEd.diffTable = null;
};
};


// variables needed during startup
// variables needed during startup
wikEd.diffTable = null;
wikEd.diffTableTitle = null;
wikEd.diffColSpan = null;

// diff table element


// customization, also defined in wikEd.js
// customization, also defined in wikEd.js
if (typeof(wikEd.wikEdConfigAdded) == 'undefined') { wikEd.wikEdConfigAdded = false; }
if ( wikEd.wikEdConfigAdded === undefined ) { wikEd.wikEdConfigAdded = false; }


// detect web storage capability and Greasemonkey related, also defined in wikEd.js
// detect web storage capability and Greasemonkey related, also defined in wikEd.js
if (typeof(wikEd.webStorage) == 'undefined') { wikEd.webStorage = null; }
if ( wikEd.webStorage === undefined ) { wikEd.webStorage = null; }
if (typeof(wikEd.greasemonkey) == 'undefined') { wikEd.greasemonkey = false; }
if ( wikEd.greasemonkey === undefined ) { wikEd.greasemonkey = false; }
if (typeof(wikEd.gotGlobalsHook) == 'undefined') { wikEd.gotGlobalsHook = []; }
if ( wikEd.gotGlobalsHook === undefined ) { wikEd.gotGlobalsHook = []; }
if (typeof(wikEd.getGlobalsCounter) == 'undefined') { wikEd.getGlobalsCounter = 0; }
if ( wikEd.getGlobalsCounter === undefined ) { wikEd.getGlobalsCounter = 0; }
if (typeof(wikEd.pageOrigin) == 'undefined') { wikEd.pageOrigin = ''; }
if ( wikEd.pageOrigin === undefined ) { wikEd.pageOrigin = ''; }
if (typeof(wikEd.head) == 'undefined') { wikEd.head = null; }
if ( wikEd.head === undefined ) { wikEd.head = null; }
if (typeof(wikEd.diffTableLinkified) == 'undefined') { wikEd.diffTableLinkified = false; }
if ( wikEd.diffTableLinkified === undefined ) { wikEd.diffTableLinkified = false; }


// get global MediaWiki settings, also defined in wikEd.js
// get global MediaWiki settings, also defined in wikEd.js
if (typeof(wikEd.wikiGlobals) == 'undefined') { wikEd.wikiGlobals = {}; }
if ( wikEd.wikiGlobals === undefined ) { wikEd.wikiGlobals = {}; }
if (typeof(wikEd.pageName) == 'undefined') { wikEd.pageName = null; }
if ( wikEd.pageName === undefined ) { wikEd.pageName = null; }

// check for web storage availability, throws error in FF 3.6 with dom.storage.enabled=false, see bug 599479 (code copied from wikEd.js)
if (typeof(wikEdTypeofLocalStorage) == 'undefined') {
window.wikEdTypeofLocalStorage = '';
setTimeout('window.wikEdTypeofLocalStorage = typeof(window.localStorage);', 0);
}




Zeile 155: Zeile 153:
//
//


wikEd.DiffStartup = function() {
wikEd.DiffStartup = function () {


// MediaWiki pages always have their title set, filter out Greasemonkey running on created iframes
// MediaWiki pages always have their title set, filter out Greasemonkey running on created iframes
if (document.title == '') {
if ( document.title === '' ) {
return;
return;
}
}


// check if wikEdDiff has already started up
// check if wikEdDiff has already started up
if (document.getElementsByName('wikEdDiffStartupFlag')[0] != null) {
if ( document.getElementsByName( 'wikEdDiffStartupFlag')[0] !== undefined ) {
return;
return;
}
}


// define current window head
// define current window head
wikEd.head = document.getElementsByTagName('head')[0];
wikEd.head = document.getElementsByTagName( 'head')[0] || null;


// set startup flag
// set startup flag
var flag = document.createElement('meta');
var flag = document.createElement( 'meta' );
flag.setAttribute('name', 'wikEdDiffStartupFlag');
flag.setAttribute( 'name', 'wikEdDiffStartupFlag' );
wikEd.head.appendChild(flag);
wikEd.head.appendChild( flag );


// get site of origin (window.location.href is about:blank if Firefox during page load)
// get site of origin (window.location.href is about:blank if Firefox during page load)
var origin = wikEd.head.baseURI;
var origin = wikEd.head.baseURI;
if (origin == null) {
if ( origin === undefined ) {
origin = window.location.toString();
origin = window.location.toString();
}
}
wikEd.pageOrigin = origin.replace(/^((https?|file):\/\/[^\/?#]*)?.*$/, '$1');
wikEd.pageOrigin = origin.replace( /^((https?|file):\/\/[^\/?#]*)?.*$/, '$1' );


// check if this runs under Greasemonkey
// check if this runs under Greasemonkey
if (typeof(GM_getValue) == 'function') {
if ( typeof GM_info === 'object' ) {
wikEd.greasemonkey = true;
wikEd.greasemonkey = true;
}
}
Zeile 189: Zeile 187:
// parse global-context (MediaWiki) variables into hash (for Greasemonkey)
// parse global-context (MediaWiki) variables into hash (for Greasemonkey)
var globalNames = ['wgServer', 'wgArticlePath', 'wgScriptPath', 'wgCurRevisionId', 'wikEdTypeofLocalStorage', 'wgPageName'];
var globalNames = ['wgServer', 'wgArticlePath', 'wgScriptPath', 'wgCurRevisionId', 'wikEdTypeofLocalStorage', 'wgPageName'];
if (wikEd.greasemonkey == true) {
if ( wikEd.greasemonkey === true ) {
globalNames.push('wikEdConfig');
globalNames.push( 'wikEdConfig' );
}
}


// copy custom config settings after values have arrived
// copy custom config settings after values have arrived
var gotGlobalsHook = [
var gotGlobalsHook = [
function() {
function () {
if ( (typeof(wikEd.wikiGlobals.wikEdConfig) == 'object') && (wikEd.wikEdConfigAdded == false) ) {
if ( typeof wikEd.wikiGlobals.wikEdConfig === 'object' && wikEd.wikEdConfigAdded === false ) {
wikEd.AddToObject(wikEd.config, wikEd.wikiGlobals.wikEdConfig);
wikEd.AddToObject( wikEd.config, wikEd.wikiGlobals.wikEdConfig );
wikEd.wikEdConfigAdded = true;
wikEd.wikEdConfigAdded = true;
}


// get missing wg variables from footer link, fails on /subpages (code copied from wikEd.js)
// get missing wg variables from footer link (code copied to wikEdDiff.js)
if (wikEd.wikiGlobals.wgArticlePath == null) {
if ( wikEd.wikiGlobals.wgArticlePath === undefined ) {
var printfooter = wikEd.GetElementsByClassName('printfooter', 'div')[0];
var printfooter = document.body.getElementsByClassName( 'printfooter' )[0];
if (printfooter != null) {
if ( printfooter !== undefined ) {
var articleLink = printfooter.getElementsByTagName('a')[0];
var articleLink = printfooter.getElementsByTagName( 'a' )[0];
if (articleLink != null) {
if ( articleLink !== undefined ) {
var regExpMatch = /^(https?:\/\/[^\/]*)(\/([^\/]*\/)*)([^\/]*)$/.exec(articleLink.href);
var regExpMatch = /^(https?:\/\/[^\/]*)(\/([^\/]*\/)*)([^\/]*)$/.exec( articleLink.href );
if (regExpMatch != null) {
if ( regExpMatch !== null ) {
wikEd.wikiGlobals.wgServer = regExpMatch[1];
wikEd.wikiGlobals.wgServer = regExpMatch[1];
wikEd.wikiGlobals.wgArticlePath = regExpMatch[1] + regExpMatch[2] + '$1';
wikEd.wikiGlobals.wgArticlePath = regExpMatch[1] + regExpMatch[2] + '$1';
wikEd.wikiGlobals.wgPageName = regExpMatch[4];
wikEd.wikiGlobals.wgPageName = regExpMatch[4] || '';
wikEd.wikiGlobals.wgTitle = decodeURIComponent( regExpMatch[4].replace(/_/g, ' ') );
wikEd.wikiGlobals.wgTitle = decodeURIComponent( regExpMatch[4].replace( /_/g, ' ' ) );
}
}
}
}
}
}
}
}


// get current page name
// get current page name
wikEd.pageName = wikEd.wikiGlobals.wgPageName;
wikEd.pageName = wikEd.wikiGlobals.wgPageName;
}
return;
}
}
];
];


// linkify standard diff
// linkify standard diff
gotGlobalsHook.push(wikEd.DiffLinkifyStandard);
gotGlobalsHook.push( wikEd.DiffLinkifyStandard );


// set listener for GetGlobals messaging
// set listener for GetGlobals messaging
wikEd.AddEventListener(window, 'message', wikEd.GetGlobalsReceiver, false);
wikEd.DiffAddEventListener( window, 'message', wikEd.GetGlobalsReceiver, false );


// parse globals (asynchronous)
// parse globals (asynchronous)
wikEd.GetGlobals(globalNames, gotGlobalsHook);
wikEd.GetGlobals( globalNames, gotGlobalsHook );


// run the setup routine if loaded dynamically from wikEd
// run the setup routine if page has loaded or if loaded dynamically from wikEd
if (document.getElementsByName('wikEdSetupFlag')[0] != null) {
if ( document.readyState === 'complete' || document.getElementsByName( 'wikEdSetupFlag' )[0] !== undefined ) {
wikEd.DiffSetup();
wikEd.DiffSetup();
}
}
Zeile 240: Zeile 237:
// schedule the setup routine
// schedule the setup routine
else {
else {
wikEd.AddEventListener(window, 'load', wikEd.DiffSetup, false);
wikEd.DiffAddEventListener( window, 'load', wikEd.DiffSetup, false );
}
}
};
};
Zeile 249: Zeile 246:
//
//


wikEd.DiffSetup = function() {
wikEd.DiffSetup = function () {


// check if wikEdDiff has already set up
// check if wikEdDiff has already set up
if (document.getElementsByName('wikEdDiffSetupFlag')[0] != null) {
if ( document.getElementsByName( 'wikEdDiffSetupFlag' )[0] !== undefined ) {
return;
return;
}
}


// set setup flag
// set setup flag
var flag = document.createElement('meta');
var flag = document.createElement( 'meta' );
flag.setAttribute('name', 'wikEdDiffSetupFlag');
flag.setAttribute( 'name', 'wikEdDiffSetupFlag' );
wikEd.head.appendChild(flag);
wikEd.head.appendChild( flag );


// import customization
// import customization
if ( (typeof(wikEdConfig) == 'object') && (wikEd.wikEdConfigAdded == false) ) {
if ( wikEdConfig !== undefined && wikEd.wikEdConfigAdded === false ) {
wikEd.AddToObject(wikEd.config, wikEdConfig);
wikEd.AddToObject( wikEd.config, wikEdConfig );
wikEd.wikEdConfigAdded = true;
wikEd.wikEdConfigAdded = true;
}
}
Zeile 270: Zeile 267:
wikEd.DiffInit();
wikEd.DiffInit();


// detect diff table
// get diff table title row
var tdOld = null;
var tables = document.getElementsByTagName('table');
var tdNew = null;
for (var i = 0; i < tables.length; i ++) {
var tdArray = document.getElementsByTagName( 'td' );
if (tables.item(i).className.search(/^diff\b/) >= 0) {
for ( var i = 0; i < tdArray.length; i ++ ) {
wikEd.diffTable = tables.item(i);

// get old title cell
if ( tdArray[i].className === 'diff-otitle' ) {
tdOld = tdArray[i];
}
}
}


// get new title cell
// check if this is a diff page
if (wikEd.diffTable == null) {
else if ( tdArray[i].className === 'diff-ntitle' ) {
tdNew = tdArray[i];
return;
}

if ( tdOld !== null && tdNew !== null ) {
break;
}
}
}


// get table
// detect already loaded external scripts, also in wikEd.js
if (wikEd.externalScripts == null) {
if ( tdOld !== null ) {
wikEd.externalScripts = [];
wikEd.diffTableTitle = tdOld.parentNode;
var node = wikEd.diffTableTitle.parentNode;
var pageScripts = document.getElementsByTagName('script');
for (var i = 0; i < pageScripts.length; i ++) {
while ( node !== null ) {
if ( node.nodeName === 'TABLE' ) {
var scriptSrc = pageScripts[i].src;
wikEd.diffTable = node;
var nameMatch = scriptSrc.match(/\btitle=([^&]*)/);
break;
if (nameMatch == null) {
nameMatch = scriptSrc.match(/\/([^\/]*?)($|\?)/);
}
if (nameMatch != null) {
var scriptName = nameMatch[1];
if (scriptName != '') {

// ignore other diff.js scripts
if ( (scriptName == 'diff.js') && (scriptSrc != wikEd.config.diffScriptSrc) ) {
continue;
}
wikEd.externalScripts[scriptName] = true;
}
}
}
node = node.parentNode;
}
}
}
}


// load the external diff script
// get number of diff table columns
if (wikEd.externalScripts['diff.js'] == null) {
if ( tdOld !== null && tdNew !== null ) {
wikEd.diffColSpan = tdOld.colSpan + tdNew.colSpan;
if (typeof(WDiffString) == 'undefined') {
}
var script = document.createElement('script');
if ( isNaN( wikEd.diffColSpan ) === true ) {
script.type = 'text/javascript';
wikEd.diffColSpan = 4;
script.src = wikEd.config.diffScriptSrc;
}
wikEd.head.appendChild(script);

}
// check if this is a diff page
wikEd.externalScripts['diff.js'] = true;
if ( wikEd.diffTable === null ) {
return;
}
}


// add stylesheet definitions (slow method for IE compatibility)
// add stylesheet definitions ( slow method for IE compatibility )
var diffStyle = new wikEd.StyleSheet();
var diffStyle = new wikEd.DiffStyleSheet();
for (var ruleName in wikEd.config.diffCSS) {
for ( var ruleName in wikEd.config.diffCSS ) {
if (wikEd.config.diffCSS.hasOwnProperty(ruleName) == true) {
if ( Object.prototype.hasOwnProperty.call( wikEd.config.diffCSS, ruleName ) === true ) {
var ruleStyle = wikEd.config.diffCSS[ruleName];
var ruleStyle = wikEd.config.diffCSS[ruleName];
diffStyle.AddCSSRule(ruleName, ruleStyle);
diffStyle.AddCSSRule( ruleName, ruleStyle );
}
}
}
}


// create wikEdDiff wrapper
// get saved wikEdDiff setting
var setting = wikEd.GetCookie( 'wikEdDiff' );
wikEd.diffWrapper = document.createElement('div');
if ( setting === '' && typeof wikEd.config.diffPreset === 'boolean' ) {
wikEd.diff = wikEd.config.diffPreset;
}
else if ( setting === '1' ) {
wikEd.diff = true;
}

// create wikEdDiff wrapper row
var diffRow = document.createElement( 'tr' );

// create wikEdDiff wrapper (td)
wikEd.diffWrapper = document.createElement( 'td' );
wikEd.diffWrapper.id = 'wikEdDiffWrapper';
wikEd.diffWrapper.id = 'wikEdDiffWrapper';
wikEd.diffWrapper.className = 'wikEdDiffWrapper';
wikEd.diffWrapper.className = 'wikEdDiffWrapper';
wikEd.diffWrapper.setAttribute( 'colspan', wikEd.diffColSpan );
diffRow.appendChild( wikEd.diffWrapper );


// create wikEdDiff button wrapper
// create wikEdDiff button wrapper
wikEd.diffButtonWrapper = document.createElement('div');
wikEd.diffButtonWrapper = document.createElement( 'div' );
wikEd.diffButtonWrapper.id = 'wikEdDiffButtonWrapper';
wikEd.diffButtonWrapper.id = 'wikEdDiffButtonWrapper';
wikEd.diffButtonWrapper.className = 'wikEdDiffButtonWrapper';
wikEd.diffButtonWrapper.className = 'wikEdDiffButtonWrapper';
wikEd.diffWrapper.appendChild(wikEd.diffButtonWrapper);
wikEd.diffWrapper.appendChild( wikEd.diffButtonWrapper );


// create wikEdDiff button
// create wikEdDiff button
wikEd.diffButton = document.createElement('button');
wikEd.diffButton = document.createElement( 'button' );
wikEd.diffButton.id = 'wikEdDiffButton';
wikEd.diffButton.id = 'wikEdDiffButton';
wikEd.diffButton.title = wikEd.config.text['wikEdDiffButton title'];
wikEd.diffButton.title = wikEd.config.text['wikEdDiffButton title'];
if ( wikEd.diff === true ) {
wikEd.diffButton.className = 'wikEdDiffButton';
wikEd.diffButton.className = 'wikEdDiffButtonChecked';
wikEd.diffButtonWrapper.appendChild(wikEd.diffButton);
}
else {
wikEd.diffButton.className = 'wikEdDiffButtonUnchecked';
}
wikEd.diffButtonWrapper.appendChild( wikEd.diffButton );


// add button image
// add button image
var diffImg = document.createElement('img');
var diffImg = document.createElement( 'img' );
diffImg.id = 'wikEdDiffButtonImg';
diffImg.id = 'wikEdDiffButtonImg';
diffImg.src = wikEd.config.image['wikEdDiff'];
diffImg.src = wikEd.config.image['wikEdDiff'];
diffImg.title = wikEd.config.text['wikEdDiffButton title'];
diffImg.title = wikEd.config.text['wikEdDiffButton title'];
diffImg.alt = wikEd.config.text['wikEdDiffButtonImg alt'];
diffImg.alt = wikEd.config.text['wikEdDiffButtonImg alt'];
wikEd.diffButton.appendChild(diffImg);
wikEd.diffButton.appendChild( diffImg );


wikEd.diffDiv = document.createElement('div');
wikEd.diffDiv = document.createElement( 'div' );
wikEd.diffDiv.id = 'wikEdDiffDiv';
wikEd.diffDiv.id = 'wikEdDiffDiv';
wikEd.diffDiv.className = 'wikEdDiffDiv';
wikEd.diffDiv.className = 'wikEdDiffDiv';
wikEd.diffDiv.style.display = 'none';
wikEd.diffDiv.style.display = 'none';


// add wrapper after diff table
// insert wrapper row after title row
if ( document.getElementsByName( 'wpTextbox2' )[0] === undefined ) {
wikEd.diffWrapper.appendChild(wikEd.diffDiv);
tdOld.parentNode.parentNode.insertBefore( diffRow, tdOld.parentNode.nextSibling );
if (wikEd.diffTable.nextSibling != null) {
wikEd.diffTable.parentNode.insertBefore(wikEd.diffWrapper, wikEd.diffTable.nextSibling);
}
}

// insert wrapper row before title row for edit conflict page
else {
else {
wikEd.diffTable.parentNode.appendChild(wikEd.diffWrapper);
tdOld.parentNode.parentNode.insertBefore( diffRow, tdOld.parentNode );
}
}
wikEd.diffWrapper.appendChild( wikEd.diffDiv );


// add event listener to button
// add event listener to button
wikEd.AddEventListener(wikEd.diffButton, 'click', wikEd.Diff);
wikEd.DiffAddEventListener( wikEd.diffButton, 'click', wikEd.DiffButtonHandler );


// add event listener to button
// run WikEdDiff if enabled in wikEd
wikEd.DiffAddEventListener( wikEd.diffTable, 'dblclick', wikEd.DiffWrapperHandler );
var setting = wikEd.GetPersistent('wikEdDiff');

if ( (setting == '') && (typeof(wikEd.config.diffPreset) == 'boolean') ) {
// detect already loaded external scripts, also in wikEd.js
setting = wikEd.config.diffPreset;
if ( wikEd.externalScripts === null ) {
wikEd.externalScripts = [];
var pageScripts = document.getElementsByTagName( 'script' );
for ( var i = 0; i < pageScripts.length; i ++ ) {
var scriptSrc = pageScripts[i].src;
var nameMatch = scriptSrc.match( /\btitle=([^&]*)/ );
if ( nameMatch === null ) {
nameMatch = scriptSrc.match( /\/([^\/]*?)($|\?)/ );
}
if ( nameMatch !== null ) {
var scriptName = nameMatch[1];
if ( scriptName !== '' ) {

// ignore other diff.js scripts
if ( scriptName === 'diff.js' && scriptSrc !== wikEd.config.diffScriptSrc ) {
continue;
}
wikEd.externalScripts[scriptName] = pageScripts[i];
}
}
}
}
}

else if (setting == '1') {
// load the external diff script
setting = true;
if ( wikEd.externalScripts['diff.js'] === undefined ) {
if ( WikEdDiff === undefined ) {
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = wikEd.config.diffScriptSrc;
wikEd.head.appendChild( script );
wikEd.externalScripts['diff.js'] = script;
}
}
}

if (setting == true) {
wikEd.Diff();
// call or schedule wikEd.Diff if enabled
if ( wikEd.diff === true ) {
if ( WikEdDiff !== undefined ) {
wikEd.Diff();
}
else {
var script = wikEd.externalScripts['diff.js'];

// MS IE 8
if ( script.onreadystatechange !== undefined ) {
script.onreadystatechange = function () {
if ( this.readyState === 'loaded' ) {
wikEd.Diff();
}
};
}

// Standards
else {
wikEd.DiffAddEventListener( script, 'load', wikEd.Diff, false );
}
}
}
}


// linkify standard diff
// linkify standard diff
wikEd.DiffLinkifyStandard();
wikEd.DiffLinkifyStandard();

// register links for Lupin's Wikipedia:Tools/Navigation_popups
// register links for Lupin's Wikipedia:Tools/Navigation_popups
if (typeof(setupTooltips) == 'function') {
if ( typeof window.setupTooltips === 'function' ) {
setupTooltips(wikEd.diffTable);
window.setupTooltips( wikEd.diffTable );
}
}


return;
};


//
// wikEd.DiffButtonHandler: event handler for diff button: toggle wikEdDiff button and box and set cookie
//

wikEd.DiffButtonHandler = function ( event ) {

if ( event.preventDefault !== undefined ) {
event.preventDefault();
}
else {
event.returnValue = false;
}

// turn wikEdDiff off
if ( wikEd.diff === true ) {
wikEd.diff = false;
wikEd.diffButton.className = 'wikEdDiffButtonUnchecked';
wikEd.SetCookie( 'wikEdDiff', '0', 0, '/' );
if ( typeof wikEd.diffDiv === 'object' ) {
if ( wikEd.diffDiv !== null ) {
wikEd.diffDiv.style.display = 'none';
}
}
}

// turn wikEdDiff on
else {
wikEd.diff = true;
wikEd.diffButton.className = 'wikEdDiffButtonChecked';
wikEd.SetCookie( 'wikEdDiff', '1', 0, '/' );
if ( typeof wikEd.diffDiv === 'object' && wikEd.diffDiv !== null ) {
wikEd.diffDiv.style.display = 'block';
wikEd.Diff();
}
}
return;
return;
};
};
Zeile 398: Zeile 504:
//
//


wikEd.DiffLinkifyStandard = function() {
wikEd.DiffLinkifyStandard = function () {


if ( (wikEd.diffTable == null) || (wikEd.wikiGlobals.wgServer == null) || (wikEd.diffTableLinkified == true) ) {
if ( wikEd.diffTable === null || wikEd.wikiGlobals.wgServer === null || wikEd.diffTableLinkified === true ) {
return;
return;
}
}
wikEd.diffTableLinkified = true;
wikEd.diffTableLinkified = true;
var cells = wikEd.diffTable.getElementsByTagName('td');
var cells = wikEd.diffTable.getElementsByTagName( 'td' );
for (var i = 0; i < cells.length; i ++) {
for ( var i = 0; i < cells.length; i ++ ) {
var cell = cells.item(i);
var cell = cells.item( i );
if ( /\b( diff-context|diff-deletedline|diff-addedline )\b/.test( cell.className ) === true ) {
if (
(cell.className == 'diff-context') ||
cell.innerHTML = wikEd.DiffLinkify( cell.innerHTML );
(cell.className == 'diff-deletedline') ||
(cell.className == 'diff-addedline')
) {
cell.innerHTML = wikEd.DiffLinkify(cell.innerHTML);
}
}
}
}
Zeile 422: Zeile 524:
//
//


wikEd.Diff = function() {
wikEd.Diff = function () {


// check if set tup
// check if set tup
if (wikEd.diffDiv == null) {
if ( wikEd.diffDiv === null ) {
return;
return;
}
}


// check if diff.js is loaded
// check if diff.js is loaded
if ( WikEdDiff === undefined ) {
if (typeof(WDiffString) != 'function') {
return;
return;
}
}
Zeile 438: Zeile 540:


// fetch only once
// fetch only once
if (wikEd.diffDiv.innerHTML.length > 0) {
if ( wikEd.diffDiv.innerHTML.length > 0 ) {
return;
return;
}
}


// check if this is a diff page
// check if this is a diff page
if (wikEd.diffTable == null) {
if ( wikEd.diffTable === null ) {
return;
return;
}
}


// set pushed button style
// display div
wikEd.diffButton.className = 'wikEdDiffButtonPressed';
wikEd.diffDiv.innerHTML = wikEd.config.text['wikEdDiffLoading'];


// display div
// generate request url from MediaWiki variables or from location url
wikEd.diffDiv.innerHTML =
var url;
'<div class="wikEdDiffWorking">' + wikEd.config.text['wikEdDiffLoading'] + '</div>';
var server = wikEd.wikiGlobals.wgServer;
var scriptPath = wikEd.wikiGlobals.wgScriptPath;
scriptPath = scriptPath.replace(server, '');
if ( (server != '') && (scriptPath != '') ) {
url = server + scriptPath.replace(/\$1/, '') + '/index.php';
}
else {
url = window.location.protocol + '//' + window.location.hostname + '/' + window.location.pathname;
}

var article;
var pageName = wikEd.wikiGlobals.wgPageName;
if (pageName != '') {
article = pageName;
}
else {
var articleMatch = window.location.search.match(/(\?|&)title=([^&#]+)/);
if(articleMatch != null) {
article = articleMatch[2];
}
}
url += '?title=' + encodeURIComponent(article) + '&action=raw&maxage=0';


// get diff table and version link cells
// get diff table and version link cells
var tdArray = document.getElementsByTagName('td');
var tdArray = wikEd.diffTable.getElementsByTagName( 'td' );
var tdOld;
var tdOld;
var tdNew;
var tdNew;
for (var i = 0; i < tdArray.length; i ++) {
for ( var i = 0; i < tdArray.length; i ++ ) {
if (tdArray[i].className == 'diff-otitle') {
if ( tdArray[i].className === 'diff-otitle' ) {
tdOld = tdArray[i];
tdOld = tdArray[i];
}
}
else if (tdArray[i].className == 'diff-ntitle') {
else if ( tdArray[i].className === 'diff-ntitle' ) {
tdNew = tdArray[i];
tdNew = tdArray[i];
break;
break;
}
}
}
}
if ( (tdOld == null) || (tdNew == null) ) {
if ( tdOld === null || tdNew === null ) {
return;
return;
}
}
Zeile 498: Zeile 579:
var newUrl;
var newUrl;


// preview pages use latest article version and textarea
// preview pages use textarea and latest article version or second textarea
if (
if (
(/(\?|&)action=submit\b/.test(window.location.search) == true) ||
/(\?|&)action=submit\b/.test( window.location.search ) === true ||
(/(\?|&)undoafter=/.test(window.location.search) == true)
/(\?|&)undoafter=/.test( window.location.search ) === true
) {
) {

var textarea = document.getElementsByName('wpTextbox1');
// get new version from textarea
if (textarea.length == 0) {
var textarea = document.getElementsByName( 'wpTextbox1' )[0];
if ( textarea === undefined ) {
return;
return;
}
}
newVersion = textarea[0].value;
newVersion = textarea.value;
newVersion = newVersion.replace(/\s+$/g, '');
newVersion = newVersion.replace( /\s+$/g, '' );

// get old version from second textarea ( edit conflict )
var textarea2 = document.getElementsByName( 'wpTextbox2' )[0];
if ( textarea2 !== undefined ) {
oldVersion = textarea2.value;
oldVersion = oldVersion.replace( /\s+$/g, '' );

// calculate diff
wikEd.diffDiv.innerHTML = wikEd.DiffResponse( oldVersion, newVersion );
wikEd.diffDiv.style.display = 'block';
wikEd.diffButton.className = 'wikEdDiffButtonChecked';
return;
}

// generate url from MediaWiki variables or from location url
var url;
var server = wikEd.wikiGlobals.wgServer;
var scriptPath = wikEd.wikiGlobals.wgScriptPath;
scriptPath = scriptPath.replace( server, '' );
if ( server !== '' && scriptPath !== '' ) {
url = server + scriptPath.replace( /\$1/, '' ) + '/index.php';
}
else {
url = window.location.protocol + '//' + window.location.hostname + '/' + window.location.pathname;
}

var article;
var pageName = wikEd.wikiGlobals.wgPageName;
if ( pageName !== '' ) {
article = pageName;
}
else {
var articleMatch = window.location.search.match( /(\?|&)title=([^&#]+)/ );
if ( articleMatch !== null ) {
article = articleMatch[2];
}
}
url += '?title=' + encodeURIComponent( article ) + '&action=raw&maxage=0';

var curRevisionId = wikEd.wikiGlobals.wgCurRevisionId;
var curRevisionId = wikEd.wikiGlobals.wgCurRevisionId;
if (curRevisionId != '') {
if ( curRevisionId !== undefined && curRevisionId !== '' ) {
oldUrl = url + '&oldid=' + curRevisionId;
oldUrl = url + '&oldid=' + curRevisionId;
}
}
Zeile 518: Zeile 640:


// get section for section editing
// get section for section editing
var section = document.getElementsByName('wpSection');
var section = document.getElementsByName( 'wpSection' );
if (section != null) {
if ( section !== null ) {
if (section.length > 0) {
if ( section.length > 0 ) {
if (section[0].value != '') {
if ( section[0].value !== '' ) {
oldUrl += '&section=' + section[0].value;
oldUrl += '&section=' + section[0].value;
}
}
Zeile 531: Zeile 653:
else {
else {


// get revision id numbers from links in table cells
// get revision id numbers from title links in table cells
var versionMatchOld = tdOld.innerHTML.match(/(\?|&amp;)oldid=(\d+)/);
var versionMatchOld = tdOld.innerHTML.match( /\bhref="([^#"<>]+?(&(amp;)?|\?)oldid=\d+[^#"<>]*?)"/ );
var versionMatchNew = tdNew.innerHTML.match(/(\?|&amp;)oldid=(\d+)/);
var versionMatchNew = tdNew.innerHTML.match( /\bhref="([^#"<>]+?(&(amp;)?|\?)oldid=\d+[^#"<>]*?)"/ );
if (versionMatchOld == null) {
if ( versionMatchOld === null || versionMatchNew === null ) {
return;
return;
}
}
oldUrl = url + '&oldid=' + versionMatchOld[2];
oldUrl = versionMatchOld[1];
newUrl = versionMatchNew[1];
if (versionMatchNew != null) {

newUrl = url + '&oldid=' + versionMatchNew[2];
oldUrl = oldUrl.replace( /&amp;/g, '&' );
}
newUrl = newUrl.replace( /&amp;/g, '&' );
else {

newUrl = url;
oldUrl += '&action=raw&maxage=0';
}
newUrl += '&action=raw&maxage=0';
}
}


Zeile 551: Zeile 674:
var postFields = null;
var postFields = null;
var overrideMimeType = null;
var overrideMimeType = null;
wikEd.AjaxRequest(requestMethod, requestUrl, postFields, overrideMimeType, function(ajax) {
wikEd.DiffAjaxRequest( requestMethod, requestUrl, postFields, overrideMimeType, function ( ajax ) {
oldVersion = ajax.responseText;
oldVersion = ajax.responseText;

if (newVersion != null) {
// calculate diff
wikEd.diffDiv.innerHTML = wikEd.DiffResponse(oldVersion, newVersion);
if ( newVersion !== null ) {
wikEd.diffDiv.innerHTML = wikEd.DiffResponse( oldVersion, newVersion );
wikEd.diffDiv.style.display = 'block';
wikEd.diffDiv.style.display = 'block';
wikEd.diffButton.className = 'wikEdDiffButtonChecked';
}
}
return;
return;
});
} );


// get the new version using ajax and linkify
// get the new version using ajax and linkify
if (newUrl != null) {
if ( newUrl !== undefined ) {
var requestMethod = 'GET';
var requestMethod = 'GET';
var requestUrl = newUrl;
var requestUrl = newUrl;
var postFields = null;
var postFields = null;
var overrideMimeType = null;
var overrideMimeType = null;
wikEd.AjaxRequest(requestMethod, requestUrl, postFields, overrideMimeType, function(ajax) {
wikEd.DiffAjaxRequest( requestMethod, requestUrl, postFields, overrideMimeType, function ( ajax ) {
newVersion = ajax.responseText;
newVersion = ajax.responseText;

if (oldVersion != null) {
// calculate diff
wikEd.diffDiv.innerHTML = wikEd.DiffResponse(oldVersion, newVersion);
if ( oldVersion !== null ) {
wikEd.diffDiv.innerHTML = wikEd.DiffResponse( oldVersion, newVersion );
wikEd.diffDiv.style.display = 'block';
wikEd.diffDiv.style.display = 'block';
wikEd.diffButton.className = 'wikEdDiffButtonChecked';
}
}
return;
return;
});
} );
}
}

return;
return;
};
};
Zeile 581: Zeile 709:


//
//
// wikEd.DiffResponse: calculate and linkify the diff between two versions (code copied from wikEd.js)
// wikEd.DiffResponse: calculate and linkify the diff between two versions ( code copied from wikEd.js )
//
//


if (typeof(wikEd.DiffResponse) == 'undefined')
if ( wikEd.DiffResponse === undefined )
wikEd.DiffResponse = function(oldVersion, newVersion) {
wikEd.DiffResponse = function ( oldVersion, newVersion ) {


// add trailing newline
// add trailing newline
if (oldVersion.substr(oldVersion.length - 1, 1) != '\n') {
if ( oldVersion.substr( oldVersion.length - 1, 1 ) !== '\n' ) {
oldVersion += '\n';
oldVersion += '\n';
}
}
if (newVersion.substr(newVersion.length - 1, 1) != '\n') {
if ( newVersion.substr( newVersion.length - 1, 1 ) !== '\n' ) {
newVersion += '\n';
newVersion += '\n';
}
}


// call external diff program
// call external diff program
var diffText = WDiffString(oldVersion, newVersion);
var wikEdDiff = new WikEdDiff();
var diffText = wikEdDiff.diff( oldVersion, newVersion );
if (wikEd.config.fullDiff != true) {
diffText = WDiffShortenOutput(diffText);
}


// linkify blockwise with breaks at delete and block move tags
// linkify blockwise with breaks at delete and block move tags
var diffTextLinkified = '';
var diffTextLinkified = '';
var regExp = /<span\b[^>]+?\bclass="wDiffHtml(Delete|Block)"[^>]*>/g;
var regExp = /<span\b[^>]+?\bclass="wikEdDiff(Delete|Block)"[^>]*>/g;
var regExpMatch;
var regExpMatch;
var pos = 0;
var pos = 0;
while ( (regExpMatch = regExp.exec(diffText)) != null) {
while ( ( regExpMatch = regExp.exec( diffText ) ) !== null ) {
diffTextLinkified += wikEd.DiffLinkify(diffText.substring(pos, regExpMatch.index)) + regExpMatch[0];
diffTextLinkified += wikEd.DiffLinkify( diffText.substring( pos, regExpMatch.index ) ) + regExpMatch[0];
pos = regExp.lastIndex;
pos = regExp.lastIndex;
}
}
diffTextLinkified += wikEd.DiffLinkify(diffText.substr(pos));
diffTextLinkified += wikEd.DiffLinkify( diffText.substr( pos ) );
return(diffTextLinkified);
return diffTextLinkified;
};
};


Zeile 619: Zeile 745:
//
//


if (typeof(wikEd.DiffLinkify) == 'undefined')
if ( wikEd.DiffLinkify === undefined )
wikEd.DiffLinkify = function(html) {
wikEd.DiffLinkify = function ( html ) {


// &lt; &gt; to \x00 \x01
// &lt; &gt; to \x00 \x01
html = html.replace(/&lt;/g, '\x00');
html = html.replace( /&lt;/g, '\x00' );
html = html.replace(/&gt;/g, '\x01');
html = html.replace( /&gt;/g, '\x01' );


// split into valid html tags and plain text fragments
// split into valid html tags and plain text fragments
var linkified = '';
var linkified = '';
var regExp = /(<[^<>]*>)|([^<>]+|<|>)/g;
var regExp = /(<[^<>]*>)|([^<>]+|<|>)/g;
while ( (regExpMatch = regExp.exec(html)) != null) {
var regExpMatch;
while ( ( regExpMatch = regExp.exec( html) ) !== null ) {
var tag = regExpMatch[1] || '';
var tag = regExpMatch[1] || '';
var plain = regExpMatch[2] || '';
var plain = regExpMatch[2] || '';


// process tags (FF && MSIE)
// process tags
if (tag != '') {
if ( tag !== '' ) {
linkified += tag;
linkified += tag;
}
}
Zeile 640: Zeile 767:
// process plain tags
// process plain tags
else {
else {

// escape bogus < or >
// escape bogus < or >
plain = plain.replace(/>/g, '&gt;');
plain = plain.replace( />/g, '&gt;' );
plain = plain.replace(/</g, '&lt;');
plain = plain.replace( /</g, '&lt;' );


// external links 123 3 2 14 4 5 6 65
// external links 123 3 2 14 4 5 6 65
plain = plain.replace(/\b(((https?|ftp|irc|gopher):\/\/)|news:|mailto:)([^\x00-\x20\s"\[\]\x7f\|\{\}<>]|<[^>]*>)+?(?=([\!"\(\)\.\,\:\;\‘-•]*\s|[\x00-\x20\s"\[\]\x7f\|\{\}]|$))/gi,
plain = plain.replace(/(((\bhttps?:|\bftp:|\birc:|\bgopher:|)\/\/)|\bnews:|\bmailto:)([^\x00-\x20\s"\[\]\x7f\|\{\}<>]|<[^>]*>)+?(?=([!"().,:;‘-•]*\s|[\x00-\x20\s"\[\]\x7f|{}]|$))/gi,
function (p) {
function ( p ) {
var whole = p;
var whole = p;


var title = whole;
// remove tags and comments
var url = whole;
title = title.replace(/\x00!--.*?--\x01/g, '');
title = title.replace(/.*--\x01|\x00!--.*()/g, '');
url = url.replace( /\x00!--.*?--\x01/g, '' );
title = title.replace(/<.*?>/g, '');
url = url.replace( /.*--\x01|\x00!--.*()/g, '' );
title = title.replace(/^.*>|<.*$/g, '');
url = url.replace( /<.*?>/g, '' );
title = title.replace(/^\s+|\s+$/g, '');
url = url.replace( /^.*>|<.*$/g, '' );
title = decodeURI(title);
url = url.replace( /^\s+|\s+$/g, '' );


var url = title;
// make title as readable as possible
url = encodeURI(url);
var title = url;
url = url.replace(/ /g, '%20');
title = title.replace( /\+/g, ' ' );
url = url.replace(/"/g, '%22');
url = url.replace(/'/g, '%27');
url = url.replace(/#/g, '%23');


// decodeURI breaks for invalid UTF-8 escapes
var linkTitle = title.replace(/"/g, '&quot;');
title = title.replace( /(%[0-9a-f]{2})+/gi,
function ( p, p1 ) {
try {
return decodeURI( p );
}
catch ( exception ) {
return p;
}
}
);
title = title.replace( /</g, '&lt;' );
title = title.replace( />/g, '&gt;' );
title = title.replace( /"/g, '&quot;' );


// linkify all url text fragments between highlighting <span>s seperately
// linkify all url text fragments between highlighting <span>s seperately
var anchorOpen = '<a href = "' + url + '" style="text-decoration: none; color: inherit; color: expression(parentElement.currentStyle.color);" title="' + linkTitle + '">';
var anchorOpen = '<a href = "' + url + '" style="text-decoration: none; color: inherit; color: expression(parentElement.currentStyle.color);" title="' + title + '">';
var anchorClose = '</a>';
var anchorClose = '</a>';
whole = whole.replace(/(<[^>]*>)/g, anchorClose + '$1' + anchorOpen);
whole = whole.replace( /(<[^>]*>)/g, anchorClose + '$1' + anchorOpen );
return(anchorOpen + whole + anchorClose);
return anchorOpen + whole + anchorClose;
}
}
);
);


// linkify links and templates
// linkify links and templates
if ( (wikEd.wikiGlobals.wgServer != null) && (wikEd.wikiGlobals.wgArticlePath != null) ) {
if ( wikEd.wikiGlobals.wgServer !== null && wikEd.wikiGlobals.wgArticlePath !== null ) {


// 1 [[ 2title 23 | text 3 ]]1 4 {{ 5title 56 6 4
// 1 [[ 2title 23 | text 3 ]]1 4 {{ 5title 56 6 4
plain = plain.replace(/(\[\[([^|\[\]{}\n]+)(\|[^\[\]{}<>]*)?\]\])|(\{\{([^|\[\]{}\n]*)([^\[\]{}<>]*\}\})?)/g,
plain = plain.replace( /(\[\[([^|\[\]{}\n]+)(\|[^\[\]{}<>]*)?\]\])|(\{\{([^|\[\]{}\n]*)([^\[\]{}<>]*\}\})?)/g,
function (p, p1, p2, p3, p4, p5, p6) {
function ( p, p1, p2, p3, p4, p5, p6 ) {
var articleName = p2 || '';
var articleName = p2 || '';
var templateName = p5 || '';
var templateName = p5 || '';
Zeile 687: Zeile 824:
// extract title
// extract title
var title = articleName;
var title = articleName;
if (title == '') {
if ( title === '' ) {
title = templateName;
title = templateName;
}
}
title = title.replace(/\x00!--.*?--\x01/g, '');
title = title.replace( /\x00!--.*?--\x01/g, '' );
title = title.replace(/.*--\x01|\x00!--.*()/g, '');
title = title.replace( /.*--\x01|\x00!--.*()/g, '' );
title = title.replace(/<.*?>/g, '');
title = title.replace( /<.*?>/g, '' );
title = title.replace(/^.*>|<.*$/g, '');
title = title.replace( /^.*>|<.*$/g, '' );
title = title.replace(/^\s+|\s+$/g, '');
title = title.replace( /^\s+|\s+$/g, '' );


// [[/subpage]] refers to a subpage of the current page, [[#section]] to a section of the current page
// [[/subpage]] refers to a subpage of the current page, [[#section]] to a section of the current page
if ( (title.indexOf('/') == 0) || (title.indexOf('#') == 0) ) {
if ( title.indexOf( '/' ) === 0 || title.indexOf( '#' ) === 0 ) {
title = wikEd.pageName + title;
title = wikEd.pageName + title;
}
}


// create url
// create url
var url = title.replace(/\s/g, '_');
var url = wikEd.EncodeTitle( title );
url = encodeURI(url);
var articleTitle = title.replace( /"/g, '&quot;' );
url = url.replace(/"/g, '%22');
if ( templateName !== '' ) {
if ( /:/.test( title ) === false ) {
url = url.replace(/'/g, '%27');
url = url.replace(/#/g, '%23');
var articleTitle = title.replace(/"/g, '&quot;');
if (templateName != '') {
if (/:/.test(title) == false) {
url = 'Template:' + url;
url = 'Template:' + url;
articleTitle = 'Template:' + articleTitle;
articleTitle = 'Template:' + articleTitle;
}
}
}
}
url = wikEd.wikiGlobals.wgServer + wikEd.wikiGlobals.wgArticlePath.replace(/\$1/, url);
url = wikEd.wikiGlobals.wgServer + wikEd.wikiGlobals.wgArticlePath.replace( /\$1/, url );


// linkify all text fragments between highlighting <span>s seperately
// linkify all text fragments between highlighting <span>s seperately
var anchorOpen = '<a href = "' + url + '" style = "text-decoration: none; color: inherit; color: expression(parentElement.currentStyle.color)" title="' + articleTitle + '">';
var anchorOpen = '<a href = "' + url + '" style = "text-decoration: none; color: inherit; color: expression(parentElement.currentStyle.color)" title="' + articleTitle + '">';
var anchorClose = '</a>';
var anchorClose = '</a>';
whole = whole.replace(/(<[^>]*>)/g, anchorClose + '$1' + anchorOpen);
whole = whole.replace( /(<[^>]*>)/g, anchorClose + '$1' + anchorOpen );
return(anchorOpen + whole + anchorClose);
return anchorOpen + whole + anchorClose;
}
}
);
);
Zeile 727: Zeile 860:
}
}
}
}

// \x00 and \x01 back to &lt; and &gt;
// \x00 and \x01 back to &lt; and &gt;
linkified = linkified.replace(/\x00/g, '&lt;');
linkified = linkified.replace( /\x00/g, '&lt;' );
linkified = linkified.replace(/\x01/g, '&gt;');
linkified = linkified.replace( /\x01/g, '&gt;' );


return(linkified);
return linkified;
};
};




//
//
// wikEd.InitObject: initialize object, keep pre-defined values (code copied from wikEd.js)
// wikEd.EncodeTitle: encode article title for use in url (code copied from wikEd.js)
//
//


if (typeof(wikEd.InitObject) == 'undefined')
if ( wikEd.EncodeTitle === undefined )
wikEd.InitObject = function(target, source, showMissing) {
wikEd.EncodeTitle = function ( title ) {


if (typeof(target) == 'object') {
if ( title === undefined ) {
title = wikEd.wikiGlobals.wgTitle;
for (var key in source) {
}
if (typeof(target[key]) == 'undefined') {

// characters not supported
title = title.replace( /[<>\[\]|{}]/g, '' );

title = title.replace( / /g, '_' );
title = encodeURI( title );
title = title.replace( /%25(\d\d)/g, '%$1' );
title = title.replace( /&/g, '%26' );
title = title.replace( /#/g, '%23' );
title = title.replace( /'/g, '%27' );
title = title.replace( /\?/g, '%3F' );
title = title.replace( /\+/g, '%2B' );
return title;
};


//
// wikEd.InitObject: initialize object, keep pre-defined values ( code copied from wikEd.js )
//

if ( wikEd.InitObject === undefined )
wikEd.InitObject = function ( target, source, showMissing ) {

if ( typeof target === 'object' ) {
for ( var key in source ) {
if ( target[key] === undefined ) {
target[key] = source[key];
target[key] = source[key];


// show missing array entries
// show missing array entries
if (showMissing == true) {
if ( showMissing === true ) {
if (typeof(target[key]) == 'string') {
if ( typeof target[key] === 'string' ) {
wikEd.config.debugStartUp += '\t\t\t\'' + key + '\': \'' + target[key].replace(/\n/g, '\\n') + '\',\n';
wikEd.config.debugStartUp += '\t\t\t\'' + key + '\': \'' + target[key].replace( /\n/g, '\\n' ) + '\',\n';
}
}
}
}
Zeile 764: Zeile 924:
//
//


if (typeof(wikEd.AddToObject) == 'undefined')
if ( wikEd.AddToObject === undefined )
wikEd.AddToObject = function(target, source) {
wikEd.AddToObject = function ( target, source, priority ) {

if (typeof(target) == 'object') {
if ( priority === undefined ) {
for (var key in source) {
target[key] = source[key];
priority = {};
}
if ( typeof target === 'object' ) {
for ( var key in source ) {
if ( priority[key] !== undefined ) {
target[key] = priority[key];
}
else {
target[key] = source[key];
}
}
}
}
}
Zeile 779: Zeile 948:
//
//


if (typeof(wikEd.InitImage) == 'undefined')
if ( wikEd.InitImage === undefined )
wikEd.InitImage = function(target, source) {
wikEd.InitImage = function ( target, source ) {


var server = window.location.href.replace( /^(\w+:\/\/.*?)\/.*/, '$1' );
for (var key in source) {
var protocol = server.replace( /^(\w+:)\/\/.*/, '$1' );
if (typeof(target[key]) == 'undefined') {

for ( var key in source ) {
if ( target[key] === undefined ) {


// remove MediaWiki path prefixes and add local path
// remove MediaWiki path prefixes and add local path
if (wikEd.config.useLocalImages == true) {
if ( wikEd.config.useLocalImages === true ) {
target[key] = wikEd.config.imagePathLocal + source[key].replace(/^[0-9a-f]+\/[0-9a-f]+\/()/, '');
target[key] = wikEd.config.imagePathLocal + source[key].replace( /^[0-9a-f]+\/[0-9a-f]+\/()/, '' );
}
}


Zeile 793: Zeile 965:
else {
else {
target[key] = wikEd.config.imagePath + source[key];
target[key] = wikEd.config.imagePath + source[key];
}

// Chrome 33.0.1750.146 m bug, not displaying frame html background image without complete URL
if ( /^\/\//.test( target[key] ) === true ) {
target[key] = protocol + target[key];
}
else if ( /^\//.test( target[key] ) === true ) {
target[key] = server + target[key];
}
}
}
}
Zeile 801: Zeile 981:


//
//
// wikEd.StyleSheet: create a new style sheet object (code copied from wikEd.js)
// wikEd.DiffStyleSheet: create a new style sheet object
//
//


wikEd.DiffStyleSheet = function ( contextObj ) {
if (typeof(wikEd.StyleSheet) == 'undefined')
wikEd.StyleSheet = function(contextObj) {


if (contextObj == null) {
if ( contextObj === undefined ) {
contextObj = document;
contextObj = document;
}
}
Zeile 813: Zeile 992:


// MS IE compatibility
// MS IE compatibility
if (contextObj.createStyleSheet) {
if ( contextObj.createStyleSheet ) {
this.styleElement = contextObj.createStyleSheet();
this.styleElement = contextObj.createStyleSheet();
}
}
Zeile 819: Zeile 998:
// standards compliant browsers
// standards compliant browsers
else {
else {
this.styleElement = contextObj.createElement('style');
this.styleElement = contextObj.createElement( 'style' );
this.styleElement.from = 'text/css';
this.styleElement.from = 'text/css';
var insert = contextObj.getElementsByTagName('head')[0];
var insert = contextObj.getElementsByTagName( 'head' )[0];
if (insert != null) {
if ( insert !== undefined ) {
this.styleElement.appendChild(contextObj.createTextNode('')); // Safari 3 fix
this.styleElement.appendChild( contextObj.createTextNode( '' ) ); // Safari 3 fix
insert.appendChild(this.styleElement);
insert.appendChild( this.styleElement );
}
}
}
}


//
//
// wikEd.StyleSheet.AddCSSRule: add one rule at the time using DOM method, very slow
// wikEd.DiffStyleSheet.AddCSSRule: add one rule at the time using DOM method, very slow
//
//


this.AddCSSRule = function(selector, declaration) {
this.AddCSSRule = function ( selector, declaration ) {


// MS IE compatibility
// MS IE compatibility
if (this.styleElement.addRule != null) {
if ( this.styleElement.addRule !== undefined ) {
if (declaration.length > 0) {
if ( declaration.length > 0 ) {
this.styleElement.addRule(selector, declaration);
this.styleElement.addRule( selector, declaration );
}
}
}
}
Zeile 843: Zeile 1.022:
// standards compliant browsers
// standards compliant browsers
else {
else {
if (this.styleElement.sheet != null) {
if ( this.styleElement.sheet !== undefined ) {
if (this.styleElement.sheet.insertRule != null) {
if ( this.styleElement.sheet.insertRule !== undefined ) {
this.styleElement.sheet.insertRule(selector + ' { ' + declaration + ' } ', 0);
this.styleElement.sheet.insertRule( selector + ' { ' + declaration + ' } ', 0 );
}
}
}
}
Zeile 853: Zeile 1.032:


//
//
// wikEd.StyleSheet.AddCSSRules: add or replace all rules at once, much faster
// wikEd.DiffStyleSheet.AddCSSRules: add or replace all rules at once, much faster
//
//


this.AddCSSRules = function(rules) {
this.AddCSSRules = function ( rules ) {


// MS IE compatibility
// MS IE compatibility
if (this.styleElement.innerHTML == null) {
if ( this.styleElement.innerHTML === null ) {
this.styleElement.cssText = rules;
this.styleElement.cssText = rules;
}
}


// Safari, Chrome, WebKit
// Safari, Chrome, WebKit
else if ( (wikEd.safari == true) || (wikEd.chrome == true) || (wikEd.webkit == true) ) {
else if ( wikEd.safari === true || wikEd.chrome === true || wikEd.webkit === true ) {
if (this.styleElement.firstChild != null) {
if ( this.styleElement.firstChild !== null ) {
this.styleElement.removeChild(this.styleElement.firstChild);
this.styleElement.removeChild( this.styleElement.firstChild );
}
}
this.styleElement.appendChild(contextObj.createTextNode(rules));
this.styleElement.appendChild( contextObj.createTextNode( rules ) );
}
}


Zeile 884: Zeile 1.063:
//
//


if (typeof(wikEd.GetPersistent) == 'undefined')
if ( wikEd.GetPersistent === undefined )
wikEd.GetPersistent = function(name) {
wikEd.GetPersistent = function ( name ) {


var getStr = '';
var getStr;


// check for web storage
// check for web storage
Zeile 893: Zeile 1.072:


// get a value from web storage
// get a value from web storage
if (wikEd.webStorage == true) {
if ( wikEd.webStorage === true ) {
getStr = window.localStorage.getItem(name);
getStr = window.localStorage.getItem( name );
}
}


// get a Greasemonkey persistent value
// get a Greasemonkey persistent value
else if (wikEd.greasemonkey == true) {
else if ( wikEd.greasemonkey === true ) {
getStr = GM_getValue(name, '');
getStr = GM_getValue( name, '' );
}
}


// get a cookie value
// get a cookie value
else {
else {
getStr = wikEd.GetCookie(name);
getStr = wikEd.GetCookie( name );
}
}

return(getStr);
// return string
if ( typeof getStr !== 'string' ) {
getStr = '';
}
return getStr;
};
};




//
//
// wikEd.DetectWebStorage: detect if local storage is available (code copied to wikEd.js)
// wikEd.DetectWebStorage: detect if local storage is available (code copied from wikEd.js)
//
//


if (typeof(wikEd.DetectWebStorage ) == 'undefined')
if ( wikEd.DetectWebStorage === undefined )
wikEd.DetectWebStorage = function() {
wikEd.DetectWebStorage = function () {


if (wikEd.webStorage == null) {
if ( wikEd.webStorage === null ) {
wikEd.webStorage = false;
wikEd.webStorage = false;

if (typeof(window.localStorage) == 'object') {
// https://bugzilla.mozilla.org/show_bug.cgi?id=748620
try {
// web storage does not persist between local html page loads in firefox
if (/^file:\/\//.test(wikEd.pageOrigin) == false) {
if ( typeof window.localStorage === 'object' ) {

wikEd.webStorage = true;
// web storage does not persist between local html page loads in firefox
if ( /^file:\/\//.test( wikEd.pageOrigin ) === false ) {
wikEd.webStorage = true;
}
}
}
}
catch ( exception ) {
}
}
}
}
Zeile 935: Zeile 1.125:
//
//


if (typeof(wikEd.GetCookie) == 'undefined')
if ( wikEd.GetCookie === undefined )
wikEd.GetCookie = function(cookieName) {
wikEd.GetCookie = function ( cookieName ) {


var cookie = ' ' + document.cookie;
var cookie = ' ' + document.cookie;
Zeile 943: Zeile 1.133:
var offset = 0;
var offset = 0;
var end = 0;
var end = 0;
offset = cookie.indexOf(search);
offset = cookie.indexOf( search );
if (offset != -1) {
if ( offset !== -1 ) {
offset += search.length;
offset += search.length;
end = cookie.indexOf(';', offset);
end = cookie.indexOf( ';', offset );
if (end == -1) {
if ( end === -1 ) {
end = cookie.length;
end = cookie.length;
}
}
cookieValue = cookie.substring(offset, end);
cookieValue = cookie.substring( offset, end );
cookieValue = cookieValue.replace(/\\+/g, ' ');
cookieValue = cookieValue.replace( /\\+/g, ' ' );
cookieValue = decodeURIComponent(cookieValue);
cookieValue = decodeURIComponent( cookieValue );
}
}
return(cookieValue);
return cookieValue;
};
};




//
// wikEd.SetCookie: set a cookie, deletes a cookie for expire = -1 (code copied from wikEdDiff.js)
//

if ( wikEd.SetCookie === undefined )
wikEd.SetCookie = function ( name, value, expires, path, domain, secure ) {

var cookie = name + '=' + encodeURIComponent( value );

if ( expires !== undefined && expires !== null ) {

// generate a date 1 hour ago to delete the cookie
if ( expires === -1 ) {
var cookieExpire = new Date();
expires = cookieExpire.setTime( cookieExpire.getTime() - 60 * 60 * 1000 );
expires = cookieExpire.toUTCString();
}

// get date from expiration preset
else if ( expires === 0 ) {
var cookieExpire = new Date();
expires = cookieExpire.setTime( cookieExpire.getTime() + wikEd.config.cookieExpireSec * 1000 );
expires = cookieExpire.toUTCString();
}
cookie += '; expires=' + expires;
}
if ( typeof path === 'string' ) {
cookie += '; path=' + path;
}
if ( typeof domain === 'string' ) {
cookie += '; domain=' + domain;
}
if ( secure === true ) {
cookie += '; secure';
}
document.cookie = cookie;
return;
};


//
//
// wikEd.AjaxRequest: cross browser wrapper for Ajax requests (code copied from wikEd.js)
// wikEd.DiffAjaxRequest: cross browser wrapper for Ajax requests
//
//


wikEd.DiffAjaxRequest = function ( requestMethod, requestUrl, postFields, overrideMimeType, ResponseHandler ) {
if (typeof(wikEd.AjaxRequest) == 'undefined')
wikEd.AjaxRequest = function(requestMethod, requestUrl, postFields, overrideMimeType, ResponseHandler) {


var request;
var request;
var headers = {};
var formData;


// prepare POST request
// generate body data from form field object
if ( requestMethod === 'POST' ) {
var headerName = null;
var headerValue = null;
var bodyData = '';
if (requestMethod == 'POST') {


// assemble string body
//create boundary
if ( typeof FormData !== 'function' ) {
var boundary = wikEd.CreateRandomString(12);


// POST header
// create boundary
var boundary = wikEd.CreateRandomString( 12 );
headerName = 'Content-Type';
headerValue = 'multipart/form-data; boundary=' + boundary;


// POST header, charset: WebKit workaround http://aautar.digital-radiation.com/blog/?p=1645
// assemble body data
headers['Content-Type'] = 'multipart/form-data; charset=UTF-8; boundary=' + boundary;
for (var fieldName in postFields) {

if (postFields.hasOwnProperty(fieldName) == true) {
// assemble body data
var fieldValue = postFields[fieldName];
bodyData += '--' + boundary + '\r\n';
formData = '';
for ( var fieldName in postFields ) {
bodyData += 'Content-Disposition: form-data; name="' + fieldName + '"\r\n\r\n' + fieldValue + '\r\n';
if ( Object.prototype.hasOwnProperty.call( postFields, fieldName ) === true ) {
formData += '--' + boundary + '\r\n';
formData += 'Content-Disposition: form-data; name="' + fieldName + '"\r\n\r\n' + postFields[fieldName] + '\r\n';
}
}
}
formData += '--' + boundary + '--\r\n';
}
}
bodyData += '--' + boundary + '--\r\n';
}


// use Greasemonkey GM_xmlhttpRequest
// use FormData object
else {
if (wikEd.greasemonkey == true) {
formData = new window.FormData();
var headerObj = { 'User-Agent': navigator.userAgent };
for ( var fieldName in postFields ) {
if (headerName != null) {
if ( Object.prototype.hasOwnProperty.call( postFields, fieldName ) === true ) {
headerObj[headerName] = headerValue;
formData.append( fieldName, postFields[fieldName] );
}
}
}
}
}

// send the request using Greasemonkey GM_xmlhttpRequest
if ( wikEd.greasemonkey === true ) {
headers['User-Agent'] = window.navigator.userAgent;


// workaround for Error: Greasemonkey access violation: unsafeWindow cannot call GM_xmlhttpRequest.
// workaround for Error: Greasemonkey access violation: unsafeWindow cannot call GM_xmlhttpRequest.
// see http://wiki.greasespot.net/Greasemonkey_access_violation
// see http://wiki.greasespot.net/Greasemonkey_access_violation
setTimeout(function() {
window.setTimeout( function () {
new GM_xmlhttpRequest({
new GM_xmlhttpRequest( {
'method': requestMethod,
'method': requestMethod,
'url': requestUrl,
'url': requestUrl,
'overrideMimeType': overrideMimeType,
'overrideMimeType': overrideMimeType,
'headers': headerObj,
'headers': headers,
'data': bodyData,
'data': formData,
'onreadystatechange':
'onreadystatechange':
function(ajax) {
function ( ajax ) {
if (ajax.readyState != 4) {
if ( ajax.readyState !== 4 ) {
return;
return;
}
}
ResponseHandler(ajax);
ResponseHandler( ajax );
return;
return;
}
}
});
} );
}, 0);
}, 0);
}
}
Zeile 1.023: Zeile 1.259:
else {
else {


// allow ajax request from local copy for testing
// allow ajax request from local copy for testing no longer working, see https://bugzilla.mozilla.org/show_bug.cgi?id=546848
if (wikEd.config.allowLocalAjax == true) {
if (typeof(netscape) == 'object') {
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
}
}


// new ajax request object
// create new XMLHttpRequest object
if ( (typeof(XMLHttpRequest) == 'function') || (typeof(XMLHttpRequest) == 'object') ) {
if ( typeof window.XMLHttpRequest === 'function' || typeof window.XMLHttpRequest === 'object' ) {
request = new XMLHttpRequest();
request = new window.XMLHttpRequest();
}
}


// IE
// IE
else if (typeof(ActiveXObject) == 'object') {
else if ( typeof window.ActiveXObject === 'object' ) {


// IE 6
// IE 6
try {
try {
request = new ActiveXObject('Microsoft.XMLHTTP');
request = new window.ActiveXObject( 'Microsoft.XMLHTTP' );
}
}


// IE 5.5
// IE 5.5
catch(err) {
catch ( exception ) {
try {
try {
request = new ActiveXObject('Msxml2.XMLHTTP');
request = new window.ActiveXObject( 'Msxml2.XMLHTTP' );
}
}
catch(err) {
catch ( exceptionInner ) {
return;
return;
}
}
}
}
}
}
if (request == null) {
if ( request === undefined ) {
return;
return;
}
}

request.open(requestMethod, requestUrl, true);
// open the request
if (headerName != null) {
request.setRequestHeader(headerName, headerValue);
request.open( requestMethod, requestUrl, true );

// set the headers
for ( var headerName in headers ) {
if ( Object.prototype.hasOwnProperty.call( headers, headerName ) === true ) {
request.setRequestHeader( headerName, headers[headerName] );
}
}
}

if ( (request.overrideMimeType != null) && (overrideMimeType != null) ) {
// set the mime type
request.overrideMimeType(overrideMimeType);
if ( request.overrideMimeType !== undefined && overrideMimeType !== null ) {
request.overrideMimeType( overrideMimeType );
}
}


// catch security violations Opera 0.9.51
// send the request, catch security violations Opera 0.9.51
try {
try {
request.send(bodyData);
request.send( formData );
}
}
catch(err) {
catch ( exception ) {
return;
return;
}
}


// wait for the data
request.onreadystatechange = function() {
if (request.readyState != 4) {
request.onreadystatechange = function () {
if ( request.readyState !== 4 ) {
return;
return;
}
}
ResponseHandler(request);
ResponseHandler( request );
return;
return;
};
};
Zeile 1.082: Zeile 1.322:
return;
return;
};
};





//
//
// wikEd.CreateRandomString: create random string of specified length and character set
// wikEd.CreateRandomString: create random string of specified length and character set (code copied from wikEd.js)
//
//


if (typeof(wikEd.CreateRandomString) == 'undefined')
if ( wikEd.CreateRandomString === undefined )
wikEd.CreateRandomString = function(strLength, charSet) {
wikEd.CreateRandomString = function ( strLength, charSet ) {


if (charSet == null) {
if ( charSet === undefined ) {
charSet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789';
charSet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_';
}
}
var str = '';
var str = '';
for (var i = 0; i < strLength; i ++) {
for ( var i = 0; i < strLength; i ++ ) {
str += charSet.charAt(Math.floor(Math.random() * charSet.length));
str += charSet.charAt( Math.floor( Math.random() * charSet.length ) );
}
}
return(str);
return str;
};
};


Zeile 1.107: Zeile 1.346:
//
//


if (typeof(wikEd.GetOffsetTop) == 'undefined')
if ( wikEd.GetOffsetTop === undefined )
wikEd.GetOffsetTop = function(element) {
wikEd.GetOffsetTop = function ( element ) {

var offset = 0;
var offset = 0;
do {
do {
offset += element.offsetTop;
offset += element.offsetTop;
} while ( (element = element.offsetParent) != null );
} while ( ( element = element.offsetParent ) !== null );
return(offset);
return offset;
};
};


Zeile 1.121: Zeile 1.361:
// uses postMessage, head script, and JSON encoding for Greasemonkey global to GM context access
// uses postMessage, head script, and JSON encoding for Greasemonkey global to GM context access


if (typeof(wikEd.GetGlobals) == 'undefined')
if ( wikEd.GetGlobals === undefined )
wikEd.GetGlobals = function(names, gotGlobalsHook) {
wikEd.GetGlobals = function ( names, gotGlobalsHook ) {


if (gotGlobalsHook != null) {
if ( gotGlobalsHook !== undefined ) {
wikEd.gotGlobalsHook.push(gotGlobalsHook);
wikEd.gotGlobalsHook.push( gotGlobalsHook );
}
}


// code already running in global context
// code already running in global context
if (wikEd.greasemonkey != true) {
if ( wikEd.greasemonkey !== true ) {
var globalScopeCode = '';
var globalScopeCode = '';
for (var i = 0; i < names.length; i ++) {
for ( var i = 0; i < names.length; i ++ ) {
globalScopeCode += ''
globalScopeCode += '' +
+ 'if (typeof(' + names[i] + ') != \'undefined\') {'
'if ( typeof ' + names[i] + ' !== \'undefined\' ) {' +
+ ' wikEd.wikiGlobals.' + names[i] + ' = ' + names[i] + ';'
' wikEd.wikiGlobals.' + names[i] + ' = ' + names[i] + ';' +
+ '}';
'}';
}
}
if (gotGlobalsHook != null) {
if ( gotGlobalsHook !== undefined ) {
globalScopeCode += 'wikEd.ExecuteHook(wikEd.gotGlobalsHook[' + (wikEd.gotGlobalsHook.length - 1) + '], true);';
globalScopeCode += 'wikEd.ExecuteHook( wikEd.gotGlobalsHook[' + ( wikEd.gotGlobalsHook.length - 1 ) + '], true );';
}
}
eval(globalScopeCode);
eval( globalScopeCode );
return;
return;
}
}


// prepare code to be executed in global context for Greasemonkey
// prepare code to be executed in global context for Greasemonkey
if ( (typeof(window.postMessage) == 'undefined') || (typeof(JSON) != 'object') ) {
if ( window.postMessage === undefined || typeof JSON !== 'object' ) {
return;
return;
}
}
var globalScopeCode = 'var globalObj = {};';
var globalScopeCode = 'var globalObj = {};';
if (gotGlobalsHook != null) {
if ( gotGlobalsHook !== undefined ) {
wikEd.gotGlobalsHook.push(gotGlobalsHook);
wikEd.gotGlobalsHook.push( gotGlobalsHook );
globalScopeCode += 'globalObj.hookNumber = ' + (wikEd.gotGlobalsHook.length - 1) + ';';
globalScopeCode += 'globalObj.hookNumber = ' + ( wikEd.gotGlobalsHook.length - 1 ) + ';';
}
}
globalScopeCode += 'globalObj.scriptId = \'wikEdGetGlobalScript' + wikEd.getGlobalsCounter + '\';';
globalScopeCode += 'globalObj.scriptId = \'wikEdGetGlobalScript' + wikEd.getGlobalsCounter + '\';';
Zeile 1.157: Zeile 1.397:


// add global scope variables
// add global scope variables
for (var i = 0; i < names.length; i ++) {
for ( var i = 0; i < names.length; i ++ ) {
globalScopeCode += ''
globalScopeCode += '' +
+ 'if (typeof(' + names[i] + ') != \'undefined\') {'
'if ( typeof ' + names[i] + ' !== \'undefined\' ) {' +
+ ' globalObj.wikEdGetGlobals[\'' + names[i] + '\'] = ' + names[i] + ';'
' globalObj.wikEdGetGlobals[\'' + names[i] + '\'] = ' + names[i] + ';' +
+ '}';
'}';
}
}
globalScopeCode += 'var globalObjStr = JSON.stringify(globalObj);';
globalScopeCode += 'var globalObjStr = \'wikEd:\' + JSON.stringify( globalObj );';
var origin = wikEd.pageOrigin;
var origin = wikEd.pageOrigin;
if (origin == 'file://') {
if ( origin === 'file://' ) {
origin = '*';
origin = '*';
}
}
globalScopeCode += 'window.postMessage(globalObjStr, \'' + origin + '\');';
globalScopeCode += 'window.postMessage( globalObjStr, \'' + origin + '\' );';


// create head script to execute the code
// create head script to execute the code
var script = document.createElement('script');
var script = document.createElement( 'script' );
script.id = 'wikEdGetGlobalScript' + wikEd.getGlobalsCounter;
script.id = 'wikEdGetGlobalScript' + wikEd.getGlobalsCounter;
wikEd.getGlobalsCounter ++;
wikEd.getGlobalsCounter ++;
if (typeof(script.innerText) != 'undefined') {
if ( typeof script.innerText !== 'undefined' ) {
script.innerText = globalScopeCode;
script.innerText = globalScopeCode;
}
}
Zeile 1.180: Zeile 1.420:
script.textContent = globalScopeCode;
script.textContent = globalScopeCode;
}
}
wikEd.head.appendChild(script);
wikEd.head.appendChild( script );

return;
return;
};
};
Zeile 1.190: Zeile 1.429:
//
//


if (typeof(wikEd.GetGlobalsReceiver) == 'undefined')
if ( wikEd.GetGlobalsReceiver === undefined )
wikEd.GetGlobalsReceiver = function(event) {
wikEd.GetGlobalsReceiver = function ( event ) {


if (event.source != window) {
if ( event.source !== window ) {
return;
return;
}
}
if ( (event.origin != 'null') && (event.origin != wikEd.pageOrigin) ) {
if ( event.origin !== 'null' && event.origin !== wikEd.pageOrigin ) {
return;
return;
}
}
if (event.data != '') {
if ( event.data !== '' ) {

var globalObj = JSON.parse(event.data);
// test if sent by wikEd
if ( /^wikEd:/.test( event.data ) === false ) {
return;
}
event.stopPropagation();
var data = event.data.replace( /wikEd:/, '' );
var globalObj = JSON.parse( data );
var globals = globalObj.wikEdGetGlobals;
var globals = globalObj.wikEdGetGlobals;
if (globals != null) {
if ( globals !== null ) {
for (var key in globals) {
for ( var key in globals ) {
if (globals.hasOwnProperty(key) == true) {
if ( Object.prototype.hasOwnProperty.call( globals, key ) === true ) {
wikEd.wikiGlobals[key] = globals[key];
wikEd.wikiGlobals[key] = globals[key];
}
}
Zeile 1.210: Zeile 1.456:


// run scheduled functions only once
// run scheduled functions only once
if (globalObj.hookNumber != null) {
if ( globalObj.hookNumber !== undefined && wikEd.gotGlobalsHook[globalObj.hookNumber] !== undefined ) {
wikEd.ExecuteHook(wikEd.gotGlobalsHook[globalObj.hookNumber], true);
wikEd.ExecuteHook( wikEd.gotGlobalsHook[globalObj.hookNumber], true );
}
}


// clean up head script
// clean up head script
var script = document.getElementById(globalObj.scriptId);
var script = document.getElementById( globalObj.scriptId );
wikEd.head.removeChild(script);
if ( script !== null ) {
wikEd.head.removeChild( script );
}
}
}
}
}
Zeile 1.224: Zeile 1.472:


//
//
// wikEd.AddEventListener: wrapper for addEventListener (http://ejohn.org/projects/flexible-javascript-events/) (code copied from wikEd.js)
// wikEd.DiffAddEventListener: wrapper for addEventListener (http://ejohn.org/projects/flexible-javascript-events/)
//
//


wikEd.DiffAddEventListener = function ( domElement, eventType, eventHandler, useCapture ) {
if (typeof(wikEd.AddEventListener) == 'undefined')
wikEd.AddEventListener = function(domElement, eventType, eventHandler, useCapture) {


if (domElement == null) {
if ( domElement === undefined ) {
return;
return;
}
}
if (typeof(domElement.addEventListener) == 'function') {
if ( typeof domElement.addEventListener === 'function' ) {
domElement.addEventListener(eventType, eventHandler, useCapture);
domElement.addEventListener( eventType, eventHandler, useCapture );
}
}
else {
else {
domElement['wikEd' + eventType + eventHandler] = eventHandler;
domElement['wikEd' + eventType + eventHandler] = eventHandler;
domElement[eventType + eventHandler] = function() {
domElement[eventType + eventHandler] = function () {
var eventRootElement = document;
var eventRootElement = document;
if (document.addEventListener == null) {
if ( document.addEventListener === undefined ) {
eventRootElement = window;
eventRootElement = window;
}
}
domElement['wikEd' + eventType + eventHandler](eventRootElement.event);
domElement['wikEd' + eventType + eventHandler]( eventRootElement.event );
};
};
domElement.attachEvent('on' + eventType, domElement[eventType + eventHandler] );
domElement.attachEvent( 'on' + eventType, domElement[eventType + eventHandler] );
}
}
return;
return;
Zeile 1.255: Zeile 1.502:
//
//


if (typeof(wikEd.ExecuteHook) == 'undefined')
if ( wikEd.ExecuteHook === undefined )
wikEd.ExecuteHook = function(functionsHook, onlyOnce) {
wikEd.ExecuteHook = function ( functionsHook, onlyOnce ) {


if ( functionsHook === undefined ) {
for (var i = 0; i < functionsHook.length; i ++) {
return;
functionsHook[i]();
}
}
for ( var i = 0; i < functionsHook.length; i ++ ) {
if (onlyOnce == true) {
if ( typeof functionsHook[i] === 'function' ) {
functionsHook[i]();
}
}
if ( onlyOnce === true ) {
functionsHook = [];
functionsHook = [];
}
return;
};


//
// wikEd.DiffWrapperHandler: event handler for diff table: scroll to edit field (double click) or close (shift/ctrl/alt-double click)
//

wikEd.DiffWrapperHandler = function ( event ) {

// toggle (shift/ctrl/alt-double click)
if ( event.shiftKey === true || event.ctrlKey === true || event.altKey === true || event.metaKey === true ) {
wikEd.DiffButtonHandler();
}

// scroll to edit field (double click)
else {

// filter out selecting double clicks on text
if ( window.getSelection !== undefined ) {
var sel = window.getSelection();

// explicitOriginalTarget (Firefox)
var textTarget = event.explicitOriginalTarget;
if ( textTarget !== undefined ) {
if ( textTarget.nodeName === '#text' ) {
return;
}
}

// ignore for non-blank selection
else if ( sel !== null && /^\s*$/.test( sel.toString() ) === false ) {
return;
}
sel.collapseToEnd();
}

// scroll to edit area
var scrollTo;
if ( wikEd.inputWrapper !== null ) {
scrollTo = wikEd.inputWrapper;
}

// or article preview
if ( scrollTo === undefined && window.getElementsByClassName !== undefined ) {
scrollTo = document.getElementsByClassName( 'diff-currentversion-title' )[0];
}

// or divider between diff and preview
if ( scrollTo === undefined && window.getElementsByClassName !== undefined ) {
scrollTo = document.getElementsByClassName( 'diff-hr' )[0];
}

// or diff table title
if ( scrollTo === undefined ) {
if ( wikEd.diffTableTitle !== null ) {
scrollTo = wikEd.diffTableTitle;
}
}

// scroll
if ( scrollTo !== undefined ) {
window.scroll( 0, wikEd.GetOffsetTop( scrollTo ) );
}
}
}
return;
return;
Zeile 1.271: Zeile 1.588:
wikEd.DiffStartup();
wikEd.DiffStartup();


// </source>
// </syntaxhighlight>

Aktuelle Version vom 20. Oktober 2014, 13:38 Uhr

// Kopie von https://en.wikipedia.org/w/index.php?title=User%3ACacycle%2FwikEdDiff.js&diff=629600284&oldid=629595952
// zur Einbindung in meine monobook.js - Leider ist die aktuelle Version von [[en:user:Cacycle]] buggy für IE Nutzer, deshalb hier eine alte Version
// 22. August 2012, Fix von Cacycle für IE übernommen
// 20. Oktober 2014 neue Version übernommen, alte funktionert nicht mehr
// <syntaxhighlight lang="JavaScript">

// ==UserScript==
// @name        wikEdDiff
// @version     0.9.38
// @date        October 14, 2014
// @description improved diff with block move detection for comparing article versions
// @homepage    https://en.wikipedia.org/wiki/User:Cacycle/wikEdDiff
// @source      https://en.wikipedia.org/wiki/User:Cacycle/wikEdDiff.js
// @author      Cacycle (https://en.wikipedia.org/wiki/User:Cacycle)
// @license     released into the public domain
// @include     /\b(action=submit|diff=)\b/
// @require     https://en.wikipedia.org/w/index.php?title=User:Cacycle/diff.js&action=raw&ctype=text/javascript
// @grant       GM_getValue
// @grant       GM_xmlhttpRequest
// ==/UserScript==

/*

Features:
* Additions, deletions, and block moves are highlighted by color in the same text
* Block moves and character differences are detected
* Unchanged regions are omitted from the output
* Highly optimized for MediaWiki source texts

wikEdDiff uses the diff.js library (https://en.wikipedia.org/wiki/User:Cacycle/Cacycle/diff) and has been integrated
into wikEd, a full-featured JavaScript in-browser editor (https://en.wikipedia.org/wiki/User:Cacycle/wikEd).
For installation details, please see https://en.wikipedia.org/wiki/User:Cacycle/wikEdDiff.

*/

// JSHint options
/* jshint -W004, -W100, newcap: false, browser: true, jquery: true, sub: true, bitwise: true, curly: false, evil: true, forin: true, freeze: true, globalstrict: true, immed: true, latedef: true, loopfunc: true, quotmark: single, strict: true, undef: true */
/* global GM_getValue, GM_xmlhttpRequest, console */

// turn on ECMAScript 5 strict mode
'use strict';

// define global objects
var wikEd; if ( wikEd === undefined ) { wikEd = {}; }
if ( wikEd.config === undefined ) { wikEd.config = {}; }
var WikEdDiff;
var wikEdConfig;

//
// wikEd.DiffInit: initialize variables
//

wikEd.DiffInit = function () {

//
// user configurable variables
//

	// wikEd code home base URL, also defined in wikEd.js
	if ( wikEd.config.homeBaseUrl === undefined ) { wikEd.config.homeBaseUrl = '//en.wikipedia.org/'; }

	// diff library URL, also defined in wikEd.js
	if ( wikEd.config.diffScriptSrc === undefined ) { wikEd.config.diffScriptSrc = wikEd.config.homeBaseUrl + 'w/index.php?title=User:Cacycle/diff.js&action=raw&ctype=text/javascript'; }

	// wikEdDiff css rules
	if ( wikEd.config.diffCSS === undefined ) { wikEd.config.diffCSS = {}; }
	wikEd.InitObject( wikEd.config.diffCSS, {
		'.wikEdDiffWrapper': 'padding: 0.33em 0.5em;',
		'.wikEdDiffButtonWrapper': 'text-align: center;',
		'.wikEdDiffButtonChecked':
			'padding: 0.1em 0.1em 0.2em; background: #c8c4c0; border: 1px solid; ' +
			'border-color: #555 #e8e8e8 #e8e8e8 #555; border-radius: 0.25em; cursor: pointer;',
		'.wikEdDiffButtonUnchecked':
			'padding: 0.1em 0.1em 0.2em; background: #d8d4d0; border: 1px solid; ' +
			'border-color: #f0f0f0 #666 #666 #f0f0f0; border-radius: 0.25em; cursor: pointer;',
		'.wikEdDiffButtonPressed':
			'padding: 0.1em 0.1em 0.2em; background: #c8c4c0; border: 1px solid; ' +
			'border-color: #666 #f0f0f0 #f0f0f0 #666; border-radius: 0.25em; cursor: wait;',
		'.wikEdDiffDiv': 'margin-top: 0.5em;',
		'.wikEdDiffWorking':
			'background: #fcfcfc; border: 1px #bbb solid; border-radius: 0.5em; line-height: 1.6; ' +
			'box-shadow: 2px 2px 2px #ddd; padding: 0.5em; margin: 1em 0; text-align: center;'
	} );

	// use local copies of images for testing (set to true in local copy of edit page), also defined in wikEd.js
	if ( wikEd.config.localImages === undefined ) { wikEd.config.localImages = false; }

	// path to local wikEd images for testing, also defined in wikEd.js
	if ( wikEd.config.imagePathLocal === undefined ) { wikEd.config.imagePathLocal = 'file:///D:/wikEd/images/'; }

	// path to wikEd images, also defined in wikEd.js
	if ( wikEd.config.imagePath === undefined ) { wikEd.config.imagePath = '/media/wikipedia/commons/'; }

	// wikEd image filenames, also defined in wikEd.js
	if ( wikEd.config.image === undefined ) { wikEd.config.image = {}; }
	wikEd.InitImage( wikEd.config.image, {
		'wikEdDiff': 'c/c6/WikEdDiff.png'
	} );

	// user readable texts, copy changes to http://en.wikipedia.org/wiki/User:Cacycle/wikEd_international_en.js, also defined in wikEd.js
	if ( wikEd.config.text === undefined ) { wikEd.config.text = {}; }
	wikEd.InitObject( wikEd.config.text, {
		'wikEdDiffButtonImg alt': 'wikEdDiff',
		'wikEdDiffButton title':  'Show improved diff view',
		'wikEdDiffLoading':       '...'
	} );

	// expiration time span for permanent cookies in seconds, also defined in wikEd.js
	if ( wikEd.config.cookieExpireSec === undefined ) { wikEd.config.cookieExpireSec = 1 * 30 * 24 * 60 * 60; }

	//
	// end of user configurable variables
	//

	// global dom elements
	wikEd.diffDiv = null;
	wikEd.diffWrapper = null;
	wikEd.diffButtonWrapper = null;
	wikEd.diffButton = null;
	wikEd.diffGetGlobalNode = null;

	// hash of loaded scripts, also defined in wikEd.js
	if ( wikEd.externalScripts === undefined ) { wikEd.externalScripts = null; }
	if ( wikEd.diffPreset === undefined ) { wikEd.diffPreset = false; }
};

// variables needed during startup
wikEd.diffTable = null;
wikEd.diffTableTitle = null;
wikEd.diffColSpan = null;

// diff table element

// customization, also defined in wikEd.js
if ( wikEd.wikEdConfigAdded === undefined ) { wikEd.wikEdConfigAdded = false; }

// detect web storage capability and Greasemonkey related, also defined in wikEd.js
if ( wikEd.webStorage === undefined ) { wikEd.webStorage = null; }
if ( wikEd.greasemonkey === undefined ) { wikEd.greasemonkey = false; }
if ( wikEd.gotGlobalsHook === undefined ) { wikEd.gotGlobalsHook = []; }
if ( wikEd.getGlobalsCounter === undefined ) { wikEd.getGlobalsCounter = 0; }
if ( wikEd.pageOrigin === undefined ) { wikEd.pageOrigin = ''; }
if ( wikEd.head === undefined ) { wikEd.head = null; }
if ( wikEd.diffTableLinkified === undefined ) { wikEd.diffTableLinkified = false; }

// get global MediaWiki settings, also defined in wikEd.js
if ( wikEd.wikiGlobals === undefined ) { wikEd.wikiGlobals = {}; }
if ( wikEd.pageName === undefined ) { wikEd.pageName = null; }


//
// wikEd.DiffStartup: call the setup routine
//

wikEd.DiffStartup = function () {

	// MediaWiki pages always have their title set, filter out Greasemonkey running on created iframes
	if ( document.title === '' ) {
		return;
	}

	// check if wikEdDiff has already started up
	if ( document.getElementsByName( 'wikEdDiffStartupFlag')[0] !== undefined ) {
		return;
	}

	// define current window head
	wikEd.head = document.getElementsByTagName( 'head')[0] || null;

	// set startup flag
	var flag = document.createElement( 'meta' );
	flag.setAttribute( 'name', 'wikEdDiffStartupFlag' );
	wikEd.head.appendChild( flag );

	// get site of origin (window.location.href is about:blank if Firefox during page load)
	var origin = wikEd.head.baseURI;
	if ( origin === undefined ) {
		origin = window.location.toString();
	}
	wikEd.pageOrigin = origin.replace( /^((https?|file):\/\/[^\/?#]*)?.*$/, '$1' );

	// check if this runs under Greasemonkey
	if ( typeof GM_info === 'object' ) {
		wikEd.greasemonkey = true;
	}

	// parse global-context (MediaWiki) variables into hash (for Greasemonkey)
	var globalNames = ['wgServer', 'wgArticlePath', 'wgScriptPath', 'wgCurRevisionId', 'wikEdTypeofLocalStorage', 'wgPageName'];
	if ( wikEd.greasemonkey === true ) {
		globalNames.push( 'wikEdConfig' );
	}

	// copy custom config settings after values have arrived
	var gotGlobalsHook = [
		function () {
			if ( typeof wikEd.wikiGlobals.wikEdConfig === 'object' && wikEd.wikEdConfigAdded === false ) {
				wikEd.AddToObject( wikEd.config, wikEd.wikiGlobals.wikEdConfig );
				wikEd.wikEdConfigAdded = true;
			}

			// get missing wg variables from footer link (code copied to wikEdDiff.js)
			if ( wikEd.wikiGlobals.wgArticlePath === undefined ) {
				var printfooter = document.body.getElementsByClassName( 'printfooter' )[0];
				if ( printfooter !== undefined ) {
					var articleLink = printfooter.getElementsByTagName( 'a' )[0];
					if ( articleLink !== undefined ) {
						var regExpMatch = /^(https?:\/\/[^\/]*)(\/([^\/]*\/)*)([^\/]*)$/.exec( articleLink.href );
						if ( regExpMatch !== null ) {
							wikEd.wikiGlobals.wgServer = regExpMatch[1];
							wikEd.wikiGlobals.wgArticlePath = regExpMatch[1] + regExpMatch[2] + '$1';
							wikEd.wikiGlobals.wgPageName = regExpMatch[4] || '';
							wikEd.wikiGlobals.wgTitle = decodeURIComponent( regExpMatch[4].replace( /_/g, ' ' ) );
						}
					}
				}
			}

			// get current page name
			wikEd.pageName = wikEd.wikiGlobals.wgPageName;
		}
	];

	// linkify standard diff
	gotGlobalsHook.push( wikEd.DiffLinkifyStandard );

	// set listener for GetGlobals messaging
	wikEd.DiffAddEventListener( window, 'message', wikEd.GetGlobalsReceiver, false );

	// parse globals (asynchronous)
	wikEd.GetGlobals( globalNames, gotGlobalsHook );

	// run the setup routine if page has loaded or if loaded dynamically from wikEd
	if ( document.readyState === 'complete' || document.getElementsByName( 'wikEdSetupFlag' )[0] !== undefined ) {
		wikEd.DiffSetup();
	}

	// schedule the setup routine
	else {
		wikEd.DiffAddEventListener( window, 'load', wikEd.DiffSetup, false );
	}
};


//
// wikEd.DiffSetup: create wikEdDiff elements
//

wikEd.DiffSetup = function () {

	// check if wikEdDiff has already set up
	if ( document.getElementsByName( 'wikEdDiffSetupFlag' )[0] !== undefined ) {
		return;
	}

	// set setup flag
	var flag = document.createElement( 'meta' );
	flag.setAttribute( 'name', 'wikEdDiffSetupFlag' );
	wikEd.head.appendChild( flag );

	// import customization
	if ( wikEdConfig !== undefined && wikEd.wikEdConfigAdded === false ) {
		wikEd.AddToObject( wikEd.config, wikEdConfig );
		wikEd.wikEdConfigAdded = true;
	}

	// initialize variables
	wikEd.DiffInit();

	// get diff table title row
	var tdOld = null;
	var tdNew = null;
	var tdArray = document.getElementsByTagName( 'td' );
	for ( var i = 0; i < tdArray.length; i ++ ) {

		// get old title cell
		if ( tdArray[i].className === 'diff-otitle' ) {
			tdOld = tdArray[i];
		}

		// get new title cell
		else if ( tdArray[i].className === 'diff-ntitle' ) {
			tdNew = tdArray[i];
		}

		if ( tdOld !== null && tdNew !== null ) {
			break;
		}
	}

	// get table
	if ( tdOld !== null ) {
		wikEd.diffTableTitle = tdOld.parentNode;
		var node = wikEd.diffTableTitle.parentNode;
		while ( node !== null ) {
			if ( node.nodeName === 'TABLE' ) {
				wikEd.diffTable = node;
				break;
			}
			node = node.parentNode;
		}
	}

	// get number of diff table columns
	if ( tdOld !== null && tdNew !== null ) {
		wikEd.diffColSpan = tdOld.colSpan + tdNew.colSpan;
	}
	if ( isNaN( wikEd.diffColSpan ) === true ) {
		wikEd.diffColSpan = 4;
	}

	// check if this is a diff page
	if ( wikEd.diffTable === null ) {
		return;
	}

	// add stylesheet definitions ( slow method for IE compatibility )
	var diffStyle = new wikEd.DiffStyleSheet();
	for ( var ruleName in wikEd.config.diffCSS ) {
		if ( Object.prototype.hasOwnProperty.call( wikEd.config.diffCSS, ruleName ) === true ) {
			var ruleStyle = wikEd.config.diffCSS[ruleName];
			diffStyle.AddCSSRule( ruleName, ruleStyle );
		}
	}

	// get saved wikEdDiff setting
	var setting = wikEd.GetCookie( 'wikEdDiff' );
	if ( setting === '' && typeof wikEd.config.diffPreset === 'boolean' ) {
		wikEd.diff = wikEd.config.diffPreset;
	}
	else if ( setting === '1' ) {
		wikEd.diff = true;
	}

	// create wikEdDiff wrapper row
	var diffRow = document.createElement( 'tr' );

	// create wikEdDiff wrapper (td)
	wikEd.diffWrapper = document.createElement( 'td' );
	wikEd.diffWrapper.id = 'wikEdDiffWrapper';
	wikEd.diffWrapper.className = 'wikEdDiffWrapper';
	wikEd.diffWrapper.setAttribute( 'colspan', wikEd.diffColSpan );
	diffRow.appendChild( wikEd.diffWrapper );

	// create wikEdDiff button wrapper
	wikEd.diffButtonWrapper = document.createElement( 'div' );
	wikEd.diffButtonWrapper.id = 'wikEdDiffButtonWrapper';
	wikEd.diffButtonWrapper.className = 'wikEdDiffButtonWrapper';
	wikEd.diffWrapper.appendChild( wikEd.diffButtonWrapper );

	// create wikEdDiff button
	wikEd.diffButton = document.createElement( 'button' );
	wikEd.diffButton.id = 'wikEdDiffButton';
	wikEd.diffButton.title = wikEd.config.text['wikEdDiffButton title'];
	if ( wikEd.diff === true ) {
		wikEd.diffButton.className = 'wikEdDiffButtonChecked';
	}
	else {
		wikEd.diffButton.className = 'wikEdDiffButtonUnchecked';
	}
	wikEd.diffButtonWrapper.appendChild( wikEd.diffButton );

	// add button image
	var diffImg = document.createElement( 'img' );
	diffImg.id = 'wikEdDiffButtonImg';
	diffImg.src = wikEd.config.image['wikEdDiff'];
	diffImg.title = wikEd.config.text['wikEdDiffButton title'];
	diffImg.alt = wikEd.config.text['wikEdDiffButtonImg alt'];
	wikEd.diffButton.appendChild( diffImg );

	wikEd.diffDiv = document.createElement( 'div' );
	wikEd.diffDiv.id = 'wikEdDiffDiv';
	wikEd.diffDiv.className = 'wikEdDiffDiv';
	wikEd.diffDiv.style.display = 'none';

	// insert wrapper row after title row
	if ( document.getElementsByName( 'wpTextbox2' )[0] === undefined ) {
		tdOld.parentNode.parentNode.insertBefore( diffRow, tdOld.parentNode.nextSibling );
	}

	// insert wrapper row before title row for edit conflict page
	else {
		tdOld.parentNode.parentNode.insertBefore( diffRow, tdOld.parentNode );
	}
	wikEd.diffWrapper.appendChild( wikEd.diffDiv );

	// add event listener to button
	wikEd.DiffAddEventListener( wikEd.diffButton, 'click', wikEd.DiffButtonHandler );

	// add event listener to button
	wikEd.DiffAddEventListener( wikEd.diffTable, 'dblclick', wikEd.DiffWrapperHandler );

	// detect already loaded external scripts, also in wikEd.js
	if ( wikEd.externalScripts === null ) {
		wikEd.externalScripts = [];
		var pageScripts = document.getElementsByTagName( 'script' );
		for ( var i = 0; i < pageScripts.length; i ++ ) {
			var scriptSrc = pageScripts[i].src;
			var nameMatch = scriptSrc.match( /\btitle=([^&]*)/ );
			if ( nameMatch === null ) {
				nameMatch = scriptSrc.match( /\/([^\/]*?)($|\?)/ );
			}
			if ( nameMatch !== null ) {
				var scriptName = nameMatch[1];
				if ( scriptName !== '' ) {

					// ignore other diff.js scripts
					if ( scriptName === 'diff.js' && scriptSrc !== wikEd.config.diffScriptSrc ) {
						continue;
					}
					wikEd.externalScripts[scriptName] = pageScripts[i];
				}
			}
		}
	}

	// load the external diff script
	if ( wikEd.externalScripts['diff.js'] === undefined ) {
		if ( WikEdDiff === undefined ) {
			var script = document.createElement( 'script' );
			script.type = 'text/javascript';
			script.src = wikEd.config.diffScriptSrc;
			wikEd.head.appendChild( script );
			wikEd.externalScripts['diff.js'] = script;
		}
	}

	// call or schedule wikEd.Diff if enabled
	if ( wikEd.diff === true ) {
		if ( WikEdDiff !== undefined ) {
			wikEd.Diff();
		}
		else {
			var script = wikEd.externalScripts['diff.js'];

			// MS IE 8
			if ( script.onreadystatechange !== undefined ) {
				script.onreadystatechange = function () {
					if ( this.readyState === 'loaded' ) {
						wikEd.Diff();
					}
				};
			}

			// Standards
			else {
				wikEd.DiffAddEventListener( script, 'load', wikEd.Diff, false );
			}
		}
	}

	// linkify standard diff
	wikEd.DiffLinkifyStandard();

	// register links for Lupin's Wikipedia:Tools/Navigation_popups
	if ( typeof window.setupTooltips === 'function' ) {
		window.setupTooltips( wikEd.diffTable );
	}

	return;
};


//
// wikEd.DiffButtonHandler: event handler for diff button: toggle wikEdDiff button and box and set cookie
//

wikEd.DiffButtonHandler = function ( event ) {

	if ( event.preventDefault !== undefined ) {
		event.preventDefault();
	}
	else {
		event.returnValue = false;
	}

	// turn wikEdDiff off
	if ( wikEd.diff === true ) {
		wikEd.diff = false;
		wikEd.diffButton.className = 'wikEdDiffButtonUnchecked';
		wikEd.SetCookie( 'wikEdDiff', '0', 0, '/' );
		if ( typeof wikEd.diffDiv === 'object' ) {
			if ( wikEd.diffDiv !== null ) {
				wikEd.diffDiv.style.display = 'none';
			}
		}
	}

	// turn wikEdDiff on
	else {
		wikEd.diff = true;
		wikEd.diffButton.className = 'wikEdDiffButtonChecked';
		wikEd.SetCookie( 'wikEdDiff', '1', 0, '/' );
		if ( typeof wikEd.diffDiv === 'object' && wikEd.diffDiv !== null ) {
			wikEd.diffDiv.style.display = 'block';
			wikEd.Diff();
		}
	}
	return;
};


//
// wikEd.DiffLinkifyStandard: linkify wikilinks in standard diff text
//

wikEd.DiffLinkifyStandard = function () {

	if ( wikEd.diffTable === null || wikEd.wikiGlobals.wgServer === null || wikEd.diffTableLinkified === true ) {
		return;
	}
	wikEd.diffTableLinkified = true;
	var cells = wikEd.diffTable.getElementsByTagName( 'td' );
	for ( var i = 0; i < cells.length; i ++ ) {
		var cell = cells.item( i );
		if ( /\b( diff-context|diff-deletedline|diff-addedline )\b/.test( cell.className ) === true ) {
			cell.innerHTML = wikEd.DiffLinkify( cell.innerHTML );
		}
	}
};


//
// wikEd.Diff: fetch the old versions using ajax to display a diff
//

wikEd.Diff = function () {

	// check if set tup
	if ( wikEd.diffDiv === null ) {
		return;
	}

	// check if diff.js is loaded
	if ( WikEdDiff === undefined ) {
		return;
	}

	// display diff
	wikEd.diffDiv.style.display = 'block';

	// fetch only once
	if ( wikEd.diffDiv.innerHTML.length > 0 ) {
		return;
	}

	// check if this is a diff page
	if ( wikEd.diffTable === null ) {
		return;
	}

	// set pushed button style
	wikEd.diffButton.className = 'wikEdDiffButtonPressed';

	// display div
	wikEd.diffDiv.innerHTML =
		'<div class="wikEdDiffWorking">' + wikEd.config.text['wikEdDiffLoading'] + '</div>';

	// get diff table and version link cells
	var tdArray = wikEd.diffTable.getElementsByTagName( 'td' );
	var tdOld;
	var tdNew;
	for ( var i = 0; i < tdArray.length; i ++ ) {
		if ( tdArray[i].className === 'diff-otitle' ) {
			tdOld = tdArray[i];
		}
		else if ( tdArray[i].className === 'diff-ntitle' ) {
			tdNew = tdArray[i];
			break;
		}
	}
	if ( tdOld === null || tdNew === null ) {
		return;
	}

	var oldVersion = null;
	var newVersion = null;

	var oldUrl;
	var newUrl;

	// preview pages use textarea and latest article version or second textarea
	if (
		/(\?|&)action=submit\b/.test( window.location.search ) === true ||
		/(\?|&)undoafter=/.test( window.location.search ) === true
	) {

		// get new version from textarea
		var textarea = document.getElementsByName( 'wpTextbox1' )[0];
		if ( textarea === undefined ) {
			return;
		}
		newVersion = textarea.value;
		newVersion = newVersion.replace( /\s+$/g, '' );

		// get old version from second textarea ( edit conflict )
		var textarea2 = document.getElementsByName( 'wpTextbox2' )[0];
		if ( textarea2 !== undefined ) {
			oldVersion = textarea2.value;
			oldVersion = oldVersion.replace( /\s+$/g, '' );

			// calculate diff
			wikEd.diffDiv.innerHTML = wikEd.DiffResponse( oldVersion, newVersion );
			wikEd.diffDiv.style.display = 'block';
			wikEd.diffButton.className = 'wikEdDiffButtonChecked';
			return;
		}

		// generate url from MediaWiki variables or from location url
		var url;
		var server = wikEd.wikiGlobals.wgServer;
		var scriptPath = wikEd.wikiGlobals.wgScriptPath;
		scriptPath = scriptPath.replace( server, '' );
		if ( server !== '' && scriptPath !== '' ) {
			url = server + scriptPath.replace( /\$1/, '' ) + '/index.php';
		}
		else {
			url = window.location.protocol + '//' + window.location.hostname + '/' + window.location.pathname;
		}

		var article;
		var pageName = wikEd.wikiGlobals.wgPageName;
		if ( pageName !== '' ) {
			article = pageName;
		}
		else {
			var articleMatch = window.location.search.match( /(\?|&)title=([^&#]+)/ );
			if ( articleMatch !== null ) {
				article = articleMatch[2];
			}
		}
		url += '?title=' + encodeURIComponent( article ) + '&action=raw&maxage=0';

		var curRevisionId = wikEd.wikiGlobals.wgCurRevisionId;
		if ( curRevisionId !== undefined && curRevisionId !== '' ) {
			oldUrl = url + '&oldid=' + curRevisionId;
		}
		else {
			oldUrl = url;
		}

		// get section for section editing
		var section = document.getElementsByName( 'wpSection' );
		if ( section !== null ) {
			if ( section.length > 0 ) {
				if ( section[0].value !== '' ) {
					oldUrl += '&section=' + section[0].value;
				}
			}
		}
	}

	// diff pages use two different old versions
	else {

		// get revision id numbers from title links in table cells
		var versionMatchOld = tdOld.innerHTML.match( /\bhref="([^#"<>]+?(&(amp;)?|\?)oldid=\d+[^#"<>]*?)"/ );
		var versionMatchNew = tdNew.innerHTML.match( /\bhref="([^#"<>]+?(&(amp;)?|\?)oldid=\d+[^#"<>]*?)"/ );
		if ( versionMatchOld === null || versionMatchNew === null ) {
			return;
		}
		oldUrl = versionMatchOld[1];
		newUrl = versionMatchNew[1];

		oldUrl = oldUrl.replace( /&amp;/g, '&' );
		newUrl = newUrl.replace( /&amp;/g, '&' );

		oldUrl += '&action=raw&maxage=0';
		newUrl += '&action=raw&maxage=0';
	}

	// get the old version using ajax
	var requestMethod = 'GET';
	var requestUrl = oldUrl;
	var postFields = null;
	var overrideMimeType = null;
	wikEd.DiffAjaxRequest( requestMethod, requestUrl, postFields, overrideMimeType, function ( ajax ) {
		oldVersion = ajax.responseText;

		// calculate diff
		if ( newVersion !== null ) {
			wikEd.diffDiv.innerHTML = wikEd.DiffResponse( oldVersion, newVersion );
			wikEd.diffDiv.style.display = 'block';
			wikEd.diffButton.className = 'wikEdDiffButtonChecked';
		}
		return;
	} );

	// get the new version using ajax and linkify
	if ( newUrl !== undefined ) {
		var requestMethod = 'GET';
		var requestUrl = newUrl;
		var postFields = null;
		var overrideMimeType = null;
		wikEd.DiffAjaxRequest( requestMethod, requestUrl, postFields, overrideMimeType, function ( ajax ) {
			newVersion = ajax.responseText;

			// calculate diff
			if ( oldVersion !== null ) {
				wikEd.diffDiv.innerHTML = wikEd.DiffResponse( oldVersion, newVersion );
				wikEd.diffDiv.style.display = 'block';
				wikEd.diffButton.className = 'wikEdDiffButtonChecked';
			}
			return;
		} );
	}
	return;
};


//
// wikEd.DiffResponse: calculate and linkify the diff between two versions ( code copied from wikEd.js )
//

if ( wikEd.DiffResponse === undefined )
wikEd.DiffResponse = function ( oldVersion, newVersion ) {

	// add trailing newline
	if ( oldVersion.substr( oldVersion.length - 1, 1 ) !== '\n' ) {
		oldVersion += '\n';
	}
	if ( newVersion.substr( newVersion.length - 1, 1 ) !== '\n' ) {
		newVersion += '\n';
	}

	// call external diff program
	var wikEdDiff = new WikEdDiff();
	var diffText = wikEdDiff.diff( oldVersion, newVersion );

	// linkify blockwise with breaks at delete and block move tags
	var diffTextLinkified = '';
	var regExp = /<span\b[^>]+?\bclass="wikEdDiff(Delete|Block)"[^>]*>/g;
	var regExpMatch;
	var pos = 0;
	while ( ( regExpMatch = regExp.exec( diffText ) ) !== null ) {
		diffTextLinkified += wikEd.DiffLinkify( diffText.substring( pos, regExpMatch.index ) ) + regExpMatch[0];
		pos = regExp.lastIndex;
	}
	diffTextLinkified += wikEd.DiffLinkify( diffText.substr( pos ) );
	return diffTextLinkified;
};


//
// wikEd.DiffLinkify: linkify external links and wikilinks in diffed text as <a> anchor elements (code copied from wikEd.js)
//

if ( wikEd.DiffLinkify === undefined )
wikEd.DiffLinkify = function ( html ) {

	// &lt; &gt; to \x00 \x01
	html = html.replace( /&lt;/g, '\x00' );
	html = html.replace( /&gt;/g, '\x01' );

	// split into valid html tags and plain text fragments
	var linkified = '';
	var regExp = /(<[^<>]*>)|([^<>]+|<|>)/g;
	var regExpMatch;
	while ( ( regExpMatch = regExp.exec( html) ) !== null ) {
		var tag = regExpMatch[1] || '';
		var plain = regExpMatch[2] || '';

		// process tags
		if ( tag !== '' ) {
			linkified += tag;
		}

		// process plain tags
		else {

			// escape bogus < or >
			plain = plain.replace( />/g, '&gt;' );
			plain = plain.replace( /</g, '&lt;' );

			// external links        123                     3     2              14                                       4  5  6                                               65
			plain = plain.replace(/(((\bhttps?:|\bftp:|\birc:|\bgopher:|)\/\/)|\bnews:|\bmailto:)([^\x00-\x20\s"\[\]\x7f\|\{\}<>]|<[^>]*>)+?(?=([!"().,:;‘-•]*\s|[\x00-\x20\s"\[\]\x7f|{}]|$))/gi,
				function ( p ) {
					var whole = p;

					// remove tags and comments
					var url = whole;
					url = url.replace( /\x00!--.*?--\x01/g, '' );
					url = url.replace( /.*--\x01|\x00!--.*()/g, '' );
					url = url.replace( /<.*?>/g, '' );
					url = url.replace( /^.*>|<.*$/g, '' );
					url = url.replace( /^\s+|\s+$/g, '' );

					// make title as readable as possible
					var title = url;
					title = title.replace( /\+/g, ' ' );

					// decodeURI breaks for invalid UTF-8 escapes
					title = title.replace( /(%[0-9a-f]{2})+/gi,
						function ( p, p1 ) {
							try {
								return decodeURI( p );
							}
							catch ( exception ) {
								return p;
							}
						}
					);
					title = title.replace( /</g, '&lt;' );
					title = title.replace( />/g, '&gt;' );
					title = title.replace( /"/g, '&quot;' );

					// linkify all url text fragments between highlighting <span>s seperately
					var anchorOpen = '<a href = "' + url + '" style="text-decoration: none; color: inherit; color: expression(parentElement.currentStyle.color);" title="' + title + '">';
					var anchorClose = '</a>';
					whole = whole.replace( /(<[^>]*>)/g, anchorClose + '$1' + anchorOpen );
					return anchorOpen + whole + anchorClose;
				}
			);

			// linkify links and templates
			if ( wikEd.wikiGlobals.wgServer !== null && wikEd.wikiGlobals.wgArticlePath !== null ) {

				//                      1 [[ 2title        23 | text       3   ]]1 4 {{ 5title        56                6 4
				plain = plain.replace( /(\[\[([^|\[\]{}\n]+)(\|[^\[\]{}<>]*)?\]\])|(\{\{([^|\[\]{}\n]*)([^\[\]{}<>]*\}\})?)/g,
				function ( p, p1, p2, p3, p4, p5, p6 ) {
						var articleName = p2 || '';
						var templateName = p5 || '';
						var whole = p;

						// extract title
						var title = articleName;
						if ( title === '' ) {
							title = templateName;
						}
						title = title.replace( /\x00!--.*?--\x01/g, '' );
						title = title.replace( /.*--\x01|\x00!--.*()/g, '' );
						title = title.replace( /<.*?>/g, '' );
						title = title.replace( /^.*>|<.*$/g, '' );
						title = title.replace( /^\s+|\s+$/g, '' );

						// [[/subpage]] refers to a subpage of the current page, [[#section]] to a section of the current page
						if ( title.indexOf( '/' ) === 0 || title.indexOf( '#' ) === 0 ) {
							title = wikEd.pageName + title;
						}

						// create url
						var url = wikEd.EncodeTitle( title );
						var articleTitle = title.replace( /"/g, '&quot;' );
						if ( templateName !== '' ) {
							if ( /:/.test( title ) === false ) {
								url = 'Template:' + url;
								articleTitle = 'Template:' + articleTitle;
							}
						}
						url = wikEd.wikiGlobals.wgServer + wikEd.wikiGlobals.wgArticlePath.replace( /\$1/, url );

						// linkify all text fragments between highlighting <span>s seperately
						var anchorOpen = '<a href = "' + url + '" style = "text-decoration: none; color: inherit; color: expression(parentElement.currentStyle.color)" title="' + articleTitle + '">';
						var anchorClose = '</a>';
						whole = whole.replace( /(<[^>]*>)/g, anchorClose + '$1' + anchorOpen );
						return anchorOpen + whole + anchorClose;
					}
				);
			}
			linkified += plain;
		}
	}

	// \x00 and \x01 back to &lt; and &gt;
	linkified = linkified.replace( /\x00/g, '&lt;' );
	linkified = linkified.replace( /\x01/g, '&gt;' );

	return linkified;
};


//
// wikEd.EncodeTitle: encode article title for use in url (code copied from wikEd.js)
//

if ( wikEd.EncodeTitle === undefined )
wikEd.EncodeTitle = function ( title ) {

	if ( title === undefined ) {
		title = wikEd.wikiGlobals.wgTitle;
	}

	// characters not supported
	title = title.replace( /[<>\[\]|{}]/g, '' );

	title = title.replace( / /g, '_' );
	title = encodeURI( title );
	title = title.replace( /%25(\d\d)/g, '%$1' );
	title = title.replace( /&/g, '%26' );
	title = title.replace( /#/g, '%23' );
	title = title.replace( /'/g, '%27' );
	title = title.replace( /\?/g, '%3F' );
	title = title.replace( /\+/g, '%2B' );
	return title;
};


//
// wikEd.InitObject: initialize object, keep pre-defined values ( code copied from wikEd.js )
//

if ( wikEd.InitObject === undefined )
wikEd.InitObject = function ( target, source, showMissing ) {

	if ( typeof target === 'object' ) {
		for ( var key in source ) {
			if ( target[key] === undefined ) {
				target[key] = source[key];

				// show missing array entries
				if ( showMissing === true ) {
					if ( typeof target[key] === 'string' ) {
						wikEd.config.debugStartUp += '\t\t\t\'' + key + '\': \'' + target[key].replace( /\n/g, '\\n' ) + '\',\n';
					}
				}
			}
		}
	}
	return;
};


//
// wikEd.AddToObject: add or replace properties, replace existing values (code copied from wikEd.js)
//

if ( wikEd.AddToObject === undefined )
wikEd.AddToObject = function ( target, source, priority ) {

	if ( priority === undefined ) {
		priority = {};
	}
	if ( typeof target === 'object' ) {
		for ( var key in source ) {
			if ( priority[key] !== undefined ) {
				target[key] = priority[key];
			}
			else {
				target[key] = source[key];
			}
		}
	}
	return;
};


//
// wikEd.InitImage: initialize images, keep pre-defined values (code copied from wikEd.js)
//

if ( wikEd.InitImage === undefined )
wikEd.InitImage = function ( target, source ) {

	var server = window.location.href.replace( /^(\w+:\/\/.*?)\/.*/, '$1' );
	var protocol = server.replace( /^(\w+:)\/\/.*/, '$1' );

	for ( var key in source ) {
		if ( target[key] === undefined ) {

			// remove MediaWiki path prefixes and add local path
			if ( wikEd.config.useLocalImages === true ) {
				target[key] = wikEd.config.imagePathLocal + source[key].replace( /^[0-9a-f]+\/[0-9a-f]+\/()/, '' );
			}

			// add path
			else {
				target[key] = wikEd.config.imagePath + source[key];
			}

			// Chrome 33.0.1750.146 m bug, not displaying frame html background image without complete URL
			if ( /^\/\//.test( target[key] ) === true ) {
				target[key] = protocol + target[key];
			}
			else if ( /^\//.test( target[key] ) === true ) {
				target[key] = server + target[key];
			}
		}
	}
	return;
};


//
// wikEd.DiffStyleSheet: create a new style sheet object
//

wikEd.DiffStyleSheet = function ( contextObj ) {

	if ( contextObj === undefined ) {
		contextObj = document;
	}
	this.styleElement = null;

	// MS IE compatibility
	if ( contextObj.createStyleSheet ) {
		this.styleElement = contextObj.createStyleSheet();
	}

	// standards compliant browsers
	else {
		this.styleElement = contextObj.createElement( 'style' );
		this.styleElement.from = 'text/css';
		var insert = contextObj.getElementsByTagName( 'head' )[0];
		if ( insert !== undefined ) {
			this.styleElement.appendChild( contextObj.createTextNode( '' ) ); // Safari 3 fix
			insert.appendChild( this.styleElement );
		}
	}

//
// wikEd.DiffStyleSheet.AddCSSRule: add one rule at the time using DOM method, very slow
//

	this.AddCSSRule = function ( selector, declaration ) {

		// MS IE compatibility
		if ( this.styleElement.addRule !== undefined ) {
			if ( declaration.length > 0 ) {
				this.styleElement.addRule( selector, declaration );
			}
		}

		// standards compliant browsers
		else {
			if ( this.styleElement.sheet !== undefined ) {
				if ( this.styleElement.sheet.insertRule !== undefined ) {
					this.styleElement.sheet.insertRule( selector + ' { ' + declaration + ' } ', 0 );
				}
			}
		}
	};


//
// wikEd.DiffStyleSheet.AddCSSRules: add or replace all rules at once, much faster
//

	this.AddCSSRules = function ( rules ) {

		// MS IE compatibility
		if ( this.styleElement.innerHTML === null ) {
			this.styleElement.cssText = rules;
		}

		// Safari, Chrome, WebKit
		else if ( wikEd.safari === true || wikEd.chrome === true || wikEd.webkit === true ) {
			if ( this.styleElement.firstChild !== null ) {
				this.styleElement.removeChild( this.styleElement.firstChild );
			}
			this.styleElement.appendChild( contextObj.createTextNode( rules ) );
		}

		// via innerHTML
		else {
			this.styleElement.innerHTML = rules;
		}
		return;
	};
};


//
// wikEd.GetPersistent: get a cookie or a Greasemonkey persistent value (code copied from wikEd.js)
//

if ( wikEd.GetPersistent === undefined )
wikEd.GetPersistent = function ( name ) {

	var getStr;

	// check for web storage
	wikEd.DetectWebStorage();

	// get a value from web storage
	if ( wikEd.webStorage === true ) {
		getStr = window.localStorage.getItem( name );
	}

	// get a Greasemonkey persistent value
	else if ( wikEd.greasemonkey === true ) {
		getStr = GM_getValue( name, '' );
	}

	// get a cookie value
	else {
		getStr = wikEd.GetCookie( name );
	}

	// return string
	if ( typeof getStr !== 'string' ) {
		getStr = '';
	}
	return getStr;
};


//
// wikEd.DetectWebStorage: detect if local storage is available (code copied from wikEd.js)
//

if ( wikEd.DetectWebStorage === undefined )
wikEd.DetectWebStorage = function () {

	if ( wikEd.webStorage === null ) {
		wikEd.webStorage = false;

		// https://bugzilla.mozilla.org/show_bug.cgi?id=748620
		try {
			if ( typeof window.localStorage === 'object' ) {

				// web storage does not persist between local html page loads in firefox
				if ( /^file:\/\//.test( wikEd.pageOrigin ) === false ) {
					wikEd.webStorage = true;
				}
			}
		}
		catch ( exception ) {
		}
	}
	return;
};


//
// wikEd.GetCookie: get a cookie (code copied from wikEd.diff.js)
//

if ( wikEd.GetCookie === undefined )
wikEd.GetCookie = function ( cookieName ) {

	var cookie = ' ' + document.cookie;
	var search = ' ' + cookieName + '=';
	var cookieValue = '';
	var offset = 0;
	var end = 0;
	offset = cookie.indexOf( search );
	if ( offset !== -1 ) {
		offset += search.length;
		end = cookie.indexOf( ';', offset );
		if ( end === -1 ) {
			end = cookie.length;
		}
		cookieValue = cookie.substring( offset, end );
		cookieValue = cookieValue.replace( /\\+/g, ' ' );
		cookieValue = decodeURIComponent( cookieValue );
	}
	return cookieValue;
};


//
// wikEd.SetCookie: set a cookie, deletes a cookie for expire = -1 (code copied from wikEdDiff.js)
//

if ( wikEd.SetCookie === undefined )
wikEd.SetCookie = function ( name, value, expires, path, domain, secure ) {

	var cookie = name + '=' + encodeURIComponent( value );

	if ( expires !== undefined && expires !== null ) {

		// generate a date 1 hour ago to delete the cookie
		if ( expires === -1 ) {
			var cookieExpire = new Date();
			expires = cookieExpire.setTime( cookieExpire.getTime() - 60 * 60 * 1000 );
			expires = cookieExpire.toUTCString();
		}

		// get date from expiration preset
		else if ( expires === 0 ) {
			var cookieExpire = new Date();
			expires = cookieExpire.setTime( cookieExpire.getTime() + wikEd.config.cookieExpireSec * 1000 );
			expires = cookieExpire.toUTCString();
		}
		cookie += '; expires=' + expires;
	}
	if ( typeof path === 'string' ) {
		cookie += '; path=' + path;
	}
	if ( typeof domain === 'string' ) {
		cookie += '; domain=' + domain;
	}
	if ( secure === true ) {
		cookie += '; secure';
	}
	document.cookie = cookie;
	return;
};

//
// wikEd.DiffAjaxRequest: cross browser wrapper for Ajax requests
//

wikEd.DiffAjaxRequest = function ( requestMethod, requestUrl, postFields, overrideMimeType, ResponseHandler ) {

	var request;
	var headers = {};
	var formData;

	// prepare POST request
	if ( requestMethod === 'POST' ) {

		// assemble string body
		if ( typeof FormData !== 'function' ) {

			// create boundary
			var boundary = wikEd.CreateRandomString( 12 );

			// POST header, charset: WebKit workaround http://aautar.digital-radiation.com/blog/?p=1645
			headers['Content-Type'] = 'multipart/form-data; charset=UTF-8; boundary=' + boundary;

			// assemble body data
			formData = '';
			for ( var fieldName in postFields ) {
				if ( Object.prototype.hasOwnProperty.call( postFields, fieldName ) === true ) {
					formData += '--' + boundary + '\r\n';
					formData += 'Content-Disposition: form-data; name="' + fieldName + '"\r\n\r\n' + postFields[fieldName] + '\r\n';
				}
			}
			formData += '--' + boundary + '--\r\n';
		}

		// use FormData object
		else {
			formData = new window.FormData();
			for ( var fieldName in postFields ) {
				if ( Object.prototype.hasOwnProperty.call( postFields, fieldName ) === true ) {
					formData.append( fieldName, postFields[fieldName] );
				}
			}
		}
	}

	// send the request using Greasemonkey GM_xmlhttpRequest
	if ( wikEd.greasemonkey === true ) {
		headers['User-Agent'] = window.navigator.userAgent;

		// workaround for Error: Greasemonkey access violation: unsafeWindow cannot call GM_xmlhttpRequest.
		// see http://wiki.greasespot.net/Greasemonkey_access_violation
		window.setTimeout( function () {
			new GM_xmlhttpRequest( {
				'method':  requestMethod,
				'url':     requestUrl,
				'overrideMimeType': overrideMimeType,
				'headers': headers,
				'data':    formData,
				'onreadystatechange':
					function ( ajax ) {
						if ( ajax.readyState !== 4 ) {
							return;
						}
						ResponseHandler( ajax );
						return;
					}
			} );
		}, 0);
	}

	// use standard XMLHttpRequest
	else {

		// allow ajax request from local copy for testing no longer working, see https://bugzilla.mozilla.org/show_bug.cgi?id=546848

		// create new XMLHttpRequest object
		if ( typeof window.XMLHttpRequest === 'function' || typeof window.XMLHttpRequest === 'object' ) {
			request = new window.XMLHttpRequest();
		}

		// IE
		else if ( typeof window.ActiveXObject === 'object' ) {

			// IE 6
			try {
				request = new window.ActiveXObject( 'Microsoft.XMLHTTP' );
			}

			// IE 5.5
			catch ( exception ) {
				try {
					request = new window.ActiveXObject( 'Msxml2.XMLHTTP' );
				}
				catch ( exceptionInner ) {
					return;
				}
			}
		}
		if ( request === undefined ) {
			return;
		}

		// open the request
		request.open( requestMethod, requestUrl, true );

		// set the headers
		for ( var headerName in headers ) {
			if ( Object.prototype.hasOwnProperty.call( headers, headerName ) === true ) {
				request.setRequestHeader( headerName, headers[headerName] );
			}
		}

		// set the mime type
		if ( request.overrideMimeType !== undefined && overrideMimeType !== null ) {
			request.overrideMimeType( overrideMimeType );
		}

		// send the request, catch security violations Opera 0.9.51
		try {
			request.send( formData );
		}
		catch ( exception ) {
			return;
		}

		// wait for the data
		request.onreadystatechange = function () {
			if ( request.readyState !== 4 ) {
				return;
			}
			ResponseHandler( request );
			return;
		};
	}
	return;
};


//
// wikEd.CreateRandomString: create random string of specified length and character set (code copied from wikEd.js)
//

if ( wikEd.CreateRandomString === undefined )
wikEd.CreateRandomString = function ( strLength, charSet ) {

	if ( charSet === undefined ) {
		charSet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789';
	}
	var str = '';
	for ( var i = 0; i < strLength; i ++ ) {
		str += charSet.charAt( Math.floor( Math.random() * charSet.length ) );
	}
	return str;
};


//
// wikEd.GetOffsetTop: get element offset relative to window top (code copied from wikEd.js)
//

if ( wikEd.GetOffsetTop === undefined )
wikEd.GetOffsetTop = function ( element ) {

	var offset = 0;
	do {
		offset += element.offsetTop;
	} while ( ( element = element.offsetParent ) !== null );
	return offset;
};


//
// wikEd.GetGlobals: parse global context variables (code copied from wikEd.js)
//   uses postMessage, head script, and JSON encoding for Greasemonkey global to GM context access

if ( wikEd.GetGlobals === undefined )
wikEd.GetGlobals = function ( names, gotGlobalsHook ) {

	if ( gotGlobalsHook !== undefined ) {
		wikEd.gotGlobalsHook.push( gotGlobalsHook );
	}

	// code already running in global context
	if ( wikEd.greasemonkey !== true ) {
		var globalScopeCode = '';
		for ( var i = 0; i < names.length; i ++ ) {
			globalScopeCode += '' +
				'if ( typeof ' + names[i] + ' !== \'undefined\' ) {' +
				'  wikEd.wikiGlobals.' + names[i] + ' = ' + names[i] + ';' +
				'}';
		}
		if ( gotGlobalsHook !== undefined ) {
			globalScopeCode += 'wikEd.ExecuteHook( wikEd.gotGlobalsHook[' + ( wikEd.gotGlobalsHook.length - 1 ) + '], true );';
		}
		eval( globalScopeCode );
		return;
	}

	// prepare code to be executed in global context for Greasemonkey
	if ( window.postMessage === undefined || typeof JSON !== 'object' ) {
		return;
	}
	var globalScopeCode = 'var globalObj = {};';
	if ( gotGlobalsHook !== undefined ) {
		wikEd.gotGlobalsHook.push( gotGlobalsHook );
		globalScopeCode += 'globalObj.hookNumber = ' + ( wikEd.gotGlobalsHook.length - 1 ) + ';';
	}
	globalScopeCode += 'globalObj.scriptId = \'wikEdGetGlobalScript' + wikEd.getGlobalsCounter + '\';';
	globalScopeCode += 'globalObj.wikEdGetGlobals = {};';

	// add global scope variables
	for ( var i = 0; i < names.length; i ++ ) {
		globalScopeCode += '' +
			'if ( typeof ' + names[i] + ' !== \'undefined\' ) {' +
			'  globalObj.wikEdGetGlobals[\'' + names[i] + '\'] = ' + names[i] + ';' +
			'}';
	}
	globalScopeCode += 'var globalObjStr = \'wikEd:\' + JSON.stringify( globalObj );';
	var origin = wikEd.pageOrigin;
	if ( origin === 'file://' ) {
		origin = '*';
	}
	globalScopeCode += 'window.postMessage( globalObjStr, \'' + origin + '\' );';

	// create head script to execute the code
	var script = document.createElement( 'script' );
	script.id = 'wikEdGetGlobalScript' + wikEd.getGlobalsCounter;
	wikEd.getGlobalsCounter ++;
	if ( typeof script.innerText !== 'undefined' ) {
		script.innerText = globalScopeCode;
	}
	else {
		script.textContent = globalScopeCode;
	}
	wikEd.head.appendChild( script );
	return;
};


//
// wikEd.GetGlobalsReceiver: event handler for wikEd.GetGlobals postMessage (code copied from wikEd.js)
//

if ( wikEd.GetGlobalsReceiver === undefined )
wikEd.GetGlobalsReceiver = function ( event ) {

	if ( event.source !== window ) {
		return;
	}
	if ( event.origin !== 'null' && event.origin !== wikEd.pageOrigin ) {
		return;
	}
	if ( event.data !== '' ) {

		// test if sent by wikEd
		if ( /^wikEd:/.test( event.data ) === false ) {
			return;
		}
		event.stopPropagation();
		var data = event.data.replace( /wikEd:/, '' );
		var globalObj = JSON.parse( data );
		var globals = globalObj.wikEdGetGlobals;
		if ( globals !== null ) {
			for ( var key in globals ) {
				if ( Object.prototype.hasOwnProperty.call( globals, key ) === true ) {
					wikEd.wikiGlobals[key] = globals[key];
				}
			}

			// run scheduled functions only once
			if ( globalObj.hookNumber !== undefined && wikEd.gotGlobalsHook[globalObj.hookNumber] !== undefined ) {
				wikEd.ExecuteHook( wikEd.gotGlobalsHook[globalObj.hookNumber], true );
			}

			// clean up head script
			var script = document.getElementById( globalObj.scriptId );
			if ( script !== null ) {
				wikEd.head.removeChild( script );
			}
		}
	}
	return;
};


//
// wikEd.DiffAddEventListener: wrapper for addEventListener (http://ejohn.org/projects/flexible-javascript-events/)
//

wikEd.DiffAddEventListener = function ( domElement, eventType, eventHandler, useCapture ) {

	if ( domElement === undefined ) {
		return;
	}
	if ( typeof domElement.addEventListener === 'function' ) {
		domElement.addEventListener( eventType, eventHandler, useCapture );
	}
	else {
		domElement['wikEd' + eventType + eventHandler] = eventHandler;
		domElement[eventType + eventHandler] = function () {
			var eventRootElement = document;
			if ( document.addEventListener === undefined ) {
				eventRootElement = window;
			}
			domElement['wikEd' + eventType + eventHandler]( eventRootElement.event );
		};
		domElement.attachEvent( 'on' + eventType, domElement[eventType + eventHandler] );
	}
	return;
};


//
// wikEd.ExecuteHook: executes scheduled custom functions from functionsHook array (code copied from wikEd.js)
//

if ( wikEd.ExecuteHook === undefined )
wikEd.ExecuteHook = function ( functionsHook, onlyOnce ) {

	if ( functionsHook === undefined ) {
		return;
	}
	for ( var i = 0; i < functionsHook.length; i ++ ) {
		if ( typeof functionsHook[i] === 'function' ) {
			functionsHook[i]();
		}
	}
	if ( onlyOnce === true ) {
		functionsHook = [];
	}
	return;
};


//
// wikEd.DiffWrapperHandler: event handler for diff table: scroll to edit field (double click) or close (shift/ctrl/alt-double click)
//

wikEd.DiffWrapperHandler = function ( event ) {

	// toggle (shift/ctrl/alt-double click)
	if ( event.shiftKey === true || event.ctrlKey === true || event.altKey === true || event.metaKey === true ) {
		wikEd.DiffButtonHandler();
	}

	// scroll to edit field (double click)
	else {

		// filter out selecting double clicks on text
		if ( window.getSelection !== undefined ) {
			var sel = window.getSelection();

			// explicitOriginalTarget (Firefox)
			var textTarget = event.explicitOriginalTarget;
			if ( textTarget !== undefined ) {
				if ( textTarget.nodeName === '#text' ) {
					return;
				}
			}

			// ignore for non-blank selection
			else if ( sel !== null && /^\s*$/.test( sel.toString() ) === false ) {
				return;
			}
			sel.collapseToEnd();
		}

		// scroll to edit area
		var scrollTo;
		if ( wikEd.inputWrapper !== null ) {
			scrollTo = wikEd.inputWrapper;
		}

		// or article preview
		if ( scrollTo === undefined && window.getElementsByClassName !== undefined ) {
			scrollTo = document.getElementsByClassName( 'diff-currentversion-title' )[0];
		}

		// or divider between diff and preview
		if ( scrollTo === undefined && window.getElementsByClassName !== undefined ) {
			scrollTo = document.getElementsByClassName( 'diff-hr' )[0];
		}

		// or diff table title
		if ( scrollTo === undefined ) {
			if ( wikEd.diffTableTitle !== null ) {
				scrollTo = wikEd.diffTableTitle;
			}
		}

		// scroll
		if ( scrollTo !== undefined ) {
			window.scroll( 0, wikEd.GetOffsetTop( scrollTo ) );
		}
	}
	return;
};


// call startup
wikEd.DiffStartup();

// </syntaxhighlight>