MediaWiki:Gadget-wikidebug.js: Różnice pomiędzy wersjami
Wygląd
Usunięta treść Dodana treść
Minor clean up |
rework |
||
Linia 5: | Linia 5: | ||
@section Dependencies |
@section Dependencies |
||
- jQuery - weakly dependent (might be easily rewritten to use something else); uses the "jQuery" object |
- jQuery - weakly dependent (might be easily rewritten to use something else); uses the "jQuery" object |
||
- |
- mediawiki.util - for addPortletLink() |
||
- oojs-ui-core - for OO.ui.alert() |
|||
@section done Functionality |
@section done Functionality |
||
Linia 27: | Linia 28: | ||
*/ |
*/ |
||
var errors = [], |
|||
/** |
|||
stateIcons = { |
|||
@brief Class for debugging |
|||
*/ |
|||
function wikiDbgClass() |
|||
{ |
|||
//! Version of class |
|||
this.ver = this.version = '1.0.2'; |
|||
//! @brief Array of errors that were caught |
|||
//! this is an array of objects: {strErrMsg:'error message', strFileName:'some.script.name.js', intLine:123} |
|||
this.arrErrors = []; |
|||
//! <private> variable containing an object of the class |
|||
var self = this; |
|||
//! <private> Icons urls depending on state of the debugger |
|||
var oStateIcons = { |
|||
'active' : '//upload.wikimedia.org/wikipedia/commons/1/16/Wikidebug_state_bug.png', |
'active' : '//upload.wikimedia.org/wikipedia/commons/1/16/Wikidebug_state_bug.png', |
||
'inactive' : '//upload.wikimedia.org/wikipedia/commons/4/44/Wikidebug_state_bug_inactive.png', |
'inactive' : '//upload.wikimedia.org/wikipedia/commons/4/44/Wikidebug_state_bug_inactive.png', |
||
'error' : '//upload.wikimedia.org/wikipedia/commons/3/39/Wikidebug_state_bug_occured.png' |
'error' : '//upload.wikimedia.org/wikipedia/commons/3/39/Wikidebug_state_bug_occured.png' |
||
} |
}, |
||
strState = 'active'; |
|||
// test ver. |
|||
if (location.hostname == 'localhost') |
|||
{ |
|||
oStateIcons = { |
|||
'active' : 'img/bug.png', |
|||
'inactive' : 'img/bug_inactive.png', |
|||
'error' : 'img/bug_occured.png' |
|||
}; |
|||
} |
|||
window.onerror = function ( strErrMsg, strFileName, intLine ) { |
|||
//! <private> state of the debugger |
|||
strState = 'error'; |
|||
errors.push( { |
|||
strErrMsg: strErrMsg, |
|||
strFileName: strFileName, |
|||
intLine: intLine |
|||
} ); |
|||
return true; |
|||
}; |
|||
function getBrowser() { |
|||
//! <private> Main container element |
|||
return navigator.userAgent; |
|||
var elContainer = null; |
|||
} |
|||
//! <private> Icon element |
|||
var elIcon = null; |
|||
//! <private> Number of bugs indicator element |
|||
var elNumBugs = null; |
|||
function getScripts() { |
|||
/** |
|||
var scripts = document.getElementsByTagName( 'script' ); |
|||
@brief <private> Error handler to be run onerror |
|||
return [].slice.call( scripts ).reduce( function ( arr, el ) { |
|||
function errorHandler(strErrMsg, strFileName, intLine) |
|||
return el.src ? arr.concat( el.src ) : arr; |
|||
{ |
|||
}, [] ); |
|||
strState = 'error'; |
|||
} |
|||
self.arrErrors.push({ |
|||
'strErrMsg':strErrMsg, 'strFileName':strFileName, 'intLine':intLine |
|||
}); |
|||
return true; |
|||
} |
|||
/** |
|||
@brief <private> Init stuff that needs to have the page ready |
|||
*/ |
|||
function pageReady() |
|||
{ |
|||
// add container for info and icons |
|||
elContainer = document.createElement('div'); |
|||
var elParent = document.getElementById('p-personal'); |
|||
if (!elParent) |
|||
{ |
|||
elParent = document.body; |
|||
//elContainer.style.cssText = 'position:absolute; right:0; top:0; z-index:10000; background-color:white;'; |
|||
} |
|||
else |
|||
{ |
|||
//elContainer.style.cssText = 'position:relative; z-index:10000; background-color:white;'; |
|||
} |
|||
elContainer.setAttribute('id', 'wikidebug-container'); |
|||
elParent.appendChild(elContainer); |
|||
// add num of bugs |
|||
elNumBugs = document.createElement('span'); |
|||
if (self.arrErrors.length) |
|||
{ |
|||
elNumBugs.innerHTML = self.arrErrors.length; |
|||
} |
|||
elContainer.appendChild(elNumBugs); |
|||
// add bugs icon |
|||
elIcon = document.createElement('img'); |
|||
elIcon.src = oStateIcons[strState]; |
|||
elIcon.setAttribute('alt', 'bug:'+strState); |
|||
elIcon.onclick = function() { self.showInfo(); }; |
|||
elContainer.appendChild(elIcon); |
|||
} |
|||
/** |
|||
@brief <private> Get browser details |
|||
*/ |
|||
function getBrowser() |
|||
{ |
|||
return navigator.userAgent; |
|||
} |
|||
/** |
|||
@brief <private> Get loaded scripts |
|||
*/ |
|||
function getScripts() |
|||
{ |
|||
var arrScripts = []; |
|||
//var reShortenScriptUrl = /^http:\/\/([^\/]+).+?[?&]title=([^?&]+).+/; |
|||
jQuery('script').each(function() |
|||
{ |
|||
var url = this.src; |
|||
/* |
|||
if (url.search(reShortenScriptUrl)>=0) |
|||
{ |
|||
url = url.replace(reShortenScriptUrl, '$1/$2'); |
|||
} |
|||
*/ |
|||
if (url && url.length) // external script |
|||
{ |
|||
arrScripts.push(url); |
|||
} |
|||
}); |
|||
return arrScripts; |
|||
} |
|||
/** |
|||
@brief Init debugging |
|||
*/ |
|||
this.init = function () |
|||
{ |
|||
if (strState == 'active') |
|||
{ |
|||
window.onerror = errorHandler; |
|||
} |
|||
jQuery(document).ready(pageReady); |
|||
}; |
|||
function showInfo() { |
|||
/** |
|||
var msg = mw.format( |
|||
@brief Show debug info |
|||
'=== Browser ===\n$1\n\n=== Scripts ===\n$2\n\n=== Errors ===\n$3', |
|||
*/ |
|||
getBrowser(), |
|||
this.showInfo = function() |
|||
getScripts().map( function ( script ) { |
|||
{ |
|||
return '* ' + script; |
|||
// conv. errors |
|||
} ).join( '\n' ), |
|||
errors.map( function ( err ) { |
|||
for (var i in self.arrErrors) |
|||
return mw.format( '* [$1 @$2] $3', err.strFileName, err.intLine, err.strErrMsg ); |
|||
{ |
|||
} ).join( '\n' ) |
|||
strErrors += '\n* ['+self.arrErrors[i].strFileName+' @'+self.arrErrors[i].intLine+'] ' |
|||
+self.arrErrors[i].strErrMsg |
|||
; |
|||
} |
|||
// show |
|||
jsAlert('' |
|||
+'<div><textarea rows="10" style="width:100%">' |
|||
+'=== Browser ===\n' |
|||
+getBrowser() |
|||
+'\n\n' |
|||
+'=== Scripts ===\n' |
|||
+'\n* '+getScripts().join('\n* ') |
|||
+'\n\n' |
|||
+'=== Errors ===\n' |
|||
+strErrors |
|||
+'\n\n' |
|||
+'</textarea></div>' |
|||
); |
); |
||
}; |
|||
OO.ui.alert( $( '<textarea>' ).attr( 'rows', 15 ).text( msg ), { |
|||
size: 'large', |
|||
title: 'wikidebug' |
|||
} ); |
|||
} |
} |
||
$( function () { |
|||
// |
|||
$( mw.util.addPortletLink( 'p-personal', '#', 'wikidebug', 'p-wikidebug', 'wikidebug' ) ) |
|||
// Init debugger object |
|||
.append( [ |
|||
// |
|||
$( '<span>' ).text( errors.length || '' ), |
|||
var wikidbg = new wikiDbgClass(); |
|||
$( '<img>' ).attr( 'src', stateIcons[ strState ] ) |
|||
// this should start debugging |
|||
] ) |
|||
wikidbg.init(); |
|||
.on( 'click', function ( evt ) { |
|||
// EOF |
|||
mw.loader.using( 'oojs-ui-core' ).done( showInfo ); |
|||
} ); |
|||
} ); |
Wersja z 21:13, 18 gru 2021
/**
@package wikidebug
@brief Script for debugging JS scripts
@section Dependencies
- jQuery - weakly dependent (might be easily rewritten to use something else); uses the "jQuery" object
- mediawiki.util - for addPortletLink()
- oojs-ui-core - for OO.ui.alert()
@section done Functionality
- Collect errors in an array.
- Add a debugger icon.
- Display an error indicator (different icon).
- Display number of errors caught near the icon.
- Show errors and browser info upon click on an icon.
- Display a list of scripts in the info alert.
@todo
- Change info alert to some menu or make a right-click menu.
- Debugger deactivation when the icon(?) is clicked - or maybe when an option is choose (save in a cookie).
- Check if window.onerror is actualy working. So far:
- working in: IE, FF
- not working in: Opera, Chrome, Safari
- i18n, titles.
- styling (ids/classes + CSS)
- Add a link to start wiki debugging mode (document.cookie="resourceLoaderDebug=1;path=/").
- Display a list of styles?
*/
var errors = [],
stateIcons = {
'active' : '//upload.wikimedia.org/wikipedia/commons/1/16/Wikidebug_state_bug.png',
'inactive' : '//upload.wikimedia.org/wikipedia/commons/4/44/Wikidebug_state_bug_inactive.png',
'error' : '//upload.wikimedia.org/wikipedia/commons/3/39/Wikidebug_state_bug_occured.png'
},
strState = 'active';
window.onerror = function ( strErrMsg, strFileName, intLine ) {
strState = 'error';
errors.push( {
strErrMsg: strErrMsg,
strFileName: strFileName,
intLine: intLine
} );
return true;
};
function getBrowser() {
return navigator.userAgent;
}
function getScripts() {
var scripts = document.getElementsByTagName( 'script' );
return [].slice.call( scripts ).reduce( function ( arr, el ) {
return el.src ? arr.concat( el.src ) : arr;
}, [] );
}
function showInfo() {
var msg = mw.format(
'=== Browser ===\n$1\n\n=== Scripts ===\n$2\n\n=== Errors ===\n$3',
getBrowser(),
getScripts().map( function ( script ) {
return '* ' + script;
} ).join( '\n' ),
errors.map( function ( err ) {
return mw.format( '* [$1 @$2] $3', err.strFileName, err.intLine, err.strErrMsg );
} ).join( '\n' )
);
OO.ui.alert( $( '<textarea>' ).attr( 'rows', 15 ).text( msg ), {
size: 'large',
title: 'wikidebug'
} );
}
$( function () {
$( mw.util.addPortletLink( 'p-personal', '#', 'wikidebug', 'p-wikidebug', 'wikidebug' ) )
.append( [
$( '<span>' ).text( errors.length || '' ),
$( '<img>' ).attr( 'src', stateIcons[ strState ] )
] )
.on( 'click', function ( evt ) {
mw.loader.using( 'oojs-ui-core' ).done( showInfo );
} );
} );