JSDuck: Generated code documentation!
See CODING.md for how to run it.
Mistakes fixed:
* Warning: Unknown type function
-> Function
* Warning: Unknown type DOMElement
-> HTMLElement
* Warning: Unknown type DOM Node
-> HTMLElement
* Warning: Unknown type Integer
-> Mixed
* Warning: Unknown type Command
-> ve.Command
* Warning: Unknown type any
-> number
* Warning: Unknown type ve.Transaction
-> ve.dm.Transaction
* Warning: Unknown type ve.dm.AnnotationSet
-> ve.AnnotationSet
* Warning: Unknown type false
-> boolean
* Warning: Unknown type ve.dm.AlienNode
ve.dm doesn't have a generic AlienNode like ve.ce
-> Unknown type ve.dm.AlienInlineNode|ve.dm.AlienBlockNode
* Warning: Unknown type ve.ve.Surface
-> ve.ce.Surface
* ve.example.lookupNode:
-> Last @param should be @return
* ve.dm.Transaction.prototype.pushReplace:
-> @param {Array] should be @param {Array}
* Warning: ve.BranchNode.js:27: {@link ve.Node#hasChildren} links to non-existing member
-> (removed)
* Warning: ve.LeafNode.js:21: {@link ve.Node#hasChildren} links to non-existing member
-> (removed)
Differences fixed:
* Variadic arguments are like @param {Type...} [name]
instead of @param {Type} [name...]
* Convert all file headers from /** to /*! because JSDuck tries
to parse all /** blocks and fails to parse with all sorts of
errors for "Global property", "Unnamed property", and
"Duplicate property".
Find: \/\*\*([^@]+)(@copyright)
Replace: /*!$1$2
* Indented blocks are considered code examples.
A few methods had documentation with numbered lists that were
indented, which have now been updated to not be intended.
* The free-form text descriptions are parsed with Markdown,
which requires lists to be separated from paragraphs by an
empty line.
And we should use `backticks` instead of {braces} for inline
code in text paragraphs.
* Doc blocks for classes and their constructor have to be
in the correct order (@constructor, @param, @return must be
before @class, @abstract, @extends etc.)
* `@extends Class` must not have Class {wrapped}
* @throws must start with a {Type}
* @example means something else. It is used for an inline demo
iframe, not code block. For that simply indent with spaces.
* @member means something else.
Non-function properties are marked with @property, not @member.
* To create a link to a class or member, in most cases the name
is enough to create a link. E.g. Foo, Foo.bar, Foo.bar#quux,
where a hash stands for "instance member", so Foo.bar#quux,
links to Foo.bar.prototype.quux (the is not supported, as
"prototype" is considered an implementation detail, it only
indexes class name and method name).
If the magic linker doesn't work for some case, the
verbose syntax is {@link #target label}.
* @property can't have sub-properties (nested @param and @return
values are supported, only @static @property can't be nested).
We only have one case of this, which can be worked around by
moving those in a new virtual class. The code is unaltered
(only moved down so that it isn't with the scope of the main
@class block). ve.dm.TransactionProcessor.processors.
New:
* @mixins: Classes mixed into the current class.
* @event: Events that can be emitted by a class. These are also
inherited by subclasses. (+ @param, @return and @preventable).
So ve.Node#event-attach is inherited to ve.dm.BreakNode,
just like @method is.
* @singleton: Plain objects such as ve, ve.dm, ve.ce were missing
documentation causing a tree error. Documented those as a
JSDuck singleton, which they but just weren't documented yet.
NB: Members of @singleton don't need @static (if present,
triggers a compiler warning).
* @chainable: Shorthand for "@return this". We were using
"@return {classname}" which is ambiguous (returns the same
instance or another instance?), @chainable is specifically
for "@return this". Creates proper labels in the generated
HTML pages.
Removed:
* @mixin: (not to be confused with @mixins). Not supported by
JSDuck. Every class is standalone anyway. Where needed marked
them @class + @abstract instead.
Change-Id: I6a7c9e8ee8f995731bc205d666167874eb2ebe23
2013-01-04 08:54:17 +00:00
|
|
|
|
/*!
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* VisualEditor ContentEditable Surface class.
|
2012-07-19 21:25:16 +00:00
|
|
|
|
*
|
2012-07-19 00:11:26 +00:00
|
|
|
|
* @copyright 2011-2012 VisualEditor Team and others; see AUTHORS.txt
|
|
|
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
|
|
|
*/
|
2013-01-15 20:15:17 +00:00
|
|
|
|
/*global rangy */
|
2012-07-19 00:11:26 +00:00
|
|
|
|
|
2012-02-07 19:13:19 +00:00
|
|
|
|
/**
|
2012-06-20 01:20:28 +00:00
|
|
|
|
* ContentEditable surface.
|
2012-03-07 19:33:00 +00:00
|
|
|
|
*
|
2012-02-07 19:13:19 +00:00
|
|
|
|
* @class
|
JSDuck: Generated code documentation!
See CODING.md for how to run it.
Mistakes fixed:
* Warning: Unknown type function
-> Function
* Warning: Unknown type DOMElement
-> HTMLElement
* Warning: Unknown type DOM Node
-> HTMLElement
* Warning: Unknown type Integer
-> Mixed
* Warning: Unknown type Command
-> ve.Command
* Warning: Unknown type any
-> number
* Warning: Unknown type ve.Transaction
-> ve.dm.Transaction
* Warning: Unknown type ve.dm.AnnotationSet
-> ve.AnnotationSet
* Warning: Unknown type false
-> boolean
* Warning: Unknown type ve.dm.AlienNode
ve.dm doesn't have a generic AlienNode like ve.ce
-> Unknown type ve.dm.AlienInlineNode|ve.dm.AlienBlockNode
* Warning: Unknown type ve.ve.Surface
-> ve.ce.Surface
* ve.example.lookupNode:
-> Last @param should be @return
* ve.dm.Transaction.prototype.pushReplace:
-> @param {Array] should be @param {Array}
* Warning: ve.BranchNode.js:27: {@link ve.Node#hasChildren} links to non-existing member
-> (removed)
* Warning: ve.LeafNode.js:21: {@link ve.Node#hasChildren} links to non-existing member
-> (removed)
Differences fixed:
* Variadic arguments are like @param {Type...} [name]
instead of @param {Type} [name...]
* Convert all file headers from /** to /*! because JSDuck tries
to parse all /** blocks and fails to parse with all sorts of
errors for "Global property", "Unnamed property", and
"Duplicate property".
Find: \/\*\*([^@]+)(@copyright)
Replace: /*!$1$2
* Indented blocks are considered code examples.
A few methods had documentation with numbered lists that were
indented, which have now been updated to not be intended.
* The free-form text descriptions are parsed with Markdown,
which requires lists to be separated from paragraphs by an
empty line.
And we should use `backticks` instead of {braces} for inline
code in text paragraphs.
* Doc blocks for classes and their constructor have to be
in the correct order (@constructor, @param, @return must be
before @class, @abstract, @extends etc.)
* `@extends Class` must not have Class {wrapped}
* @throws must start with a {Type}
* @example means something else. It is used for an inline demo
iframe, not code block. For that simply indent with spaces.
* @member means something else.
Non-function properties are marked with @property, not @member.
* To create a link to a class or member, in most cases the name
is enough to create a link. E.g. Foo, Foo.bar, Foo.bar#quux,
where a hash stands for "instance member", so Foo.bar#quux,
links to Foo.bar.prototype.quux (the is not supported, as
"prototype" is considered an implementation detail, it only
indexes class name and method name).
If the magic linker doesn't work for some case, the
verbose syntax is {@link #target label}.
* @property can't have sub-properties (nested @param and @return
values are supported, only @static @property can't be nested).
We only have one case of this, which can be worked around by
moving those in a new virtual class. The code is unaltered
(only moved down so that it isn't with the scope of the main
@class block). ve.dm.TransactionProcessor.processors.
New:
* @mixins: Classes mixed into the current class.
* @event: Events that can be emitted by a class. These are also
inherited by subclasses. (+ @param, @return and @preventable).
So ve.Node#event-attach is inherited to ve.dm.BreakNode,
just like @method is.
* @singleton: Plain objects such as ve, ve.dm, ve.ce were missing
documentation causing a tree error. Documented those as a
JSDuck singleton, which they but just weren't documented yet.
NB: Members of @singleton don't need @static (if present,
triggers a compiler warning).
* @chainable: Shorthand for "@return this". We were using
"@return {classname}" which is ambiguous (returns the same
instance or another instance?), @chainable is specifically
for "@return this". Creates proper labels in the generated
HTML pages.
Removed:
* @mixin: (not to be confused with @mixins). Not supported by
JSDuck. Every class is standalone anyway. Where needed marked
them @class + @abstract instead.
Change-Id: I6a7c9e8ee8f995731bc205d666167874eb2ebe23
2013-01-04 08:54:17 +00:00
|
|
|
|
* @extends ve.EventEmitter
|
2012-02-07 19:13:19 +00:00
|
|
|
|
* @constructor
|
2012-09-17 13:30:50 +00:00
|
|
|
|
* @param {jQuery} $container
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* @param {ve.dm.Surface} model Surface model to observe
|
|
|
|
|
* @param {ve.Surface} surface Surface to view
|
2012-02-07 19:13:19 +00:00
|
|
|
|
*/
|
2012-10-24 22:20:41 +00:00
|
|
|
|
ve.ce.Surface = function VeCeSurface( $container, model, surface ) {
|
Object management: Object create/inherit/clone utilities
* For the most common case:
- replace ve.extendClass with ve.inheritClass (chose slightly
different names to detect usage of the old/new one, and I
like 'inherit' better).
- move it up to below the constructor, see doc block for why.
* Cases where more than 2 arguments were passed to
ve.extendClass are handled differently depending on the case.
In case of a longer inheritance tree, the other arguments
could be omitted (like in "ve.ce.FooBar, ve.FooBar,
ve.Bar". ve.ce.FooBar only needs to inherit from ve.FooBar,
because ve.ce.FooBar inherits from ve.Bar).
In the case of where it previously had two mixins with
ve.extendClass(), either one becomes inheritClass and one
a mixin, both to mixinClass().
No visible changes should come from this commit as the
instances still all have the same visible properties in the
end. No more or less than before.
* Misc.:
- Be consistent in calling parent constructors in the
same order as the inheritance.
- Add missing @extends and @param documentation.
- Replace invalid {Integer} type hint with {Number}.
- Consistent doc comments order:
@class, @abstract, @constructor, @extends, @params.
- Fix indentation errors
A fairly common mistake was a superfluous space before the
identifier on the assignment line directly below the
documentation comment.
$ ack "^ [^*]" --js modules/ve
- Typo "Inhertiance" -> "Inheritance".
- Replacing the other confusing comment "Inheritance" (inside
the constructor) with "Parent constructor".
- Add missing @abstract for ve.ui.Tool.
- Corrected ve.FormatDropdownTool to ve.ui.FormatDropdownTool.js
- Add function names to all @constructor functions. Now that we
have inheritance it is important and useful to have these
functions not be anonymous.
Example of debug shot: http://cl.ly/image/1j3c160w3D45
Makes the difference between
< documentNode;
> ve_dm_DocumentNode
...
: ve_dm_BranchNode
...
: ve_dm_Node
...
: ve_dm_Node
...
: Object
...
without names (current situation):
< documentNode;
> Object
...
: Object
...
: Object
...
: Object
...
: Object
...
though before this commit, it really looks like this
(flattened since ve.extendClass really did a mixin):
< documentNode;
> Object
...
...
...
Pattern in Sublime (case-sensitive) to find nameless
constructor functions:
"^ve\..*\.([A-Z])([^\.]+) = function \("
Change-Id: Iab763954fb8cf375900d7a9a92dec1c755d5407e
2012-09-05 06:07:47 +00:00
|
|
|
|
// Parent constructor
|
2012-02-07 19:13:19 +00:00
|
|
|
|
ve.EventEmitter.call( this );
|
|
|
|
|
|
|
|
|
|
// Properties
|
2012-10-24 22:20:41 +00:00
|
|
|
|
this.surface = surface;
|
2012-10-11 18:31:28 +00:00
|
|
|
|
this.inIme = false;
|
2012-02-07 19:13:19 +00:00
|
|
|
|
this.model = model;
|
2012-10-05 00:08:26 +00:00
|
|
|
|
this.documentView = new ve.ce.Document( model.getDocument(), this );
|
|
|
|
|
this.surfaceObserver = new ve.ce.SurfaceObserver( this.documentView );
|
2012-06-20 01:20:28 +00:00
|
|
|
|
this.selectionTimeout = null;
|
|
|
|
|
this.$ = $container;
|
|
|
|
|
this.$document = $( document );
|
2012-03-01 22:27:23 +00:00
|
|
|
|
this.clipboard = {};
|
2012-12-05 23:05:49 +00:00
|
|
|
|
this.renderingEnabled = true;
|
2012-11-02 22:45:26 +00:00
|
|
|
|
this.dragging = false;
|
|
|
|
|
this.selecting = false;
|
2013-01-16 21:06:05 +00:00
|
|
|
|
this.$phantoms = $( '<div>' );
|
|
|
|
|
this.$pasteTarget = $( '<div>' );
|
2012-12-07 22:58:29 +00:00
|
|
|
|
this.pasting = false;
|
2012-12-21 18:51:20 +00:00
|
|
|
|
this.clickHistory = [];
|
2012-02-07 19:13:19 +00:00
|
|
|
|
|
2012-06-20 01:20:28 +00:00
|
|
|
|
// Events
|
2012-10-05 00:08:26 +00:00
|
|
|
|
this.surfaceObserver.addListenerMethods(
|
|
|
|
|
this, { 'contentChange': 'onContentChange', 'selectionChange': 'onSelectionChange' }
|
|
|
|
|
);
|
2012-10-01 20:05:06 +00:00
|
|
|
|
this.model.addListenerMethods(
|
|
|
|
|
this, { 'change': 'onChange', 'lock': 'onLock', 'unlock': 'onUnlock' }
|
|
|
|
|
);
|
2012-10-05 00:08:26 +00:00
|
|
|
|
this.documentView.getDocumentNode().$.on( {
|
|
|
|
|
'focus': ve.bind( this.documentOnFocus, this ),
|
|
|
|
|
'blur': ve.bind( this.documentOnBlur, this )
|
|
|
|
|
} );
|
2012-03-16 22:01:09 +00:00
|
|
|
|
this.$.on( {
|
2012-08-11 08:14:56 +00:00
|
|
|
|
'cut': ve.bind( this.onCut, this ),
|
|
|
|
|
'copy': ve.bind( this.onCopy, this ),
|
|
|
|
|
'paste': ve.bind( this.onPaste, this ),
|
2013-01-16 21:51:05 +00:00
|
|
|
|
'dragover drop': ve.bind( this.onDragoverDrop, this ),
|
2012-03-16 22:01:09 +00:00
|
|
|
|
} );
|
2012-06-20 01:20:28 +00:00
|
|
|
|
if ( $.browser.msie ) {
|
2012-08-11 08:14:56 +00:00
|
|
|
|
this.$.on( 'beforepaste', ve.bind( this.onPaste, this ) );
|
2012-06-20 01:20:28 +00:00
|
|
|
|
}
|
2012-02-13 22:45:18 +00:00
|
|
|
|
|
2012-03-01 01:28:39 +00:00
|
|
|
|
// Initialization
|
2012-06-20 01:20:28 +00:00
|
|
|
|
rangy.init();
|
2013-01-16 21:51:05 +00:00
|
|
|
|
this.cleanLocalStorage();
|
2013-01-16 21:06:05 +00:00
|
|
|
|
this.$phantoms.addClass( 've-ce-phantoms' );
|
|
|
|
|
this.$pasteTarget.addClass( 've-ce-surface-paste' ).prop( 'contenteditable', true );
|
|
|
|
|
this.$.append( this.documentView.getDocumentNode().$, this.$phantoms, this.$pasteTarget );
|
2012-03-01 01:28:39 +00:00
|
|
|
|
};
|
2012-02-08 06:28:38 +00:00
|
|
|
|
|
Object management: Object create/inherit/clone utilities
* For the most common case:
- replace ve.extendClass with ve.inheritClass (chose slightly
different names to detect usage of the old/new one, and I
like 'inherit' better).
- move it up to below the constructor, see doc block for why.
* Cases where more than 2 arguments were passed to
ve.extendClass are handled differently depending on the case.
In case of a longer inheritance tree, the other arguments
could be omitted (like in "ve.ce.FooBar, ve.FooBar,
ve.Bar". ve.ce.FooBar only needs to inherit from ve.FooBar,
because ve.ce.FooBar inherits from ve.Bar).
In the case of where it previously had two mixins with
ve.extendClass(), either one becomes inheritClass and one
a mixin, both to mixinClass().
No visible changes should come from this commit as the
instances still all have the same visible properties in the
end. No more or less than before.
* Misc.:
- Be consistent in calling parent constructors in the
same order as the inheritance.
- Add missing @extends and @param documentation.
- Replace invalid {Integer} type hint with {Number}.
- Consistent doc comments order:
@class, @abstract, @constructor, @extends, @params.
- Fix indentation errors
A fairly common mistake was a superfluous space before the
identifier on the assignment line directly below the
documentation comment.
$ ack "^ [^*]" --js modules/ve
- Typo "Inhertiance" -> "Inheritance".
- Replacing the other confusing comment "Inheritance" (inside
the constructor) with "Parent constructor".
- Add missing @abstract for ve.ui.Tool.
- Corrected ve.FormatDropdownTool to ve.ui.FormatDropdownTool.js
- Add function names to all @constructor functions. Now that we
have inheritance it is important and useful to have these
functions not be anonymous.
Example of debug shot: http://cl.ly/image/1j3c160w3D45
Makes the difference between
< documentNode;
> ve_dm_DocumentNode
...
: ve_dm_BranchNode
...
: ve_dm_Node
...
: ve_dm_Node
...
: Object
...
without names (current situation):
< documentNode;
> Object
...
: Object
...
: Object
...
: Object
...
: Object
...
though before this commit, it really looks like this
(flattened since ve.extendClass really did a mixin):
< documentNode;
> Object
...
...
...
Pattern in Sublime (case-sensitive) to find nameless
constructor functions:
"^ve\..*\.([A-Z])([^\.]+) = function \("
Change-Id: Iab763954fb8cf375900d7a9a92dec1c755d5407e
2012-09-05 06:07:47 +00:00
|
|
|
|
/* Inheritance */
|
|
|
|
|
|
|
|
|
|
ve.inheritClass( ve.ce.Surface, ve.EventEmitter );
|
|
|
|
|
|
2013-01-15 23:38:49 +00:00
|
|
|
|
/* Static Properties */
|
2012-11-14 20:06:16 +00:00
|
|
|
|
|
2013-01-15 23:38:49 +00:00
|
|
|
|
/**
|
|
|
|
|
* @static
|
|
|
|
|
* @property
|
|
|
|
|
* @inheritable
|
|
|
|
|
*/
|
2012-11-14 20:06:16 +00:00
|
|
|
|
ve.ce.Surface.static = {};
|
|
|
|
|
|
2013-01-15 23:38:49 +00:00
|
|
|
|
/**
|
|
|
|
|
* Phantom element template.
|
|
|
|
|
*
|
|
|
|
|
* @static
|
|
|
|
|
* @property
|
|
|
|
|
* @type {jQuery}
|
|
|
|
|
*/
|
2013-01-16 21:06:05 +00:00
|
|
|
|
ve.ce.Surface.static.$phantomTemplate = $( '<div>' )
|
|
|
|
|
.addClass( 've-ce-surface-phantom' )
|
|
|
|
|
.attr( {
|
|
|
|
|
'title': ve.msg ( 'visualeditor-aliennode-tooltip' ),
|
|
|
|
|
'draggable': false
|
|
|
|
|
} );
|
2012-11-14 20:06:16 +00:00
|
|
|
|
|
2013-01-15 23:38:49 +00:00
|
|
|
|
/**
|
|
|
|
|
* Pattern matching "normal" characters which we can let the browser handle natively.
|
|
|
|
|
*
|
|
|
|
|
* @static
|
|
|
|
|
* @property
|
|
|
|
|
* @type {RegExp}
|
|
|
|
|
*/
|
2013-01-16 21:06:05 +00:00
|
|
|
|
ve.ce.Surface.static.textPattern = new RegExp(
|
2013-01-15 23:38:49 +00:00
|
|
|
|
'[a-zA-Z\\-_’\'‘ÆÐƎƏƐƔIJŊŒẞÞǷȜæðǝəɛɣijŋœĸſßþƿȝĄƁÇĐƊĘĦĮƘŁØƠŞȘŢȚŦŲƯY̨Ƴąɓçđɗęħįƙłøơşșţțŧųưy̨ƴÁÀÂÄ' +
|
|
|
|
|
'ǍĂĀÃÅǺĄÆǼǢƁĆĊĈČÇĎḌĐƊÐÉÈĖÊËĚĔĒĘẸƎƏƐĠĜǦĞĢƔáàâäǎăāãåǻąæǽǣɓćċĉčçďḍđɗðéèėêëěĕēęẹǝəɛġĝǧğģɣĤḤĦIÍÌİ' +
|
|
|
|
|
'ÎÏǏĬĪĨĮỊIJĴĶƘĹĻŁĽĿʼNŃN̈ŇÑŅŊÓÒÔÖǑŎŌÕŐỌØǾƠŒĥḥħıíìiîïǐĭīĩįịijĵķƙĸĺļłľŀʼnńn̈ňñņŋóòôöǒŏōõőọøǿơœŔŘŖŚŜ' +
|
|
|
|
|
'ŠŞȘṢẞŤŢṬŦÞÚÙÛÜǓŬŪŨŰŮŲỤƯẂẀŴẄǷÝỲŶŸȲỸƳŹŻŽẒŕřŗſśŝšşșṣßťţṭŧþúùûüǔŭūũűůųụưẃẁŵẅƿýỳŷÿȳỹƴźżžẓ]',
|
|
|
|
|
'g'
|
|
|
|
|
);
|
|
|
|
|
|
2012-03-01 01:28:39 +00:00
|
|
|
|
/* Methods */
|
2012-02-08 02:12:21 +00:00
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
/*! Initialization */
|
|
|
|
|
|
2012-12-03 21:45:38 +00:00
|
|
|
|
/**
|
2013-01-16 21:51:05 +00:00
|
|
|
|
* Enable editing.
|
2012-12-03 21:45:38 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
*/
|
2013-01-16 21:51:05 +00:00
|
|
|
|
ve.ce.Surface.prototype.enable = function () {
|
|
|
|
|
this.documentView.getDocumentNode().enable();
|
2012-12-03 21:45:38 +00:00
|
|
|
|
};
|
|
|
|
|
|
2012-12-12 00:28:39 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Disable editing.
|
2012-12-12 00:28:39 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
*/
|
|
|
|
|
ve.ce.Surface.prototype.disable = function () {
|
|
|
|
|
this.documentView.getDocumentNode().disable();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
2013-01-16 21:51:05 +00:00
|
|
|
|
* Destroy the surface, removing all DOM elements.
|
2012-12-12 00:28:39 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
2013-01-16 21:51:05 +00:00
|
|
|
|
* @returns {ve.ui.Context} Context user interface
|
2012-12-12 00:28:39 +00:00
|
|
|
|
*/
|
2013-01-16 21:51:05 +00:00
|
|
|
|
ve.ce.Surface.prototype.destroy = function () {
|
|
|
|
|
this.$.remove();
|
2012-10-11 18:31:28 +00:00
|
|
|
|
};
|
|
|
|
|
|
2012-10-04 20:59:29 +00:00
|
|
|
|
/**
|
2013-01-16 21:51:05 +00:00
|
|
|
|
* Clean copy and paste data that's at least a day old in localStorage.
|
2012-10-04 20:59:29 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
*/
|
2013-01-16 21:51:05 +00:00
|
|
|
|
ve.ce.Surface.prototype.cleanLocalStorage = function () {
|
|
|
|
|
var i, len, key, time, now,
|
|
|
|
|
keysToRemove = [];
|
2012-10-04 20:59:29 +00:00
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
for ( i = 0, len = localStorage.length; i < len; i++ ) {
|
|
|
|
|
key = localStorage.key( i );
|
2012-12-04 00:34:27 +00:00
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
if ( key.indexOf( 've-' ) !== 0 ) {
|
|
|
|
|
return false;
|
2012-10-04 20:59:29 +00:00
|
|
|
|
}
|
2012-12-04 00:34:27 +00:00
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
time = JSON.parse( localStorage.getItem( key ) ).time;
|
|
|
|
|
now = new Date().getTime();
|
2012-12-04 00:34:27 +00:00
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
// Offset: 24 days (in miliseconds)
|
|
|
|
|
if ( now - time > ( 24 * 3600 * 1000 ) ) {
|
|
|
|
|
// Don't remove keys while iterating. Store them for later removal.
|
|
|
|
|
keysToRemove.push( key );
|
|
|
|
|
}
|
2012-12-04 00:34:27 +00:00
|
|
|
|
}
|
2012-10-04 20:59:29 +00:00
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
$.each( keysToRemove, function ( i, val ) {
|
|
|
|
|
localStorage.removeItem( val );
|
|
|
|
|
} );
|
2012-10-01 20:05:06 +00:00
|
|
|
|
};
|
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
/*! Native Browser Events */
|
2012-10-01 20:05:06 +00:00
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Handle document focus events.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.ce.Surface.prototype.documentOnFocus = function () {
|
2012-06-22 22:39:43 +00:00
|
|
|
|
this.$document.off( '.ve-ce-Surface' );
|
2012-06-20 01:20:28 +00:00
|
|
|
|
this.$document.on( {
|
2013-01-15 23:38:49 +00:00
|
|
|
|
'keydown.ve-ce-Surface': ve.bind( this.onDocumentKeyDown, this ),
|
|
|
|
|
'keyup.ve-ce-Surface': ve.bind( this.onDocumentKeyUp, this ),
|
|
|
|
|
'keypress.ve-ce-Surface': ve.bind( this.onDocumentKeyPress, this ),
|
|
|
|
|
'mousedown.ve-ce-Surface': ve.bind( this.onDocumentMouseDown, this ),
|
|
|
|
|
'mouseup.ve-ce-Surface': ve.bind( this.onDocumentMouseUp, this ),
|
|
|
|
|
'mousemove.ve-ce-Surface': ve.bind( this.onDocumentMouseMove, this ),
|
|
|
|
|
'compositionstart.ve-ce-Surface': ve.bind( this.onDocumentCompositionStart, this ),
|
|
|
|
|
'compositionend.ve-ce-Surface': ve.bind( this.onDocumentCompositionEnd, this ),
|
2012-06-20 01:20:28 +00:00
|
|
|
|
} );
|
2012-10-04 20:59:29 +00:00
|
|
|
|
this.surfaceObserver.start( true );
|
2012-04-26 21:49:12 +00:00
|
|
|
|
};
|
|
|
|
|
|
2013-01-15 23:38:49 +00:00
|
|
|
|
/**
|
2013-01-16 21:51:05 +00:00
|
|
|
|
* Handle document blur events.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.ce.Surface.prototype.documentOnBlur = function () {
|
2012-06-20 01:20:28 +00:00
|
|
|
|
this.$document.off( '.ve-ce-Surface' );
|
2012-10-04 20:59:29 +00:00
|
|
|
|
this.surfaceObserver.stop( true );
|
2012-04-06 15:10:30 +00:00
|
|
|
|
};
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Handle document mouse down events.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
2013-01-15 23:38:49 +00:00
|
|
|
|
ve.ce.Surface.prototype.onDocumentMouseDown = function ( e ) {
|
2012-11-02 22:45:26 +00:00
|
|
|
|
// Remember the mouse is down
|
|
|
|
|
this.dragging = true;
|
|
|
|
|
|
2012-10-04 20:59:29 +00:00
|
|
|
|
// Old code to figure out if user clicked inside the document or not - leave it here for now
|
2012-10-05 22:17:39 +00:00
|
|
|
|
// $( e.target ).closest( '.ve-ce-documentNode' ).length === 0
|
2012-04-27 22:26:38 +00:00
|
|
|
|
|
2012-10-04 20:59:29 +00:00
|
|
|
|
if ( e.which === 1 ) {
|
|
|
|
|
this.surfaceObserver.stop( true );
|
2012-04-27 22:26:38 +00:00
|
|
|
|
}
|
2012-06-20 01:20:28 +00:00
|
|
|
|
|
|
|
|
|
// Block / prevent triple click
|
2012-12-21 18:51:20 +00:00
|
|
|
|
if ( this.getClickCount( e.originalEvent ) > 2 ) {
|
2012-06-20 01:20:28 +00:00
|
|
|
|
e.preventDefault();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2012-10-04 20:59:29 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Handle document mouse up events.
|
2012-10-04 20:59:29 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
2013-01-15 23:38:49 +00:00
|
|
|
|
ve.ce.Surface.prototype.onDocumentMouseUp = function ( e ) {
|
2012-10-04 20:59:29 +00:00
|
|
|
|
this.surfaceObserver.start();
|
2012-11-02 22:45:26 +00:00
|
|
|
|
if ( !e.shiftKey && this.selecting ) {
|
|
|
|
|
this.emit( 'selectionEnd' );
|
|
|
|
|
this.selecting = false;
|
|
|
|
|
}
|
|
|
|
|
this.dragging = false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Handle document mouse move events.
|
2012-11-02 22:45:26 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
2013-01-15 23:38:49 +00:00
|
|
|
|
ve.ce.Surface.prototype.onDocumentMouseMove = function () {
|
2012-11-02 22:45:26 +00:00
|
|
|
|
// Detect beginning of selection by moving mouse while dragging
|
|
|
|
|
if ( this.dragging && !this.selecting ) {
|
|
|
|
|
this.selecting = true;
|
|
|
|
|
this.emit( 'selectionStart' );
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
2013-01-16 21:51:05 +00:00
|
|
|
|
* Handle document dragover and drop events.
|
|
|
|
|
*
|
|
|
|
|
* Prevents native dragging and dropping of content.
|
2012-11-02 22:45:26 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
2013-01-16 21:51:05 +00:00
|
|
|
|
ve.ce.Surface.prototype.onDocumentDragoverDrop = function ( e ) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
return false;
|
2012-10-04 20:59:29 +00:00
|
|
|
|
};
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Handle document key down events.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
2013-01-15 23:38:49 +00:00
|
|
|
|
ve.ce.Surface.prototype.onDocumentKeyDown = function ( e ) {
|
2012-10-11 18:31:28 +00:00
|
|
|
|
if ( this.inIme === true ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2012-10-14 19:28:06 +00:00
|
|
|
|
if ( e.which === 229 && $.browser.msie === true ) {
|
|
|
|
|
this.inIme = true;
|
|
|
|
|
this.handleInsertion();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-02 22:45:26 +00:00
|
|
|
|
// Detect start of selecting using shift+arrow keys
|
|
|
|
|
if ( !this.dragging && !this.selecting && e.shiftKey && e.keyCode >= 37 && e.keyCode <= 40 ) {
|
|
|
|
|
this.selecting = true;
|
|
|
|
|
this.emit( 'selectionStart' );
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-20 01:20:28 +00:00
|
|
|
|
switch ( e.keyCode ) {
|
|
|
|
|
// Left arrow
|
|
|
|
|
case 37:
|
2012-11-28 01:29:09 +00:00
|
|
|
|
if ( this.adjustCursor( -1 ) ) {
|
2012-06-21 05:24:12 +00:00
|
|
|
|
e.preventDefault();
|
|
|
|
|
}
|
2012-06-20 01:20:28 +00:00
|
|
|
|
break;
|
|
|
|
|
// Right arrow
|
|
|
|
|
case 39:
|
2012-11-28 01:29:09 +00:00
|
|
|
|
if ( this.adjustCursor( 1 ) ) {
|
2012-06-21 05:24:12 +00:00
|
|
|
|
e.preventDefault();
|
|
|
|
|
}
|
2012-06-20 01:20:28 +00:00
|
|
|
|
break;
|
|
|
|
|
// Enter
|
|
|
|
|
case 13:
|
|
|
|
|
e.preventDefault();
|
2012-06-22 22:05:35 +00:00
|
|
|
|
this.handleEnter( e );
|
2012-06-20 01:20:28 +00:00
|
|
|
|
break;
|
|
|
|
|
// Backspace
|
|
|
|
|
case 8:
|
2012-08-17 23:28:29 +00:00
|
|
|
|
this.handleDelete( e, true );
|
2012-11-07 00:09:38 +00:00
|
|
|
|
this.surfaceObserver.stop( true );
|
2012-10-18 20:22:20 +00:00
|
|
|
|
this.surfaceObserver.start();
|
2012-06-20 01:20:28 +00:00
|
|
|
|
break;
|
|
|
|
|
// Delete
|
|
|
|
|
case 46:
|
2012-08-17 23:28:29 +00:00
|
|
|
|
this.handleDelete( e, false );
|
2012-11-07 00:09:38 +00:00
|
|
|
|
this.surfaceObserver.stop( true );
|
2012-10-18 20:22:20 +00:00
|
|
|
|
this.surfaceObserver.start();
|
2012-06-20 01:20:28 +00:00
|
|
|
|
break;
|
2012-11-07 00:09:38 +00:00
|
|
|
|
default:
|
|
|
|
|
// Execute key command if available
|
2012-11-21 21:22:29 +00:00
|
|
|
|
this.surfaceObserver.stop( true );
|
2012-11-07 00:09:38 +00:00
|
|
|
|
if ( this.surface.execute( new ve.Command( e ) ) ) {
|
2012-06-21 18:07:18 +00:00
|
|
|
|
e.preventDefault();
|
2012-06-26 00:45:43 +00:00
|
|
|
|
}
|
2012-11-21 21:22:29 +00:00
|
|
|
|
this.surfaceObserver.start();
|
2012-06-20 01:20:28 +00:00
|
|
|
|
}
|
2012-04-27 22:26:38 +00:00
|
|
|
|
};
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-16 21:51:05 +00:00
|
|
|
|
* Handle document key press events.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
2013-01-16 21:51:05 +00:00
|
|
|
|
ve.ce.Surface.prototype.onDocumentKeyPress = function ( e ) {
|
|
|
|
|
if ( ve.ce.Surface.isShortcutKey( e ) || e.which === 13 || e.which === 8 || e.which === 0 ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.handleInsertion();
|
|
|
|
|
setTimeout( ve.bind( function () {
|
|
|
|
|
this.surfaceObserver.start();
|
|
|
|
|
}, this ), 0 );
|
|
|
|
|
};
|
2012-04-06 15:10:30 +00:00
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
/**
|
|
|
|
|
* Handle document key up events.
|
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
|
|
|
|
ve.ce.Surface.prototype.onDocumentKeyUp = function ( e ) {
|
|
|
|
|
// Detect end of selecting by letting go of shift
|
|
|
|
|
if ( !this.dragging && this.selecting && e.keyCode === 16 ) {
|
|
|
|
|
this.selecting = false;
|
|
|
|
|
this.emit( 'selectionEnd' );
|
2012-06-29 00:26:10 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
2012-06-20 01:20:28 +00:00
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Handle cut events.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.ce.Surface.prototype.onCut = function ( e ) {
|
2012-06-29 00:26:10 +00:00
|
|
|
|
var surface = this;
|
2012-06-27 16:29:58 +00:00
|
|
|
|
|
2012-10-05 21:54:32 +00:00
|
|
|
|
this.surfaceObserver.stop();
|
2012-06-27 16:29:58 +00:00
|
|
|
|
|
2012-06-29 00:26:10 +00:00
|
|
|
|
this.onCopy( e );
|
2012-06-27 16:29:58 +00:00
|
|
|
|
|
Kranitor #3: jQuerlyfornication ft. The Cascaders
* Classicifation (JS)
Use addClass instead of attr( 'class' ) whenever possible.
addClass will manipulate the properties directly instead of
(re-)setting an attribute which (most) browsers then sync
with the properties.
Difference between:
elem.className
and
elem.setAttribute( 'class', .. );
Just like .checked, .value, .disabled and other interactive
properties, the HTML attributes should only be used for initial
values from the html document. When in javascript, only set
properties. Attributes are either ignored or slow.
* Styling (JS)
Use .css() instead of attr( 'style' ).
Again, setting properties instead of attributes is much faster,
easier and safer. And this way it takes care of cross-browser
issues where applicable, and less prone to error due to dealing
with key-value pairs instead of css strings.
Difference between:
elem.style.foo = 'bar';
and
elem.setAttribute( 'style', 'foo: bar;' );
* Finding (JS)
Use .find( 'foo bar' ) instead of .find( 'foo' ).find( 'bar' ).
It is CSS!
* Vendor prefixes (CSS)
It is important to always list newer (standards-compliant) versions
*after* the older/prefixed variants.
See also http://css-tricks.com/ordering-css3-properties/
So the following three:
-webkit-gradient (Chrome, Safari 4)
-webkit-linear-gradient (Chrome 10, Safari 5+)
linear-gradient (CSS3 standard)
... must be in that order.
Notes:
- "-moz-opacity" is from before Mozilla 1.7 (Firefox < 0.8)
Has not been renamed to "opacity" since Firefox 0.9.
- Removed redundant "-moz-opacity"
- Added "filter: alpha(opacity=**);" where missing
- Fixed order of css3 properties (old to new)
- Add standardized css3 versions where missing
(some 'border-radius' groups didn't have the non-prefixed version)
- Spacing
- @embed
- Shorten hex colors where possible (#dddddd -> #ddd)
$ ack '#([0-9a-f])\1{5}' --css
$ ack '#([0-9a-f])\1{2};' --css
Change-Id: I386fedb9058c2567fd0af5f55291e9859a53329d
2012-07-28 19:15:23 +00:00
|
|
|
|
setTimeout( function () {
|
2012-10-15 18:45:50 +00:00
|
|
|
|
var selection,
|
2012-06-29 00:26:10 +00:00
|
|
|
|
tx;
|
2012-06-27 16:29:58 +00:00
|
|
|
|
|
2012-06-29 00:26:10 +00:00
|
|
|
|
// We don't like how browsers cut, so let's undo it and do it ourselves.
|
|
|
|
|
document.execCommand( 'undo', false, false );
|
2012-06-20 01:20:28 +00:00
|
|
|
|
|
2012-06-29 00:26:10 +00:00
|
|
|
|
selection = surface.model.getSelection();
|
|
|
|
|
|
|
|
|
|
// Transact
|
|
|
|
|
tx = ve.dm.Transaction.newFromRemoval( surface.documentView.model, selection );
|
|
|
|
|
surface.model.change( tx, new ve.Range( selection.start ) );
|
|
|
|
|
|
2012-10-05 21:54:32 +00:00
|
|
|
|
surface.surfaceObserver.clear();
|
|
|
|
|
surface.surfaceObserver.start();
|
2012-06-29 00:26:10 +00:00
|
|
|
|
}, 1 );
|
2012-06-20 01:20:28 +00:00
|
|
|
|
};
|
2012-04-06 15:10:30 +00:00
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
/**
|
|
|
|
|
* Handle copy events.
|
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
|
|
|
|
ve.ce.Surface.prototype.onCopy = function () {
|
|
|
|
|
var sel = rangy.getSelection(),
|
|
|
|
|
$frag = $( sel.getRangeAt(0).cloneContents() ),
|
|
|
|
|
slice = this.documentView.model.getSlice( this.model.getSelection() ),
|
|
|
|
|
key = '';
|
|
|
|
|
|
|
|
|
|
// Create key from text and element names
|
|
|
|
|
$frag.contents().each( function () {
|
|
|
|
|
key += this.textContent || this.nodeName;
|
|
|
|
|
} );
|
|
|
|
|
key = 've-' + key.replace( /\s/gm, '' );
|
|
|
|
|
|
|
|
|
|
// Set clipboard and localStorage
|
|
|
|
|
this.clipboard[key] = slice;
|
|
|
|
|
try {
|
|
|
|
|
localStorage.setItem(
|
|
|
|
|
key,
|
|
|
|
|
JSON.stringify( {
|
|
|
|
|
'time': new Date().getTime(),
|
|
|
|
|
'data': slice
|
|
|
|
|
} )
|
|
|
|
|
);
|
|
|
|
|
} catch ( e ) {
|
|
|
|
|
// Silently ignore
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Handle paste events.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
2012-12-07 22:58:29 +00:00
|
|
|
|
ve.ce.Surface.prototype.onPaste = function ( e ) {
|
|
|
|
|
// Prevent pasting until after we are done
|
|
|
|
|
if ( this.pasting ) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
this.pasting = true;
|
|
|
|
|
|
|
|
|
|
var tx, scrollTop,
|
|
|
|
|
$window = $( window ),
|
2012-09-17 13:30:50 +00:00
|
|
|
|
view = this,
|
|
|
|
|
selection = this.model.getSelection();
|
2012-06-27 16:29:58 +00:00
|
|
|
|
|
2012-10-05 21:54:32 +00:00
|
|
|
|
this.surfaceObserver.stop();
|
2012-06-27 16:29:58 +00:00
|
|
|
|
|
2012-06-20 01:20:28 +00:00
|
|
|
|
// Pasting into a range? Remove first.
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
if ( !rangy.getSelection().isCollapsed ) {
|
2012-07-19 03:40:49 +00:00
|
|
|
|
tx = ve.dm.Transaction.newFromRemoval( view.documentView.model, selection );
|
|
|
|
|
view.model.change( tx );
|
2012-06-20 01:20:28 +00:00
|
|
|
|
}
|
2012-06-27 16:29:58 +00:00
|
|
|
|
|
2012-12-07 22:58:29 +00:00
|
|
|
|
// Save scroll position and change focus to "offscreen" paste target
|
|
|
|
|
scrollTop = $window.scrollTop();
|
2013-01-16 21:06:05 +00:00
|
|
|
|
this.$pasteTarget.html( '' ).show().focus();
|
2012-04-06 15:10:30 +00:00
|
|
|
|
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
setTimeout( function () {
|
2012-11-20 01:05:34 +00:00
|
|
|
|
var pasteText, pasteData, tx,
|
|
|
|
|
key = '';
|
2012-06-27 16:29:58 +00:00
|
|
|
|
|
2012-06-20 01:20:28 +00:00
|
|
|
|
// Create key from text and element names
|
2013-01-16 21:06:05 +00:00
|
|
|
|
view.$pasteTarget.hide().contents().each( function () {
|
2012-06-20 01:20:28 +00:00
|
|
|
|
key += this.textContent || this.nodeName;
|
2012-06-29 00:26:10 +00:00
|
|
|
|
} );
|
|
|
|
|
key = 've-' + key.replace( /\s/gm, '' );
|
2012-06-20 01:20:28 +00:00
|
|
|
|
|
2013-01-15 23:38:49 +00:00
|
|
|
|
// Get linear model from clipboard, localStorage or create array from unknown pasted content
|
2012-06-29 00:26:10 +00:00
|
|
|
|
if ( view.clipboard[key] ) {
|
|
|
|
|
pasteData = view.clipboard[key];
|
2012-10-18 22:59:55 +00:00
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
else if ( localStorage.getItem( key ) ) {
|
|
|
|
|
pasteData = localStorage.getItem( key ).data;
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
else {
|
2013-01-16 21:06:05 +00:00
|
|
|
|
pasteText = view.$pasteTarget.text().replace( /\n/gm, '');
|
2012-12-07 01:23:03 +00:00
|
|
|
|
pasteData = new ve.dm.DocumentSlice( pasteText.split( '' ) );
|
2012-06-29 00:26:10 +00:00
|
|
|
|
}
|
2012-06-20 01:20:28 +00:00
|
|
|
|
|
|
|
|
|
// Transact
|
2012-12-07 01:23:03 +00:00
|
|
|
|
try {
|
|
|
|
|
tx = ve.dm.Transaction.newFromInsertion(
|
|
|
|
|
view.documentView.model,
|
|
|
|
|
selection.start,
|
|
|
|
|
pasteData.getData()
|
|
|
|
|
);
|
|
|
|
|
} catch ( e ) {
|
|
|
|
|
tx = ve.dm.Transaction.newFromInsertion(
|
|
|
|
|
view.documentView.model,
|
|
|
|
|
selection.start,
|
|
|
|
|
pasteData.getBalancedData()
|
|
|
|
|
);
|
|
|
|
|
}
|
2012-12-07 22:58:29 +00:00
|
|
|
|
|
|
|
|
|
// Restore focus and scroll position
|
2012-07-19 03:40:49 +00:00
|
|
|
|
view.documentView.documentNode.$.focus();
|
2012-12-07 22:58:29 +00:00
|
|
|
|
$window.scrollTop( scrollTop );
|
|
|
|
|
|
2012-12-07 22:49:11 +00:00
|
|
|
|
view.model.change( tx, tx.translateRange( selection ).truncate( 0 ) );
|
2012-12-07 22:58:29 +00:00
|
|
|
|
|
|
|
|
|
// Allow pasting again
|
|
|
|
|
view.pasting = false;
|
2012-10-18 22:59:55 +00:00
|
|
|
|
}, 0 );
|
2012-06-20 01:20:28 +00:00
|
|
|
|
};
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-16 21:51:05 +00:00
|
|
|
|
* Handle document composition start events.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
2013-01-16 21:51:05 +00:00
|
|
|
|
ve.ce.Surface.prototype.onDocumentCompositionStart = function () {
|
|
|
|
|
if ( $.browser.msie === true ) {
|
2012-06-21 06:21:53 +00:00
|
|
|
|
return;
|
|
|
|
|
}
|
2013-01-16 21:51:05 +00:00
|
|
|
|
this.inIme = true;
|
2012-10-11 18:31:28 +00:00
|
|
|
|
this.handleInsertion();
|
2012-04-06 15:10:30 +00:00
|
|
|
|
};
|
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
/**
|
|
|
|
|
* Handle document composition end events.
|
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
|
|
|
|
ve.ce.Surface.prototype.onDocumentCompositionEnd = function () {
|
|
|
|
|
this.inIme = false;
|
|
|
|
|
this.surfaceObserver.start();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*! Custom Events */
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Handle change events.
|
|
|
|
|
*
|
|
|
|
|
* @see ve.dm.Surface.prototype.change.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {ve.dm.Transaction|null} transaction
|
|
|
|
|
* @param {ve.Range|undefined} selection
|
|
|
|
|
*/
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.ce.Surface.prototype.onChange = function ( transaction, selection ) {
|
2012-12-05 23:05:49 +00:00
|
|
|
|
if ( selection && this.isRenderingEnabled() ) {
|
2012-10-24 22:20:41 +00:00
|
|
|
|
this.showSelection( selection );
|
2012-03-07 19:37:17 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
/**
|
|
|
|
|
* Handle selection change events.
|
|
|
|
|
*
|
|
|
|
|
* @see ve.ce.SurfaceObserver.prototype.poll
|
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {ve.Range} oldRange
|
|
|
|
|
* @param {ve.Range} newRange
|
|
|
|
|
*/
|
|
|
|
|
ve.ce.Surface.prototype.onSelectionChange = function ( oldRange, newRange ) {
|
|
|
|
|
this.disableRendering();
|
|
|
|
|
this.model.change( null, newRange );
|
|
|
|
|
this.enableRendering();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle content change events.
|
|
|
|
|
*
|
|
|
|
|
* @see ve.ce.SurfaceObserver.prototype.poll
|
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {HTMLElement} node DOM node the change occured in
|
|
|
|
|
* @param {Object} previous Old data
|
|
|
|
|
* @param {Object} previous.text Old plain text content
|
|
|
|
|
* @param {Object} previous.hash Old DOM hash
|
|
|
|
|
* @param {Object} previous.range Old selection
|
|
|
|
|
* @param {Object} next New data
|
|
|
|
|
* @param {Object} next.text New plain text content
|
|
|
|
|
* @param {Object} next.hash New DOM hash
|
|
|
|
|
* @param {Object} next.range New selection
|
|
|
|
|
*/
|
|
|
|
|
ve.ce.Surface.prototype.onContentChange = function ( node, previous, next ) {
|
|
|
|
|
var data, range, len, annotations, offsetDiff, lengthDiff, sameLeadingAndTrailing,
|
|
|
|
|
previousStart, nextStart, newRange,
|
|
|
|
|
fromLeft = 0,
|
|
|
|
|
fromRight = 0,
|
|
|
|
|
nodeOffset = node.getModel().getOffset();
|
|
|
|
|
|
|
|
|
|
if ( previous.range && next.range ) {
|
|
|
|
|
offsetDiff = ( previous.range.isCollapsed() && next.range.isCollapsed() ) ?
|
|
|
|
|
next.range.start - previous.range.start : null;
|
|
|
|
|
lengthDiff = next.text.length - previous.text.length;
|
|
|
|
|
previousStart = previous.range.start - nodeOffset - 1;
|
|
|
|
|
nextStart = next.range.start - nodeOffset - 1;
|
|
|
|
|
sameLeadingAndTrailing = offsetDiff !== null && (
|
|
|
|
|
// TODO: rewrite to static method with tests
|
|
|
|
|
(
|
|
|
|
|
lengthDiff > 0 &&
|
|
|
|
|
previous.text.substring( 0, previousStart ) ===
|
|
|
|
|
next.text.substring( 0, previousStart ) &&
|
|
|
|
|
previous.text.substring( previousStart ) ===
|
|
|
|
|
next.text.substring( nextStart )
|
|
|
|
|
) ||
|
|
|
|
|
(
|
|
|
|
|
lengthDiff < 0 &&
|
|
|
|
|
previous.text.substring( 0, nextStart ) ===
|
|
|
|
|
next.text.substring( 0, nextStart ) &&
|
|
|
|
|
previous.text.substring( previousStart - lengthDiff + offsetDiff) ===
|
|
|
|
|
next.text.substring( nextStart )
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Simple insertion
|
|
|
|
|
if ( lengthDiff > 0 && offsetDiff === lengthDiff /* && sameLeadingAndTrailing */) {
|
|
|
|
|
data = next.text.substring(
|
|
|
|
|
previous.range.start - nodeOffset - 1,
|
|
|
|
|
next.range.start - nodeOffset - 1
|
|
|
|
|
).split( '' );
|
|
|
|
|
// Apply insertion annotations
|
|
|
|
|
annotations = this.model.getInsertionAnnotations();
|
|
|
|
|
if ( annotations instanceof ve.AnnotationSet ) {
|
|
|
|
|
ve.dm.Document.addAnnotationsToData( data, this.model.getInsertionAnnotations() );
|
|
|
|
|
}
|
|
|
|
|
this.disableRendering();
|
|
|
|
|
this.model.change(
|
|
|
|
|
ve.dm.Transaction.newFromInsertion(
|
|
|
|
|
this.documentView.model, previous.range.start, data
|
|
|
|
|
),
|
|
|
|
|
next.range
|
|
|
|
|
);
|
|
|
|
|
this.enableRendering();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Simple deletion
|
|
|
|
|
if ( ( offsetDiff === 0 || offsetDiff === lengthDiff ) && sameLeadingAndTrailing ) {
|
|
|
|
|
if ( offsetDiff === 0 ) {
|
|
|
|
|
range = new ve.Range( next.range.start, next.range.start - lengthDiff );
|
|
|
|
|
} else {
|
|
|
|
|
range = new ve.Range( next.range.start, previous.range.start );
|
|
|
|
|
}
|
|
|
|
|
this.disableRendering();
|
|
|
|
|
this.model.change(
|
|
|
|
|
ve.dm.Transaction.newFromRemoval( this.documentView.model, range ),
|
|
|
|
|
next.range
|
|
|
|
|
);
|
|
|
|
|
this.enableRendering();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Complex change
|
|
|
|
|
|
|
|
|
|
len = Math.min( previous.text.length, next.text.length );
|
|
|
|
|
// Count same characters from left
|
|
|
|
|
while ( fromLeft < len && previous.text[fromLeft] === next.text[fromLeft] ) {
|
|
|
|
|
++fromLeft;
|
|
|
|
|
}
|
|
|
|
|
// Count same characters from right
|
|
|
|
|
while (
|
|
|
|
|
fromRight < len - fromLeft &&
|
|
|
|
|
previous.text[previous.text.length - 1 - fromRight] ===
|
|
|
|
|
next.text[next.text.length - 1 - fromRight]
|
|
|
|
|
) {
|
|
|
|
|
++fromRight;
|
|
|
|
|
}
|
|
|
|
|
data = next.text.substring( fromLeft, next.text.length - fromRight ).split( '' );
|
|
|
|
|
// Get annotations to the left of new content and apply
|
|
|
|
|
annotations =
|
|
|
|
|
this.model.getDocument().getAnnotationsFromOffset( nodeOffset + 1 + fromLeft );
|
|
|
|
|
if ( annotations.getLength() ) {
|
|
|
|
|
ve.dm.Document.addAnnotationsToData( data, annotations );
|
|
|
|
|
}
|
|
|
|
|
newRange = next.range;
|
|
|
|
|
if ( newRange.isCollapsed() ) {
|
|
|
|
|
newRange = new ve.Range( this.getNearestCorrectOffset( newRange.start, 1 ) );
|
|
|
|
|
}
|
|
|
|
|
if ( data.length > 0 ) {
|
|
|
|
|
this.model.change(
|
|
|
|
|
ve.dm.Transaction.newFromInsertion(
|
|
|
|
|
this.documentView.model, nodeOffset + 1 + fromLeft, data
|
|
|
|
|
),
|
|
|
|
|
newRange
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if ( fromLeft + fromRight < previous.text.length ) {
|
|
|
|
|
this.model.change(
|
|
|
|
|
ve.dm.Transaction.newFromRemoval(
|
|
|
|
|
this.documentView.model,
|
|
|
|
|
new ve.Range(
|
|
|
|
|
data.length + nodeOffset + 1 + fromLeft,
|
|
|
|
|
data.length + nodeOffset + 1 + previous.text.length - fromRight
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
newRange
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle surface lock events.
|
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
*/
|
|
|
|
|
ve.ce.Surface.prototype.onLock = function () {
|
|
|
|
|
this.surfaceObserver.stop();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle surface unlock events.
|
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
*/
|
|
|
|
|
ve.ce.Surface.prototype.onUnlock = function () {
|
|
|
|
|
this.surfaceObserver.clear( this.model.getSelection() );
|
|
|
|
|
this.surfaceObserver.start();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*! Utilities */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handle insertion of content.
|
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
*/
|
|
|
|
|
ve.ce.Surface.prototype.handleInsertion = function () {
|
|
|
|
|
var slug, data, range, annotations, insertionAnnotations, placeholder,
|
|
|
|
|
selection = this.model.getSelection();
|
|
|
|
|
|
|
|
|
|
// Handles removing expanded selection before inserting new text
|
|
|
|
|
if ( !selection.isCollapsed() ) {
|
|
|
|
|
// Pull annotations from the first character in the selection
|
|
|
|
|
annotations = this.model.documentModel.getAnnotationsFromRange(
|
|
|
|
|
new ve.Range( selection.start, selection.start + 1 )
|
|
|
|
|
);
|
|
|
|
|
this.model.change(
|
|
|
|
|
ve.dm.Transaction.newFromRemoval( this.documentView.model, selection ),
|
|
|
|
|
new ve.Range( selection.start )
|
|
|
|
|
);
|
|
|
|
|
this.surfaceObserver.clear();
|
|
|
|
|
selection = this.model.getSelection();
|
|
|
|
|
this.model.setInsertionAnnotations( annotations );
|
|
|
|
|
}
|
|
|
|
|
insertionAnnotations = this.model.getInsertionAnnotations() || new ve.AnnotationSet();
|
|
|
|
|
if ( selection.isCollapsed() ) {
|
|
|
|
|
slug = this.documentView.getSlugAtOffset( selection.start );
|
|
|
|
|
// Is this a slug or are the annotations to the left different than the insertion
|
|
|
|
|
// annotations?
|
|
|
|
|
if (
|
|
|
|
|
slug || (
|
|
|
|
|
selection.start > 0 &&
|
|
|
|
|
!ve.compareObjects (
|
|
|
|
|
this.model.getDocument().getAnnotationsFromOffset( selection.start - 1 ),
|
|
|
|
|
insertionAnnotations
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
) {
|
|
|
|
|
placeholder = '\u2659';
|
|
|
|
|
if ( !insertionAnnotations.isEmpty() ) {
|
|
|
|
|
placeholder = [placeholder, insertionAnnotations];
|
|
|
|
|
}
|
|
|
|
|
// is this a slug and if so, is this a block slug?
|
|
|
|
|
if ( slug && ve.dm.Document.isStructuralOffset(
|
|
|
|
|
this.documentView.model.data, selection.start
|
|
|
|
|
) ) {
|
|
|
|
|
range = new ve.Range( selection.start + 1, selection.start + 2 );
|
|
|
|
|
data = [{ 'type' : 'paragraph' }, placeholder, { 'type' : '/paragraph' }];
|
|
|
|
|
} else {
|
|
|
|
|
range = new ve.Range( selection.start, selection.start + 1 );
|
|
|
|
|
data = [placeholder];
|
|
|
|
|
}
|
|
|
|
|
this.model.change(
|
|
|
|
|
ve.dm.Transaction.newFromInsertion(
|
|
|
|
|
this.documentView.model, selection.start, data
|
|
|
|
|
),
|
|
|
|
|
range
|
|
|
|
|
);
|
|
|
|
|
this.surfaceObserver.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this.surfaceObserver.stop( true );
|
|
|
|
|
};
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Handle enter key events.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.ce.Surface.prototype.handleEnter = function ( e ) {
|
2012-08-02 18:46:13 +00:00
|
|
|
|
var tx, outerParent, outerChildrenCount, list,
|
|
|
|
|
selection = this.model.getSelection(),
|
2012-06-21 00:36:18 +00:00
|
|
|
|
documentModel = this.model.getDocument(),
|
2012-06-21 04:10:48 +00:00
|
|
|
|
emptyParagraph = [{ 'type': 'paragraph' }, { 'type': '/paragraph' }],
|
2012-07-19 03:40:49 +00:00
|
|
|
|
advanceCursor = true,
|
2012-08-02 18:46:13 +00:00
|
|
|
|
node = this.documentView.getNodeFromOffset( selection.from ),
|
|
|
|
|
nodeModel = node.getModel(),
|
|
|
|
|
cursor = selection.from,
|
|
|
|
|
contentBranchModel = nodeModel.isContent() ? nodeModel.getParent() : nodeModel,
|
|
|
|
|
contentBranchModelRange = contentBranchModel.getRange(),
|
|
|
|
|
stack = [],
|
|
|
|
|
outermostNode = null;
|
2012-06-22 22:05:35 +00:00
|
|
|
|
|
2012-06-21 00:36:18 +00:00
|
|
|
|
// Stop polling while we work
|
2012-10-05 21:54:32 +00:00
|
|
|
|
this.surfaceObserver.stop();
|
2012-06-22 22:05:35 +00:00
|
|
|
|
|
2012-06-21 00:36:18 +00:00
|
|
|
|
// Handle removal first
|
2012-06-20 01:20:28 +00:00
|
|
|
|
if ( selection.from !== selection.to ) {
|
2012-06-21 00:36:18 +00:00
|
|
|
|
tx = ve.dm.Transaction.newFromRemoval( documentModel, selection );
|
|
|
|
|
selection = tx.translateRange( selection );
|
|
|
|
|
this.model.change( tx, selection );
|
2012-06-20 01:20:28 +00:00
|
|
|
|
}
|
2012-06-21 03:00:44 +00:00
|
|
|
|
|
2012-08-02 18:46:13 +00:00
|
|
|
|
// Handle insertion
|
2012-06-21 03:00:44 +00:00
|
|
|
|
if (
|
|
|
|
|
contentBranchModel.getType() !== 'paragraph' &&
|
|
|
|
|
(
|
|
|
|
|
cursor === contentBranchModelRange.from ||
|
|
|
|
|
cursor === contentBranchModelRange.to
|
|
|
|
|
)
|
|
|
|
|
) {
|
2012-06-21 00:36:18 +00:00
|
|
|
|
// If we're at the start/end of something that's not a paragraph, insert a paragraph
|
|
|
|
|
// before/after
|
|
|
|
|
if ( cursor === contentBranchModelRange.from ) {
|
|
|
|
|
tx = ve.dm.Transaction.newFromInsertion(
|
|
|
|
|
documentModel, contentBranchModel.getOuterRange().from, emptyParagraph
|
|
|
|
|
);
|
|
|
|
|
} else if ( cursor === contentBranchModelRange.to ) {
|
|
|
|
|
tx = ve.dm.Transaction.newFromInsertion(
|
|
|
|
|
documentModel, contentBranchModel.getOuterRange().to, emptyParagraph
|
|
|
|
|
);
|
2012-06-20 01:20:28 +00:00
|
|
|
|
}
|
2012-06-21 00:36:18 +00:00
|
|
|
|
} else {
|
|
|
|
|
// Split
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.Node.traverseUpstream( node, function ( node ) {
|
2012-06-21 00:36:18 +00:00
|
|
|
|
if ( !node.canBeSplit() ) {
|
|
|
|
|
return false;
|
2012-06-20 01:20:28 +00:00
|
|
|
|
}
|
2012-06-21 00:36:18 +00:00
|
|
|
|
stack.splice(
|
|
|
|
|
stack.length / 2,
|
|
|
|
|
0,
|
2012-06-21 01:59:12 +00:00
|
|
|
|
{ 'type': '/' + node.type },
|
|
|
|
|
node.model.getClonedElement()
|
2012-06-21 00:36:18 +00:00
|
|
|
|
);
|
2012-06-21 04:10:48 +00:00
|
|
|
|
outermostNode = node;
|
2012-06-22 22:05:35 +00:00
|
|
|
|
if ( e.shiftKey ) {
|
|
|
|
|
return false;
|
|
|
|
|
} else {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2012-06-21 00:36:18 +00:00
|
|
|
|
} );
|
2012-06-22 22:05:35 +00:00
|
|
|
|
|
2012-07-19 03:40:49 +00:00
|
|
|
|
outerParent = outermostNode.getModel().getParent();
|
|
|
|
|
outerChildrenCount = outerParent.getChildren().length;
|
2012-06-22 22:05:35 +00:00
|
|
|
|
|
2012-06-27 16:29:58 +00:00
|
|
|
|
if (
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
// This is a list item
|
|
|
|
|
outermostNode.type === 'listItem' &&
|
2013-01-16 21:51:05 +00:00
|
|
|
|
// This is the last list item
|
|
|
|
|
outerParent.getChildren()[outerChildrenCount - 1] === outermostNode.getModel() &&
|
|
|
|
|
// There is one child
|
|
|
|
|
outermostNode.children.length === 1 &&
|
|
|
|
|
// The child is empty
|
|
|
|
|
node.model.length === 0
|
|
|
|
|
) {
|
|
|
|
|
// Enter was pressed in an empty list item.
|
|
|
|
|
list = outermostNode.getModel().getParent();
|
|
|
|
|
// Remove the list item
|
|
|
|
|
tx = ve.dm.Transaction.newFromRemoval(
|
|
|
|
|
documentModel, outermostNode.getModel().getOuterRange()
|
|
|
|
|
);
|
|
|
|
|
this.model.change( tx );
|
|
|
|
|
// Insert a paragraph
|
|
|
|
|
tx = ve.dm.Transaction.newFromInsertion(
|
|
|
|
|
documentModel, list.getOuterRange().to, emptyParagraph
|
|
|
|
|
);
|
|
|
|
|
advanceCursor = false;
|
2012-11-28 01:29:09 +00:00
|
|
|
|
} else {
|
2013-01-16 21:51:05 +00:00
|
|
|
|
// We must process the transaction first because getRelativeContentOffset can't help us
|
|
|
|
|
// yet
|
|
|
|
|
tx = ve.dm.Transaction.newFromInsertion( documentModel, selection.from, stack );
|
2012-11-28 01:29:09 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2013-01-16 21:51:05 +00:00
|
|
|
|
|
|
|
|
|
// Commit the transaction
|
|
|
|
|
this.model.change( tx );
|
|
|
|
|
|
|
|
|
|
// Now we can move the cursor forward
|
|
|
|
|
if ( advanceCursor ) {
|
2012-11-28 01:29:09 +00:00
|
|
|
|
this.model.change(
|
2013-01-16 21:51:05 +00:00
|
|
|
|
null, new ve.Range( documentModel.getRelativeContentOffset( selection.from, 1 ) )
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
this.model.change(
|
|
|
|
|
null, new ve.Range( documentModel.getNearestContentOffset( selection.from ) )
|
2012-11-28 01:29:09 +00:00
|
|
|
|
);
|
|
|
|
|
}
|
2013-01-16 21:51:05 +00:00
|
|
|
|
// Reset and resume polling
|
|
|
|
|
this.surfaceObserver.clear();
|
|
|
|
|
this.surfaceObserver.start();
|
2012-11-28 01:29:09 +00:00
|
|
|
|
};
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Handle backspace and delete key down events.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
2013-01-15 20:15:17 +00:00
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
* @param {boolean} backspace Key was a backspace
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*/
|
2012-08-17 23:28:29 +00:00
|
|
|
|
ve.ce.Surface.prototype.handleDelete = function ( e, backspace ) {
|
2012-11-20 01:05:34 +00:00
|
|
|
|
var sourceOffset,
|
2012-06-20 01:20:28 +00:00
|
|
|
|
targetOffset,
|
|
|
|
|
sourceSplitableNode,
|
|
|
|
|
targetSplitableNode,
|
|
|
|
|
tx,
|
2012-07-19 03:40:49 +00:00
|
|
|
|
cursorAt,
|
|
|
|
|
sourceNode,
|
|
|
|
|
targetNode,
|
|
|
|
|
sourceData,
|
Remainder JSHint fixes on modules/ve/*
[jshint]
ce/ve.ce.Surface.js: line 670, col 9, Too many var statements.
ce/ve.ce.Surface.js: line 695, col 6, Missing semicolon.
ce/ve.ce.Surface.js: line 726, col 22, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 726, col 41, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 733, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 734, col 24, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 1013, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 1019, col 17, Too many var statements.
ce/ve.ce.Surface.js: line 1023, col 18, Too many ar statements.
ce/ve.ce.Surface.js: line 1027, col 13, Too many var statements.
dm/annotations/ve.dm.LinkAnnotation.js: line 70, col 52, Insecure '.'.
dm/ve.dm.Converter.js: line 383, col 29, Empty block.
dm/ve.dm.Converter.js: line 423, col 33, Empty block.
Commands:
* jshint .
* ack '(if|else|function|switch|for|while)\('
* Sublime Text 2:
Find(*): (if|else|function|switch|for|while)\(
Replace: $1 (
* ack ' ' -Q # double spaces, except in certain comments
Change-Id: I8e34bf2924bc8688fdf8acef08bbc4f6707e93be
2012-09-02 21:45:01 +00:00
|
|
|
|
nodeToDelete,
|
|
|
|
|
adjacentData,
|
|
|
|
|
adjacentText,
|
|
|
|
|
adjacentTextAfterMatch,
|
|
|
|
|
endOffset,
|
2012-11-20 01:05:34 +00:00
|
|
|
|
i,
|
2012-11-29 00:44:34 +00:00
|
|
|
|
selection = this.model.getSelection(),
|
|
|
|
|
containsInlineElements = false;
|
2012-03-01 22:27:23 +00:00
|
|
|
|
|
2013-01-16 20:22:07 +00:00
|
|
|
|
if ( selection.isCollapsed() ) {
|
2012-08-17 23:28:29 +00:00
|
|
|
|
// Set source and target linmod offsets
|
|
|
|
|
if ( backspace ) {
|
2012-06-21 00:42:12 +00:00
|
|
|
|
sourceOffset = selection.to;
|
2012-06-21 04:34:11 +00:00
|
|
|
|
targetOffset = this.getNearestCorrectOffset( sourceOffset - 1, -1 );
|
2012-08-17 23:28:29 +00:00
|
|
|
|
|
|
|
|
|
// At the beginning of the document - don't do anything and preventDefault
|
|
|
|
|
if ( sourceOffset === targetOffset ) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2012-03-01 22:27:23 +00:00
|
|
|
|
} else {
|
2012-06-20 01:20:28 +00:00
|
|
|
|
sourceOffset = this.model.getDocument().getRelativeContentOffset( selection.to, 1 );
|
|
|
|
|
targetOffset = selection.to;
|
2012-08-17 23:28:29 +00:00
|
|
|
|
|
|
|
|
|
// At the end of the document - don't do anything and preventDefault
|
|
|
|
|
if ( sourceOffset <= targetOffset ) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2012-03-01 22:27:23 +00:00
|
|
|
|
}
|
|
|
|
|
|
2012-08-17 23:28:29 +00:00
|
|
|
|
// Set source and target nodes
|
|
|
|
|
sourceNode = this.documentView.getNodeFromOffset( sourceOffset, false ),
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
targetNode = this.documentView.getNodeFromOffset( targetOffset, false );
|
2012-06-27 16:29:58 +00:00
|
|
|
|
|
2012-06-20 01:20:28 +00:00
|
|
|
|
if ( sourceNode.type === targetNode.type ) {
|
|
|
|
|
sourceSplitableNode = ve.ce.Node.getSplitableNode( sourceNode );
|
|
|
|
|
targetSplitableNode = ve.ce.Node.getSplitableNode( targetNode );
|
|
|
|
|
}
|
2012-06-29 00:26:10 +00:00
|
|
|
|
//ve.log(sourceSplitableNode, targetSplitableNode);
|
2012-02-13 22:45:18 +00:00
|
|
|
|
|
2012-08-17 23:28:29 +00:00
|
|
|
|
// Save target location of cursor
|
2012-06-27 16:29:58 +00:00
|
|
|
|
cursorAt = targetOffset;
|
2012-02-13 22:45:18 +00:00
|
|
|
|
|
2012-08-17 23:28:29 +00:00
|
|
|
|
// Get text from cursor location to end of node in the proper direction
|
Remainder JSHint fixes on modules/ve/*
[jshint]
ce/ve.ce.Surface.js: line 670, col 9, Too many var statements.
ce/ve.ce.Surface.js: line 695, col 6, Missing semicolon.
ce/ve.ce.Surface.js: line 726, col 22, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 726, col 41, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 733, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 734, col 24, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 1013, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 1019, col 17, Too many var statements.
ce/ve.ce.Surface.js: line 1023, col 18, Too many ar statements.
ce/ve.ce.Surface.js: line 1027, col 13, Too many var statements.
dm/annotations/ve.dm.LinkAnnotation.js: line 70, col 52, Insecure '.'.
dm/ve.dm.Converter.js: line 383, col 29, Empty block.
dm/ve.dm.Converter.js: line 423, col 33, Empty block.
Commands:
* jshint .
* ack '(if|else|function|switch|for|while)\('
* Sublime Text 2:
Find(*): (if|else|function|switch|for|while)\(
Replace: $1 (
* ack ' ' -Q # double spaces, except in certain comments
Change-Id: I8e34bf2924bc8688fdf8acef08bbc4f6707e93be
2012-09-02 21:45:01 +00:00
|
|
|
|
adjacentData = null;
|
|
|
|
|
adjacentText = '';
|
2012-08-17 23:28:29 +00:00
|
|
|
|
|
Remainder JSHint fixes on modules/ve/*
[jshint]
ce/ve.ce.Surface.js: line 670, col 9, Too many var statements.
ce/ve.ce.Surface.js: line 695, col 6, Missing semicolon.
ce/ve.ce.Surface.js: line 726, col 22, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 726, col 41, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 733, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 734, col 24, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 1013, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 1019, col 17, Too many var statements.
ce/ve.ce.Surface.js: line 1023, col 18, Too many ar statements.
ce/ve.ce.Surface.js: line 1027, col 13, Too many var statements.
dm/annotations/ve.dm.LinkAnnotation.js: line 70, col 52, Insecure '.'.
dm/ve.dm.Converter.js: line 383, col 29, Empty block.
dm/ve.dm.Converter.js: line 423, col 33, Empty block.
Commands:
* jshint .
* ack '(if|else|function|switch|for|while)\('
* Sublime Text 2:
Find(*): (if|else|function|switch|for|while)\(
Replace: $1 (
* ack ' ' -Q # double spaces, except in certain comments
Change-Id: I8e34bf2924bc8688fdf8acef08bbc4f6707e93be
2012-09-02 21:45:01 +00:00
|
|
|
|
if ( backspace ) {
|
|
|
|
|
adjacentData = sourceNode.model.doc.data.slice(
|
|
|
|
|
sourceNode.model.getOffset() + ( sourceNode.model.isWrapped() ? 1 : 0 ) ,
|
|
|
|
|
sourceOffset
|
|
|
|
|
);
|
2012-08-17 23:28:29 +00:00
|
|
|
|
} else {
|
Remainder JSHint fixes on modules/ve/*
[jshint]
ce/ve.ce.Surface.js: line 670, col 9, Too many var statements.
ce/ve.ce.Surface.js: line 695, col 6, Missing semicolon.
ce/ve.ce.Surface.js: line 726, col 22, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 726, col 41, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 733, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 734, col 24, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 1013, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 1019, col 17, Too many var statements.
ce/ve.ce.Surface.js: line 1023, col 18, Too many ar statements.
ce/ve.ce.Surface.js: line 1027, col 13, Too many var statements.
dm/annotations/ve.dm.LinkAnnotation.js: line 70, col 52, Insecure '.'.
dm/ve.dm.Converter.js: line 383, col 29, Empty block.
dm/ve.dm.Converter.js: line 423, col 33, Empty block.
Commands:
* jshint .
* ack '(if|else|function|switch|for|while)\('
* Sublime Text 2:
Find(*): (if|else|function|switch|for|while)\(
Replace: $1 (
* ack ' ' -Q # double spaces, except in certain comments
Change-Id: I8e34bf2924bc8688fdf8acef08bbc4f6707e93be
2012-09-02 21:45:01 +00:00
|
|
|
|
endOffset = targetNode.model.getOffset() +
|
|
|
|
|
targetNode.model.getLength() +
|
|
|
|
|
( targetNode.model.isWrapped() ? 1 : 0 );
|
2012-08-17 23:28:29 +00:00
|
|
|
|
adjacentData = targetNode.model.doc.data.slice( targetOffset, endOffset );
|
|
|
|
|
}
|
|
|
|
|
|
Remainder JSHint fixes on modules/ve/*
[jshint]
ce/ve.ce.Surface.js: line 670, col 9, Too many var statements.
ce/ve.ce.Surface.js: line 695, col 6, Missing semicolon.
ce/ve.ce.Surface.js: line 726, col 22, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 726, col 41, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 733, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 734, col 24, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 1013, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 1019, col 17, Too many var statements.
ce/ve.ce.Surface.js: line 1023, col 18, Too many ar statements.
ce/ve.ce.Surface.js: line 1027, col 13, Too many var statements.
dm/annotations/ve.dm.LinkAnnotation.js: line 70, col 52, Insecure '.'.
dm/ve.dm.Converter.js: line 383, col 29, Empty block.
dm/ve.dm.Converter.js: line 423, col 33, Empty block.
Commands:
* jshint .
* ack '(if|else|function|switch|for|while)\('
* Sublime Text 2:
Find(*): (if|else|function|switch|for|while)\(
Replace: $1 (
* ack ' ' -Q # double spaces, except in certain comments
Change-Id: I8e34bf2924bc8688fdf8acef08bbc4f6707e93be
2012-09-02 21:45:01 +00:00
|
|
|
|
for ( i = 0; i < adjacentData.length; i++ ) {
|
2012-11-29 00:44:34 +00:00
|
|
|
|
if ( adjacentData[i].type !== undefined ) {
|
|
|
|
|
containsInlineElements = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2012-08-17 23:28:29 +00:00
|
|
|
|
adjacentText += adjacentData[i][0];
|
|
|
|
|
}
|
|
|
|
|
|
2012-11-29 00:44:34 +00:00
|
|
|
|
if ( !containsInlineElements ) {
|
2013-01-15 23:38:49 +00:00
|
|
|
|
adjacentTextAfterMatch = adjacentText.match( this.constructor.static.textPattern );
|
|
|
|
|
// If there are "normal" characters in the adjacent text let the browser handle natively
|
2012-11-29 00:44:34 +00:00
|
|
|
|
if ( adjacentTextAfterMatch !== null && adjacentTextAfterMatch.length ) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2012-08-17 23:28:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ve.log('handleDelete programatically');
|
|
|
|
|
e.preventDefault();
|
2012-10-05 21:54:32 +00:00
|
|
|
|
this.surfaceObserver.stop();
|
2012-08-17 23:28:29 +00:00
|
|
|
|
|
2012-06-21 07:01:32 +00:00
|
|
|
|
if (
|
|
|
|
|
// Source and target are the same node
|
|
|
|
|
sourceNode === targetNode ||
|
|
|
|
|
(
|
|
|
|
|
// Source and target have the same parent (list items)
|
|
|
|
|
sourceSplitableNode !== undefined &&
|
|
|
|
|
sourceSplitableNode.getParent() === targetSplitableNode.getParent()
|
|
|
|
|
)
|
|
|
|
|
) {
|
|
|
|
|
// Simple removal
|
|
|
|
|
tx = ve.dm.Transaction.newFromRemoval(
|
|
|
|
|
this.documentView.model, new ve.Range( targetOffset, sourceOffset )
|
|
|
|
|
);
|
2012-06-20 01:20:28 +00:00
|
|
|
|
this.model.change( tx, new ve.Range( cursorAt ) );
|
2012-06-21 07:01:32 +00:00
|
|
|
|
} else if ( sourceNode.getType() === 'document' ) {
|
|
|
|
|
// Source is a slug - move the cursor somewhere useful
|
|
|
|
|
this.model.change( null, new ve.Range( cursorAt ) );
|
2012-06-20 01:20:28 +00:00
|
|
|
|
} else {
|
2012-08-17 23:28:29 +00:00
|
|
|
|
// Source and target are different nodes or do not share a parent, perform tricky merge
|
2012-06-20 22:54:22 +00:00
|
|
|
|
// Get the data for the source node
|
2012-07-19 03:40:49 +00:00
|
|
|
|
sourceData = this.documentView.model.getData( sourceNode.model.getRange() );
|
2012-08-17 23:28:29 +00:00
|
|
|
|
|
2012-06-20 01:20:28 +00:00
|
|
|
|
// Find the node that should be completely removed
|
2012-07-19 03:40:49 +00:00
|
|
|
|
nodeToDelete = sourceNode;
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.Node.traverseUpstream( nodeToDelete, function ( node ) {
|
2012-06-20 01:20:28 +00:00
|
|
|
|
if ( node.getParent().children.length === 1 ) {
|
|
|
|
|
nodeToDelete = node.getParent();
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
} );
|
2012-08-17 23:28:29 +00:00
|
|
|
|
|
2012-06-21 07:01:32 +00:00
|
|
|
|
this.model.change(
|
2012-08-17 23:28:29 +00:00
|
|
|
|
[
|
|
|
|
|
// Remove source node or source node ancestor
|
|
|
|
|
ve.dm.Transaction.newFromRemoval(
|
|
|
|
|
this.documentView.model, nodeToDelete.getModel().getOuterRange()
|
|
|
|
|
),
|
|
|
|
|
// Append source data to target
|
|
|
|
|
ve.dm.Transaction.newFromInsertion(
|
|
|
|
|
this.documentView.model, targetOffset, sourceData
|
|
|
|
|
)
|
|
|
|
|
],
|
2012-06-21 07:01:32 +00:00
|
|
|
|
new ve.Range( cursorAt )
|
|
|
|
|
);
|
2012-03-12 21:50:22 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2012-06-21 07:01:32 +00:00
|
|
|
|
// Selection removal
|
2012-08-17 23:28:29 +00:00
|
|
|
|
ve.log('selection removal - handle programatically');
|
|
|
|
|
e.preventDefault();
|
2012-06-21 07:01:32 +00:00
|
|
|
|
this.model.change(
|
|
|
|
|
ve.dm.Transaction.newFromRemoval( this.documentView.model, selection ),
|
|
|
|
|
new ve.Range( selection.start )
|
|
|
|
|
);
|
2012-03-12 21:50:22 +00:00
|
|
|
|
}
|
2012-02-13 22:45:18 +00:00
|
|
|
|
|
2012-10-05 21:54:32 +00:00
|
|
|
|
this.surfaceObserver.clear();
|
|
|
|
|
this.surfaceObserver.start();
|
2012-02-13 22:45:18 +00:00
|
|
|
|
};
|
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
/**
|
|
|
|
|
* Adjust the cursor position in a given distance.
|
|
|
|
|
*
|
|
|
|
|
* This method only affects the selection target, preserving selections that are not collapsed and
|
|
|
|
|
* the direction of the selection.
|
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {number} adjustment Distance to adjust the cursor, can be positive or negative
|
|
|
|
|
* @returns {boolean} Cursor was moved
|
|
|
|
|
*/
|
|
|
|
|
ve.ce.Surface.prototype.adjustCursor = function ( adjustment ) {
|
|
|
|
|
// Bypass for zero-adjustment
|
|
|
|
|
if ( !adjustment ) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
var adjustedTargetOffset,
|
|
|
|
|
bias = adjustment > 0 ? 1 : -1,
|
|
|
|
|
selection = this.model.getSelection(),
|
|
|
|
|
targetOffset = selection.to,
|
|
|
|
|
documentModel = this.model.getDocument(),
|
|
|
|
|
relativeContentOffset = documentModel.getRelativeContentOffset( targetOffset, adjustment ),
|
|
|
|
|
relativeStructuralOffset = documentModel.getRelativeStructuralOffset(
|
|
|
|
|
targetOffset + bias, adjustment, true
|
|
|
|
|
);
|
|
|
|
|
// Check if we've moved into a slug
|
|
|
|
|
if ( this.hasSlugAtOffset( relativeStructuralOffset ) ) {
|
|
|
|
|
// Check if the relative content offset is in the opposite direction we are trying to go
|
|
|
|
|
if ( ( relativeContentOffset - targetOffset < 0 ? -1 : 1 ) !== bias ) {
|
|
|
|
|
// There's nothing past the slug we are already in, stay in it
|
|
|
|
|
adjustedTargetOffset = relativeStructuralOffset;
|
|
|
|
|
} else {
|
|
|
|
|
// There's a slug neaby, go into it if it's closer
|
|
|
|
|
adjustedTargetOffset = adjustment < 0 ?
|
|
|
|
|
Math.max( relativeContentOffset, relativeStructuralOffset ) :
|
|
|
|
|
Math.min( relativeContentOffset, relativeStructuralOffset );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Check if we've moved a different distance than we asked for
|
|
|
|
|
else if ( relativeContentOffset !== targetOffset + adjustment ) {
|
|
|
|
|
// We can't trust the browser, move programatically
|
|
|
|
|
adjustedTargetOffset = relativeContentOffset;
|
|
|
|
|
}
|
|
|
|
|
// If the target changed, update the model
|
|
|
|
|
if ( adjustedTargetOffset ) {
|
|
|
|
|
this.model.change(
|
|
|
|
|
null,
|
|
|
|
|
new ve.Range(
|
|
|
|
|
selection.isCollapsed() ?
|
|
|
|
|
adjustedTargetOffset : selection.from, adjustedTargetOffset
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Show the cursor at an offset.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
JSDuck: Generated code documentation!
See CODING.md for how to run it.
Mistakes fixed:
* Warning: Unknown type function
-> Function
* Warning: Unknown type DOMElement
-> HTMLElement
* Warning: Unknown type DOM Node
-> HTMLElement
* Warning: Unknown type Integer
-> Mixed
* Warning: Unknown type Command
-> ve.Command
* Warning: Unknown type any
-> number
* Warning: Unknown type ve.Transaction
-> ve.dm.Transaction
* Warning: Unknown type ve.dm.AnnotationSet
-> ve.AnnotationSet
* Warning: Unknown type false
-> boolean
* Warning: Unknown type ve.dm.AlienNode
ve.dm doesn't have a generic AlienNode like ve.ce
-> Unknown type ve.dm.AlienInlineNode|ve.dm.AlienBlockNode
* Warning: Unknown type ve.ve.Surface
-> ve.ce.Surface
* ve.example.lookupNode:
-> Last @param should be @return
* ve.dm.Transaction.prototype.pushReplace:
-> @param {Array] should be @param {Array}
* Warning: ve.BranchNode.js:27: {@link ve.Node#hasChildren} links to non-existing member
-> (removed)
* Warning: ve.LeafNode.js:21: {@link ve.Node#hasChildren} links to non-existing member
-> (removed)
Differences fixed:
* Variadic arguments are like @param {Type...} [name]
instead of @param {Type} [name...]
* Convert all file headers from /** to /*! because JSDuck tries
to parse all /** blocks and fails to parse with all sorts of
errors for "Global property", "Unnamed property", and
"Duplicate property".
Find: \/\*\*([^@]+)(@copyright)
Replace: /*!$1$2
* Indented blocks are considered code examples.
A few methods had documentation with numbered lists that were
indented, which have now been updated to not be intended.
* The free-form text descriptions are parsed with Markdown,
which requires lists to be separated from paragraphs by an
empty line.
And we should use `backticks` instead of {braces} for inline
code in text paragraphs.
* Doc blocks for classes and their constructor have to be
in the correct order (@constructor, @param, @return must be
before @class, @abstract, @extends etc.)
* `@extends Class` must not have Class {wrapped}
* @throws must start with a {Type}
* @example means something else. It is used for an inline demo
iframe, not code block. For that simply indent with spaces.
* @member means something else.
Non-function properties are marked with @property, not @member.
* To create a link to a class or member, in most cases the name
is enough to create a link. E.g. Foo, Foo.bar, Foo.bar#quux,
where a hash stands for "instance member", so Foo.bar#quux,
links to Foo.bar.prototype.quux (the is not supported, as
"prototype" is considered an implementation detail, it only
indexes class name and method name).
If the magic linker doesn't work for some case, the
verbose syntax is {@link #target label}.
* @property can't have sub-properties (nested @param and @return
values are supported, only @static @property can't be nested).
We only have one case of this, which can be worked around by
moving those in a new virtual class. The code is unaltered
(only moved down so that it isn't with the scope of the main
@class block). ve.dm.TransactionProcessor.processors.
New:
* @mixins: Classes mixed into the current class.
* @event: Events that can be emitted by a class. These are also
inherited by subclasses. (+ @param, @return and @preventable).
So ve.Node#event-attach is inherited to ve.dm.BreakNode,
just like @method is.
* @singleton: Plain objects such as ve, ve.dm, ve.ce were missing
documentation causing a tree error. Documented those as a
JSDuck singleton, which they but just weren't documented yet.
NB: Members of @singleton don't need @static (if present,
triggers a compiler warning).
* @chainable: Shorthand for "@return this". We were using
"@return {classname}" which is ambiguous (returns the same
instance or another instance?), @chainable is specifically
for "@return this". Creates proper labels in the generated
HTML pages.
Removed:
* @mixin: (not to be confused with @mixins). Not supported by
JSDuck. Every class is standalone anyway. Where needed marked
them @class + @abstract instead.
Change-Id: I6a7c9e8ee8f995731bc205d666167874eb2ebe23
2013-01-04 08:54:17 +00:00
|
|
|
|
* @param {number} offset Offset to show cursor at
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*/
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.ce.Surface.prototype.showCursor = function ( offset ) {
|
2012-06-20 01:20:28 +00:00
|
|
|
|
this.showSelection( new ve.Range( offset ) );
|
2012-03-01 01:28:39 +00:00
|
|
|
|
};
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Show selection on a range.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {ve.Range} range Range to show selection on
|
|
|
|
|
*/
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.ce.Surface.prototype.showSelection = function ( range ) {
|
2012-11-20 01:05:34 +00:00
|
|
|
|
var start, end,
|
|
|
|
|
rangySel = rangy.getSelection(),
|
|
|
|
|
rangyRange = rangy.createRange();
|
2012-06-20 01:20:28 +00:00
|
|
|
|
|
2012-11-26 23:01:35 +00:00
|
|
|
|
// Ensure the range we are asking to select is from and to correct offsets - failure to do so
|
|
|
|
|
// may cause getNodeAndOffset to throw an exception
|
|
|
|
|
range = new ve.Range(
|
|
|
|
|
this.getNearestCorrectOffset( range.start ),
|
|
|
|
|
this.getNearestCorrectOffset( range.end )
|
|
|
|
|
);
|
|
|
|
|
|
2013-01-16 20:22:07 +00:00
|
|
|
|
if ( !range.isCollapsed() ) {
|
2012-06-20 01:20:28 +00:00
|
|
|
|
start = this.getNodeAndOffset( range.start );
|
2012-06-21 18:04:26 +00:00
|
|
|
|
end = this.getNodeAndOffset( range.end );
|
|
|
|
|
|
2012-10-11 18:31:28 +00:00
|
|
|
|
if ( false && $.browser.msie ) {
|
2012-06-21 18:04:26 +00:00
|
|
|
|
if ( range.start === range.from ) {
|
|
|
|
|
if (
|
|
|
|
|
start.node === this.poll.rangySelection.anchorNode &&
|
|
|
|
|
start.offset === this.poll.rangySelection.anchorOffset &&
|
|
|
|
|
end.node === this.poll.rangySelection.focusNode &&
|
|
|
|
|
end.offset === this.poll.rangySelection.focusOffset
|
|
|
|
|
) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (
|
|
|
|
|
end.node === this.poll.rangySelection.anchorNode &&
|
|
|
|
|
end.offset === this.poll.rangySelection.anchorOffset &&
|
|
|
|
|
start.node === this.poll.rangySelection.focusNode &&
|
|
|
|
|
start.offset === this.poll.rangySelection.focusOffset
|
|
|
|
|
) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-20 01:20:28 +00:00
|
|
|
|
rangyRange.setStart( start.node, start.offset );
|
|
|
|
|
rangyRange.setEnd( end.node, end.offset );
|
|
|
|
|
rangySel.removeAllRanges();
|
|
|
|
|
rangySel.addRange( rangyRange, range.start !== range.from );
|
|
|
|
|
} else {
|
|
|
|
|
start = end = this.getNodeAndOffset( range.start );
|
2012-06-21 18:04:26 +00:00
|
|
|
|
|
2012-10-11 18:31:28 +00:00
|
|
|
|
if ( false && $.browser.msie ) {
|
2012-06-21 18:04:26 +00:00
|
|
|
|
if (
|
|
|
|
|
start.node === this.poll.rangySelection.anchorNode &&
|
|
|
|
|
start.offset === this.poll.rangySelection.anchorOffset
|
|
|
|
|
) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-20 01:20:28 +00:00
|
|
|
|
rangyRange.setStart( start.node, start.offset );
|
|
|
|
|
rangySel.setSingleRange( rangyRange );
|
|
|
|
|
}
|
2012-03-02 02:07:55 +00:00
|
|
|
|
};
|
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
/*! Helpers */
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Get the nearest offset that a cursor can be placed at.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* TODO: Find a better name and a better place for this method
|
|
|
|
|
*
|
|
|
|
|
* @method
|
JSDuck: Generated code documentation!
See CODING.md for how to run it.
Mistakes fixed:
* Warning: Unknown type function
-> Function
* Warning: Unknown type DOMElement
-> HTMLElement
* Warning: Unknown type DOM Node
-> HTMLElement
* Warning: Unknown type Integer
-> Mixed
* Warning: Unknown type Command
-> ve.Command
* Warning: Unknown type any
-> number
* Warning: Unknown type ve.Transaction
-> ve.dm.Transaction
* Warning: Unknown type ve.dm.AnnotationSet
-> ve.AnnotationSet
* Warning: Unknown type false
-> boolean
* Warning: Unknown type ve.dm.AlienNode
ve.dm doesn't have a generic AlienNode like ve.ce
-> Unknown type ve.dm.AlienInlineNode|ve.dm.AlienBlockNode
* Warning: Unknown type ve.ve.Surface
-> ve.ce.Surface
* ve.example.lookupNode:
-> Last @param should be @return
* ve.dm.Transaction.prototype.pushReplace:
-> @param {Array] should be @param {Array}
* Warning: ve.BranchNode.js:27: {@link ve.Node#hasChildren} links to non-existing member
-> (removed)
* Warning: ve.LeafNode.js:21: {@link ve.Node#hasChildren} links to non-existing member
-> (removed)
Differences fixed:
* Variadic arguments are like @param {Type...} [name]
instead of @param {Type} [name...]
* Convert all file headers from /** to /*! because JSDuck tries
to parse all /** blocks and fails to parse with all sorts of
errors for "Global property", "Unnamed property", and
"Duplicate property".
Find: \/\*\*([^@]+)(@copyright)
Replace: /*!$1$2
* Indented blocks are considered code examples.
A few methods had documentation with numbered lists that were
indented, which have now been updated to not be intended.
* The free-form text descriptions are parsed with Markdown,
which requires lists to be separated from paragraphs by an
empty line.
And we should use `backticks` instead of {braces} for inline
code in text paragraphs.
* Doc blocks for classes and their constructor have to be
in the correct order (@constructor, @param, @return must be
before @class, @abstract, @extends etc.)
* `@extends Class` must not have Class {wrapped}
* @throws must start with a {Type}
* @example means something else. It is used for an inline demo
iframe, not code block. For that simply indent with spaces.
* @member means something else.
Non-function properties are marked with @property, not @member.
* To create a link to a class or member, in most cases the name
is enough to create a link. E.g. Foo, Foo.bar, Foo.bar#quux,
where a hash stands for "instance member", so Foo.bar#quux,
links to Foo.bar.prototype.quux (the is not supported, as
"prototype" is considered an implementation detail, it only
indexes class name and method name).
If the magic linker doesn't work for some case, the
verbose syntax is {@link #target label}.
* @property can't have sub-properties (nested @param and @return
values are supported, only @static @property can't be nested).
We only have one case of this, which can be worked around by
moving those in a new virtual class. The code is unaltered
(only moved down so that it isn't with the scope of the main
@class block). ve.dm.TransactionProcessor.processors.
New:
* @mixins: Classes mixed into the current class.
* @event: Events that can be emitted by a class. These are also
inherited by subclasses. (+ @param, @return and @preventable).
So ve.Node#event-attach is inherited to ve.dm.BreakNode,
just like @method is.
* @singleton: Plain objects such as ve, ve.dm, ve.ce were missing
documentation causing a tree error. Documented those as a
JSDuck singleton, which they but just weren't documented yet.
NB: Members of @singleton don't need @static (if present,
triggers a compiler warning).
* @chainable: Shorthand for "@return this". We were using
"@return {classname}" which is ambiguous (returns the same
instance or another instance?), @chainable is specifically
for "@return this". Creates proper labels in the generated
HTML pages.
Removed:
* @mixin: (not to be confused with @mixins). Not supported by
JSDuck. Every class is standalone anyway. Where needed marked
them @class + @abstract instead.
Change-Id: I6a7c9e8ee8f995731bc205d666167874eb2ebe23
2013-01-04 08:54:17 +00:00
|
|
|
|
* @param {number} offset Offset to start looking at
|
|
|
|
|
* @param {number} [direction=-1] Direction to look in, +1 or -1
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*/
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.ce.Surface.prototype.getNearestCorrectOffset = function ( offset, direction ) {
|
Remainder JSHint fixes on modules/ve/*
[jshint]
ce/ve.ce.Surface.js: line 670, col 9, Too many var statements.
ce/ve.ce.Surface.js: line 695, col 6, Missing semicolon.
ce/ve.ce.Surface.js: line 726, col 22, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 726, col 41, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 733, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 734, col 24, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 1013, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 1019, col 17, Too many var statements.
ce/ve.ce.Surface.js: line 1023, col 18, Too many ar statements.
ce/ve.ce.Surface.js: line 1027, col 13, Too many var statements.
dm/annotations/ve.dm.LinkAnnotation.js: line 70, col 52, Insecure '.'.
dm/ve.dm.Converter.js: line 383, col 29, Empty block.
dm/ve.dm.Converter.js: line 423, col 33, Empty block.
Commands:
* jshint .
* ack '(if|else|function|switch|for|while)\('
* Sublime Text 2:
Find(*): (if|else|function|switch|for|while)\(
Replace: $1 (
* ack ' ' -Q # double spaces, except in certain comments
Change-Id: I8e34bf2924bc8688fdf8acef08bbc4f6707e93be
2012-09-02 21:45:01 +00:00
|
|
|
|
var contentOffset, structuralOffset;
|
2012-04-06 15:10:30 +00:00
|
|
|
|
|
2012-11-20 01:05:34 +00:00
|
|
|
|
direction = direction > 0 ? 1 : -1;
|
2012-06-20 01:20:28 +00:00
|
|
|
|
if (
|
|
|
|
|
ve.dm.Document.isContentOffset( this.documentView.model.data, offset ) ||
|
|
|
|
|
this.hasSlugAtOffset( offset )
|
|
|
|
|
) {
|
|
|
|
|
return offset;
|
2012-03-02 02:07:55 +00:00
|
|
|
|
}
|
2012-06-20 01:20:28 +00:00
|
|
|
|
|
Remainder JSHint fixes on modules/ve/*
[jshint]
ce/ve.ce.Surface.js: line 670, col 9, Too many var statements.
ce/ve.ce.Surface.js: line 695, col 6, Missing semicolon.
ce/ve.ce.Surface.js: line 726, col 22, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 726, col 41, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 733, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 734, col 24, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 1013, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 1019, col 17, Too many var statements.
ce/ve.ce.Surface.js: line 1023, col 18, Too many ar statements.
ce/ve.ce.Surface.js: line 1027, col 13, Too many var statements.
dm/annotations/ve.dm.LinkAnnotation.js: line 70, col 52, Insecure '.'.
dm/ve.dm.Converter.js: line 383, col 29, Empty block.
dm/ve.dm.Converter.js: line 423, col 33, Empty block.
Commands:
* jshint .
* ack '(if|else|function|switch|for|while)\('
* Sublime Text 2:
Find(*): (if|else|function|switch|for|while)\(
Replace: $1 (
* ack ' ' -Q # double spaces, except in certain comments
Change-Id: I8e34bf2924bc8688fdf8acef08bbc4f6707e93be
2012-09-02 21:45:01 +00:00
|
|
|
|
contentOffset = this.documentView.model.getNearestContentOffset( offset, direction );
|
2013-01-15 23:38:49 +00:00
|
|
|
|
structuralOffset =
|
|
|
|
|
this.documentView.model.getNearestStructuralOffset( offset, direction, true );
|
2012-06-20 01:20:28 +00:00
|
|
|
|
|
|
|
|
|
if ( !this.hasSlugAtOffset( structuralOffset ) ) {
|
|
|
|
|
return contentOffset;
|
2012-03-02 00:10:08 +00:00
|
|
|
|
}
|
2012-06-20 01:20:28 +00:00
|
|
|
|
|
|
|
|
|
if ( direction === 1 ) {
|
|
|
|
|
if ( contentOffset < offset ) {
|
|
|
|
|
return structuralOffset;
|
|
|
|
|
} else {
|
|
|
|
|
return Math.min( contentOffset, structuralOffset );
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if ( contentOffset > offset ) {
|
|
|
|
|
return structuralOffset;
|
|
|
|
|
} else {
|
|
|
|
|
return Math.max( contentOffset, structuralOffset );
|
|
|
|
|
}
|
2012-03-02 01:35:34 +00:00
|
|
|
|
}
|
2012-03-02 00:10:08 +00:00
|
|
|
|
};
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Check if an offset is inside a slug.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* TODO: Find a better name and a better place for this method - probably in a document view?
|
|
|
|
|
*
|
|
|
|
|
* @method
|
JSDuck: Generated code documentation!
See CODING.md for how to run it.
Mistakes fixed:
* Warning: Unknown type function
-> Function
* Warning: Unknown type DOMElement
-> HTMLElement
* Warning: Unknown type DOM Node
-> HTMLElement
* Warning: Unknown type Integer
-> Mixed
* Warning: Unknown type Command
-> ve.Command
* Warning: Unknown type any
-> number
* Warning: Unknown type ve.Transaction
-> ve.dm.Transaction
* Warning: Unknown type ve.dm.AnnotationSet
-> ve.AnnotationSet
* Warning: Unknown type false
-> boolean
* Warning: Unknown type ve.dm.AlienNode
ve.dm doesn't have a generic AlienNode like ve.ce
-> Unknown type ve.dm.AlienInlineNode|ve.dm.AlienBlockNode
* Warning: Unknown type ve.ve.Surface
-> ve.ce.Surface
* ve.example.lookupNode:
-> Last @param should be @return
* ve.dm.Transaction.prototype.pushReplace:
-> @param {Array] should be @param {Array}
* Warning: ve.BranchNode.js:27: {@link ve.Node#hasChildren} links to non-existing member
-> (removed)
* Warning: ve.LeafNode.js:21: {@link ve.Node#hasChildren} links to non-existing member
-> (removed)
Differences fixed:
* Variadic arguments are like @param {Type...} [name]
instead of @param {Type} [name...]
* Convert all file headers from /** to /*! because JSDuck tries
to parse all /** blocks and fails to parse with all sorts of
errors for "Global property", "Unnamed property", and
"Duplicate property".
Find: \/\*\*([^@]+)(@copyright)
Replace: /*!$1$2
* Indented blocks are considered code examples.
A few methods had documentation with numbered lists that were
indented, which have now been updated to not be intended.
* The free-form text descriptions are parsed with Markdown,
which requires lists to be separated from paragraphs by an
empty line.
And we should use `backticks` instead of {braces} for inline
code in text paragraphs.
* Doc blocks for classes and their constructor have to be
in the correct order (@constructor, @param, @return must be
before @class, @abstract, @extends etc.)
* `@extends Class` must not have Class {wrapped}
* @throws must start with a {Type}
* @example means something else. It is used for an inline demo
iframe, not code block. For that simply indent with spaces.
* @member means something else.
Non-function properties are marked with @property, not @member.
* To create a link to a class or member, in most cases the name
is enough to create a link. E.g. Foo, Foo.bar, Foo.bar#quux,
where a hash stands for "instance member", so Foo.bar#quux,
links to Foo.bar.prototype.quux (the is not supported, as
"prototype" is considered an implementation detail, it only
indexes class name and method name).
If the magic linker doesn't work for some case, the
verbose syntax is {@link #target label}.
* @property can't have sub-properties (nested @param and @return
values are supported, only @static @property can't be nested).
We only have one case of this, which can be worked around by
moving those in a new virtual class. The code is unaltered
(only moved down so that it isn't with the scope of the main
@class block). ve.dm.TransactionProcessor.processors.
New:
* @mixins: Classes mixed into the current class.
* @event: Events that can be emitted by a class. These are also
inherited by subclasses. (+ @param, @return and @preventable).
So ve.Node#event-attach is inherited to ve.dm.BreakNode,
just like @method is.
* @singleton: Plain objects such as ve, ve.dm, ve.ce were missing
documentation causing a tree error. Documented those as a
JSDuck singleton, which they but just weren't documented yet.
NB: Members of @singleton don't need @static (if present,
triggers a compiler warning).
* @chainable: Shorthand for "@return this". We were using
"@return {classname}" which is ambiguous (returns the same
instance or another instance?), @chainable is specifically
for "@return this". Creates proper labels in the generated
HTML pages.
Removed:
* @mixin: (not to be confused with @mixins). Not supported by
JSDuck. Every class is standalone anyway. Where needed marked
them @class + @abstract instead.
Change-Id: I6a7c9e8ee8f995731bc205d666167874eb2ebe23
2013-01-04 08:54:17 +00:00
|
|
|
|
* @param {number} offset Offset to check for a slug at
|
|
|
|
|
* @returns {boolean} A slug exists at the given offset
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*/
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.ce.Surface.prototype.hasSlugAtOffset = function ( offset ) {
|
2012-11-28 01:29:09 +00:00
|
|
|
|
return !!this.documentView.getSlugAtOffset( offset );
|
2012-06-20 01:20:28 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Get a DOM node and DOM element offset for a document offset.
|
2012-06-20 01:20:28 +00:00
|
|
|
|
*
|
|
|
|
|
* The results of this function are meant to be used with rangy.
|
|
|
|
|
*
|
|
|
|
|
* @method
|
JSDuck: Generated code documentation!
See CODING.md for how to run it.
Mistakes fixed:
* Warning: Unknown type function
-> Function
* Warning: Unknown type DOMElement
-> HTMLElement
* Warning: Unknown type DOM Node
-> HTMLElement
* Warning: Unknown type Integer
-> Mixed
* Warning: Unknown type Command
-> ve.Command
* Warning: Unknown type any
-> number
* Warning: Unknown type ve.Transaction
-> ve.dm.Transaction
* Warning: Unknown type ve.dm.AnnotationSet
-> ve.AnnotationSet
* Warning: Unknown type false
-> boolean
* Warning: Unknown type ve.dm.AlienNode
ve.dm doesn't have a generic AlienNode like ve.ce
-> Unknown type ve.dm.AlienInlineNode|ve.dm.AlienBlockNode
* Warning: Unknown type ve.ve.Surface
-> ve.ce.Surface
* ve.example.lookupNode:
-> Last @param should be @return
* ve.dm.Transaction.prototype.pushReplace:
-> @param {Array] should be @param {Array}
* Warning: ve.BranchNode.js:27: {@link ve.Node#hasChildren} links to non-existing member
-> (removed)
* Warning: ve.LeafNode.js:21: {@link ve.Node#hasChildren} links to non-existing member
-> (removed)
Differences fixed:
* Variadic arguments are like @param {Type...} [name]
instead of @param {Type} [name...]
* Convert all file headers from /** to /*! because JSDuck tries
to parse all /** blocks and fails to parse with all sorts of
errors for "Global property", "Unnamed property", and
"Duplicate property".
Find: \/\*\*([^@]+)(@copyright)
Replace: /*!$1$2
* Indented blocks are considered code examples.
A few methods had documentation with numbered lists that were
indented, which have now been updated to not be intended.
* The free-form text descriptions are parsed with Markdown,
which requires lists to be separated from paragraphs by an
empty line.
And we should use `backticks` instead of {braces} for inline
code in text paragraphs.
* Doc blocks for classes and their constructor have to be
in the correct order (@constructor, @param, @return must be
before @class, @abstract, @extends etc.)
* `@extends Class` must not have Class {wrapped}
* @throws must start with a {Type}
* @example means something else. It is used for an inline demo
iframe, not code block. For that simply indent with spaces.
* @member means something else.
Non-function properties are marked with @property, not @member.
* To create a link to a class or member, in most cases the name
is enough to create a link. E.g. Foo, Foo.bar, Foo.bar#quux,
where a hash stands for "instance member", so Foo.bar#quux,
links to Foo.bar.prototype.quux (the is not supported, as
"prototype" is considered an implementation detail, it only
indexes class name and method name).
If the magic linker doesn't work for some case, the
verbose syntax is {@link #target label}.
* @property can't have sub-properties (nested @param and @return
values are supported, only @static @property can't be nested).
We only have one case of this, which can be worked around by
moving those in a new virtual class. The code is unaltered
(only moved down so that it isn't with the scope of the main
@class block). ve.dm.TransactionProcessor.processors.
New:
* @mixins: Classes mixed into the current class.
* @event: Events that can be emitted by a class. These are also
inherited by subclasses. (+ @param, @return and @preventable).
So ve.Node#event-attach is inherited to ve.dm.BreakNode,
just like @method is.
* @singleton: Plain objects such as ve, ve.dm, ve.ce were missing
documentation causing a tree error. Documented those as a
JSDuck singleton, which they but just weren't documented yet.
NB: Members of @singleton don't need @static (if present,
triggers a compiler warning).
* @chainable: Shorthand for "@return this". We were using
"@return {classname}" which is ambiguous (returns the same
instance or another instance?), @chainable is specifically
for "@return this". Creates proper labels in the generated
HTML pages.
Removed:
* @mixin: (not to be confused with @mixins). Not supported by
JSDuck. Every class is standalone anyway. Where needed marked
them @class + @abstract instead.
Change-Id: I6a7c9e8ee8f995731bc205d666167874eb2ebe23
2013-01-04 08:54:17 +00:00
|
|
|
|
* @param {number} offset Linear model offset
|
2012-06-20 01:20:28 +00:00
|
|
|
|
* @returns {Object} Object containing a node and offset property where node is an HTML element and
|
|
|
|
|
* offset is the position within the element
|
2012-11-26 23:01:35 +00:00
|
|
|
|
* @throws {Error} Offset could not be translated to a DOM element and offset
|
2012-06-20 01:20:28 +00:00
|
|
|
|
*/
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.ce.Surface.prototype.getNodeAndOffset = function ( offset ) {
|
2012-11-20 01:05:34 +00:00
|
|
|
|
var node, startOffset, current, stack, item, $item, length,
|
|
|
|
|
slug = this.documentView.getSlugAtOffset( offset );
|
2012-10-17 19:28:08 +00:00
|
|
|
|
if ( slug ) {
|
|
|
|
|
return { node: slug[0].childNodes[0], offset: 0 };
|
|
|
|
|
}
|
|
|
|
|
node = this.documentView.getNodeFromOffset( offset );
|
|
|
|
|
startOffset = this.documentView.getDocumentNode().getOffsetFromNode( node ) +
|
|
|
|
|
( ( node.isWrapped() ) ? 1 : 0 );
|
|
|
|
|
current = [node.$.contents(), 0];
|
|
|
|
|
stack = [current];
|
2012-03-01 01:28:39 +00:00
|
|
|
|
|
2012-02-13 22:45:18 +00:00
|
|
|
|
while ( stack.length > 0 ) {
|
|
|
|
|
if ( current[1] >= current[0].length ) {
|
|
|
|
|
stack.pop();
|
|
|
|
|
current = stack[ stack.length - 1 ];
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2012-06-20 01:20:28 +00:00
|
|
|
|
item = current[0][current[1]];
|
|
|
|
|
if ( item.nodeType === Node.TEXT_NODE ) {
|
|
|
|
|
length = item.textContent.length;
|
|
|
|
|
if ( offset >= startOffset && offset <= startOffset + length ) {
|
|
|
|
|
return {
|
|
|
|
|
node: item,
|
|
|
|
|
offset: offset - startOffset
|
|
|
|
|
};
|
2012-02-13 22:45:18 +00:00
|
|
|
|
} else {
|
2012-06-20 01:20:28 +00:00
|
|
|
|
startOffset += length;
|
2012-02-13 22:45:18 +00:00
|
|
|
|
}
|
2012-06-20 01:20:28 +00:00
|
|
|
|
} else if ( item.nodeType === Node.ELEMENT_NODE ) {
|
|
|
|
|
$item = current[0].eq( current[1] );
|
|
|
|
|
if ( $item.hasClass('ve-ce-slug') ) {
|
|
|
|
|
if ( offset === startOffset ) {
|
|
|
|
|
return {
|
|
|
|
|
node: $item[0],
|
|
|
|
|
offset: 1
|
|
|
|
|
};
|
2012-02-13 22:45:18 +00:00
|
|
|
|
}
|
2012-06-20 01:20:28 +00:00
|
|
|
|
} else if ( $item.is( '.ve-ce-branchNode, .ve-ce-leafNode' ) ) {
|
|
|
|
|
length = $item.data( 'node' ).model.getOuterLength();
|
|
|
|
|
if ( offset >= startOffset && offset < startOffset + length ) {
|
|
|
|
|
stack.push( [$item.contents(), 0] );
|
|
|
|
|
current[1]++;
|
|
|
|
|
current = stack[stack.length-1];
|
|
|
|
|
continue;
|
|
|
|
|
} else {
|
|
|
|
|
startOffset += length;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2012-02-13 22:45:18 +00:00
|
|
|
|
stack.push( [$item.contents(), 0] );
|
|
|
|
|
current[1]++;
|
|
|
|
|
current = stack[stack.length-1];
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
current[1]++;
|
|
|
|
|
}
|
2012-11-26 23:01:35 +00:00
|
|
|
|
throw new Error( 'Offset could not be translated to a DOM element and offset: ' + offset );
|
2012-02-13 22:45:18 +00:00
|
|
|
|
};
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Check if keyboard shortcut modifier key is pressed.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @param {jQuery.Event} e
|
|
|
|
|
*/
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.ce.Surface.isShortcutKey = function ( e ) {
|
2012-06-21 18:07:18 +00:00
|
|
|
|
if ( e.ctrlKey || e.metaKey ) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-16 21:51:05 +00:00
|
|
|
|
* Get the number of consecutive clicks the user has performed.
|
|
|
|
|
*
|
|
|
|
|
* This is required for supporting double, tripple, etc. clicking across all browsers.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
2013-01-16 21:51:05 +00:00
|
|
|
|
* @param {Event} e Native event object.
|
|
|
|
|
* @returns {number} Number of clicks detected.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*/
|
2013-01-16 21:51:05 +00:00
|
|
|
|
ve.ce.Surface.prototype.getClickCount = function ( e ) {
|
|
|
|
|
if ( !$.browser.msie ) {
|
|
|
|
|
return e.detail;
|
|
|
|
|
}
|
2012-06-29 00:26:10 +00:00
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
var i, response = 1;
|
2012-06-29 00:26:10 +00:00
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
// Add select MouseEvent properties to the beginning of the clickHistory
|
|
|
|
|
this.clickHistory.unshift( {
|
|
|
|
|
x: e.x,
|
|
|
|
|
y: e.y,
|
|
|
|
|
timeStamp: e.timeStamp
|
|
|
|
|
} );
|
2012-06-29 00:26:10 +00:00
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
// Compare history
|
|
|
|
|
if ( this.clickHistory.length > 1 ) {
|
|
|
|
|
for ( i = 0; i < this.clickHistory.length - 1; i++ ) {
|
|
|
|
|
if (
|
|
|
|
|
this.clickHistory[i].x === this.clickHistory[i + 1].x &&
|
|
|
|
|
this.clickHistory[i].y === this.clickHistory[i + 1].y &&
|
|
|
|
|
this.clickHistory[i].timeStamp - this.clickHistory[i + 1].timeStamp < 500
|
|
|
|
|
) {
|
|
|
|
|
response++;
|
|
|
|
|
} else {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2012-06-29 00:26:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-01-16 21:51:05 +00:00
|
|
|
|
// Trim old history if necessary
|
|
|
|
|
if ( this.clickHistory.length > 2 ) {
|
|
|
|
|
this.clickHistory.pop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return response;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/*! Getters */
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the coordinates of the selection anchor.
|
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
*/
|
|
|
|
|
ve.ce.Surface.prototype.getSelectionRect = function () {
|
|
|
|
|
var rangySel = rangy.getSelection();
|
|
|
|
|
return {
|
|
|
|
|
start: rangySel.getStartDocumentPos(),
|
|
|
|
|
end: rangySel.getEndDocumentPos()
|
|
|
|
|
};
|
2012-06-29 00:26:10 +00:00
|
|
|
|
};
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Get the surface model.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @returns {ve.dm.Surface} Surface model
|
|
|
|
|
*/
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.ce.Surface.prototype.getModel = function () {
|
2012-06-20 01:20:28 +00:00
|
|
|
|
return this.model;
|
2012-03-02 01:35:34 +00:00
|
|
|
|
};
|
|
|
|
|
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
|
* Get the document view.
|
Make use of new jshint options
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
2012-08-07 06:02:18 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
* @returns {ve.ce.Document} Document view
|
|
|
|
|
*/
|
Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.
.gitignore:
* Add .DS_Store to the ignore list so that browsing the directories
on Mac OS X, will not add these files to the list of untracked
files.
* Fix missing newline at end of file
.jshintrc
* raises -> throws
* +module (QUnit.module)
* remove 'Node' (as of node-jshint 1.7.2 this is now part of
'browser:true', as it should be)
Authors:
* Adding myself
MWExtension/VisualEditor.php
* Fix default value of wgVisualEditorParsoidURL to not
point to the experimental instance in WMF Labs.
Issues:
* ve.ce.TextNode:
- Fix TODO: Don't perform a useless clone of an already-jQuerified object.
- Use .html() to set html content instead of encapsulating between
two strings. This is slightly faster but more importantly safer,
and prevents situations where the resulting jQuery collection
actually contains 2 elements instead of 1, thus messing up
what .contents() is iterating over.
* ve.ce.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Document.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.Transaction.test.js
- Fix: ReferenceError: assert is not defined
* ve.dm.TransactionProcessor.test.js
- Fix: ReferenceError: assert is not defined
* ext.visualEditor.viewPageTarget
- Missing dependency on 'mediawiki.Title'
Code conventions / Misc cleanup
* Various JSHint warnings.
* Whitespace
* jQuery(): Use '<tag>' for element creation,
use '<valid><xml/></valid>' for parsing
* Use the default operator instead of ternary when the condition and
first value are the same.
x = foo ? foo : bar; -> x = foo || bar;
Because contrary to some programming language (PHP...), in JS the
default operator does not enforce a boolean result but returns the
original value, hence it being called the 'default' operator, as
opposed to the 'or' operator.
* No need to call addClass() twice, it takes a space-separated list
(jQuery splits by space and adds if needed)
* Use .on( event[, selector], fn ) instead of the deprecated
routers to it such as .bind(), .delegate() and .live().
All these three are now built-in and fully compatible with .on()
* Add 'XXX:' comments for suspicious code that I don't want to change
as part of a clean up commit.
* Remove unused variables (several var x = this; where x was not
used anywhere, possibly from boilerplate copy/paste)
* Follows-up Trevor's commit that converts test suites to the new
QUnit format. Also removed the globals since we no longer use those
any more.
Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 08:43:33 +00:00
|
|
|
|
ve.ce.Surface.prototype.getDocument = function () {
|
2012-06-20 19:20:22 +00:00
|
|
|
|
return this.documentView;
|
|
|
|
|
};
|
2012-10-04 20:00:39 +00:00
|
|
|
|
|
|
|
|
|
/**
|
2013-01-16 21:51:05 +00:00
|
|
|
|
* Check if rendering is enabled.
|
2013-01-15 23:38:49 +00:00
|
|
|
|
*
|
2012-10-04 20:00:39 +00:00
|
|
|
|
* @method
|
2013-01-16 21:51:05 +00:00
|
|
|
|
* @returns {boolean} Render is enabled
|
2012-10-04 20:00:39 +00:00
|
|
|
|
*/
|
2013-01-16 21:51:05 +00:00
|
|
|
|
ve.ce.Surface.prototype.isRenderingEnabled = function () {
|
|
|
|
|
return this.renderingEnabled;
|
2012-10-04 20:00:39 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
2013-01-16 21:51:05 +00:00
|
|
|
|
* Enable rendering.
|
2013-01-15 23:38:49 +00:00
|
|
|
|
*
|
2012-10-04 20:00:39 +00:00
|
|
|
|
* @method
|
|
|
|
|
*/
|
2013-01-16 21:51:05 +00:00
|
|
|
|
ve.ce.Surface.prototype.enableRendering = function () {
|
|
|
|
|
this.renderingEnabled = true;
|
2012-10-05 21:54:32 +00:00
|
|
|
|
};
|
2012-12-21 18:51:20 +00:00
|
|
|
|
|
|
|
|
|
/**
|
2013-01-16 21:51:05 +00:00
|
|
|
|
* Disable rendering.
|
2012-12-21 18:51:20 +00:00
|
|
|
|
*
|
|
|
|
|
* @method
|
|
|
|
|
*/
|
2013-01-16 21:51:05 +00:00
|
|
|
|
ve.ce.Surface.prototype.disableRendering = function () {
|
|
|
|
|
this.renderingEnabled = false;
|
2013-01-08 20:43:52 +00:00
|
|
|
|
};
|