ve.ui.MWCategoriesPage.js 0000666 00000021614 15133476425 0011277 0 ustar 00 /*!
* VisualEditor user interface MWCategoriesPage class.
*
* @copyright 2011-2020 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
* MediaWiki meta dialog categories page.
*
* @class
* @extends OO.ui.PageLayout
*
* @constructor
* @param {string} name Unique symbolic name of page
* @param {Object} [config] Configuration options
* @cfg {jQuery} [$overlay] Overlay to render dropdowns in
*/
ve.ui.MWCategoriesPage = function VeUiMWCategoriesPage( name, config ) {
// Configuration initialization
config = config || {};
// Parent constructor
ve.ui.MWCategoriesPage.super.apply( this, arguments );
// Properties
this.fragment = null;
this.defaultSortKeyTouched = false;
this.fallbackDefaultSortKey = ve.init.target.getPageName();
this.categoriesFieldset = new OO.ui.FieldsetLayout( {
label: ve.msg( 'visualeditor-dialog-meta-categories-data-label' ),
icon: 'tag'
} );
this.categoryOptionsFieldset = new OO.ui.FieldsetLayout( {
label: ve.msg( 'visualeditor-dialog-meta-categories-options' ),
icon: 'settings'
} );
this.categoryWidget = new ve.ui.MWCategoryWidget( {
$overlay: config.$overlay
} );
this.addCategory = new OO.ui.FieldLayout(
this.categoryWidget,
{
$overlay: config.$overlay,
align: 'top',
label: ve.msg( 'visualeditor-dialog-meta-categories-addcategory-label' )
}
);
this.defaultSortInput = new OO.ui.TextInputWidget( {
placeholder: this.fallbackDefaultSortKey
} );
this.defaultSortInput.$element.addClass( 've-ui-mwCategoriesPage-defaultsort' );
this.defaultSort = new OO.ui.FieldLayout(
this.defaultSortInput,
{
$overlay: config.$overlay,
align: 'top',
label: ve.msg( 'visualeditor-dialog-meta-categories-defaultsort-label' ),
help: ve.msg( 'visualeditor-dialog-meta-categories-defaultsort-help' )
}
);
// Events
this.categoryWidget.connect( this, {
newCategory: 'onNewCategory',
updateSortkey: 'onUpdateSortKey'
} );
this.defaultSortInput.connect( this, {
change: 'onDefaultSortChange'
} );
// Initialization
this.categoriesFieldset.addItems( [ this.addCategory ] );
this.categoryOptionsFieldset.addItems( [ this.defaultSort ] );
this.$element.append( this.categoriesFieldset.$element, this.categoryOptionsFieldset.$element );
};
/* Inheritance */
OO.inheritClass( ve.ui.MWCategoriesPage, OO.ui.PageLayout );
/* Methods */
/**
* @inheritdoc
*/
ve.ui.MWCategoriesPage.prototype.setupOutlineItem = function () {
this.outlineItem
.setIcon( 'tag' )
.setLabel( ve.msg( 'visualeditor-dialog-meta-categories-section' ) );
};
/**
* Handle category default sort change events.
*
* @param {string} value Default sort value
*/
ve.ui.MWCategoriesPage.prototype.onDefaultSortChange = function ( value ) {
this.categoryWidget.setDefaultSortKey( value === '' ? this.fallbackDefaultSortKey : value );
this.defaultSortKeyTouched = true;
};
/**
* Inserts new category into meta list
*
* @param {Object} item
* @param {ve.dm.MWCategoryMetaItem} [beforeMetaItem] Meta item to insert before,
* or undefined to go at the end
*/
ve.ui.MWCategoriesPage.prototype.onNewCategory = function ( item, beforeMetaItem ) {
this.fragment.insertMeta(
this.getCategoryItemForInsertion( item ),
beforeMetaItem ? beforeMetaItem.getOffset() : undefined
);
};
/**
* Removes and re-inserts updated category widget item
*
* @param {Object} item
*/
ve.ui.MWCategoriesPage.prototype.onUpdateSortKey = function ( item ) {
// Replace meta item with updated one
this.fragment.replaceMeta( item.metaItem, this.getCategoryItemForInsertion( item, item.metaItem.getElement() ) );
};
/**
* Bound to MetaList insert event for adding meta dialog components.
*
* @param {ve.dm.MetaItem} metaItem
*/
ve.ui.MWCategoriesPage.prototype.onMetaListInsert = function ( metaItem ) {
// Responsible for adding UI components
if ( metaItem.element.type === 'mwCategory' ) {
var index = this.fragment.getDocument().getMetaList().getItemsInGroup( 'mwCategory' ).indexOf( metaItem );
this.categoryWidget.addItems(
[ this.getCategoryItemFromMetaListItem( metaItem ) ],
index
);
}
};
/**
* Bound to MetaList insert event for removing meta dialog components.
*
* @param {ve.dm.MetaItem} metaItem
*/
ve.ui.MWCategoriesPage.prototype.onMetaListRemove = function ( metaItem ) {
if ( metaItem.element.type === 'mwCategory' ) {
var item = this.categoryWidget.categories[ this.getCategoryItemFromMetaListItem( metaItem ).value ];
this.categoryWidget.removeItems( [ item ] );
}
};
/**
* Get default sort key item.
*
* @return {string} Default sort key item
*/
ve.ui.MWCategoriesPage.prototype.getDefaultSortKeyItem = function () {
return this.fragment.getDocument().getMetaList().getItemsInGroup( 'mwDefaultSort' )[ 0 ] || null;
};
/**
* Get array of category items from meta list
*
* @return {Object[]} items
*/
ve.ui.MWCategoriesPage.prototype.getCategoryItems = function () {
var items = [],
categories = this.fragment.getDocument().getMetaList().getItemsInGroup( 'mwCategory' );
// Loop through MwCategories and build out items
for ( var i = 0; i < categories.length; i++ ) {
items.push( this.getCategoryItemFromMetaListItem( categories[ i ] ) );
}
return items;
};
/**
* Gets category item from meta list item
*
* @param {ve.dm.MWCategoryMetaItem} metaItem
* @return {Object} item
*/
ve.ui.MWCategoriesPage.prototype.getCategoryItemFromMetaListItem = function ( metaItem ) {
var title = mw.Title.newFromText( metaItem.element.attributes.category ),
value = title ? title.getMainText() : '';
return {
name: metaItem.element.attributes.category,
value: value,
// TODO: sortkey is lcase, make consistent throughout CategoryWidget
sortKey: metaItem.element.attributes.sortkey,
metaItem: metaItem
};
};
/**
* Get metaList like object to insert from item
*
* @param {Object} item category widget item
* @param {Object} [oldData] Metadata object that was previously associated with this item, if any
* @return {Object} metaBase
*/
ve.ui.MWCategoriesPage.prototype.getCategoryItemForInsertion = function ( item, oldData ) {
var newData = {
attributes: { category: item.name, sortkey: item.sortKey || '' },
type: 'mwCategory'
};
if ( oldData ) {
return ve.extendObject( {}, oldData, newData );
}
return newData;
};
/**
* Setup categories page.
*
* @param {ve.dm.SurfaceFragment} fragment Surface fragment
* @param {Object} config
* @param {Object} [config.data] Dialog setup data
* @param {boolean} [config.isReadOnly=false] Dialog is in read-only mode
* @return {jQuery.Promise}
*/
ve.ui.MWCategoriesPage.prototype.setup = function ( fragment, config ) {
var page = this;
this.fragment = fragment;
this.fragment.getDocument().getMetaList().connect( this, {
insert: 'onMetaListInsert',
remove: 'onMetaListRemove'
} );
var defaultSortKeyItem = this.getDefaultSortKeyItem();
this.categoryWidget.setFragment( fragment );
var promise = this.categoryWidget.addItems( this.getCategoryItems() ).then( function () {
page.categoryWidget.setDisabled( config.isReadOnly );
} );
this.defaultSortInput.setValue(
defaultSortKeyItem ? defaultSortKeyItem.getAttribute( 'content' ) : this.fallbackDefaultSortKey
).setReadOnly( config.isReadOnly );
this.defaultSortKeyTouched = false;
// Update input position after transition
setTimeout( function () {
page.categoryWidget.fitInput();
}, OO.ui.theme.getDialogTransitionDuration() );
return promise;
};
/**
* @inheritdoc
*/
ve.ui.MWCategoriesPage.prototype.focus = function () {
this.categoryWidget.focus();
};
/**
* Tear down the page. This is called when the MWMetaDialog is torn down.
*
* @param {Object} [data] Dialog tear down data
*/
ve.ui.MWCategoriesPage.prototype.teardown = function ( data ) {
var currentDefaultSortKeyItem = this.getDefaultSortKeyItem(),
newDefaultSortKey = this.defaultSortInput.getValue(),
newDefaultSortKeyData = {
type: 'mwDefaultSort',
attributes: { content: newDefaultSortKey }
};
if ( data && data.action === 'done' ) {
// Alter the default sort key iff it's been touched & is actually different
if ( this.defaultSortKeyTouched ) {
if ( newDefaultSortKey === '' || newDefaultSortKey === this.fallbackDefaultSortKey ) {
if ( currentDefaultSortKeyItem ) {
this.fragment.removeMeta( currentDefaultSortKeyItem );
}
} else {
if ( !currentDefaultSortKeyItem ) {
this.fragment.insertMeta( newDefaultSortKeyData );
} else if ( currentDefaultSortKeyItem.getAttribute( 'content' ) !== newDefaultSortKey ) {
this.fragment.replaceMeta(
currentDefaultSortKeyItem,
ve.extendObject( true, {},
currentDefaultSortKeyItem.getElement(),
newDefaultSortKeyData
)
);
}
}
}
}
this.categoryWidget.clearItems();
this.categoryWidget.setFragment( null );
this.fragment.getDocument().getMetaList().disconnect( this );
this.fragment = null;
};
ve.ui.MWCategoriesPage.prototype.getFieldsets = function () {
return [
this.categoriesFieldset,
this.categoryOptionsFieldset
];
};
ve.ui.SpecialCharacterPage.js 0000666 00000004570 15133476715 0012147 0 ustar 00 /*!
* VisualEditor user interface SpecialCharacterPage class.
*
* @copyright 2011-2020 VisualEditor Team and others; see http://ve.mit-license.org
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
* Special character toolbar dialog.
*
* @class
* @extends OO.ui.PageLayout
*
* @constructor
* @param {string} name Unique symbolic name of page
* @param {Object} [config] Configuration options
* @cfg {string} [label]
* @cfg {Object} [characters] Character set
* @cfg {Object} [attributes] Extra attributes, currently `lang` and `dir`
* @cfg {boolean} [source] Source mode only set
*/
ve.ui.SpecialCharacterPage = function VeUiSpecialCharacterPage( name, config ) {
// Parent constructor
ve.ui.SpecialCharacterPage.super.apply( this, arguments );
this.label = config.label;
var characters = config.characters;
var $characters = $( '<div>' ).addClass( 've-ui-specialCharacterPage-characters' );
var charactersNode = $characters[ 0 ];
var source = config.source;
// The body of this loop is executed a few thousand times when opening
// ve.ui.SpecialCharacterDialog, avoid jQuery wrappers.
for ( var character in characters ) {
if ( !source && characters[ character ].source ) {
continue;
}
var characterNode = document.createElement( 'div' );
characterNode.className = 've-ui-specialCharacterPage-character';
if ( characters[ character ].titleMsg ) {
// eslint-disable-next-line mediawiki/msg-doc
characterNode.setAttribute( 'title', ve.msg( characters[ character ].titleMsg ) );
}
if ( characters[ character ].source ) {
characterNode.classList.add( 've-ui-specialCharacterPage-character-source' );
}
characterNode.textContent = character;
$.data( characterNode, 'character', characters[ character ] );
charactersNode.appendChild( characterNode );
}
if ( config.attributes ) {
$characters.attr( 'lang', config.attributes.lang );
$characters.attr( 'dir', config.attributes.dir );
}
this.$element
.addClass( 've-ui-specialCharacterPage' )
.append( $( '<h3>' ).text( this.label ), $characters );
};
/* Inheritance */
OO.inheritClass( ve.ui.SpecialCharacterPage, OO.ui.PageLayout );
/* Methods */
/**
* @inheritdoc
*/
ve.ui.SpecialCharacterPage.prototype.setupOutlineItem = function () {
// Parent method
ve.ui.SpecialCharacterPage.super.prototype.setupOutlineItem.apply( this, arguments );
this.outlineItem.setLabel( this.label );
};
aliens.html 0000666 00000015746 15133505122 0006723 0 ustar 00 <div rel="ve:Alien" style="float: right; height: 75px; width: 200px;">Single alien, floated right</div>
<p>Lorem Ipsum <span rel="ve:Alien" title="Invisible Alien"></span> has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled <span rel="ve:Alien">ALIEN1</span> it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was <a href="https://www.mediawiki.org/wiki/VisualEditor/Team">popularised</a> in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. <span rel="ve:Alien">[LONG INLINE ALIEN:Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled <span rel="ve:Alien">ALIEN1</span> it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially</span> unchanged. It was <a href="https://www.mediawiki.org/wiki/VisualEditor/Team">popularised</a> in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<p>Foo <span about="#group1" rel="ve:Alien">About</span><sup about="#group1" rel="ve:Alien">Grouped</sup><sub about="#group1" rel="ve:Alien">Aliens</sub> Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.</p>
<div rel="ve:Alien">
<div style="float: right; height: 75px; width: 200px;">Alien with two floats!</div>
<div style="float: left; height: 75px; width: 200px;">Alien with <span><span><span>two</span></span></span> Lorem Ipsum floats!</div>
</div>
<p>Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled <span rel="ve:Alien">ALIEN1</span> it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was <a href="https://www.mediawiki.org/wiki/VisualEditor/Team">popularised</a> in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. <a href="Foo"><span rel="ve:Alien">[LONG ANNOTATED INLINE ALIEN:Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled <span rel="ve:Alien">NESTED ALIEN</span> it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially</span></a>. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled <span rel="ve:Alien">ALIEN1</span> it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was <a href="https://www.mediawiki.org/wiki/VisualEditor/Team">popularised</a> in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<div rel="ve:Alien" style="height: 75px; width: 200px;">
<div style="float: left">float</div>
No floating or positioning at all
</div>
<div rel="ve:Alien" style="height: 75px; width: 200px;">
Another alien
</div>
<pre rel="ve:Alien">Preformatted alien
Preformatted alien
Preformatted alien</pre>
<p><span rel="ve:Alien"><span><a href="http://example.com/" title="example.com" style="position: absolute; top: 0; right: 0; z-index: 2000;">I shouldn't be clickable</a></span></span>Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled <span rel="ve:Alien">ALIEN1</span> it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was <a href="https://www.mediawiki.org/wiki/VisualEditor/Team">popularised</a> in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled <span rel="ve:Alien">ALIEN1</span> it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was <a href="https://www.mediawiki.org/wiki/VisualEditor/Team">popularised</a> in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<div rel="ve:Alien" style="position: absolute; top: 200px; left: 200px;">
Oh no, I'm absolutely positioned!
</div>
<p>Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled <span rel="ve:Alien">ALIEN1</span> it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was <a href="https://www.mediawiki.org/wiki/VisualEditor/Team">popularised</a> in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled <span rel="ve:Alien">ALIEN1</span> it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was <a href="https://www.mediawiki.org/wiki/VisualEditor/Team">popularised</a> in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.</p>
<div rel="ve:Alien" style="overflow: scroll; width: 200px; height: 100px; border: 1px solid;">
<div style="width: 300px; height: 100px;">Overflow: scroll alien</div>
</div>
<div rel="ve:Alien" style="overflow: visible; width: 200px; height: 100px; border: 1px solid;">
<div style="width: 300px; height: 100px;">Overflow: visible alien</div>
</div>
<table>
<caption>No slugs between alienated table rows</caption>
<tr rel="ve:Alien"><td>Lorem Ipsum has been the industry's</td></tr>
<tr rel="ve:Alien"><td>standard dummy text ever since the 1500s,</td></tr>
<tr rel="ve:Alien"><td>when an unknown printer took a galley</td></tr>
</table>
h1.html 0000666 00000000021 15133505122 0005734 0 ustar 00 <h1>abcdefg</h1>