mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-09-25 11:16:51 +00:00
Merge "Throw ve.Error instead of string literals"
This commit is contained in:
commit
08b349d7dd
|
@ -101,6 +101,7 @@ $wgResourceModules += array(
|
|||
'scripts' => array(
|
||||
// ve
|
||||
've/ve.js',
|
||||
've/ve.Error.js',
|
||||
've/ve.EventEmitter.js',
|
||||
've/init/ve.init.js',
|
||||
've/init/ve.init.Platform.js',
|
||||
|
|
|
@ -57,6 +57,7 @@ $html = '<div>' . file_get_contents( $page ) . '</div>';
|
|||
<script src="../../modules/jquery/jquery.json.js"></script>
|
||||
<script src="../../modules/ve/ve.js"></script>
|
||||
<script src="../../modules/ve/ve.debug.js"></script>
|
||||
<script src="../../modules/ve/ve.Error.js"></script>
|
||||
<script src="../../modules/ve/ve.EventEmitter.js"></script>
|
||||
<script src="../../modules/ve/ve.Factory.js"></script>
|
||||
<script src="../../modules/ve/ve.Position.js"></script>
|
||||
|
|
|
@ -157,7 +157,7 @@ ve.ce.TextNode.annotationRenderers = {
|
|||
*/
|
||||
ve.ce.TextNode.prototype.onUpdate = function ( force ) {
|
||||
if ( !force && !this.root.getSurface ) {
|
||||
throw 'Can not update a text node that is not attached to a document';
|
||||
throw new ve.Error( 'Can not update a text node that is not attached to a document' );
|
||||
}
|
||||
if ( force === true || this.root.getSurface().render === true ) {
|
||||
var $new = $( '<span>' ).html( this.getHtml() ).contents();
|
||||
|
|
|
@ -66,11 +66,11 @@ ve.ce.BranchNode.getDomWrapperType = function ( model, key ) {
|
|||
var types,
|
||||
value = model.getAttribute( key );
|
||||
if ( value === undefined ) {
|
||||
throw 'Undefined attribute: ' + key;
|
||||
throw new ve.Error( 'Undefined attribute: ' + key );
|
||||
}
|
||||
types = ve.ce.nodeFactory.lookup( model.getType() ).domWrapperElementTypes;
|
||||
if ( types[value] === undefined ) {
|
||||
throw 'Invalid attribute value: ' + value;
|
||||
throw new ve.Error( 'Invalid attribute value: ' + value );
|
||||
}
|
||||
return types[value];
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ ve.ce.NodeFactory.prototype.canNodeBeSplit = function ( type ) {
|
|||
if ( type in this.registry ) {
|
||||
return this.registry[type].rules.canBeSplit;
|
||||
}
|
||||
throw 'Unknown node type: ' + type;
|
||||
throw new ve.Error( 'Unknown node type: ' + type );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
|
|
@ -75,7 +75,7 @@ ve.dm.Converter.getDataContentFromText = function ( text, annotations ) {
|
|||
*/
|
||||
ve.dm.Converter.prototype.onNodeRegister = function ( dataElementType, constructor ) {
|
||||
if ( constructor.converters === undefined ) {
|
||||
throw 'Missing conversion data in node implementation of ' + dataElementType;
|
||||
throw new ve.Error( 'Missing conversion data in node implementation of ' + dataElementType );
|
||||
} else if ( constructor.converters !== null ) {
|
||||
var i,
|
||||
domElementTypes = constructor.converters.domElementTypes,
|
||||
|
@ -100,7 +100,7 @@ ve.dm.Converter.prototype.onNodeRegister = function ( dataElementType, construct
|
|||
*/
|
||||
ve.dm.Converter.prototype.onAnnotationRegister = function ( dataElementType, constructor ) {
|
||||
if ( constructor.converters === undefined ) {
|
||||
throw 'Missing conversion data in annotation implementation of ' + dataElementType;
|
||||
throw new ve.Error( 'Missing conversion data in annotation implementation of ' + dataElementType );
|
||||
} else if ( constructor.converters !== null ) {
|
||||
var i,
|
||||
domElementTypes = constructor.converters.domElementTypes,
|
||||
|
|
|
@ -93,7 +93,7 @@ ve.dm.Document = function ( data, parentDocument ) {
|
|||
parentStack = stack[stack.length - 2];
|
||||
if ( !parentStack ) {
|
||||
// This can only happen if we got unbalanced data
|
||||
throw 'Unbalanced input passed to document';
|
||||
throw new ve.Error( 'Unbalanced input passed to document' );
|
||||
}
|
||||
|
||||
if ( children.length === 0 &&
|
||||
|
@ -574,7 +574,7 @@ ve.dm.Document.prototype.getAnnotatedRangeFromSelection = function ( range, anno
|
|||
*/
|
||||
ve.dm.Document.prototype.offsetContainsMatchingAnnotations = function ( offset, pattern ) {
|
||||
if ( !( pattern instanceof RegExp ) ) {
|
||||
throw 'Invalid Pattern. Pattern not instance of RegExp';
|
||||
throw new ve.Error( 'Invalid Pattern. Pattern not instance of RegExp' );
|
||||
}
|
||||
var hash,
|
||||
annotations = ve.isArray( this.data[offset] ) ?
|
||||
|
@ -599,7 +599,7 @@ ve.dm.Document.prototype.offsetContainsMatchingAnnotations = function ( offset,
|
|||
*/
|
||||
ve.dm.Document.prototype.getMatchingAnnotationsFromOffset = function ( offset, pattern ) {
|
||||
if ( !( pattern instanceof RegExp ) ) {
|
||||
throw 'Invalid Pattern. Pattern not instance of RegExp';
|
||||
throw new ve.Error( 'Invalid Pattern. Pattern not instance of RegExp' );
|
||||
}
|
||||
var hash,
|
||||
matches = {},
|
||||
|
@ -626,7 +626,7 @@ ve.dm.Document.prototype.getMatchingAnnotationsFromOffset = function ( offset, p
|
|||
*/
|
||||
ve.dm.Document.getMatchingAnnotations = function ( annotations, pattern ) {
|
||||
if ( !( pattern instanceof RegExp ) ) {
|
||||
throw 'Invalid Pattern. Pattern not instance of RegExp';
|
||||
throw new ve.Error( 'Invalid Pattern. Pattern not instance of RegExp' );
|
||||
}
|
||||
var hash,
|
||||
matches = {};
|
||||
|
@ -1045,16 +1045,16 @@ ve.dm.Document.prototype.fixupInsertion = function ( data, offset ) {
|
|||
closingStack.push( parentNode );
|
||||
parentNode = parentNode.getParent();
|
||||
if ( !parentNode ) {
|
||||
throw 'Inserted data is trying to close the root node ' +
|
||||
'(at index ' + index + ')';
|
||||
throw new ve.Error( 'Inserted data is trying to close the root node ' +
|
||||
'(at index ' + index + ')' );
|
||||
}
|
||||
parentType = expectedType;
|
||||
|
||||
// Validate
|
||||
// FIXME this breaks certain input, should fix it up, not scream and die
|
||||
if ( element.type !== '/' + expectedType ) {
|
||||
throw 'Type mismatch, expected /' + expectedType +
|
||||
' but got ' + element.type + ' (at index ' + index + ')';
|
||||
throw new ve.Error( 'Type mismatch, expected /' + expectedType +
|
||||
' but got ' + element.type + ' (at index ' + index + ')' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1112,8 +1112,8 @@ ve.dm.Document.prototype.fixupInsertion = function ( data, offset ) {
|
|||
if ( !parentsOK ) {
|
||||
// We can't have this as the parent
|
||||
if ( allowedParents.length === 0 ) {
|
||||
throw 'Cannot insert ' + childType + ' because it ' +
|
||||
' cannot have a parent (at index ' + i + ')';
|
||||
throw new ve.Error( 'Cannot insert ' + childType + ' because it ' +
|
||||
' cannot have a parent (at index ' + i + ')' );
|
||||
}
|
||||
// Open an allowed node around this node
|
||||
childType = allowedParents[0];
|
||||
|
@ -1151,9 +1151,9 @@ ve.dm.Document.prototype.fixupInsertion = function ( data, offset ) {
|
|||
reopenElements.push( parentNode.getClonedElement() );
|
||||
parentNode = parentNode.getParent();
|
||||
if ( !parentNode ) {
|
||||
throw 'Cannot insert ' + childType + ' even ' +
|
||||
throw new ve.Error( 'Cannot insert ' + childType + ' even ' +
|
||||
' after closing all containing nodes ' +
|
||||
'(at index ' + i + ')';
|
||||
'(at index ' + i + ')' );
|
||||
}
|
||||
parentType = parentNode.getType();
|
||||
}
|
||||
|
|
|
@ -268,7 +268,7 @@ ve.dm.DocumentSynchronizer.prototype.synchronize = function () {
|
|||
if ( action.type in ve.dm.DocumentSynchronizer.synchronizers ) {
|
||||
ve.dm.DocumentSynchronizer.synchronizers[action.type].call( this, action );
|
||||
} else {
|
||||
throw 'Invalid action type ' + action.type;
|
||||
throw new ve.Error( 'Invalid action type ' + action.type );
|
||||
}
|
||||
}
|
||||
// Emit events in the event queue
|
||||
|
|
|
@ -154,7 +154,7 @@ ve.dm.Node.prototype.getOuterRange = function () {
|
|||
*/
|
||||
ve.dm.Node.prototype.setLength = function ( length ) {
|
||||
if ( length < 0 ) {
|
||||
throw 'Length cannot be negative';
|
||||
throw new ve.Error( 'Length cannot be negative' );
|
||||
}
|
||||
// Compute length adjustment from old length
|
||||
var diff = length - this.length;
|
||||
|
|
|
@ -31,7 +31,7 @@ ve.dm.NodeFactory.prototype.getChildNodeTypes = function ( type ) {
|
|||
if ( type in this.registry ) {
|
||||
return this.registry[type].rules.childNodeTypes;
|
||||
}
|
||||
throw 'Unknown node type: ' + type;
|
||||
throw new ve.Error( 'Unknown node type: ' + type );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -46,7 +46,7 @@ ve.dm.NodeFactory.prototype.getParentNodeTypes = function ( type ) {
|
|||
if ( type in this.registry ) {
|
||||
return this.registry[type].rules.parentNodeTypes;
|
||||
}
|
||||
throw 'Unknown node type: ' + type;
|
||||
throw new ve.Error( 'Unknown node type: ' + type );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -64,7 +64,7 @@ ve.dm.NodeFactory.prototype.canNodeHaveChildren = function ( type ) {
|
|||
var types = this.registry[type].rules.childNodeTypes;
|
||||
return types === null || ( ve.isArray( types ) && types.length > 0 );
|
||||
}
|
||||
throw 'Unknown node type: ' + type;
|
||||
throw new ve.Error( 'Unknown node type: ' + type );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -81,7 +81,7 @@ ve.dm.NodeFactory.prototype.canNodeHaveGrandchildren = function ( type ) {
|
|||
!this.registry[type].rules.canContainContent &&
|
||||
!this.registry[type].rules.isContent;
|
||||
}
|
||||
throw 'Unknown node type: ' + type;
|
||||
throw new ve.Error( 'Unknown node type: ' + type );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -96,7 +96,7 @@ ve.dm.NodeFactory.prototype.isNodeWrapped = function ( type ) {
|
|||
if ( type in this.registry ) {
|
||||
return this.registry[type].rules.isWrapped;
|
||||
}
|
||||
throw 'Unknown node type: ' + type;
|
||||
throw new ve.Error( 'Unknown node type: ' + type );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -111,7 +111,7 @@ ve.dm.NodeFactory.prototype.canNodeContainContent = function ( type ) {
|
|||
if ( type in this.registry ) {
|
||||
return this.registry[type].rules.canContainContent;
|
||||
}
|
||||
throw 'Unknown node type: ' + type;
|
||||
throw new ve.Error( 'Unknown node type: ' + type );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -126,7 +126,7 @@ ve.dm.NodeFactory.prototype.isNodeContent = function ( type ) {
|
|||
if ( type in this.registry ) {
|
||||
return this.registry[type].rules.isContent;
|
||||
}
|
||||
throw 'Unknown node type: ' + type;
|
||||
throw new ve.Error( 'Unknown node type: ' + type );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
|
|
@ -82,7 +82,7 @@ ve.dm.Transaction.newFromRemoval = function ( doc, range ) {
|
|||
selection = doc.selectNodes( range, 'covered' );
|
||||
if ( selection.length === 0 ) {
|
||||
// Empty selection? Something is wrong!
|
||||
throw 'Invalid range, cannot remove from ' + range.start + ' to ' + range.end;
|
||||
throw new ve.Error( 'Invalid range, cannot remove from ' + range.start + ' to ' + range.end );
|
||||
}
|
||||
first = selection[0];
|
||||
last = selection[selection.length - 1];
|
||||
|
@ -169,11 +169,11 @@ ve.dm.Transaction.newFromAttributeChange = function ( doc, offset, key, value )
|
|||
data = doc.getData();
|
||||
// Verify element exists at offset
|
||||
if ( data[offset].type === undefined ) {
|
||||
throw 'Can not set attributes to non-element data';
|
||||
throw new ve.Error( 'Can not set attributes to non-element data' );
|
||||
}
|
||||
// Verify element is not a closing
|
||||
if ( data[offset].type.charAt( 0 ) === '/' ) {
|
||||
throw 'Can not set attributes on closing element';
|
||||
throw new ve.Error( 'Can not set attributes on closing element' );
|
||||
}
|
||||
// Retain up to element
|
||||
tx.pushRetain( offset );
|
||||
|
@ -362,7 +362,7 @@ ve.dm.Transaction.newFromWrap = function ( doc, range, unwrapOuter, wrapOuter, u
|
|||
// the range, so compensate for that
|
||||
tx.pushRetain( range.start - unwrapOuter.length );
|
||||
} else if ( range.start < unwrapOuter.length ) {
|
||||
throw 'unwrapOuter is longer than the data preceding the range';
|
||||
throw new ve.Error( 'unwrapOuter is longer than the data preceding the range' );
|
||||
}
|
||||
|
||||
// Replace the opening elements for the outer unwrap&wrap
|
||||
|
@ -371,8 +371,8 @@ ve.dm.Transaction.newFromWrap = function ( doc, range, unwrapOuter, wrapOuter, u
|
|||
unwrapOuterData = doc.data.slice( range.start - unwrapOuter.length, range.start );
|
||||
for ( i = 0; i < unwrapOuterData.length; i++ ) {
|
||||
if ( unwrapOuterData[i].type !== unwrapOuter[i].type ) {
|
||||
throw 'Element in unwrapOuter does not match: expected ' +
|
||||
unwrapOuter[i].type + ' but found ' + unwrapOuterData[i].type;
|
||||
throw new ve.Error( 'Element in unwrapOuter does not match: expected ' +
|
||||
unwrapOuter[i].type + ' but found ' + unwrapOuterData[i].type );
|
||||
}
|
||||
}
|
||||
// Instead of putting in unwrapOuter as given, put it in the
|
||||
|
@ -397,9 +397,9 @@ ve.dm.Transaction.newFromWrap = function ( doc, range, unwrapOuter, wrapOuter, u
|
|||
unwrapEachData = doc.data.slice( i, i + unwrapEach.length );
|
||||
for ( j = 0; j < unwrapEachData.length; j++ ) {
|
||||
if ( unwrapEachData[j].type !== unwrapEach[j].type ) {
|
||||
throw 'Element in unwrapEach does not match: expected ' +
|
||||
throw new ve.Error( 'Element in unwrapEach does not match: expected ' +
|
||||
unwrapEach[j].type + ' but found ' +
|
||||
unwrapEachData[j].type;
|
||||
unwrapEachData[j].type );
|
||||
}
|
||||
}
|
||||
// Instead of putting in unwrapEach as given, put it in the
|
||||
|
@ -524,7 +524,7 @@ ve.dm.Transaction.prototype.translateRange = function ( range ) {
|
|||
*/
|
||||
ve.dm.Transaction.prototype.pushRetain = function ( length ) {
|
||||
if ( length < 0 ) {
|
||||
throw 'Invalid retain length, can not retain backwards:' + length;
|
||||
throw new ve.Error( 'Invalid retain length, can not retain backwards:' + length );
|
||||
}
|
||||
if ( length ) {
|
||||
var end = this.operations.length - 1;
|
||||
|
|
|
@ -115,7 +115,7 @@ ve.dm.TransactionProcessor.processors.annotate = function ( op ) {
|
|||
} else if ( op.method === 'clear' ) {
|
||||
target = this.reversed ? this.set : this.clear;
|
||||
} else {
|
||||
throw 'Invalid annotation method ' + op.method;
|
||||
throw new ve.Error( 'Invalid annotation method ' + op.method );
|
||||
}
|
||||
|
||||
hash = $.toJSON( op.annotation );
|
||||
|
@ -150,7 +150,7 @@ ve.dm.TransactionProcessor.processors.attribute = function ( op ) {
|
|||
to = this.reversed ? op.from : op.to,
|
||||
from = this.reversed ? op.to : op.from;
|
||||
if ( element.type === undefined ) {
|
||||
throw 'Invalid element error, can not set attributes on non-element data';
|
||||
throw new ve.Error( 'Invalid element error, can not set attributes on non-element data' );
|
||||
}
|
||||
if ( to === undefined ) {
|
||||
// Clear
|
||||
|
@ -346,7 +346,7 @@ ve.dm.TransactionProcessor.processors.replace = function ( op ) {
|
|||
// Get the next operation
|
||||
operation = this.nextOperation();
|
||||
if ( !operation ) {
|
||||
throw 'Unbalanced set of replace operations found';
|
||||
throw new ve.Error( 'Unbalanced set of replace operations found' );
|
||||
}
|
||||
}
|
||||
// From all the affected ranges we have gathered, compute a range that covers all
|
||||
|
@ -384,7 +384,7 @@ ve.dm.TransactionProcessor.prototype.executeOperation = function ( op ) {
|
|||
if ( op.type in ve.dm.TransactionProcessor.processors ) {
|
||||
ve.dm.TransactionProcessor.processors[op.type].call( this, op );
|
||||
} else {
|
||||
throw 'Invalid operation error. Operation type is not supported: ' + op.type;
|
||||
throw new ve.Error( 'Invalid operation error. Operation type is not supported: ' + op.type );
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -426,9 +426,9 @@ ve.dm.TransactionProcessor.prototype.applyAnnotations = function ( to ) {
|
|||
element = item.type !== undefined;
|
||||
if ( element ) {
|
||||
if ( item.type.charAt( 0 ) === '/' ) {
|
||||
throw 'Invalid transaction, cannot annotate a branch closing element';
|
||||
throw new ve.Error( 'Invalid transaction, cannot annotate a branch closing element' );
|
||||
} else if ( ve.dm.nodeFactory.canNodeHaveChildren( item.type ) ) {
|
||||
throw 'Invalid transaction, cannot annotate a branch opening element';
|
||||
throw new ve.Error( 'Invalid transaction, cannot annotate a branch opening element' );
|
||||
}
|
||||
}
|
||||
annotated = element ? 'annotations' in item : ve.isArray( item );
|
||||
|
@ -436,13 +436,13 @@ ve.dm.TransactionProcessor.prototype.applyAnnotations = function ( to ) {
|
|||
// Set and clear annotations
|
||||
for ( hash in this.set ) {
|
||||
if ( hash in annotations ) {
|
||||
throw 'Invalid transaction, annotation to be set is already set';
|
||||
throw new ve.Error( 'Invalid transaction, annotation to be set is already set' );
|
||||
}
|
||||
annotations[hash] = this.set[hash];
|
||||
}
|
||||
for ( hash in this.clear ) {
|
||||
if ( !( hash in annotations ) ) {
|
||||
throw 'Invalid transaction, annotation to be cleared is not set';
|
||||
throw new ve.Error( 'Invalid transaction, annotation to be cleared is not set' );
|
||||
}
|
||||
delete annotations[hash];
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ ve.init.Platform = function () {
|
|||
* @returns {RegExp} Regular expression object
|
||||
*/
|
||||
ve.init.Platform.prototype.getExternalLinkUrlProtocolsRegExp = function () {
|
||||
throw 've.init.Platform.getExternalLinkUrlProtocolsRegExp must be overridden in subclass';
|
||||
throw new ve.Error( 've.init.Platform.getExternalLinkUrlProtocolsRegExp must be overridden in subclass' );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -39,7 +39,7 @@ ve.init.Platform.prototype.getExternalLinkUrlProtocolsRegExp = function () {
|
|||
* @returns {String} Remote modules URL
|
||||
*/
|
||||
ve.init.Platform.prototype.getModulesUrl = function () {
|
||||
throw 've.init.Platform.getModulesUrl must be overridden in subclass';
|
||||
throw new ve.Error( 've.init.Platform.getModulesUrl must be overridden in subclass' );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -50,7 +50,7 @@ ve.init.Platform.prototype.getModulesUrl = function () {
|
|||
* @param {Object} messages Map of message-key/message-string pairs
|
||||
*/
|
||||
ve.init.Platform.prototype.addMessages = function ( messages ) {
|
||||
throw 've.init.Platform.addMessages must be overridden in subclass';
|
||||
throw new ve.Error( 've.init.Platform.addMessages must be overridden in subclass' );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -63,7 +63,7 @@ ve.init.Platform.prototype.addMessages = function ( messages ) {
|
|||
* @returns {String} Localized message
|
||||
*/
|
||||
ve.init.Platform.prototype.getMessage = function ( key ) {
|
||||
throw 've.init.Platform.getMessage must be overridden in subclass';
|
||||
throw new ve.Error( 've.init.Platform.getMessage must be overridden in subclass' );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
|
|
@ -26,7 +26,7 @@ QUnit.test( 'canNodeBeSplit', 2, function ( assert ) {
|
|||
assert.throws( function () {
|
||||
factory.canNodeBeSplit( 'node-factory-node-stub' );
|
||||
},
|
||||
/^Unknown node type: node-factory-node-stub$/,
|
||||
ve.Error,
|
||||
'throws an exception when getting split rules for a node of an unregistered type'
|
||||
);
|
||||
factory.register( 'node-factory-node-stub', ve.ce.NodeFactoryNodeStub );
|
||||
|
|
|
@ -19,7 +19,7 @@ QUnit.test( 'constructor', 4, function ( assert ) {
|
|||
{ 'type': 'paragraph' }
|
||||
] );
|
||||
},
|
||||
/^Unbalanced input passed to document$/,
|
||||
ve.Error,
|
||||
'unbalanced input causes exception'
|
||||
);
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ QUnit.test( 'setLength', 2, function ( assert ) {
|
|||
// Length can not be negative
|
||||
node.setLength( -1 );
|
||||
},
|
||||
/^Length cannot be negative$/,
|
||||
ve.Error,
|
||||
'throws exception if length is negative'
|
||||
);
|
||||
} );
|
||||
|
|
|
@ -33,7 +33,7 @@ QUnit.test( 'getChildNodeTypes', 2, function ( assert ) {
|
|||
assert.throws( function () {
|
||||
factory.getChildNodeTypes( 'node-factory-node-stub', 23, { 'bar': 'baz' } );
|
||||
},
|
||||
/^Unknown node type: node-factory-node-stub$/,
|
||||
ve.Error,
|
||||
'throws an exception when getting allowed child nodes of a node of an unregistered type'
|
||||
);
|
||||
factory.register( 'node-factory-node-stub', ve.dm.NodeFactoryNodeStub );
|
||||
|
@ -49,7 +49,7 @@ QUnit.test( 'getParentNodeTypes', 2, function ( assert ) {
|
|||
assert.throws( function () {
|
||||
factory.getParentNodeTypes( 'node-factory-node-stub', 23, { 'bar': 'baz' } );
|
||||
},
|
||||
/^Unknown node type: node-factory-node-stub$/,
|
||||
ve.Error,
|
||||
'throws an exception when getting allowed parent nodes of a node of an unregistered type'
|
||||
);
|
||||
factory.register( 'node-factory-node-stub', ve.dm.NodeFactoryNodeStub );
|
||||
|
@ -65,7 +65,7 @@ QUnit.test( 'canNodeHaveChildren', 2, function ( assert ) {
|
|||
assert.throws( function () {
|
||||
factory.canNodeHaveChildren( 'node-factory-node-stub', 23, { 'bar': 'baz' } );
|
||||
},
|
||||
/^Unknown node type: node-factory-node-stub$/,
|
||||
ve.Error,
|
||||
'throws an exception when checking if a node of an unregistered type can have children'
|
||||
);
|
||||
factory.register( 'node-factory-node-stub', ve.dm.NodeFactoryNodeStub );
|
||||
|
@ -81,7 +81,7 @@ QUnit.test( 'canNodeHaveGrandchildren', 2, function ( assert ) {
|
|||
assert.throws( function () {
|
||||
factory.canNodeHaveGrandchildren( 'node-factory-node-stub', 23, { 'bar': 'baz' } );
|
||||
},
|
||||
/^Unknown node type: node-factory-node-stub$/,
|
||||
ve.Error,
|
||||
'throws an exception when checking if a node of an unregistered type can have grandchildren'
|
||||
);
|
||||
factory.register( 'node-factory-node-stub', ve.dm.NodeFactoryNodeStub );
|
||||
|
|
|
@ -471,11 +471,11 @@ QUnit.test( 'newFromAttributeChange', function ( assert ) {
|
|||
},
|
||||
'non-element': {
|
||||
'args': [doc, 1, 'level', 2],
|
||||
'exception': /^Can not set attributes to non-element data$/
|
||||
'exception': ve.Error
|
||||
},
|
||||
'closing element': {
|
||||
'args': [doc, 4, 'level', 2],
|
||||
'exception': /^Can not set attributes on closing element$/
|
||||
'exception': ve.Error
|
||||
}
|
||||
};
|
||||
runConstructorTests( assert, ve.dm.Transaction.newFromAttributeChange, cases );
|
||||
|
@ -704,15 +704,15 @@ QUnit.test( 'newFromWrap', function ( assert ) {
|
|||
},
|
||||
'checks integrity of unwrapOuter parameter': {
|
||||
'args': [doc, new ve.Range( 13, 32 ), [ { 'type': 'table' } ], [], [], []],
|
||||
'exception': /^Element in unwrapOuter does not match: expected table but found list$/
|
||||
'exception': ve.Error
|
||||
},
|
||||
'checks integrity of unwrapEach parameter': {
|
||||
'args': [doc, new ve.Range( 13, 32 ), [ { 'type': 'list' } ], [], [ { 'type': 'paragraph' } ], []],
|
||||
'exception': /^Element in unwrapEach does not match: expected paragraph but found listItem$/
|
||||
'exception': ve.Error
|
||||
},
|
||||
'checks that unwrapOuter fits before the range': {
|
||||
'args': [doc, new ve.Range( 1, 4 ), [ { 'type': 'listItem' }, { 'type': 'paragraph' } ], [], [], []],
|
||||
'exception': /^unwrapOuter is longer than the data preceding the range$/
|
||||
'exception': ve.Error
|
||||
}
|
||||
};
|
||||
runConstructorTests(
|
||||
|
|
|
@ -62,7 +62,7 @@ QUnit.test( 'commit/rollback', function ( assert ) {
|
|||
['pushRetain', 1],
|
||||
['pushStopAnnotating', 'invalid-method', { 'type': 'textStyle/bold' }]
|
||||
],
|
||||
'exception': /^Invalid annotation method/
|
||||
'exception': ve.Error
|
||||
},
|
||||
'annotating branch opening element throws an exception': {
|
||||
'calls': [
|
||||
|
@ -70,7 +70,7 @@ QUnit.test( 'commit/rollback', function ( assert ) {
|
|||
['pushRetain', 1],
|
||||
['pushStopAnnotating', 'set', { 'type': 'textStyle/bold' }]
|
||||
],
|
||||
'exception': /^Invalid transaction, cannot annotate a branch opening element$/
|
||||
'exception': ve.Error
|
||||
},
|
||||
'annotating branch closing element throws an exception': {
|
||||
'calls': [
|
||||
|
@ -79,7 +79,7 @@ QUnit.test( 'commit/rollback', function ( assert ) {
|
|||
['pushRetain', 1],
|
||||
['pushStopAnnotating', 'set', { 'type': 'textStyle/bold' }]
|
||||
],
|
||||
'exception': /^Invalid transaction, cannot annotate a branch closing element$/
|
||||
'exception': ve.Error
|
||||
},
|
||||
'setting duplicate annotations throws an exception': {
|
||||
'calls': [
|
||||
|
@ -88,7 +88,7 @@ QUnit.test( 'commit/rollback', function ( assert ) {
|
|||
['pushRetain', 1],
|
||||
['pushStopAnnotating', 'set', { 'type': 'textStyle/bold' }]
|
||||
],
|
||||
'exception': /^Invalid transaction, annotation to be set is already set$/
|
||||
'exception': ve.Error
|
||||
},
|
||||
'removing non-existent annotations throws an exception': {
|
||||
'calls': [
|
||||
|
@ -97,7 +97,7 @@ QUnit.test( 'commit/rollback', function ( assert ) {
|
|||
['pushRetain', 1],
|
||||
['pushStopAnnotating', 'clear', { 'type': 'textStyle/bold' }]
|
||||
],
|
||||
'exception': /^Invalid transaction, annotation to be cleared is not set$/
|
||||
'exception': ve.Error
|
||||
},
|
||||
'changing, removing and adding attributes': {
|
||||
'calls': [
|
||||
|
@ -120,7 +120,7 @@ QUnit.test( 'commit/rollback', function ( assert ) {
|
|||
['pushRetain', 1],
|
||||
['pushReplaceElementAttribute', 'foo', 23, 42]
|
||||
],
|
||||
'exception': /^Invalid element error, can not set attributes on non-element data$/
|
||||
'exception': ve.Error
|
||||
},
|
||||
'inserting text': {
|
||||
'calls': [
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
<!-- Load application -->
|
||||
<!-- ext.visualEditor.base -->
|
||||
<script src="../ve.js"></script>
|
||||
<script src="../ve.Error.js"></script>
|
||||
<script src="../ve.EventEmitter.js"></script>
|
||||
<script src="../init/ve.init.js"></script>
|
||||
<script src="../init/ve.init.Platform.js"></script>
|
||||
|
|
|
@ -152,7 +152,7 @@ QUnit.test( 'traverseLeafNodes', 1, function ( assert ) {
|
|||
{
|
||||
'node': children[1],
|
||||
'from': children[2],
|
||||
'exception': /^from parameter passed to traverseLeafNodes\(\) must be a descendant$/,
|
||||
'exception': ve.Error,
|
||||
'desc': 'Passing a sibling for from results in an exception'
|
||||
}
|
||||
];
|
||||
|
|
|
@ -22,7 +22,7 @@ QUnit.test( 'register', 1, function ( assert ) {
|
|||
function () {
|
||||
factory.register( 'factory-object-stub', 'not-a-function' );
|
||||
},
|
||||
/^Constructor must be a function, cannot be a string$/,
|
||||
ve.Error,
|
||||
'throws an exception when trying to register a non-function value as a constructor'
|
||||
);
|
||||
} );
|
||||
|
@ -33,7 +33,7 @@ QUnit.test( 'create', 2, function ( assert ) {
|
|||
function () {
|
||||
factory.create( 'factory-object-stub', 23, { 'bar': 'baz' } );
|
||||
},
|
||||
/^Unknown object type: factory-object-stub$/,
|
||||
ve.Error,
|
||||
'throws an exception when trying to create a object of an unregistered type'
|
||||
);
|
||||
factory.register( 'factory-object-stub', ve.FactoryObjectStub );
|
||||
|
|
|
@ -44,7 +44,7 @@ ve.ui.ButtonTool = function ( toolbar, name, title ) {
|
|||
/* Methods */
|
||||
|
||||
ve.ui.ButtonTool.prototype.onClick = function () {
|
||||
throw 'ButtonTool.onClick not implemented in this subclass:' + this.constructor;
|
||||
throw new ve.Error( 'ButtonTool.onClick not implemented in this subclass:' + this.constructor );
|
||||
};
|
||||
|
||||
ve.ui.ButtonTool.prototype.updateEnabled = function () {
|
||||
|
|
|
@ -63,7 +63,7 @@ ve.ui.DropdownTool = function ( toolbar, name, title, items ) {
|
|||
/* Methods */
|
||||
|
||||
ve.ui.DropdownTool.prototype.onSelect = function ( item ) {
|
||||
throw 'DropdownTool.onSelect not implemented in this subclass:' + this.constructor;
|
||||
throw new ve.Error( 'DropdownTool.onSelect not implemented in this subclass:' + this.constructor );
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
|
|
@ -226,7 +226,7 @@ ve.ui.Context.prototype.clear = function () {
|
|||
|
||||
ve.ui.Context.prototype.openInspector = function ( name ) {
|
||||
if ( !( name in this.inspectors ) ) {
|
||||
throw 'Missing inspector error. Can not open nonexistent inspector: ' + name;
|
||||
throw new ve.Error( 'Missing inspector error. Can not open nonexistent inspector: ' + name );
|
||||
}
|
||||
this.inspectors[name].open();
|
||||
this.resizeInspectorFrame( this.inspectors[name] );
|
||||
|
@ -251,7 +251,7 @@ ve.ui.Context.prototype.getInspector = function ( name ) {
|
|||
|
||||
ve.ui.Context.prototype.addInspector = function ( name, inspector ) {
|
||||
if ( name in this.inspectors ) {
|
||||
throw 'Duplicate inspector error. Previous registration with the same name: ' + name;
|
||||
throw new ve.Error( 'Duplicate inspector error. Previous registration with the same name: ' + name );
|
||||
}
|
||||
inspector.$.hide();
|
||||
this.inspectors[name] = inspector;
|
||||
|
@ -276,7 +276,7 @@ ve.ui.Context.prototype.resizeInspectorFrame = function ( inspector ) {
|
|||
|
||||
ve.ui.Context.prototype.removeInspector = function ( name ) {
|
||||
if ( name in this.inspectors ) {
|
||||
throw 'Missing inspector error. Can not remove nonexistent inspector: ' + name;
|
||||
throw new ve.Error( 'Missing inspector error. Can not remove nonexistent inspector: ' + name );
|
||||
}
|
||||
this.inspectors[name].detach();
|
||||
delete this.inspectors[name];
|
||||
|
|
|
@ -68,7 +68,7 @@ ve.ui.Menu.prototype.addItem = function ( item, before ) {
|
|||
// Items that don't have custom DOM elements will be auto-created
|
||||
if ( !item.$ ) {
|
||||
if ( !item.name ) {
|
||||
throw 'Invalid menu item error. Items must have a name property.';
|
||||
throw new ve.Error( 'Invalid menu item error. Items must have a name property.' );
|
||||
}
|
||||
if ( item.label ) {
|
||||
item.$ = $( '<div class="es-menuView-item"></div>' )
|
||||
|
|
|
@ -27,7 +27,7 @@ ve.ui.Tool.tools = {};
|
|||
/* Methods */
|
||||
|
||||
ve.ui.Tool.prototype.updateState = function () {
|
||||
throw 'Tool.updateState not implemented in this subclass:' + this.constructor;
|
||||
throw new ve.Error( 'Tool.updateState not implemented in this subclass:' + this.constructor );
|
||||
};
|
||||
|
||||
ve.ui.Tool.prototype.clearState = function () {
|
||||
|
|
|
@ -202,13 +202,13 @@ ve.BranchNode.prototype.traverseLeafNodes = function ( callback, from, reverse )
|
|||
if ( !p ) {
|
||||
// n is a root node and we haven't reached this
|
||||
// That means from isn't a descendant of this
|
||||
throw 'from parameter passed to traverseLeafNodes() must be a descendant';
|
||||
throw new ve.Error( 'from parameter passed to traverseLeafNodes() must be a descendant' );
|
||||
}
|
||||
// Find the index of n in p
|
||||
i = p.indexOf( n );
|
||||
if ( i === -1 ) {
|
||||
// This isn't supposed to be possible
|
||||
throw 'Tree corruption detected: node isn\'t in its parent\'s children array';
|
||||
throw new ve.Error( 'Tree corruption detected: node isn\'t in its parent\'s children array' );
|
||||
}
|
||||
indexStack.push( i );
|
||||
// Move up
|
||||
|
|
|
@ -85,14 +85,14 @@ ve.Document.prototype.selectNodes = function ( range, mode ) {
|
|||
|
||||
mode = mode || 'leaves';
|
||||
if ( mode !== 'leaves' && mode !== 'covered' && mode !== 'siblings' ) {
|
||||
throw 'Invalid mode: ' + mode;
|
||||
throw new ve.Error( 'Invalid mode: ' + mode );
|
||||
}
|
||||
|
||||
if ( start < 0 || start > doc.getLength() ) {
|
||||
throw 'Invalid start offset: ' + start;
|
||||
throw new ve.Error( 'Invalid start offset: ' + start );
|
||||
}
|
||||
if ( end < 0 || end > doc.getLength() ) {
|
||||
throw 'Invalid end offset: ' + end;
|
||||
throw new ve.Error( 'Invalid end offset: ' + end );
|
||||
}
|
||||
|
||||
if ( !doc.children || doc.children.length === 0 ) {
|
||||
|
|
38
modules/ve/ve.Error.js
Normal file
38
modules/ve/ve.Error.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* VisualEditor Error class.
|
||||
*
|
||||
* @copyright 2011-2012 VisualEditor Team and others; see AUTHORS.txt
|
||||
* @license The MIT License (MIT); see LICENSE.txt
|
||||
*/
|
||||
|
||||
/**
|
||||
* Error.
|
||||
*
|
||||
* @class
|
||||
* @constructor
|
||||
* @param {String} message Human-readable description of the error
|
||||
* @param {String} fileName The name of the file containing the code that caused the exception
|
||||
* @param {Number} lineNumber The line number of the code that caused the exception
|
||||
*/
|
||||
ve.Error = function () {
|
||||
// Inheritance
|
||||
Error.apply( this, arguments );
|
||||
};
|
||||
|
||||
/* Methods */
|
||||
|
||||
/**
|
||||
* Gets a human-readable description of the error, including the error type.
|
||||
*
|
||||
* @method
|
||||
* @returns {String} Error type and description
|
||||
*/
|
||||
ve.Error.prototype.toString = function () {
|
||||
return this.name + ': ' + this.message;
|
||||
};
|
||||
|
||||
/* Inheritance */
|
||||
|
||||
ve.Error.prototype = new Error();
|
||||
ve.Error.prototype.constructor = ve.Error;
|
||||
ve.Error.prototype.name = 've.Error';
|
|
@ -29,7 +29,7 @@ ve.EventEmitter = function () {
|
|||
*/
|
||||
ve.EventEmitter.prototype.emit = function ( type ) {
|
||||
if ( type === 'error' && !( 'error' in this.events ) ) {
|
||||
throw 'Missing error handler error.';
|
||||
throw new ve.Error( 'Missing error handler error.' );
|
||||
}
|
||||
if ( !( type in this.events ) ) {
|
||||
return false;
|
||||
|
@ -55,7 +55,7 @@ ve.EventEmitter.prototype.emit = function ( type ) {
|
|||
*/
|
||||
ve.EventEmitter.prototype.addListener = function ( type, listener ) {
|
||||
if ( typeof listener !== 'function' ) {
|
||||
throw 'Invalid listener error. Function expected.';
|
||||
throw new ve.Error( 'Invalid listener error. Function expected.' );
|
||||
}
|
||||
this.emit( 'newListener', type, listener );
|
||||
if ( type in this.events ) {
|
||||
|
@ -94,7 +94,7 @@ ve.EventEmitter.prototype.addListenerMethod = function ( target, event, method )
|
|||
if ( typeof target[method] === 'function' ) {
|
||||
target[method].apply( target, Array.prototype.slice.call( arguments, 0 ) );
|
||||
} else {
|
||||
throw 'Listener method error. Target has no such method: ' + method;
|
||||
throw new ve.Error( 'Listener method error. Target has no such method: ' + method );
|
||||
}
|
||||
} );
|
||||
};
|
||||
|
@ -148,7 +148,7 @@ ve.EventEmitter.prototype.once = function ( type, listener ) {
|
|||
*/
|
||||
ve.EventEmitter.prototype.removeListener = function ( type, listener ) {
|
||||
if ( typeof listener !== 'function' ) {
|
||||
throw 'Invalid listener error. Function expected.';
|
||||
throw new ve.Error( 'Invalid listener error. Function expected.' );
|
||||
}
|
||||
if ( !( type in this.events ) || !this.events[type].length ) {
|
||||
return this;
|
||||
|
|
|
@ -36,7 +36,7 @@ ve.Factory = function () {
|
|||
*/
|
||||
ve.Factory.prototype.register = function ( type, constructor ) {
|
||||
if ( typeof constructor !== 'function' ) {
|
||||
throw 'Constructor must be a function, cannot be a ' + typeof constructor;
|
||||
throw new ve.Error( 'Constructor must be a function, cannot be a ' + typeof constructor );
|
||||
}
|
||||
this.registry[type] = constructor;
|
||||
this.emit( 'register', type, constructor );
|
||||
|
@ -63,7 +63,7 @@ ve.Factory.prototype.create = function ( type, a, b ) {
|
|||
if ( type in this.registry ) {
|
||||
return new this.registry[type]( a, b );
|
||||
}
|
||||
throw 'Unknown object type: ' + type;
|
||||
throw new ve.Error( 'Unknown object type: ' + type );
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -43,7 +43,7 @@ ve.Node = function ( type ) {
|
|||
* @throws {Error} if not overridden
|
||||
*/
|
||||
ve.Node.prototype.canHaveChildren = function () {
|
||||
throw 've.Node.canHaveChildren must be overridden in subclass';
|
||||
throw new ve.Error( 've.Node.canHaveChildren must be overridden in subclass' );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -55,7 +55,7 @@ ve.Node.prototype.canHaveChildren = function () {
|
|||
* @throws {Error} if not overridden
|
||||
*/
|
||||
ve.Node.prototype.canHaveGrandchildren = function () {
|
||||
throw 've.Node.canHaveGrandchildren must be overridden in subclass';
|
||||
throw new ve.Error( 've.Node.canHaveGrandchildren must be overridden in subclass' );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -67,7 +67,7 @@ ve.Node.prototype.canHaveGrandchildren = function () {
|
|||
* @throws {Error} if not overridden
|
||||
*/
|
||||
ve.Node.prototype.isWrapped = function () {
|
||||
throw 've.Node.isWrapped must be overridden in subclass';
|
||||
throw new ve.Error( 've.Node.isWrapped must be overridden in subclass' );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -79,7 +79,7 @@ ve.Node.prototype.isWrapped = function () {
|
|||
* @throws {Error} if not overridden
|
||||
*/
|
||||
ve.Node.prototype.getLength = function () {
|
||||
throw 've.Node.getLength must be overridden in subclass';
|
||||
throw new ve.Error( 've.Node.getLength must be overridden in subclass' );
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -91,7 +91,7 @@ ve.Node.prototype.getLength = function () {
|
|||
* @throws {Error} if not overridden
|
||||
*/
|
||||
ve.Node.prototype.getOuterLength = function () {
|
||||
throw 've.Node.getOuterLength must be overridden in subclass';
|
||||
throw new ve.Error( 've.Node.getOuterLength must be overridden in subclass' );
|
||||
};
|
||||
|
||||
/* Methods */
|
||||
|
|
|
@ -45,7 +45,7 @@ ve.Range.newFromTranslatedRange = function ( range, distance ) {
|
|||
ve.Range.newCoveringRange = function ( ranges ) {
|
||||
var minStart, maxEnd, i;
|
||||
if ( !ranges || ranges.length === 0 ) {
|
||||
throw 'newCoveringRange() requires at least one range';
|
||||
throw new ve.Error( 'newCoveringRange() requires at least one range' );
|
||||
}
|
||||
minStart = ranges[0].start;
|
||||
maxEnd = ranges[0].end;
|
||||
|
|
Loading…
Reference in a new issue