User:PerfektesChaos/js/localEdit/Firefox/chrome/content/wikilocaledit.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:PerfektesChaos/js/localEdit/Firefox/chrome/content/wikilocaledit. |
/// chrome://wikilocaledit/content/wikilocaledit.js
/// Manage main app, which is browser panel toolbarbutton
// Requires:
// * content/fileIO.js
// * content/permissions.js
// * content/prefs.js
// * locale/locale.js
// Used by windows:
// * content/wikilocaledit.xul
/// 2012-12-12 PerfektesChaos@de.wikipedia
/// Fingerprint: #0#0#
/// <nowiki>
/*jshint curly:true, eqeqeq:true, strict:true, undef:true, white:false */
/*global document, gBrowser, HTMLDocument, window */
/*jslint white: true */
/*globals gBrowser: true, HTMLDocument: true,
document: true, window: true */
( function ( w ) {
"use strict";
var EVENTS, IO, PAGES, PREFS, TOOL, WLE, First;
if ( ! w.wikiLocalEdit ) {
w.wikiLocalEdit = { };
}
WLE = w.wikiLocalEdit;
WLE.pages = { };
PAGES = WLE.pages;
PREFS = WLE.prefs;
WLE.live = PREFS.getLeading();
EVENTS = { listening: false };
IO = { search: "*.txt; *.text; *.wiki",
select: "Wikitext: *.txt, *.text, *.wiki" };
TOOL = { };
First = function () {
// Initialize package. Start event listeners.
// Uses:
// w
// TOOL.fresh()
// Remark: Used as event handler -- 'this' is not WLE
// 2012-11-30 PerfektesChaos@de.wikipedia
w.removeEventListener( "load", First, false ); // myself
TOOL.fresh( false );
}; // First()
w.addEventListener( "load", First, false ); // -> gBrowser
EVENTS.fresh = function () {
// Update listener mode
// Postcondition:
// Listeners are activated or stopped
// Uses:
// this
// > .pages.userURLstatics
// > EVENTS.connect
// > .live
// > gBrowser
// >< EVENTS.listening
// .pages.fresh()
// DOM.addEventListener()
// DOM.removeEventListener()
// (EVENTS.onPageLoad)
// (EVENTS.onButton)
// 2012-11-30 PerfektesChaos@de.wikipedia
var e,
i,
n = this.connect.length;
PAGES.fresh();
if ( WLE.live &&
! this.listening &&
PAGES.userURLstatics ) {
for ( i = 0; i < n; i++ ) {
e = this.connect[ i ];
gBrowser.addEventListener( e[ 0 ], e[ 1 ], true, true );
} // for i
this.listening = true;
} else if ( this.listening ) {
for ( i = 0; i < n; i++ ) {
e = this.connect[ i ];
gBrowser.removeEventListener( e[ 0 ], e[ 1 ], true );
} // for i
this.listening = false;
}
}; // EVENTS.fresh()
EVENTS.onPageLoad = function ( event ) {
// Any page has been loaded into user browser.
// Postcondition:
// Returns true for continued event processing
// Uses:
// .pages.isPageUser()
// .pages.fiat()
// .pages.form()
// .pages.first()
// .pages.furnish()
// Remark: Used as event handler -- 'this' is not WLE
// 2012-11-30 PerfektesChaos@de.wikipedia
var doc,
doit,
emit = event.originalTarget, // Mozilla spec
got = PAGES.isPageUser( emit ),
socket;
if ( got ) {
doc = got[ 0 ];
doit = got[ 1 ];
socket = PAGES.fiat( doc );
if ( doit ) {
PAGES.form( doc, socket );
} else {
PAGES.first( socket );
PAGES.furnish( doc );
}
}
return true;
}; // EVENTS.onPageLoad()
EVENTS.onPressButton = function ( event ) {
// Any page has been loaded into user browser.
// Postcondition:
// Returns false for captured event processing
// Uses:
// .pages.isPageUser()
// DOM.getAttribute()
// .pages.file()
// IO.find()
// .pages.flush()
// .prefs.fetchBasedir()
// .pages.setDirBase()
// IO.fetchSubdir()
// .pages.setDirSub()
// Remark: Used as event handler -- 'this' is not WLE
// 2012-12-12 PerfektesChaos@de.wikipedia
var emit = event.originalTarget, // Mozilla spec
doc = emit.ownerDocument,
call = PAGES.isPageUser( doc ),
stuff = false,
scan, serve, specific, suffix, suggest;
if ( call ) {
serve = emit.getAttribute( "action" );
specific = emit.getAttribute( "specific" );
if ( call[ 1 ] ) {
if ( serve === "OpenFile" || serve === "SaveFileAs" ) {
scan = emit.getAttribute( "scan" );
suffix = emit.getAttribute( "suffix" );
suffix = ( suffix ? suffix : false );
suffix = suffix.replace( /[^a-zA-Z0-9]/g, "" );
}
switch ( serve ) {
case "OpenFile" :
// +text/saved leer oder gleich
stuff = emit.getAttribute( "lowcode" );
PAGES.file( specific,
scan,
suffix,
call[ 0 ],
( stuff === "true" ) );
break;
case "SaveFileAs" :
suggest = emit.getAttribute( "suggest" );
stuff = IO.find( specific,
scan,
suggest,
suffix,
true );
case "SaveFile" : // fall through
IO.flush( doc, stuff );
break;
case "Abort" :
break;
} // switch serve
} else {
switch ( serve ) {
case "DirBase" :
WLE.prefs.fetchBasedir();
PAGES.setDirBase( doc );
break;
case "DirSub" :
IO.fetchSubdir( specific );
PAGES.setDirSub( doc, specific );
break;
} // switch serve
}
}
return false;
}; // EVENTS.onPressButton()
EVENTS.connect = [
[ "load", EVENTS.onPageLoad ],
[ "wikilocaleditButton", EVENTS.onPressButton ]
];
IO.fetchSubdir = function ( account ) {
// Perform local directory sub project selection and storing
// Precondition:
// account -- DBname . user name
// Uses:
// > .locale.selectDirSub
// .prefs.getDirBase()
// .prefs.getDirSub()
// .fileIO.find()
// .prefs.setDirSub()
// 2012-12-12 PerfektesChaos@de.wikipedia
var n, s,
start = WLE.prefs.getDirBase();
s = WLE.fileIO.find( start + WLE.prefs.getDirSub( account ),
false,
false,
false,
WLE.locale.selectDirSub + "\n" + account,
false );
if ( typeof s === "string" ) {
n = start.length;
if ( s.substr( 0, n ) === start ) {
s = s.substr( n );
} else {
s = "";
}
WLE.prefs.setDirSub( s, account );
}
}; // IO.fetchSubdir()
IO.file = function ( account, achieve, assign, access, ansi ) {
// Retrieve file name and content and put into textarea
// Precondition:
// account -- sub path for: DBname / user name
// achieve -- pattern string
// assign -- suffix for new file
// access -- document of user edit web page
// ansi -- input file is not utf-8
// Uses:
// IO.find()
// .fileIO.feed()
// (IO.filled)
// 2012-12-12 PerfektesChaos@de.wikipedia
var stuff = IO.find( account, achieve, false, assign, false );
if ( stuff ) {
WLE.fileIO.feed( stuff, access, this.filled, ansi );
}
}; // IO.file()
IO.filled = function ( arglist ) {
// Callback after asynchronous reading from local file
// Precondition:
// arglist -- Array, or false
// [0] path (appoint)
// [1] true: write protected
// [2] content, or false
// [3] document of user web page
// achieved -- string with file content
// Uses:
// >< .pages.windows
// .pages.fiat()
// .pages.form()
// .pages.fill()
// Remark: Used as event handler -- 'this' is not IO
// 2012-11-30 PerfektesChaos@de.wikipedia
var doc, props, socket;
if ( arglist ) {
doc = arglist[ 3 ];
socket = PAGES.fiat( doc );
if ( socket ) {
props = PAGES.windows[ socket ];
if ( props ) {
props.filepath = arglist[ 0 ];
PAGES.form( doc, socket );
PAGES.fill( doc, arglist[ 2 ] );
}
}
}
}; // IO.filled()
IO.find = function ( account, achieve, assign, add, allow ) {
// Find text file name
// Precondition:
// account -- sub path for: DBname / user name
// achieve -- pattern string
// assign -- suggestion for file name
// add -- suffix for new file, or false
// allow -- save a non-existing file
// Postcondition:
// Returns string with path, or false
// Uses:
// this
// > IO.search
// > IO.select
// > .locale.selectFile
// .prefs.getDirBase()
// .prefs.getDirSub()
// .fileIO.find()
// 2012-12-12 PerfektesChaos@de.wikipedia
var r,
pattern = [ "", achieve ],
start = PREFS.getDirBase(),
suffix = add,
suggest = assign;
if ( start && account ) {
start = start + PREFS.getDirSub( account );
}
if ( ! achieve ) {
pattern[ 1 ] = this.search;
}
if ( pattern[ 1 ] === this.search ) {
pattern[ 0 ] = this.select;
}
if ( suffix ) {
suffix = ( suffix === "*" ? "" : suffix );
} else {
suffix = "txt";
}
r = WLE.fileIO.find( start,
pattern,
suggest,
suffix,
WLE.locale.selectFile,
allow );
return r;
}; // IO.find()
IO.flush = function ( access, as ) {
// Write content into text file
// Precondition:
// access -- document of user edit web page
// as -- SaveAs file path, or false
// Postcondition:
// Returns true if failed
// Uses:
// this
// w
// > .pages.windows
// .pages.fiat()
// .pages.feed()
// .fileIO.flush()
// (IO.flushed)
// 2012-11-30 PerfektesChaos@de.wikipedia
var r,
socket = PAGES.fiat( access ),
store = ( as ? as : PAGES.windows[ socket ].filepath ),
story = PAGES.feed( access );
r = WLE.fileIO.flush( story,
store,
access,
this.flushed,
[ access, story, store, socket ] );
if ( r ) {
// Handle error!
w.alert( "IO.flush() " + r );
}
return r;
}; // IO.flush()
IO.flushed = function ( approve, arglist ) {
// Callback after asynchronous written text file
// Precondition:
// approve -- status code
// arglist -- Array
// Uses:
// w
// .pages.flushed()
// Remark: Used as event handler -- 'this' is not IO
// 2012-11-30 PerfektesChaos@de.wikipedia
if ( w.Components.isSuccessCode( approve ) ) {
PAGES.flushed( arglist[ 0 ],
arglist[ 1 ],
arglist[ 2 ],
arglist[ 3 ] );
} else {
w.alert( "IO.flushed() error=" + approve);
// Handle error!
}
}; // IO.flushed()
PAGES.feed = function ( access ) {
// Retrieve content from textarea
// Precondition:
// access -- document of user edit web page
// Postcondition:
// Returns text
// Uses:
// DOM.getElementById()
// 2012-11-30 PerfektesChaos@de.wikipedia
var elt = access.getElementById( "wpTextbox1" ),
r = false;
if ( elt ) {
r = elt.value;
}
return r;
}; // .pages.feed()
PAGES.fetch = function ( ask ) {
// Retrieve unique 64-bit ID number of user window
// Precondition:
// ask -- document of user web page
// Postcondition:
// Returns ID number string (tabbrowser window count)
// Uses:
// w
// 2012-11-30 PerfektesChaos@de.wikipedia
var cif,
util,
r = false,
win = ask.defaultView;
if ( win ) {
cif = w.Components.interfaces;
util = win.QueryInterface( cif.nsIInterfaceRequestor )
.getInterface( cif.nsIDOMWindowUtils );
if ( util ) {
r = "w#" + util.outerWindowID;
}
}
return r;
}; // .pages.fetch()
PAGES.fiat = function ( ask ) {
// Ensure persistent window information for this tabbrowser
// Precondition:
// ask -- document of user web page
// Postcondition:
// Returns ID number string
// Uses:
// this
// >< .pages.windows
// .pages.fetch()
// .pages.first()
// 2012-11-30 PerfektesChaos@de.wikipedia
var r = this.fetch( ask );
if ( r ) {
if ( ! this.windows ) {
this.windows = { };
}
if ( ! this.windows[ r ] ) {
this.first( r );
}
}
return r;
}; // .pages.fiat()
PAGES.file = function ( account, achieve, assign, access, ansi ) {
// If save, retrieve file name and content and put into textarea
// Precondition:
// account -- sub path for: DBname / user name
// achieve -- pattern string
// assign -- suffix for new file
// access -- document of user edit web page
// ansi -- input file is not utf-8
// Uses:
// this
// w
// > .pages.windows
// > .locale.saveFirst
// .pages.feed()
// .pages.fiat()
// IO.file()
// 2012-11-30 PerfektesChaos@de.wikipedia
var leeway = true,
screen = this.feed( access ),
socket,
store;
if ( screen ) {
socket = this.fiat( access );
store = this.windows[ socket ].wikitext;
if ( store ) {
leeway = ( screen === store );
if ( ! leeway ) {
w.alert( WLE.locale.saveFirst );
}
}
}
if ( leeway ) {
IO.file( account, achieve, assign, access, ansi );
}
}; // .pages.file()
PAGES.fill = function ( access, apply ) {
// Fill textarea with file content
// Precondition:
// access -- document of user edit web page
// apply -- content
// Uses:
// this
// < .pages.windows
// DOM.getElementById()
// DOM.createEvent()
// DOM.initEvent()
// DOM.dispatchEvent()
// .pages.fiat()
// 2012-11-30 PerfektesChaos@de.wikipedia
var elt = access.getElementById( "wpTextbox1" ),
event,
k,
socket,
story = apply;
if ( elt ) {
elt.value = story;
event = access.createEvent( "Events" );
event.initEvent( "wikilocaleditFilled", true, false );
elt.dispatchEvent( event );
// Byte Order Mark
k = story.charCodeAt(0);
if ( k === 255 ) {
if ( story.charCodeAt(1) === 254 ) {
story = story.substr( 2 );
}
} else if ( k === 65534 ) {
story = story.substr( 1 );
}
socket = this.fiat( access );
this.windows[ socket ].wikitext = story;
}
}; // .pages.fill()
PAGES.first = function ( assign ) {
// Initialize page window object
// assign -- windows ID
// Precondition:
// Uses:
// this
// < .pages.windows
// 2012-11-30 PerfektesChaos@de.wikipedia
this.windows[ assign ] = { filepath: false,
letwrite: true,
wikitext: false };
}; // .pages.first()
PAGES.flushed = function ( adjust, apply, address, assign ) {
// File content has been written
// Precondition:
// adjust -- document of static user page
// apply -- content
// address -- text file path
// assign -- windows ID
// Uses:
// this
// >< .pages.windows
// DOM.getElementById()
// DOM.createEvent()
// DOM.initEvent()
// DOM.dispatchEvent()
// .pages.setFile()
// 2012-11-30 PerfektesChaos@de.wikipedia
var elt = adjust.getElementById( "wpTextbox1" ),
event;
if ( elt ) {
event = adjust.createEvent("Events");
event.initEvent( "wikilocaleditSaved", true, false );
elt.dispatchEvent( event );
this.windows[ assign ].wikitext = apply;
PAGES.windows[ assign ].filepath = address;
this.setFile( adjust, address );
}
}; // .pages.flushed()
PAGES.form = function ( adjust, aim ) {
// Decorate edit/submit user page of /LocalEdit
// Precondition:
// adjust -- document of static user page
// aim -- unique window identifier
// Uses:
// this
// > .pages.windows
// .pages.setFile()
// 2012-12-12 PerfektesChaos@de.wikipedia
var elt = adjust.getElementById( "WLE_select_SaveFile" ),
props = this.windows[ aim ],
s = props.filepath;
if ( elt ) {
if ( s ) {
this.setFile( adjust, s );
elt.disabled = ! props.letwrite;
} else {
this.setFile( adjust, "" );
elt.disabled = true;
}
}
}; // .pages.form()
PAGES.fresh = function () {
// Update userpage list and page URL listener
// Uses:
// this
// >< .pages.userURLstatics
// >< .pages.userURLsubmits
// .prefs.getUserlist()
// Remark: Used by content/config.js
// 2012-11-30 PerfektesChaos@de.wikipedia
var i, j, n, s, s0, s1, sift, site,
userlist = WLE.prefs.getUserlist();
if ( userlist ) {
n = userlist.length;
this.userURLstatics = new Array( n );
this.userURLsubmits = new Array( n );
for ( i = 0; i < n; i++ ) {
s = userlist[ i ];
j = s.indexOf( "/wiki/" );
if ( j > 15 ) {
site = s.substr( 0, j + 1 );
sift = s.substr( j + 6 ) + "/LocalEdit";
s0 = site + "wiki/" + sift;
s1 = site + "w/index.php?title=" + sift
+ "&action=";
} else {
s0 = "";
s1 = "";
}
this.userURLstatics[ i ] = s0;
this.userURLsubmits[ i ] = s1;
} // for i
} else if ( this.userURLstatics ) {
delete this.userURLstatics;
delete this.userURLsubmits;
}
}; // .pages.fresh()
PAGES.furnish = function ( adjust ) {
// Decorate static user page of /wiki/ /LocalEdit
// Precondition:
// adjust -- document of static user page
// Uses:
// this
// DOM.getElementById()
// DOM.setAttribute()
// .pages.setDirBase()
// .pages.setDirSub()
// 2012-11-30 PerfektesChaos@de.wikipedia
var elt, s, specific;
elt = adjust.getElementById( "WLE.inactive" );
elt.setAttribute( "style", "display:none" );
elt = adjust.getElementById( "WLE.active" );
elt.removeAttribute( "style" );
elt = adjust.getElementById( "WLE.client" );
s = elt.getAttribute( "src" );
elt = adjust.getElementById( "WLE.stateIMG" );
elt.setAttribute( "src", s );
this.setDirBase( adjust );
elt = adjust.getElementById( "WLE.DirBase" );
elt.removeAttribute( "style" );
elt = adjust.getElementById( "WLE.specific" );
specific = elt.textContent;
this.setDirSub( adjust, specific );
elt = adjust.getElementById( "WLE.startEdit" );
elt.removeAttribute( "style" );
}; // .pages.furnish()
PAGES.isPageUser = function ( approve ) {
// Check whether event has been launched from registered user page
// Precondition:
// approve -- document to be checked for origin
// Postcondition:
// Returns Array iff dispatched from requested user page
// [0] document
// [1] false: static, else dynamic action
// Uses:
// this
// > .reDomain
// > .pages.userURLstatics
// > .pages.userURLsubmits
// 2012-11-30 PerfektesChaos@de.wikipedia
var i, n, doc, s, src,
r = false;
if ( this.userURLstatics ) {
doc = approve;
if ( doc instanceof HTMLDocument ) {
// is this an inner frame?
if ( doc.defaultView.frameElement ) {
// Frame within a tab was loaded.
// Find the root document:
while ( doc.defaultView.frameElement ) {
doc = doc.defaultView.frameElement.ownerDocument;
}
}
}
src = doc.URL;
if ( WLE.reDomain.test( src ) ) {
n = this.userURLstatics.length;
for ( i = 0; i < n; i++ ) {
if ( src === this.userURLstatics[ i ] ) {
r = [ doc, false ];
break;
}
} // for i
if ( ! r ) {
for ( i = 0; i < n; i++ ) {
s = this.userURLsubmits[ i ];
if ( src.indexOf( s ) === 0 ) {
r = [ doc, src.substr( s.length ) ];
break;
}
} // for i
}
}
}
return r;
}; // .pages.isPageUser()
PAGES.setDirBase = function ( adjust ) {
// Write base directory path into static /LocalEdit user page
// Precondition:
// adjust -- document of static user page
// Postcondition:
// Returns base directory
// Uses:
// DOM.getElementById()
// .prefs.getDirBase()
// 2012-11-30 PerfektesChaos@de.wikipedia
var elt = adjust.getElementById( "WLE.dirbase" ),
r = PREFS.getDirBase();
if ( elt ) {
elt.textContent = r;
}
return r;
}; // .pages.setDirBase()
PAGES.setDirSub = function ( adjust, account ) {
// Write project directory path into static /LocalEdit user page
// Precondition:
// adjust -- document of static user page
// account -- DBname . user name
// Uses:
// DOM.getElementById()
// .prefs.getDirBase()
// DOM.removeAttribute()
// DOM.setAttribute()
// 2012-11-30 PerfektesChaos@de.wikipedia
var eltButt = adjust.getElementById( "WLE.DirSub" ),
eltPath = adjust.getElementById( "WLE.dirsub" );
if ( eltButt && eltPath ) {
if ( PREFS.getDirBase() ) {
eltButt.removeAttribute( "style" );
eltPath.removeAttribute( "style" );
eltPath.textContent = PREFS.getDirSub( account );
} else {
eltButt.setAttribute( "style", "display:none" );
eltPath.setAttribute( "style", "display:none" );
}
}
}; // .pages.setDirSub()
PAGES.setFile = function ( adjust, address ) {
// Write text file path into user page
// Precondition:
// adjust -- document of static user page
// address -- text file path
// Uses:
// DOM.getElementById()
// DOM.setAttribute()
// 2012-11-30 PerfektesChaos@de.wikipedia
var elt = adjust.getElementById( "LocalEditFilePath" ),
style;
if ( elt ) {
if ( address ) {
elt.textContent = address;
style = "margin-bottom: 1em;"
+ "border-bottom: solid 2px #0000FF;";
} else {
style = "display:none";
}
elt = adjust.getElementById( "LocalEditFileDiv" );
elt.setAttribute( "style", style );
}
}; // .pages.setFile()
WLE.toolBarClicked = function () {
// Button on panel has been clicked.
// Start or stop listening on events.
// Uses:
// >< .live
// TOOL.fresh()
// Remark: Used as event handler -- 'this' is not WLE
// 2012-11-30 PerfektesChaos@de.wikipedia
WLE.live = ! WLE.live;
TOOL.fresh( false );
}; // .toolBarClicked()
TOOL.fresh = function ( all ) {
// Update toolbar menu state
// Uses:
// this
// > TOOL.panelButton
// > .live
// DOM.getElementById()
// EVENTS.fresh()
// 2012-11-30 PerfektesChaos@de.wikipedia
var show;
if ( ! this.panelButton ) {
this.panelButton
= document.getElementById( "wikilocaleditToolbarbutton" );
}
if ( this.panelButton ) {
show = "chrome://wikilocaledit/skin/wikilocaledit-24" + "x24"
+ ( WLE.live ? "" : "-off" ) + ".png";
this.panelButton.image = show;
if ( all ) {
this.panelButton.tooltipText = "";
}
}
EVENTS.fresh();
}; // TOOL.fresh()
} ( window ) );
/// EOF </nowiki> content/wikilocaledit.js