mediawiki-extensions-Visual.../demos/ve/demo.js
Timo Tijhof ca40077866 Clean up Target properties
Move target.surface from mw.Target to Target
* All targets use this, let's standardise it.

Move target.$document from mw.ViewPageTarget to Target
* It was initialised with null in mw.ViewPageTarget, but the
  assignment happened in mw.Target. So it should be moved up
  at least to mw.Target.
* Since it is useful to have in sa.Target as well, moved it up
  to the abstract Target, and implemented in sa.Target and
  immediately used in the standalone demo where we were already
  duplicating the find( '.ve-ce-documentNode' ).

Add missing target.setupDone = false; in sa.Target

Add missing target.toolbar to Target
* Was used in all subclasses, but never initialised in any of
  the constructors. Let's standardise this property name as well
  (instead of initialising it in three places).

Move target#event-surfaceReady from mw.Target to Target
* sa.Target uses it as well, and considering Platform#initialize
  is already standardised in the abstract class, Target#setup
  being deferred is most likely to happen in each target as well
  so let's avoid different events being invented for the same
  thing and consistently use 'surfaceReady'.

Change-Id: Ia8bde188a4cde7e1615c2ae9c5b758eefc5d9cb7
2013-12-19 02:16:20 +00:00

197 lines
5.4 KiB
JavaScript

/*!
* VisualEditor standalone demo
*
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/*global console, alert */
$( function () {
var currentTarget,
$targetContainer = $( '.ve-demo-editor' ).eq( 0 ),
// Widgets
startTextInput = new OO.ui.TextInputWidget( { 'readOnly': true } ),
endTextInput = new OO.ui.TextInputWidget( { 'readOnly': true } ),
startTextInputLabel = new OO.ui.InputLabelWidget(
{ 'label': 'Start', 'input': startTextInput }
),
endTextInputLabel = new OO.ui.InputLabelWidget(
{ 'label': 'End', 'input': endTextInput }
),
getRangeButton = new OO.ui.PushButtonWidget( { 'label': 'Get selected range' } ),
logRangeButton = new OO.ui.PushButtonWidget(
{ 'label': 'Log to console', 'disabled': true }
),
dumpModelButton = new OO.ui.PushButtonWidget( { 'label': 'Dump model' } ),
validateButton = new OO.ui.PushButtonWidget( { 'label': 'Validate view and model' } );
// Initialization
$( '.ve-demo-utilities-commands' ).append(
getRangeButton.$element,
startTextInputLabel.$element,
startTextInput.$element,
endTextInputLabel.$element,
endTextInput.$element,
logRangeButton.$element,
$( '<span class="ve-demo-utilities-commands-divider">&nbsp;</span>' ),
dumpModelButton.$element,
validateButton.$element
);
$( '.ve-demo-menu' ).on( 'click', 'li a', function () {
var src = $( this ).data( 'pageSrc' );
$.ajax( {
url: src,
dataType: 'text'
} ).done( function ( pageHtml ) {
$targetContainer.slideUp();
var target = new ve.init.sa.Target(
$( '<div>' ),
ve.createDocumentFromHtml( pageHtml )
);
target.on( 'surfaceReady', function () {
// TODO: Target should have a way to tear itself down (should include removing
// elements outside target.$element, such as global overlays).
$targetContainer.promise().done( function () {
if ( currentTarget ) {
currentTarget.$element.remove();
}
$targetContainer
.append( target.$element )
.slideDown()
.promise().done( function () {
target.$document[0].focus();
currentTarget = target;
} );
} );
} );
} );
} );
// Events
getRangeButton.on( 'click', function () {
var range = ve.instances[0].view.model.getSelection();
startTextInput.setValue( range.start );
endTextInput.setValue( range.end );
logRangeButton.setDisabled( false );
} );
logRangeButton.on( 'click', function () {
var start = startTextInput.getValue(),
end = endTextInput.getValue();
// TODO: Validate input
console.dir( ve.instances[0].view.documentView.model.data.slice( start, end ) );
} );
dumpModelButton.on( 'click', function () {
/*jshint loopfunc:true */
// linear model dump
var i, $li, $label, element, text, annotations, getKids,
$ol = $( '<ol start="0"></ol>' );
for ( i = 0; i < ve.instances[0].model.documentModel.data.getLength(); i++ ) {
$li = $( '<li>' );
$label = $( '<span>' );
element = ve.instances[0].model.documentModel.data.getData( i );
if ( element.type ) {
$label.addClass( 've-demo-dump-element' );
text = element.type;
annotations = element.annotations;
} else if ( ve.isArray( element ) ){
$label.addClass( 've-demo-dump-achar' );
text = element[0];
annotations = element[1];
} else {
$label.addClass( 've-demo-dump-char' );
text = element;
annotations = undefined;
}
$label.html( ( text.match( /\S/ ) ? text : '&nbsp;' ) + ' ' );
if ( annotations ) {
$label.append(
$( '<span>' ).text(
'[' + ve.instances[0].model.documentModel.store.values( annotations ).map( function ( ann ) {
return ann.name;
} ).join( ', ' ) + ']'
)
);
}
$li.append( $label );
$ol.append( $li );
}
$( '#ve-linear-model-dump' ).html( $ol );
// tree dump
getKids = function ( obj ) {
var $li, i,
$ol = $( '<ol start="0"></ol>' );
for ( i = 0; i < obj.children.length; i++ ) {
$li = $( '<li>' );
$label = $( '<span>' ).addClass( 've-demo-dump-element' );
if ( obj.children[i].length !== undefined ) {
$li.append(
$label
.text( obj.children[i].type )
.append(
$( '<span>' ).text( ' (' + obj.children[i].length + ')' )
)
);
} else {
$li.append( $label.text( obj.children[i].type ) );
}
if ( obj.children[i].children ) {
$li.append( getKids( obj.children[i] ) );
}
$ol.append( $li );
}
return $ol;
};
$( '#ve-model-tree-dump' ).html(
getKids( ve.instances[0].model.documentModel.getDocumentNode() )
);
$( '#ve-view-tree-dump' ).html(
getKids( ve.instances[0].view.documentView.getDocumentNode() )
);
$( '#ve-dump' ).show();
} );
validateButton.on( 'click', function () {
var failed = false;
$( '.ve-ce-branchNode' ).each( function ( index, element ) {
var nodeRange, textModel, textDom,
$element = $( element ),
view = $element.data( 'view' );
if ( view.canContainContent() ) {
nodeRange = view.model.getRange();
textModel = ve.instances[0].view.model.getDocument().getText( nodeRange );
textDom = ve.ce.getDomText( view.$element[0] );
if ( textModel !== textDom ) {
failed = true;
console.log( 'Inconsistent data', {
'textModel': textModel,
'textDom': textDom,
'element': element
} );
}
}
} );
if ( failed ) {
alert( 'Not valid - check JS console for details' );
} else {
alert( 'Valid' );
}
} );
} );