[BREAKING CHANGE] Update VE core submodule to master (88fe25f)

Switch to processes for windows (dialogs/inspectors)

This conversion also required the splitting of MWLinkInspector into
MWLinkNodeInspector and MWLinkAnnotationInspector.

New changes:
88fe25f [BREAKING CHANGE] Update OOjs UI to v0.1.0-pre (dd888aba5c)

Change-Id: I662d8985463c9fc881775f70aef87ebeb454a73f
This commit is contained in:
Trevor Parscal 2014-05-30 21:47:08 -07:00 committed by Roan Kattouw
parent 4719978a47
commit f65c3c6ef1
22 changed files with 580 additions and 451 deletions

View file

@ -145,6 +145,7 @@
"classes": [
"OO.ui",
"OO.ui.Element",
"OO.ui.Process",
"OO.ui.Frame",
"OO.ui.Toolbar",
"OO.ui.Window",

View file

@ -540,6 +540,8 @@ $wgResourceModules += array(
'visualeditor-inspector-close-tooltip',
'visualeditor-inspector-remove-tooltip',
'visualeditor-linkinspector-title',
'visualeditor-linknodeinspector-title',
'visualeditor-linknodeinspector-add-label',
'visualeditor-listbutton-bullet-tooltip',
'visualeditor-listbutton-number-tooltip',
'visualeditor-mediasizewidget-button-originaldimensions',
@ -818,9 +820,10 @@ $wgResourceModules += array(
'modules/ve-mw/ui/widgets/ve.ui.MWLinkTargetInputWidget.js',
'modules/ve-mw/ui/inspectors/ve.ui.MWLinkInspector.js',
'modules/ve-mw/ui/inspectors/ve.ui.MWLinkAnnotationInspector.js',
'modules/ve-mw/ui/inspectors/ve.ui.MWLinkNodeInspector.js',
'modules/ve-mw/ui/tools/ve.ui.MWLinkInspectorTool.js',
'modules/ve-mw/ui/tools/ve.ui.MWLinkNodeInspectorTool.js',
),
'styles' => array(
'modules/ve-mw/ce/styles/nodes/ve.ce.MWNumberedExternalLinkNode.css',

2
lib/ve

@ -1 +1 @@
Subproject commit 418cd67eaf2e08a73f137cbacc7c41d413140416
Subproject commit 88fe25f529e23a2cf3c1b6d39eb4013de601e82d

View file

@ -172,6 +172,8 @@
"visualeditor-linkinspector-suggest-matching-page": "{{PLURAL:$1|Matching page|Matching pages}}",
"visualeditor-linkinspector-suggest-new-page": "New page",
"visualeditor-linkinspector-suggest-redirect-page": "{{PLURAL:$1|Redirect page|Redirect pages}}",
"visualeditor-linknodeinspector-add-label": "Add label",
"visualeditor-linknodeinspector-title": "Simple link",
"visualeditor-loadwarning": "Error loading data from server: $1. Would you like to retry?",
"visualeditor-loadwarning-token": "Error loading edit token from server: $1. Would you like to retry?",
"visualeditor-mainnamespacepagelink": "Project:Main namespace",

View file

@ -177,6 +177,8 @@
"visualeditor-linkinspector-suggest-matching-page": "Label for suggested matching local wiki page or pages in the link inspector\nParams:\n* $1 - number of matching pages, used for plural",
"visualeditor-linkinspector-suggest-new-page": "Label for a new page in the link inspector.\n{{Identical|New page}}",
"visualeditor-linkinspector-suggest-redirect-page": "Label for suggested redirect pages in the link inspector. Parameters:\n* $1 - number of redirect pages, used for plural\n{{Identical|Redirect page}}",
"visualeditor-linknodeinspector-title": "Title of inspector for editing auto-numbered, external, labelless links",
"visualeditor-linknodeinspector-add-label": "Label of button that converts an auto-numbered, external, labelless link into a labeled external link",
"visualeditor-loadwarning": "Text (JavaScript confirm()) shown when the editor fails to load properly.\n\nParameters:\n* $1 - the error message from the server, in English. e.g. \"parsoidserver-http-bad-status: 404\"",
"visualeditor-loadwarning-token": "Text (JavaScript confirm()) shown when the editor fails to load properly.\n\nParameters:\n* $1 - the error message from the server.",
"visualeditor-mainnamespacepagelink": "Name of a page describing the main namespace (NS0) in this project.\n{{doc-important|Do not translate \"Project\"; it is automatically converted to the wiki's project namespace.}}",

View file

@ -1075,7 +1075,6 @@ ve.init.mw.ViewPageTarget.prototype.tearDownSurface = function () {
if ( this.saveDialog ) {
// If we got as far as setting up the save dialog, tear it down
this.saveDialog.close();
this.saveDialog.teardown();
this.saveDialog = null;
}
// Destroy surface

View file

@ -145,29 +145,29 @@ ve.ui.MWCitationDialog.prototype.initialize = function ( data ) {
/**
* @inheritdoc
*/
ve.ui.MWCitationDialog.prototype.setup = function ( data ) {
// Parent method
ve.ui.MWCitationDialog.super.prototype.setup.call( this, data );
// Initialization
if ( this.selectedNode ) {
this.referenceNode = this.getReferenceNode();
if ( this.referenceNode ) {
this.referenceModel = ve.dm.MWReferenceModel.static.newFromReferenceNode(
this.referenceNode
);
}
}
ve.ui.MWCitationDialog.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWCitationDialog.super.prototype.getSetupProcess.call( this, data )
.next( function () {
// Initialization
if ( this.selectedNode ) {
this.referenceNode = this.getReferenceNode();
if ( this.referenceNode ) {
this.referenceModel = ve.dm.MWReferenceModel.static.newFromReferenceNode(
this.referenceNode
);
}
}
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWCitationDialog.prototype.teardown = function ( data ) {
// Parent method
ve.ui.MWCitationDialog.super.prototype.teardown.call( this, data );
// Cleanup
this.referenceModel = null;
this.referenceNode = null;
ve.ui.MWCitationDialog.prototype.getTeardownProcess = function ( data ) {
return ve.ui.MWCitationDialog.super.prototype.getTeardownProcess.call( this, data )
.next( function () {
// Cleanup
this.referenceModel = null;
this.referenceNode = null;
}, this );
};

View file

@ -23,9 +23,6 @@ ve.ui.MWMediaEditDialog = function VeUiMWMediaEditDialog( config ) {
this.mediaNode = null;
this.imageModel = null;
this.store = null;
// Events
this.connect( this, { 'ready': 'onReady' } );
};
/* Inheritance */
@ -425,110 +422,112 @@ ve.ui.MWMediaEditDialog.prototype.onTypeInputSelect = function ( item ) {
/**
* @inheritdoc
*/
ve.ui.MWMediaEditDialog.prototype.setup = function ( data ) {
var doc = this.getFragment().getSurface().getDocument();
ve.ui.MWMediaEditDialog.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWMediaEditDialog.super.prototype.getSetupProcess.call( this, data )
.next( function () {
var doc = this.getFragment().getSurface().getDocument();
// Parent method
ve.ui.MWMediaEditDialog.super.prototype.setup.call( this, data );
// Properties
this.mediaNode = this.getFragment().getSelectedNode();
// Image model
this.imageModel = ve.dm.MWImageModel.static.newFromImageNode( this.mediaNode );
// Events
this.imageModel.connect( this, {
'alignmentChange': 'onImageModelAlignmentChange',
'typeChange': 'onImageModelTypeChange'
} );
// Properties
this.mediaNode = this.getFragment().getSelectedNode();
// Image model
this.imageModel = ve.dm.MWImageModel.static.newFromImageNode( this.mediaNode );
// Events
this.imageModel.connect( this, {
'alignmentChange': 'onImageModelAlignmentChange',
'typeChange': 'onImageModelTypeChange'
} );
this.store = doc.getStore();
// Set up the caption surface
this.captionSurface = new ve.ui.SurfaceWidget(
this.imageModel.getCaptionDocument(),
{
'$': this.$,
'tools': this.constructor.static.toolbarGroups,
'commands': this.constructor.static.surfaceCommands,
'pasteRules': this.constructor.static.pasteRules
}
);
this.store = doc.getStore();
// Set up the caption surface
this.captionSurface = new ve.ui.SurfaceWidget(
this.imageModel.getCaptionDocument(),
{
'$': this.$,
'tools': this.constructor.static.toolbarGroups,
'commands': this.constructor.static.surfaceCommands,
'pasteRules': this.constructor.static.pasteRules
}
);
// Size widget
this.$spinner.hide();
this.sizeErrorLabel.$element.hide();
this.sizeWidget.setScalable( this.imageModel.getScalable() );
// Size widget
this.$spinner.hide();
this.sizeErrorLabel.$element.hide();
this.sizeWidget.setScalable( this.imageModel.getScalable() );
// Initialize size
this.sizeWidget.setSizeType(
this.imageModel.isDefaultSize() ?
'default' :
'custom'
);
// Initialize size
this.sizeWidget.setSizeType(
this.imageModel.isDefaultSize() ?
'default' :
'custom'
);
// Set initial alt text
this.altTextInput.setValue(
this.imageModel.getAltText()
);
// Set initial alt text
this.altTextInput.setValue(
this.imageModel.getAltText()
);
// Set initial alignment
this.positionInput.setDisabled(
!this.imageModel.isAligned()
);
this.positionCheckbox.setValue(
this.imageModel.isAligned()
);
this.positionInput.selectItem(
this.imageModel.isAligned() ?
this.positionInput.getItemFromData(
this.imageModel.getAlignment()
) :
null
);
// Set initial alignment
this.positionInput.setDisabled(
!this.imageModel.isAligned()
);
this.positionCheckbox.setValue(
this.imageModel.isAligned()
);
this.positionInput.selectItem(
this.imageModel.isAligned() ?
this.positionInput.getItemFromData(
this.imageModel.getAlignment()
) :
null
);
// Border flag
this.borderCheckbox.setDisabled(
!this.imageModel.isBorderable()
);
this.borderCheckbox.setValue(
this.imageModel.isBorderable() && this.imageModel.hasBorder()
);
// Border flag
this.borderCheckbox.setDisabled(
!this.imageModel.isBorderable()
);
this.borderCheckbox.setValue(
this.imageModel.isBorderable() && this.imageModel.hasBorder()
);
// Type select
this.typeInput.selectItem(
this.typeInput.getItemFromData(
this.imageModel.getType() || 'none'
)
);
// Type select
this.typeInput.selectItem(
this.typeInput.getItemFromData(
this.imageModel.getType() || 'none'
)
);
// Initialization
this.captionFieldset.$element.append( this.captionSurface.$element );
this.captionSurface.initialize();
};
/**
* Handle window ready events
*/
ve.ui.MWMediaEditDialog.prototype.onReady = function () {
// Focus the caption surface
this.captionSurface.focus();
// Initialization
this.captionFieldset.$element.append( this.captionSurface.$element );
this.captionSurface.initialize();
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWMediaEditDialog.prototype.teardown = function ( data ) {
// Cleanup
this.imageModel.disconnect( this );
ve.ui.MWMediaEditDialog.prototype.getReadyProcess = function ( data ) {
return ve.ui.MWMediaEditDialog.super.prototype.getReadyProcess.call( this, data )
.next( function () {
// Focus the caption surface
this.captionSurface.focus();
}, this );
};
this.captionSurface.destroy();
this.captionSurface = null;
this.captionNode = null;
// Reset the considerations for the scalable
// in the image node
this.mediaNode.updateType();
// Parent method
ve.ui.MWMediaEditDialog.super.prototype.teardown.call( this, data );
/**
* @inheritdoc
*/
ve.ui.MWMediaEditDialog.prototype.getTeardownProcess = function ( data ) {
return ve.ui.MWMediaEditDialog.super.prototype.getTeardownProcess.call( this, data )
.first( function () {
// Cleanup
this.imageModel.disconnect( this );
this.captionSurface.destroy();
this.captionSurface = null;
this.captionNode = null;
// Reset the considerations for the scalable
// in the image node
this.mediaNode.updateType();
}, this );
};
/**

View file

@ -138,7 +138,7 @@ ve.ui.MWMediaInsertDialog.prototype.getFileRepos = function () {
*/
ve.ui.MWMediaInsertDialog.prototype.initialize = function () {
// Parent method
ve.ui.Dialog.prototype.initialize.call( this );
ve.ui.MWMediaInsertDialog.super.prototype.initialize.call( this );
this.defaultThumbSize = mw.config.get( 'wgVisualEditorConfig' )
.defaultUserOptions.defaultthumbsize;
@ -159,50 +159,50 @@ ve.ui.MWMediaInsertDialog.prototype.initialize = function () {
/**
* @inheritdoc
*/
ve.ui.MWMediaInsertDialog.prototype.setup = function ( data ) {
// Parent method
ve.ui.Dialog.prototype.setup.call( this, data );
ve.ui.MWMediaInsertDialog.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWMediaInsertDialog.super.prototype.getSetupProcess.call( this, data )
.next( function () {
// Show a spinner while we check for file repos.
// this will only be done once per session.
//
// This is in .setup rather than .initialize so that
// the user has visual indication (spinner) during the
// ajax request
this.$spinner.show();
this.search.$element.hide();
// Show a spinner while we check for file repos.
// this will only be done once per session.
//
// This is in .setup rather than .initialize so that
// the user has visual indication (spinner) during the
// ajax request
this.$spinner.show();
this.search.$element.hide();
// Get the repos from the API first
// The ajax request will only be done once per session
this.getFileRepos().done( ve.bind( function ( repos ) {
if ( repos ) {
this.sources = repos;
this.search.setSources( this.sources );
}
// Done, hide the spinner
this.$spinner.hide();
// Get the repos from the API first
// The ajax request will only be done once per session
this.getFileRepos().done( ve.bind( function ( repos ) {
if ( repos ) {
this.sources = repos;
this.search.setSources( this.sources );
}
// Done, hide the spinner
this.$spinner.hide();
// Show the search and query the media sources
this.search.$element.show();
this.search.queryMediaSources();
// Show the search and query the media sources
this.search.$element.show();
this.search.queryMediaSources();
// Initialization
// This must be done only after there are proper
// sources defined
this.search.getQuery().focus().select();
this.search.getResults().selectItem();
this.search.getResults().highlightItem();
}, this ) );
// Initialization
// This must be done only after there are proper
// sources defined
this.search.getQuery().focus().select();
this.search.getResults().selectItem();
this.search.getResults().highlightItem();
}, this ) );
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWMediaInsertDialog.prototype.teardown = function ( data ) {
this.search.getQuery().setValue( '' );
// Parent method
ve.ui.Dialog.prototype.teardown.call( this, data );
ve.ui.MWMediaInsertDialog.prototype.getTeardownProcess = function ( data ) {
return ve.ui.MWMediaInsertDialog.super.prototype.getTeardownProcess.call( this, data )
.first( function () {
this.search.getQuery().setValue( '' );
}, this );
};
/* Registration */

View file

@ -78,56 +78,56 @@ ve.ui.MWMetaDialog.prototype.initialize = function () {
/**
* @inheritdoc
*/
ve.ui.MWMetaDialog.prototype.setup = function ( data ) {
// Parent method
ve.ui.MWMetaDialog.super.prototype.setup.call( this, data );
ve.ui.MWMetaDialog.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWMetaDialog.super.prototype.getSetupProcess.call( this, data )
.next( function () {
// Data initialization
data = data || {};
// Data initialization
data = data || {};
var surfaceModel = this.getFragment().getSurface();
var surfaceModel = this.getFragment().getSurface();
if ( data.page && this.bookletLayout.getPage( data.page ) ) {
this.bookletLayout.setPage( data.page );
}
if ( data.page && this.bookletLayout.getPage( data.page ) ) {
this.bookletLayout.setPage( data.page );
}
// Force all previous transactions to be separate from this history state
surfaceModel.breakpoint();
surfaceModel.stopHistoryTracking();
// Force all previous transactions to be separate from this history state
surfaceModel.breakpoint();
surfaceModel.stopHistoryTracking();
// Let each page set itself up ('languages' page doesn't need this yet)
this.settingsPage.setup( surfaceModel.metaList, data );
this.advancedSettingsPage.setup( surfaceModel.metaList, data );
this.categoriesPage.setup( surfaceModel.metaList, data );
// Let each page set itself up ('languages' page doesn't need this yet)
this.settingsPage.setup( surfaceModel.metaList, data );
this.advancedSettingsPage.setup( surfaceModel.metaList, data );
this.categoriesPage.setup( surfaceModel.metaList, data );
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWMetaDialog.prototype.teardown = function ( data ) {
var surfaceModel = this.getFragment().getSurface(),
// Place transactions made while dialog was open in a common history state
hasTransactions = surfaceModel.breakpoint();
ve.ui.MWMetaDialog.prototype.getTeardownProcess = function ( data ) {
return ve.ui.MWMetaDialog.super.prototype.getTeardownProcess.call( this, data )
.first( function () {
var surfaceModel = this.getFragment().getSurface(),
// Place transactions made while dialog was open in a common history state
hasTransactions = surfaceModel.breakpoint();
// Data initialization
data = data || {};
// Data initialization
data = data || {};
// Undo everything done in the dialog and prevent redoing those changes
if ( data.action === 'cancel' && hasTransactions ) {
surfaceModel.undo();
surfaceModel.truncateUndoStack();
}
// Undo everything done in the dialog and prevent redoing those changes
if ( data.action === 'cancel' && hasTransactions ) {
surfaceModel.undo();
surfaceModel.truncateUndoStack();
}
// Let each page tear itself down ('languages' page doesn't need this yet)
this.settingsPage.teardown( data );
this.advancedSettingsPage.teardown( data );
this.categoriesPage.teardown( data );
// Let each page tear itself down ('languages' page doesn't need this yet)
this.settingsPage.teardown( data );
this.advancedSettingsPage.teardown( data );
this.categoriesPage.teardown( data );
// Return to normal tracking behavior
surfaceModel.startHistoryTracking();
// Parent method
ve.ui.MWMetaDialog.super.prototype.teardown.call( this, data );
// Return to normal tracking behavior
surfaceModel.startHistoryTracking();
}, this );
};
/* Registration */

View file

@ -312,39 +312,38 @@ ve.ui.MWReferenceDialog.prototype.initialize = function () {
/**
* @inheritdoc
*/
ve.ui.MWReferenceDialog.prototype.setup = function ( data ) {
// Parent method
ve.ui.MWReferenceDialog.super.prototype.setup.call( this, data );
this.panels.setItem( this.editPanel );
if ( this.selectedNode instanceof ve.dm.MWReferenceNode ) {
this.useReference(
ve.dm.MWReferenceModel.static.newFromReferenceNode( this.selectedNode )
);
this.selectButton.$element.hide();
} else {
this.useReference( null );
this.selectButton.$element.show();
this.applyButton.setDisabled( true );
}
this.applyButton.$element.show();
this.backButton.$element.hide();
this.search.buildIndex( this.getFragment().getDocument().getInternalList() );
this.selectButton.setDisabled( this.search.isIndexEmpty() );
ve.ui.MWReferenceDialog.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWReferenceDialog.super.prototype.getSetupProcess.call( this, data )
.next( function () {
this.panels.setItem( this.editPanel );
if ( this.selectedNode instanceof ve.dm.MWReferenceNode ) {
this.useReference(
ve.dm.MWReferenceModel.static.newFromReferenceNode( this.selectedNode )
);
this.selectButton.$element.hide();
} else {
this.useReference( null );
this.selectButton.$element.show();
this.applyButton.setDisabled( true );
}
this.applyButton.$element.show();
this.backButton.$element.hide();
this.search.buildIndex( this.getFragment().getDocument().getInternalList() );
this.selectButton.setDisabled( this.search.isIndexEmpty() );
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWReferenceDialog.prototype.teardown = function ( data ) {
this.search.getQuery().setValue( '' );
this.referenceSurface.destroy();
this.referenceSurface = null;
this.referenceModel = null;
// Parent method
ve.ui.MWReferenceDialog.super.prototype.teardown.call( this, data );
ve.ui.MWReferenceDialog.prototype.getTeardownProcess = function ( data ) {
return ve.ui.MWReferenceDialog.super.prototype.getTeardownProcess.call( this, data )
.first( function () {
this.search.getQuery().setValue( '' );
this.referenceSurface.destroy();
this.referenceSurface = null;
this.referenceModel = null;
}, this );
};
/* Registration */

View file

@ -126,22 +126,22 @@ ve.ui.MWReferenceListDialog.prototype.initialize = function () {
/**
* @inheritdoc
*/
ve.ui.MWReferenceListDialog.prototype.setup = function ( data ) {
var node, refGroup;
ve.ui.MWReferenceListDialog.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWReferenceListDialog.super.prototype.getSetupProcess.call( this, data )
.next( function () {
var node, refGroup;
// Parent method
ve.ui.MWReferenceListDialog.super.prototype.setup.call( this, data );
// Prepopulate from existing node if we're editing a node
// instead of inserting a new one
node = this.getFragment().getSelectedNode();
if ( this.selectedNode instanceof ve.dm.MWReferenceListNode ) {
refGroup = node.getAttribute( 'refGroup' );
} else {
refGroup = '';
}
// Prepopulate from existing node if we're editing a node
// instead of inserting a new one
node = this.getFragment().getSelectedNode();
if ( this.selectedNode instanceof ve.dm.MWReferenceListNode ) {
refGroup = node.getAttribute( 'refGroup' );
} else {
refGroup = '';
}
this.groupInput.setValue( refGroup );
this.groupInput.setValue( refGroup );
}, this );
};
/* Registration */

View file

@ -29,9 +29,6 @@ ve.ui.MWSaveDialog = function VeUiMWSaveDialog( config ) {
this.restoring = false;
this.messages = {};
this.setupDeferred = $.Deferred();
// Events
this.connect( this, { 'ready': 'onReady' } );
};
/* Inheritance */
@ -293,7 +290,7 @@ ve.ui.MWSaveDialog.prototype.setEditSummary = function ( summary ) {
ve.ui.MWSaveDialog.prototype.initialize = function () {
var saveDialog = this;
// Parent method
ve.ui.Dialog.prototype.initialize.call( this );
ve.ui.MWSaveDialog.super.prototype.initialize.call( this );
// Properties
this.savePanel = new OO.ui.PanelLayout( {
@ -428,16 +425,13 @@ ve.ui.MWSaveDialog.prototype.initialize = function () {
/**
* @inheritdoc
*/
ve.ui.MWSaveDialog.prototype.setup = function () {
// Old messages should not persist after panel changes
this.clearAllMessages();
};
/**
* Handle window ready events
*/
ve.ui.MWSaveDialog.prototype.onReady = function () {
this.swapPanel( 'save' );
ve.ui.MWSaveDialog.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWSaveDialog.super.prototype.getSetupProcess.call( this, data )
.next( function () {
// Old messages should not persist after panel changes
this.clearAllMessages();
this.swapPanel( 'save' );
}, this );
};
/* Registration */

View file

@ -305,58 +305,60 @@ ve.ui.MWTemplateDialog.prototype.initialize = function () {
/**
* @inheritdoc
*/
ve.ui.MWTemplateDialog.prototype.setup = function ( data ) {
var template, promise;
ve.ui.MWTemplateDialog.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWTemplateDialog.super.prototype.getSetupProcess.call( this, data )
.next( function () {
var template, promise;
// Parent method
ve.ui.MWTemplateDialog.super.prototype.setup.call( this, data );
// Data initialization
data = data || {};
// Data initialization
data = data || {};
// Properties
this.loaded = false;
this.transclusionModel = new ve.dm.MWTransclusionModel();
// Properties
this.loaded = false;
this.transclusionModel = new ve.dm.MWTransclusionModel();
// Events
this.transclusionModel.connect( this, { 'replace': 'onReplacePart' } );
// Events
this.transclusionModel.connect( this, { 'replace': 'onReplacePart' } );
// Initialization
if ( !this.selectedNode ) {
if ( data.template ) {
// New specified template
template = ve.dm.MWTemplateModel.newFromName( this.transclusionModel, data.template );
promise = this.transclusionModel.addPart( template ).done( function () {
template.addPromptedParameters();
} );
} else {
// New template placeholder
promise = this.transclusionModel.addPart(
new ve.dm.MWTemplatePlaceholderModel( this.transclusionModel )
);
}
} else {
// Load existing template
promise = this.transclusionModel
.load( ve.copy( this.selectedNode.getAttribute( 'mw' ) ) );
}
this.applyButton.setDisabled( true );
this.pushPending();
promise.always( ve.bind( this.onTransclusionReady, this ) );
// Initialization
if ( !this.selectedNode ) {
if ( data.template ) {
// New specified template
template = ve.dm.MWTemplateModel.newFromName(
this.transclusionModel, data.template
);
promise = this.transclusionModel.addPart( template ).done( function () {
template.addPromptedParameters();
} );
} else {
// New template placeholder
promise = this.transclusionModel.addPart(
new ve.dm.MWTemplatePlaceholderModel( this.transclusionModel )
);
}
} else {
// Load existing template
promise = this.transclusionModel
.load( ve.copy( this.selectedNode.getAttribute( 'mw' ) ) );
}
this.applyButton.setDisabled( true );
this.pushPending();
promise.always( ve.bind( this.onTransclusionReady, this ) );
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWTemplateDialog.prototype.teardown = function ( data ) {
// Cleanup
this.$element.removeClass( 've-ui-mwTemplateDialog-ready' );
this.transclusionModel.disconnect( this );
this.transclusionModel.abortRequests();
this.transclusionModel = null;
this.bookletLayout.clearPages();
this.content = null;
// Parent method
ve.ui.MWTemplateDialog.super.prototype.teardown.call( this, data );
ve.ui.MWTemplateDialog.prototype.getTeardownProcess = function ( data ) {
return ve.ui.MWTemplateDialog.super.prototype.getTeardownProcess.call( this, data )
.first( function () {
// Cleanup
this.$element.removeClass( 've-ui-mwTemplateDialog-ready' );
this.transclusionModel.disconnect( this );
this.transclusionModel.abortRequests();
this.transclusionModel = null;
this.bookletLayout.clearPages();
this.content = null;
}, this );
};

View file

@ -320,12 +320,12 @@ ve.ui.MWTransclusionDialog.prototype.initialize = function () {
/**
* @inheritdoc
*/
ve.ui.MWTransclusionDialog.prototype.setup = function ( data ) {
this.setMode( 'single' );
this.modeButton.setDisabled( true );
// Parent method
ve.ui.MWTransclusionDialog.super.prototype.setup.call( this, data );
ve.ui.MWTransclusionDialog.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWTransclusionDialog.super.prototype.getSetupProcess.call( this, data )
.first( function () {
this.setMode( 'single' );
this.modeButton.setDisabled( true );
}, this );
};
/* Registration */

View file

@ -61,48 +61,48 @@ ve.ui.MWAlienExtensionInspector.prototype.initialize = function () {
/**
* @inheritdoc
*/
ve.ui.MWAlienExtensionInspector.prototype.setup = function () {
// Parent method
ve.ui.MWExtensionInspector.prototype.setup.apply( this, arguments );
ve.ui.MWAlienExtensionInspector.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWAlienExtensionInspector.super.prototype.getSetupProcess.call( this, data )
.next( function () {
var key, attributeInput, field,
attributes = this.getFragment().getSelectedNode().getAttribute( 'mw' ).attrs;
var key, attributeInput, field,
attributes = this.getFragment().getSelectedNode().getAttribute( 'mw' ).attrs;
if ( attributes && !ve.isEmptyObject( attributes ) ) {
for ( key in attributes ) {
attributeInput = new OO.ui.TextInputWidget( {
'$': this.$,
'value': attributes[key]
} );
this.attributeInputs[key] = attributeInput;
field = new OO.ui.FieldLayout(
attributeInput,
{
'$': this.$,
'align': 'left',
'label': key
if ( attributes && !ve.isEmptyObject( attributes ) ) {
for ( key in attributes ) {
attributeInput = new OO.ui.TextInputWidget( {
'$': this.$,
'value': attributes[key]
} );
this.attributeInputs[key] = attributeInput;
field = new OO.ui.FieldLayout(
attributeInput,
{
'$': this.$,
'align': 'left',
'label': key
}
);
this.$attributes.append( field.$element );
}
);
this.$attributes.append( field.$element );
}
}
}
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWAlienExtensionInspector.prototype.teardown = function () {
// Parent method
ve.ui.MWExtensionInspector.prototype.teardown.apply( this, arguments );
this.$attributes.empty();
this.attributeInputs = {};
ve.ui.MWAlienExtensionInspector.prototype.getTeardownProcess = function ( data ) {
return ve.ui.MWAlienExtensionInspector.super.prototype.getTeardownProcess.call( this, data )
.next( function () {
this.$attributes.empty();
this.attributeInputs = {};
}, this );
};
/** */
ve.ui.MWAlienExtensionInspector.prototype.updateMwData = function ( mwData ) {
// Parent method
ve.ui.MWExtensionInspector.prototype.updateMwData.call( this, mwData );
ve.ui.MWAlienExtensionInspector.super.prototype.updateMwData.call( this, mwData );
var key;

View file

@ -61,7 +61,7 @@ ve.ui.MWExtensionInspector.static.dir = null;
*/
ve.ui.MWExtensionInspector.prototype.initialize = function () {
// Parent method
ve.ui.Inspector.prototype.initialize.call( this );
ve.ui.MWExtensionInspector.super.prototype.initialize.call( this );
this.input = new OO.ui.TextInputWidget( {
'$': this.$,
@ -85,77 +85,79 @@ ve.ui.MWExtensionInspector.prototype.getInputPlaceholder = function () {
/**
* @inheritdoc
*/
ve.ui.MWExtensionInspector.prototype.setup = function ( data ) {
// Parent method
ve.ui.Inspector.prototype.setup.call( this, data );
ve.ui.MWExtensionInspector.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWExtensionInspector.super.prototype.getSetupProcess.call( this, data )
.next( function () {
// Initialization
this.node = this.getFragment().getSelectedNode();
// Make sure we're inspecting the right type of node
if ( !( this.node instanceof this.constructor.static.nodeModel ) ) {
this.node = null;
}
this.input.setValue( this.node ? this.node.getAttribute( 'mw' ).body.extsrc : '' );
// Initialization
this.node = this.getFragment().getSelectedNode();
// Make sure we're inspecting the right type of node
if ( !( this.node instanceof this.constructor.static.nodeModel ) ) {
this.node = null;
}
this.input.setValue( this.node ? this.node.getAttribute( 'mw' ).body.extsrc : '' );
this.input.$input.attr( 'placeholder', this.getInputPlaceholder() );
this.input.$input.attr( 'placeholder', this.getInputPlaceholder() );
var dir = this.constructor.static.dir || data.dir;
this.input.setRTL( dir === 'rtl' );
var dir = this.constructor.static.dir || data.dir;
this.input.setRTL( dir === 'rtl' );
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWExtensionInspector.prototype.ready = function () {
// Parent method
ve.ui.Inspector.prototype.ready.call( this );
// Focus the input
this.input.focus().select();
ve.ui.MWExtensionInspector.prototype.getReadyProcess = function ( data ) {
return ve.ui.MWExtensionInspector.super.prototype.getReadyProcess.call( this, data )
.next( function () {
// Focus the input
this.input.focus().select();
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWExtensionInspector.prototype.teardown = function ( data ) {
var mwData,
fragment = this.getFragment(),
surfaceModel = fragment.getSurface();
ve.ui.MWExtensionInspector.prototype.getTeardownProcess = function ( data ) {
return ve.ui.MWExtensionInspector.super.prototype.getTeardownProcess.call( this, data )
.first( function () {
var mwData,
fragment = this.getFragment(),
surfaceModel = fragment.getSurface();
if ( this.constructor.static.allowedEmpty || this.input.getValue() !== '' ) {
if ( this.node ) {
mwData = ve.copy( this.node.getAttribute( 'mw' ) );
this.updateMwData( mwData );
surfaceModel.change(
ve.dm.Transaction.newFromAttributeChanges(
surfaceModel.getDocument(), this.node.getOuterRange().start, { 'mw': mwData }
)
);
} else {
mwData = {
'name': this.constructor.static.nodeModel.static.extensionName,
'attrs': {},
'body': {}
};
this.updateMwData( mwData );
fragment.collapseRangeToEnd().insertContent( [
{
'type': this.constructor.static.nodeModel.static.name,
'attributes': {
'mw': mwData
}
},
{ 'type': '/' + this.constructor.static.nodeModel.static.name }
] );
}
} else if ( this.node && !this.constructor.static.allowedEmpty ) {
// Content has been emptied on a node which isn't allowed to
// be empty, so delete it.
fragment.removeContent();
}
// Parent method
ve.ui.Inspector.prototype.teardown.call( this, data );
if ( this.constructor.static.allowedEmpty || this.input.getValue() !== '' ) {
if ( this.node ) {
mwData = ve.copy( this.node.getAttribute( 'mw' ) );
this.updateMwData( mwData );
surfaceModel.change(
ve.dm.Transaction.newFromAttributeChanges(
surfaceModel.getDocument(),
this.node.getOuterRange().start,
{ 'mw': mwData }
)
);
} else {
mwData = {
'name': this.constructor.static.nodeModel.static.extensionName,
'attrs': {},
'body': {}
};
this.updateMwData( mwData );
fragment.collapseRangeToEnd().insertContent( [
{
'type': this.constructor.static.nodeModel.static.name,
'attributes': {
'mw': mwData
}
},
{ 'type': '/' + this.constructor.static.nodeModel.static.name }
] );
}
} else if ( this.node && !this.constructor.static.allowedEmpty ) {
// Content has been emptied on a node which isn't allowed to
// be empty, so delete it.
fragment.removeContent();
}
}, this );
};
/**

View file

@ -31,8 +31,7 @@ ve.ui.MWLinkInspector.static.name = 'link';
ve.ui.MWLinkInspector.static.modelClasses = [
ve.dm.MWExternalLinkAnnotation,
ve.dm.MWInternalLinkAnnotation,
ve.dm.MWNumberedExternalLinkNode
ve.dm.MWInternalLinkAnnotation
];
ve.ui.MWLinkInspector.static.linkTargetInputWidget = ve.ui.MWLinkTargetInputWidget;
@ -89,27 +88,6 @@ ve.ui.MWLinkInspector.prototype.getAnnotationFromFragment = function ( fragment
}
};
/**
* @inheritdoc
*/
ve.ui.MWLinkInspector.prototype.getNodeChanges = function () {
var annotations, data,
doc = this.linkNode.getDocument(),
annotation = this.getAnnotation();
if ( annotation instanceof ve.dm.MWInternalLinkAnnotation ) {
// We're inspecting a numbered external link node and attempting to set its target
// to an internal link. Replace the numbered link node with an internal link annotation,
// with the link target as the text.
annotations = doc.data.getAnnotationsFromOffset( this.linkNode.getOffset() ).clone();
annotations.push( annotation );
data = ve.splitClusters( annotation.getAttribute( 'title' ) );
ve.dm.Document.static.addAnnotationsToData( data, annotations );
return data;
}
// Parent method
return ve.ui.LinkInspector.prototype.getNodeChanges.call( this );
};
/* Registration */
ve.ui.windowFactory.register( ve.ui.MWLinkInspector );

View file

@ -0,0 +1,150 @@
/*!
* VisualEditor UserInterface MWLinkNodeInspector class.
*
* @copyright 2011-2014 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
* Link inspector.
*
* @class
* @extends ve.ui.Inspector
*
* @constructor
* @param {Object} [config] Configuration options
*/
ve.ui.MWLinkNodeInspector = function VeUiMWLinkNodeInspector( config ) {
// Parent constructor
ve.ui.Inspector.call( this, config );
// Properties
this.linkNode = null;
};
/* Inheritance */
OO.inheritClass( ve.ui.MWLinkNodeInspector, ve.ui.Inspector );
/* Static properties */
ve.ui.MWLinkNodeInspector.static.name = 'linkNode';
ve.ui.MWLinkNodeInspector.static.icon = 'link';
ve.ui.MWLinkNodeInspector.static.title = OO.ui.deferMsg( 'visualeditor-linknodeinspector-title' );
ve.ui.MWLinkNodeInspector.static.removable = false;
ve.ui.MWLinkNodeInspector.static.modelClasses = [ ve.dm.MWNumberedExternalLinkNode ];
/* Methods */
/**
* Handle convert button click events.
*/
ve.ui.MWLinkNodeInspector.prototype.onConvertButtonClick = function () {
this.close( { 'action': 'convert' } );
};
/**
* @inheritdoc
*/
ve.ui.MWLinkNodeInspector.prototype.initialize = function () {
// Parent method
ve.ui.MWLinkNodeInspector.super.prototype.initialize.call( this );
// Properties
this.targetInput = new OO.ui.TextInputWidget( { '$': this.$ } );
this.convertButton = new OO.ui.ButtonWidget( {
'$': this.$,
'frameless': true,
'icon': 'add-item',
'label': ve.msg( 'visualeditor-linknodeinspector-add-label' )
} );
// Events
this.convertButton.connect( this, { 'click': 'onConvertButtonClick' } );
// Initialization
this.$form.append( this.targetInput.$element, this.convertButton.$element );
};
/**
* @inheritdoc
*/
ve.ui.MWLinkNodeInspector.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWLinkNodeInspector.super.prototype.getSetupProcess.call( this, data )
.next( function () {
// Properties
this.linkNode = this.getFragment().getSelectedNode();
// Initialization
this.targetInput.setValue( this.linkNode ? this.linkNode.getAttribute( 'href' ) : '' );
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWLinkNodeInspector.prototype.getReadyProcess = function ( data ) {
return ve.ui.MWLinkNodeInspector.super.prototype.getReadyProcess.call( this, data )
.next( function () {
this.targetInput.focus().select();
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWLinkNodeInspector.prototype.getTeardownProcess = function ( data ) {
return ve.ui.MWLinkNodeInspector.super.prototype.getTeardownProcess.call( this, data )
.first( function () {
var content, annotation, annotations,
surfaceModel = this.getFragment().getSurface(),
doc = surfaceModel.getDocument(),
nodeRange = this.linkNode.getOuterRange(),
value = this.targetInput.getValue(),
convert = data.action === 'convert',
remove = convert || data.action === 'remove' || !value;
if ( remove ) {
surfaceModel.change(
ve.dm.Transaction.newFromRemoval( doc, nodeRange )
);
} else {
// Default to http:// if the external link doesn't already begin with a supported
// protocol - this prevents the link from being converted into literal text upon
// save and also fixes a common mistake users may make
if ( !ve.init.platform.getExternalLinkUrlProtocolsRegExp().test( value ) ) {
value = 'http://' + value;
}
surfaceModel.change(
ve.dm.Transaction.newFromAttributeChanges(
doc, nodeRange.start, { 'href': value }
)
);
}
if ( convert ) {
annotation = new ve.dm.MWExternalLinkAnnotation( {
'type': 'link/mwExternal',
'attributes': {
'href': value
}
} );
annotations = doc.data.getAnnotationsFromOffset(
this.linkNode.getOffset()
).clone();
annotations.push( annotation );
content = ve.splitClusters( value );
ve.dm.Document.static.addAnnotationsToData( content, annotations );
surfaceModel.change(
ve.dm.Transaction.newFromInsertion( doc, nodeRange.start, content )
);
}
}, this );
};
/* Registration */
ve.ui.windowFactory.register( ve.ui.MWLinkNodeInspector );

View file

@ -57,45 +57,44 @@ ve.ui.MWLiveExtensionInspector.prototype.getNewMwData = function () {
/**
* @inheritdoc
*/
ve.ui.MWLiveExtensionInspector.prototype.setup = function ( data ) {
// Parent method
ve.ui.MWExtensionInspector.prototype.setup.call( this, data );
ve.ui.MWLiveExtensionInspector.prototype.getSetupProcess = function ( data ) {
return ve.ui.MWLiveExtensionInspector.super.prototype.getSetupProcess.call( this, data )
.next( function () {
// Initialization
this.getFragment().getSurface().pushStaging();
// Initialization
this.getFragment().getSurface().pushStaging();
if ( !this.node ) {
// Create a new node
// collapseRangeToEnd returns a new fragment
this.fragment = this.getFragment().collapseRangeToEnd().insertContent( [
{
'type': this.constructor.static.nodeModel.static.name,
'attributes': { 'mw': this.getNewMwData() }
},
{ 'type': '/' + this.constructor.static.nodeModel.static.name }
] );
// Check if the node was inserted at a structural offset and wrapped in a paragraph
if ( this.getFragment().getRange().getLength() === 4 ) {
this.fragment = this.getFragment().adjustRange( 1, -1 );
}
this.getFragment().select();
this.node = this.getFragment().getSelectedNode();
}
this.input.setValue( this.node.getAttribute( 'mw' ).body.extsrc );
if ( !this.node ) {
// Create a new node
// collapseRangeToEnd returns a new fragment
this.fragment = this.getFragment().collapseRangeToEnd().insertContent( [
{
'type': this.constructor.static.nodeModel.static.name,
'attributes': { 'mw': this.getNewMwData() }
},
{ 'type': '/' + this.constructor.static.nodeModel.static.name }
] );
// Check if the node was inserted at a structural offset and wrapped in a paragraph
if ( this.getFragment().getRange().getLength() === 4 ) {
this.fragment = this.getFragment().adjustRange( 1, -1 );
}
this.getFragment().select();
this.node = this.getFragment().getSelectedNode();
}
this.input.setValue( this.node.getAttribute( 'mw' ).body.extsrc );
this.input.on( 'change', this.onChangeHandler );
this.input.on( 'change', this.onChangeHandler );
}, this );
};
/**
* @inheritdoc
*/
ve.ui.MWLiveExtensionInspector.prototype.teardown = function ( data ) {
this.input.off( 'change', this.onChangeHandler );
this.getFragment().getSurface().applyStaging();
// Parent method
ve.ui.MWExtensionInspector.prototype.teardown.call( this, data );
ve.ui.MWLiveExtensionInspector.prototype.getTeardownProcess = function ( data ) {
return ve.ui.MWLiveExtensionInspector.super.prototype.getTeardownProcess.call( this, data )
.first( function () {
this.input.off( 'change', this.onChangeHandler );
this.getFragment().getSurface().applyStaging();
}, this );
};
/**

View file

@ -14,15 +14,11 @@
* @param {OO.ui.ToolGroup} toolGroup
* @param {Object} [config] Configuration options
*/
ve.ui.MWLinkInspectorTool = function VeUiMWLinkInspectorTool( toolGroup, config ) {
ve.ui.MWLinkNodeInspectorTool = function VeUiMWLinkNodeInspectorTool( toolGroup, config ) {
ve.ui.LinkInspectorTool.call( this, toolGroup, config );
};
OO.inheritClass( ve.ui.MWLinkInspectorTool, ve.ui.LinkInspectorTool );
ve.ui.MWLinkInspectorTool.static.modelClasses =
ve.ui.MWLinkInspectorTool.static.modelClasses.concat(
[ ve.dm.MWNumberedExternalLinkNode ]
);
ve.ui.toolFactory.register( ve.ui.MWLinkInspectorTool );
OO.inheritClass( ve.ui.MWLinkNodeInspectorTool, ve.ui.LinkInspectorTool );
ve.ui.MWLinkNodeInspectorTool.static.name = 'linkNode';
ve.ui.MWLinkNodeInspectorTool.static.modelClasses = [ ve.dm.MWNumberedExternalLinkNode ];
ve.ui.MWLinkNodeInspectorTool.static.commandName = 'linkNode';
ve.ui.toolFactory.register( ve.ui.MWLinkNodeInspectorTool );

View file

@ -7,6 +7,9 @@
/* MW Command Registrations */
ve.ui.commandRegistry.register(
new ve.ui.Command( 'linkNode', 'window', 'open', 'linkNode' )
);
ve.ui.commandRegistry.register(
new ve.ui.Command( 'gallery', 'window', 'open', 'gallery' )
);