MediaWiki:Gadget-ZkontrolovanoUcitelem.js: Porovnání verzí
(Obsah stránky nahrazen textem „mw.hook( 've.activationComplete' ).add(function(){ });“) |
|||
| Řádek 1: | Řádek 1: | ||
mw.hook( 've.activationComplete' ).add(function(){ | mw.hook( 've.activationComplete' ).add(function(){ | ||
| − | + | /* Translate the following to your language: */ | |
| + | if (!mw.messages.exists( 've-SearchAndReplaceDialog-title' )) { | ||
| + | mw.messages.set({ | ||
| + | 've-SearchAndReplaceDialog-title': 'Search and replace', | ||
| + | 've-SearchAndReplaceDialog-from-label': 'From:', | ||
| + | 've-SearchAndReplaceDialog-to-label': 'To:', | ||
| + | 've-SearchAndReplaceDialog-from-placeholder': 'From text', | ||
| + | 've-SearchAndReplaceDialog-to-placeholder': 'To text', | ||
| + | 've-SearchAndReplaceDialog-replaceAll': 'Repalce all', | ||
| + | 've-SearchAndReplaceDialog-replace': 'Repalce', | ||
| + | 've-SearchAndReplaceDialog-matchcase': 'Match case', | ||
| + | 've-SearchAndReplaceDialog-replace-complete': 'Found and replaced $1 occurrences', | ||
| + | 've-ReplaceTool-ToolbarButton': 'Replace' | ||
| + | }); | ||
| + | } | ||
| + | /* end of translations */ | ||
| + | |||
| + | /*! | ||
| + | * VisualEditor replace gadget | ||
| + | * | ||
| + | * @copyright [[User:ערן|Eranroz]] and [[User:Ravid ziv|Ravid ziv]] | ||
| + | * @license The MIT License (MIT) | ||
| + | */ | ||
| + | function extractText(){ | ||
| + | var nodes = []; | ||
| + | var model = ve.instances[0].model; | ||
| + | function getTextNodes( obj ) { | ||
| + | var i; | ||
| + | |||
| + | for ( i = 0; i < obj.children.length; i++ ) { | ||
| + | if ( obj.children[i].type == 'text'){ | ||
| + | nodes.push(obj.children[i]); | ||
| + | } | ||
| + | |||
| + | if ( obj.children[i].children ) { | ||
| + | getTextNodes( obj.children[i] ); | ||
| + | } | ||
| + | } | ||
| + | } | ||
| + | getTextNodes(ve.instances[0].model.documentModel.getDocumentNode()); | ||
| + | return nodes; | ||
| + | } | ||
| + | |||
| + | function searchAndReplace( fromText, toText, replaceAll, matchCase ) { | ||
| + | var textNodes = extractText(); | ||
| + | var model = ve.instances[0].model; | ||
| + | var firstIndex = 0; | ||
| + | var numReplacements = 0; | ||
| + | for (var nodeI = 0; nodeI < textNodes.length; nodeI++) { | ||
| + | var node = textNodes[nodeI]; | ||
| + | var nodeRange = node.getRange(); | ||
| + | var nodeData = model.getFragment( nodeRange ).getData(); | ||
| + | var nodeText = $.map(nodeData, function( e ){ | ||
| + | if ( e instanceof Array){ return e[0]; } else { return e; } | ||
| + | }).join(''); | ||
| + | |||
| + | |||
| + | var fromIndex = matchCase? nodeText.toUpperCase().indexOf( fromText.toUpperCase(), firstIndex ) : nodeText.indexOf( fromText, firstIndex ); | ||
| + | if ( fromIndex == -1 ) { | ||
| + | firstIndex = 0; | ||
| + | continue; | ||
| + | } | ||
| + | var start = nodeRange.from+fromIndex; | ||
| + | var end = start+fromText.length; | ||
| + | if (!replaceAll && model.selection.start > start) { | ||
| + | continue;//skip replacements before selection | ||
| + | } | ||
| + | var removeRange = new ve.Range( start, end ); | ||
| + | var transaction = ve.dm.Transaction.newFromReplacement( | ||
| + | ve.instances[0].view.documentView.model, | ||
| + | removeRange, | ||
| + | toText | ||
| + | ); | ||
| + | var newSelection = new ve.Range(0,0); | ||
| + | if (!replaceAll) { | ||
| + | newSelection = new ve.Range( start, start+toText.length ); | ||
| + | } | ||
| + | ve.instances[0].view.changeModel(transaction, newSelection); | ||
| + | numReplacements++; | ||
| + | if (!replaceAll) { | ||
| + | break; | ||
| + | } | ||
| + | firstIndex = fromIndex + toText.length; | ||
| + | nodeI = nodeI -1; | ||
| + | } | ||
| + | if (numReplacements==0 || replaceAll) { | ||
| + | mw.notify( mw.msg( 've-SearchAndReplaceDialog-replace-complete', numReplacements ) ); | ||
| + | } | ||
| + | } | ||
| + | |||
| + | ve.ui.SearchAndReplaceDialog = function( manager, config ) { | ||
| + | // Parent constructor | ||
| + | ve.ui.SearchAndReplaceDialog.super.call( this, manager, config ); | ||
| + | |||
| + | }; | ||
| + | /* Inheritance */ | ||
| + | |||
| + | OO.inheritClass( ve.ui.SearchAndReplaceDialog, ve.ui.FragmentDialog ); | ||
| + | |||
| + | ve.ui.SearchAndReplaceDialog.prototype.getActionProcess = function ( action ) { | ||
| + | var fromVal = this.fromInput.getValue(), | ||
| + | toVal = this.toInput.getValue(), | ||
| + | matchCase = this.matchCaseCheckbox.getValue(); | ||
| + | |||
| + | if ( action === 'replace' ) { | ||
| + | return new OO.ui.Process( function () { | ||
| + | searchAndReplace( fromVal, toVal, false, matchCase ); | ||
| + | }, this ); | ||
| + | } else if ( action === 'replace-all' ) { | ||
| + | return new OO.ui.Process( function () { | ||
| + | searchAndReplace( fromVal, toVal, true, matchCase ); | ||
| + | this.close( ); | ||
| + | }, this ); | ||
| + | } | ||
| + | return ve.ui.MWMediaDialog.super.prototype.getActionProcess.call( this, action ); | ||
| + | } | ||
| + | |||
| + | ve.ui.SearchAndReplaceDialog.prototype.getBodyHeight = function () { | ||
| + | return 200; | ||
| + | }; | ||
| + | |||
| + | /* Static Properties */ | ||
| + | ve.ui.SearchAndReplaceDialog.static.name = 'search'; | ||
| + | ve.ui.SearchAndReplaceDialog.static.title = mw.msg( 've-SearchAndReplaceDialog-title' ); | ||
| + | ve.ui.SearchAndReplaceDialog.static.size = 'medium'; | ||
| + | |||
| + | ve.ui.SearchAndReplaceDialog.static.actions = [ | ||
| + | { | ||
| + | 'action': 'replace', | ||
| + | 'label': mw.msg( 've-SearchAndReplaceDialog-replace' ), | ||
| + | 'flags': [ 'constructive' ], | ||
| + | 'modes': 'insert' | ||
| + | }, | ||
| + | { | ||
| + | 'label': OO.ui.deferMsg( 'visualeditor-dialog-action-cancel' ), | ||
| + | 'flags': 'safe', | ||
| + | 'modes': [ 'edit', 'insert', 'select' ] | ||
| + | }, | ||
| + | { | ||
| + | 'action': 'replace-all', | ||
| + | 'label': mw.msg( 've-SearchAndReplaceDialog-replaceAll' ), | ||
| + | 'flags': [ 'constructive' ], | ||
| + | 'modes': 'insert' | ||
| + | } | ||
| + | ]; | ||
| + | |||
| + | ve.ui.SearchAndReplaceDialog.prototype.initialize = function () { | ||
| + | ve.ui.SearchAndReplaceDialog.super.prototype.initialize.call( this ); | ||
| + | this.panel = new OO.ui.PanelLayout( { '$': this.$, 'scrollable': true, 'padded': true } ); | ||
| + | this.inputsFieldset = new OO.ui.FieldsetLayout( { | ||
| + | '$': this.$ | ||
| + | } ); | ||
| + | // input from | ||
| + | this.fromInput = new OO.ui.TextInputWidget( | ||
| + | { '$': this.$, 'multiline': false, 'placeholder': mw.msg( 've-SearchAndReplaceDialog-from-placeholder' ) } | ||
| + | ); | ||
| + | //input to | ||
| + | this.toInput = new OO.ui.TextInputWidget( | ||
| + | { '$': this.$, 'multiline': false, 'placeholder': mw.msg( 've-SearchAndReplaceDialog-to-placeholder' ) } | ||
| + | ); | ||
| + | this.fromField = new OO.ui.FieldLayout( this.fromInput, { | ||
| + | '$': this.$, | ||
| + | 'label': mw.msg( 've-SearchAndReplaceDialog-from-label' ) | ||
| + | } ); | ||
| + | this.toField = new OO.ui.FieldLayout( this.toInput, { | ||
| + | '$': this.$, | ||
| + | 'label': mw.msg( 've-SearchAndReplaceDialog-to-label' ) | ||
| + | } ); | ||
| + | |||
| + | |||
| + | this.matchCaseCheckbox = new OO.ui.CheckboxInputWidget( { | ||
| + | '$': this.$ | ||
| + | } ); | ||
| + | var matchCaseField = new OO.ui.FieldLayout( this.matchCaseCheckbox, { | ||
| + | '$': this.$, | ||
| + | 'align': 'inline', | ||
| + | 'label': mw.msg( 've-SearchAndReplaceDialog-matchcase' ) | ||
| + | } ); | ||
| + | |||
| + | this.inputsFieldset.$element.append( | ||
| + | this.fromField.$element, | ||
| + | this.toField.$element, | ||
| + | matchCaseField.$element | ||
| + | ); | ||
| + | this.panel.$element.append( this.inputsFieldset.$element ); | ||
| + | this.$body.append( this.panel.$element ); | ||
| + | |||
| + | } | ||
| + | |||
| + | ve.ui.windowFactory.register( ve.ui.SearchAndReplaceDialog ); | ||
| + | |||
| + | //---------- replace tool ------------------ | ||
| + | |||
| + | function ReplaceTool( toolGroup, config ) { | ||
| + | OO.ui.Tool.call( this, toolGroup, config ); | ||
| + | |||
| + | } | ||
| + | OO.inheritClass( ReplaceTool, OO.ui.Tool ); | ||
| + | |||
| + | ReplaceTool.static.name = 'ReplaceTool'; | ||
| + | ReplaceTool.static.title = mw.msg('ve-ReplaceTool-ToolbarButton'); | ||
| + | |||
| + | ReplaceTool.prototype.onSelect = function () { | ||
| + | this.toolbar.getSurface().execute( 'window', 'open', 'search', null ); | ||
| + | }; | ||
| + | |||
| + | ReplaceTool.prototype.onUpdateState = function () { | ||
| + | this.setActive( false ); | ||
| + | }; | ||
| + | |||
| + | ve.ui.toolFactory.register( ReplaceTool ); | ||
}); | }); | ||
Verze z 10. 12. 2014, 19:48
mw.hook( 've.activationComplete' ).add(function(){
/* Translate the following to your language: */
if (!mw.messages.exists( 've-SearchAndReplaceDialog-title' )) {
mw.messages.set({
've-SearchAndReplaceDialog-title': 'Search and replace',
've-SearchAndReplaceDialog-from-label': 'From:',
've-SearchAndReplaceDialog-to-label': 'To:',
've-SearchAndReplaceDialog-from-placeholder': 'From text',
've-SearchAndReplaceDialog-to-placeholder': 'To text',
've-SearchAndReplaceDialog-replaceAll': 'Repalce all',
've-SearchAndReplaceDialog-replace': 'Repalce',
've-SearchAndReplaceDialog-matchcase': 'Match case',
've-SearchAndReplaceDialog-replace-complete': 'Found and replaced $1 occurrences',
've-ReplaceTool-ToolbarButton': 'Replace'
});
}
/* end of translations */
/*!
* VisualEditor replace gadget
*
* @copyright [[User:ערן|Eranroz]] and [[User:Ravid ziv|Ravid ziv]]
* @license The MIT License (MIT)
*/
function extractText(){
var nodes = [];
var model = ve.instances[0].model;
function getTextNodes( obj ) {
var i;
for ( i = 0; i < obj.children.length; i++ ) {
if ( obj.children[i].type == 'text'){
nodes.push(obj.children[i]);
}
if ( obj.children[i].children ) {
getTextNodes( obj.children[i] );
}
}
}
getTextNodes(ve.instances[0].model.documentModel.getDocumentNode());
return nodes;
}
function searchAndReplace( fromText, toText, replaceAll, matchCase ) {
var textNodes = extractText();
var model = ve.instances[0].model;
var firstIndex = 0;
var numReplacements = 0;
for (var nodeI = 0; nodeI < textNodes.length; nodeI++) {
var node = textNodes[nodeI];
var nodeRange = node.getRange();
var nodeData = model.getFragment( nodeRange ).getData();
var nodeText = $.map(nodeData, function( e ){
if ( e instanceof Array){ return e[0]; } else { return e; }
}).join('');
var fromIndex = matchCase? nodeText.toUpperCase().indexOf( fromText.toUpperCase(), firstIndex ) : nodeText.indexOf( fromText, firstIndex );
if ( fromIndex == -1 ) {
firstIndex = 0;
continue;
}
var start = nodeRange.from+fromIndex;
var end = start+fromText.length;
if (!replaceAll && model.selection.start > start) {
continue;//skip replacements before selection
}
var removeRange = new ve.Range( start, end );
var transaction = ve.dm.Transaction.newFromReplacement(
ve.instances[0].view.documentView.model,
removeRange,
toText
);
var newSelection = new ve.Range(0,0);
if (!replaceAll) {
newSelection = new ve.Range( start, start+toText.length );
}
ve.instances[0].view.changeModel(transaction, newSelection);
numReplacements++;
if (!replaceAll) {
break;
}
firstIndex = fromIndex + toText.length;
nodeI = nodeI -1;
}
if (numReplacements==0 || replaceAll) {
mw.notify( mw.msg( 've-SearchAndReplaceDialog-replace-complete', numReplacements ) );
}
}
ve.ui.SearchAndReplaceDialog = function( manager, config ) {
// Parent constructor
ve.ui.SearchAndReplaceDialog.super.call( this, manager, config );
};
/* Inheritance */
OO.inheritClass( ve.ui.SearchAndReplaceDialog, ve.ui.FragmentDialog );
ve.ui.SearchAndReplaceDialog.prototype.getActionProcess = function ( action ) {
var fromVal = this.fromInput.getValue(),
toVal = this.toInput.getValue(),
matchCase = this.matchCaseCheckbox.getValue();
if ( action === 'replace' ) {
return new OO.ui.Process( function () {
searchAndReplace( fromVal, toVal, false, matchCase );
}, this );
} else if ( action === 'replace-all' ) {
return new OO.ui.Process( function () {
searchAndReplace( fromVal, toVal, true, matchCase );
this.close( );
}, this );
}
return ve.ui.MWMediaDialog.super.prototype.getActionProcess.call( this, action );
}
ve.ui.SearchAndReplaceDialog.prototype.getBodyHeight = function () {
return 200;
};
/* Static Properties */
ve.ui.SearchAndReplaceDialog.static.name = 'search';
ve.ui.SearchAndReplaceDialog.static.title = mw.msg( 've-SearchAndReplaceDialog-title' );
ve.ui.SearchAndReplaceDialog.static.size = 'medium';
ve.ui.SearchAndReplaceDialog.static.actions = [
{
'action': 'replace',
'label': mw.msg( 've-SearchAndReplaceDialog-replace' ),
'flags': [ 'constructive' ],
'modes': 'insert'
},
{
'label': OO.ui.deferMsg( 'visualeditor-dialog-action-cancel' ),
'flags': 'safe',
'modes': [ 'edit', 'insert', 'select' ]
},
{
'action': 'replace-all',
'label': mw.msg( 've-SearchAndReplaceDialog-replaceAll' ),
'flags': [ 'constructive' ],
'modes': 'insert'
}
];
ve.ui.SearchAndReplaceDialog.prototype.initialize = function () {
ve.ui.SearchAndReplaceDialog.super.prototype.initialize.call( this );
this.panel = new OO.ui.PanelLayout( { '$': this.$, 'scrollable': true, 'padded': true } );
this.inputsFieldset = new OO.ui.FieldsetLayout( {
'$': this.$
} );
// input from
this.fromInput = new OO.ui.TextInputWidget(
{ '$': this.$, 'multiline': false, 'placeholder': mw.msg( 've-SearchAndReplaceDialog-from-placeholder' ) }
);
//input to
this.toInput = new OO.ui.TextInputWidget(
{ '$': this.$, 'multiline': false, 'placeholder': mw.msg( 've-SearchAndReplaceDialog-to-placeholder' ) }
);
this.fromField = new OO.ui.FieldLayout( this.fromInput, {
'$': this.$,
'label': mw.msg( 've-SearchAndReplaceDialog-from-label' )
} );
this.toField = new OO.ui.FieldLayout( this.toInput, {
'$': this.$,
'label': mw.msg( 've-SearchAndReplaceDialog-to-label' )
} );
this.matchCaseCheckbox = new OO.ui.CheckboxInputWidget( {
'$': this.$
} );
var matchCaseField = new OO.ui.FieldLayout( this.matchCaseCheckbox, {
'$': this.$,
'align': 'inline',
'label': mw.msg( 've-SearchAndReplaceDialog-matchcase' )
} );
this.inputsFieldset.$element.append(
this.fromField.$element,
this.toField.$element,
matchCaseField.$element
);
this.panel.$element.append( this.inputsFieldset.$element );
this.$body.append( this.panel.$element );
}
ve.ui.windowFactory.register( ve.ui.SearchAndReplaceDialog );
//---------- replace tool ------------------
function ReplaceTool( toolGroup, config ) {
OO.ui.Tool.call( this, toolGroup, config );
}
OO.inheritClass( ReplaceTool, OO.ui.Tool );
ReplaceTool.static.name = 'ReplaceTool';
ReplaceTool.static.title = mw.msg('ve-ReplaceTool-ToolbarButton');
ReplaceTool.prototype.onSelect = function () {
this.toolbar.getSurface().execute( 'window', 'open', 'search', null );
};
ReplaceTool.prototype.onUpdateState = function () {
this.setActive( false );
};
ve.ui.toolFactory.register( ReplaceTool );
});