mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-29 00:30:44 +00:00
232 lines
6.4 KiB
Plaintext
232 lines
6.4 KiB
Plaintext
|
<?php
|
||
|
/**
|
||
|
* VisualEditor standalone demo
|
||
|
*
|
||
|
* @file
|
||
|
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
||
|
* @license The MIT License (MIT); see LICENSE.txt
|
||
|
*/
|
||
|
|
||
|
// Find all .html files in the pages directory
|
||
|
$path = __DIR__ . '/pages';
|
||
|
$pages = glob( $path . '/*.html' );
|
||
|
$page = current( $pages );
|
||
|
|
||
|
// If the ?page= parameter is set, and that page exists, load it
|
||
|
if ( isset( $_GET['page'] ) && in_array( $path . '/' . $_GET['page'] . '.html', $pages ) ) {
|
||
|
$page = $path . '/' . $_GET['page'] . '.html';
|
||
|
}
|
||
|
$html = file_get_contents( $page );
|
||
|
|
||
|
// TODO: get rid of the PHP-based loading system and make the demo purely HTML+JS
|
||
|
|
||
|
?>
|
||
|
<!DOCTYPE html>
|
||
|
|
||
|
<html>
|
||
|
<head>
|
||
|
<meta charset="UTF-8">
|
||
|
<title>VisualEditor Standalone Demo</title>
|
||
|
|
||
|
<!-- STYLES -->
|
||
|
|
||
|
<!-- demo styles -->
|
||
|
<link rel="stylesheet" href="demo.css">
|
||
|
</head>
|
||
|
<body>
|
||
|
<ul class="ve-demo-docs">
|
||
|
<?php
|
||
|
foreach ( $pages as $page ): ?>
|
||
|
<li>
|
||
|
<a href="./?page=<?php echo basename( $page, '.html' ); ?>">
|
||
|
<?php echo basename( $page, '.html' ); ?>
|
||
|
</a>
|
||
|
</li>
|
||
|
<?php
|
||
|
endforeach; ?>
|
||
|
</ul>
|
||
|
<div class="ve-demo-editor"></div>
|
||
|
|
||
|
<!-- SCRIPTS -->
|
||
|
|
||
|
<!-- demo script -->
|
||
|
<script>
|
||
|
$( document ).ready( function () {
|
||
|
new ve.init.sa.Target(
|
||
|
$( '.ve-demo-editor' ),
|
||
|
ve.createDocumentFromHtml( <?php echo json_encode( $html ) ?> )
|
||
|
);
|
||
|
$( '.ve-ce-documentNode' ).focus();
|
||
|
} );
|
||
|
</script>
|
||
|
|
||
|
<div class="ve-demo-utilities">
|
||
|
<p>
|
||
|
<div class="ve-demo-utilities-commands"></div>
|
||
|
</p>
|
||
|
<table id="ve-dump" class="ve-demo-dump">
|
||
|
<thead>
|
||
|
<th>Linear model</th>
|
||
|
<th>View tree</th>
|
||
|
<th>Model tree</th>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td width="30%" id="ve-linear-model-dump"></td>
|
||
|
<td id="ve-view-tree-dump" style="vertical-align: top;"></td>
|
||
|
<td id="ve-model-tree-dump" style="vertical-align: top;"></td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</div>
|
||
|
|
||
|
<script>
|
||
|
$( function () {
|
||
|
|
||
|
// Widgets
|
||
|
var 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"> </span>' ),
|
||
|
dumpModelButton.$element,
|
||
|
validateButton.$element
|
||
|
);
|
||
|
|
||
|
// 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 () {
|
||
|
// linear model dump
|
||
|
var i, $li, element, html, annotations,
|
||
|
$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 : ' ' ) + ' ' );
|
||
|
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
|
||
|
var getKids = function ( obj ) {
|
||
|
var $ol = $( '<ol start="0"></ol>' ),
|
||
|
$li;
|
||
|
for ( var 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 $element = $( element ),
|
||
|
view = $element.data( 'view' );
|
||
|
if ( view.canContainContent() ) {
|
||
|
var nodeRange = view.model.getRange();
|
||
|
var textModel = ve.instances[0]
|
||
|
.view.model.getDocument().getText( nodeRange );
|
||
|
var 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' );
|
||
|
}
|
||
|
} );
|
||
|
} );
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|