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 DataModel Fragment class.
|
2012-08-02 00:59:38 +00:00
|
|
|
*
|
2013-02-19 23:37:34 +00:00
|
|
|
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
|
2012-08-02 00:59:38 +00:00
|
|
|
* @license The MIT License (MIT); see LICENSE.txt
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* DataModel surface fragment.
|
2012-08-02 00:59:38 +00:00
|
|
|
*
|
|
|
|
* @class
|
The Great ve.ui.Surface refactor of 2013
Prologue:
Farewell ve.Editor my good chap… Oh, hey there HTML frames - I didn't
see you there! In a world where iframes are outlaws, and symbols like
document and window are global, there were more than a few assumptions
about which document or window was being used. But fear not - for this
commit (probably) tracks them all down, leaving a trail of
iframe-compatible awesomeness in its wake. With the great ve.ui.Surface
now able to be used inside of iframes, let the reference editing
commence. But there, lurking in the darkness is a DM issue so fierce it
may take Roan and/or Ed up to 3 whole hours to sort it out.
Note to Roan and/or Ed:
Editing references seems to work fine, but when saving the page there
are "no changes" which is a reasonable indication to the contrary.
Objectives:
* Make it possible to have multiple surfaces be instantiated, get along
nicely, and be embedded inside of iframes if needed.
* Make reference content editable within a dialog
Approach:
* Move what's left of ve.Editor to ve.ui.Surface and essentially
obliterate all use of it
* Make even more stuff inherit from ve.Element (long live this.$$)
* Use the correct document or window anywhere it was being assumed to be
the top level one
* Resolve stacking order issues by removing the excessive use of z-index
and introducing global and local overlay elements for each editor
* Add a surface to the reference dialog, load up the reference contents
and save them back on apply
* Actually destroy what we create in ce and ui surfaces
* Add recursive frame offset calculation method to ve.Element
* Moved ve.ce.Surface's getSelectionRect method to the prototype
Bonus:
* Move ve.ce.DocumentNode.css contents to ve.ce.Node.css (not sure why it
was separate in the first place, but I'm likely the one to blame)
* Fix blatant lies in documentation
* Whitespace cleanup here and there
* Get rid of ve.ui.Window overlays - not used or needed
Change-Id: Iede83e7d24f7cb249b6ba3dc45d770445b862e08
2013-05-20 22:45:50 +00:00
|
|
|
*
|
2012-08-02 00:59:38 +00:00
|
|
|
* @constructor
|
|
|
|
* @param {ve.dm.Surface} surface Target surface
|
|
|
|
* @param {ve.Range} [range] Range within target document, current selection used by default
|
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 {boolean} [noAutoSelect] Update the surface's selection when making changes
|
2012-08-02 00:59:38 +00:00
|
|
|
*/
|
2012-10-13 00:29:32 +00:00
|
|
|
ve.dm.SurfaceFragment = function VeDmSurfaceFragment( surface, range, noAutoSelect ) {
|
2012-08-17 17:48:40 +00:00
|
|
|
// Short-circuit for missing-surface null fragment
|
2012-08-02 00:59:38 +00:00
|
|
|
if ( !surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Properties
|
2013-04-22 11:20:26 +00:00
|
|
|
this.surface = surface;
|
2013-04-23 16:05:48 +00:00
|
|
|
this.range = range && range instanceof ve.Range ? range : surface.getSelection();
|
2012-08-17 17:48:40 +00:00
|
|
|
// Short-circuit for invalid range null fragment
|
|
|
|
if ( !this.range ) {
|
|
|
|
return this;
|
|
|
|
}
|
2012-08-02 00:59:38 +00:00
|
|
|
this.document = surface.getDocument();
|
2012-10-13 00:29:32 +00:00
|
|
|
this.noAutoSelect = !!noAutoSelect;
|
2012-08-02 00:59:38 +00:00
|
|
|
|
|
|
|
// Initialization
|
2013-03-20 22:35:05 +00:00
|
|
|
var length = this.document.data.getLength();
|
2013-04-23 16:05:48 +00:00
|
|
|
this.range = new ve.Range(
|
2012-08-02 00:59:38 +00:00
|
|
|
// Clamp range to valid document offsets
|
|
|
|
Math.min( Math.max( this.range.from, 0 ), length ),
|
|
|
|
Math.min( Math.max( this.range.to, 0 ), length )
|
2013-04-23 16:05:48 +00:00
|
|
|
);
|
2013-05-09 21:54:25 +00:00
|
|
|
this.historyPointer = this.document.getCompleteHistoryLength();
|
2012-08-02 00:59:38 +00:00
|
|
|
};
|
|
|
|
|
2013-01-15 23:38:49 +00:00
|
|
|
/* Static Properties */
|
2012-11-20 22:51:24 +00:00
|
|
|
|
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
|
|
|
/**
|
|
|
|
* @static
|
|
|
|
* @property
|
|
|
|
* @inheritable
|
|
|
|
*/
|
2012-11-20 22:51:24 +00:00
|
|
|
ve.dm.SurfaceFragment.static = {};
|
|
|
|
|
2012-08-02 00:59:38 +00:00
|
|
|
/* Methods */
|
|
|
|
|
|
|
|
/**
|
2013-04-22 11:20:26 +00:00
|
|
|
* Update range based on un-applied transactions in the surface.
|
2012-08-02 00:59:38 +00:00
|
|
|
*
|
|
|
|
* @method
|
|
|
|
*/
|
2013-04-22 11:20:26 +00:00
|
|
|
ve.dm.SurfaceFragment.prototype.update = function () {
|
|
|
|
var i, length, txs;
|
|
|
|
// Small optimisation: check history pointer is in the past
|
2013-05-09 21:54:25 +00:00
|
|
|
if ( this.historyPointer < this.document.getCompleteHistoryLength() ) {
|
|
|
|
txs = this.document.getCompleteHistorySince( this.historyPointer );
|
2013-04-22 11:20:26 +00:00
|
|
|
for ( i = 0, length = txs.length; i < length; i++ ) {
|
|
|
|
this.range = txs[i].transaction.translateRange( this.range, txs[i].undo );
|
|
|
|
this.historyPointer++;
|
|
|
|
}
|
2012-08-21 00:49:16 +00:00
|
|
|
}
|
2012-08-02 00:59:38 +00:00
|
|
|
};
|
|
|
|
|
2012-08-17 17:48:40 +00:00
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Get the surface the fragment is a part of.
|
2012-08-17 17:48:40 +00:00
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @returns {ve.dm.Surface} Surface of fragment
|
|
|
|
*/
|
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
|
|
|
ve.dm.SurfaceFragment.prototype.getSurface = function () {
|
2012-08-17 17:48:40 +00:00
|
|
|
return this.surface;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Get the document of the surface the fragment is a part of.
|
2012-08-17 17:48:40 +00:00
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @returns {ve.dm.Document} Document of surface of fragment
|
|
|
|
*/
|
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
|
|
|
ve.dm.SurfaceFragment.prototype.getDocument = function () {
|
2012-08-17 17:48:40 +00:00
|
|
|
return this.document;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Get the range of the fragment within the surface.
|
2012-08-17 17:48:40 +00:00
|
|
|
*
|
2013-04-22 11:20:26 +00:00
|
|
|
* This method also calls update to make sure the range returned is current.
|
|
|
|
*
|
2012-08-17 17:48:40 +00:00
|
|
|
* @method
|
2013-04-22 11:20:26 +00:00
|
|
|
* @param {boolean} noCopy Return the range by reference, not a copy
|
2012-08-17 17:48:40 +00:00
|
|
|
* @returns {ve.Range} Surface range
|
|
|
|
*/
|
2013-04-22 11:20:26 +00:00
|
|
|
ve.dm.SurfaceFragment.prototype.getRange = function ( noCopy ) {
|
|
|
|
this.update();
|
|
|
|
return noCopy ? this.range : this.range.clone();
|
2012-08-17 17:48:40 +00:00
|
|
|
};
|
|
|
|
|
Death and/or destruction
So. It turns out that the design of SurfaceFragment is a little -
shall we say - wonky.
One of the best things about ve.dm.SurfaceFragment is its magical
ability to retain the intention of its range, even as transactions
are being processed. This ability is granted by each fragment
listening to the surface's change event, and responding by using
translateRange for each transaction that gets processed. Surface
fragments also have these clever methods that allow you to get a
fragment based on another, which makes adjusting the range easy to do
inline without having to manually store multiple fragments or
modifying the original.
This sounded good, and we seemed to all be convinced it was well
designed. But if you add a console.log( 'hello' ); to the first line
of ve.dm.SurfaceFragment.prototype.onTransact, and then start using
the bold tool on various selections of text, you will find that there
may indeed be a flaw. What you will probably realize is that the
number of times that particular line of code is being called is
disturbingly large, and increases each time you do just about anything
in the editor. What's going on? How did we get here? Read on…
It turns out that fragments are immortal. We create them, they listen
to the surface's transact event, we are done with them, but the
surface keeps on emitting events to the now long forgotten about
fragments. They continue to build up over time, never go out of scope,
and bloat the hell out of our program.
The same ended up being true of toolbars - and each time the context
menu fired up a new one the old one was left in limbo, still
responding to events, still taking up memory, but not being visible to
the user.
All of this immortality was causing strange and difficult to track
down problems. This patch fixes this by introducing a destroy method.
This method unbinds events, allowing the object to finally fall out of
scope and die - and more importantly stop receiving notifications of
changes.
This is a hack, but Ed will no doubt get this situation sorted out
properly by making fragments lazy-evaluate their selections by only
storing an identifier of the most recent transaction they were based
on, see bug 47343.
Change-Id: I18bb986001a44732a7871b9d79dc3015eedfb168
2013-04-18 18:44:40 +00:00
|
|
|
/**
|
2013-04-22 11:20:26 +00:00
|
|
|
* Check if the fragment is null.
|
Death and/or destruction
So. It turns out that the design of SurfaceFragment is a little -
shall we say - wonky.
One of the best things about ve.dm.SurfaceFragment is its magical
ability to retain the intention of its range, even as transactions
are being processed. This ability is granted by each fragment
listening to the surface's change event, and responding by using
translateRange for each transaction that gets processed. Surface
fragments also have these clever methods that allow you to get a
fragment based on another, which makes adjusting the range easy to do
inline without having to manually store multiple fragments or
modifying the original.
This sounded good, and we seemed to all be convinced it was well
designed. But if you add a console.log( 'hello' ); to the first line
of ve.dm.SurfaceFragment.prototype.onTransact, and then start using
the bold tool on various selections of text, you will find that there
may indeed be a flaw. What you will probably realize is that the
number of times that particular line of code is being called is
disturbingly large, and increases each time you do just about anything
in the editor. What's going on? How did we get here? Read on…
It turns out that fragments are immortal. We create them, they listen
to the surface's transact event, we are done with them, but the
surface keeps on emitting events to the now long forgotten about
fragments. They continue to build up over time, never go out of scope,
and bloat the hell out of our program.
The same ended up being true of toolbars - and each time the context
menu fired up a new one the old one was left in limbo, still
responding to events, still taking up memory, but not being visible to
the user.
All of this immortality was causing strange and difficult to track
down problems. This patch fixes this by introducing a destroy method.
This method unbinds events, allowing the object to finally fall out of
scope and die - and more importantly stop receiving notifications of
changes.
This is a hack, but Ed will no doubt get this situation sorted out
properly by making fragments lazy-evaluate their selections by only
storing an identifier of the most recent transaction they were based
on, see bug 47343.
Change-Id: I18bb986001a44732a7871b9d79dc3015eedfb168
2013-04-18 18:44:40 +00:00
|
|
|
*
|
|
|
|
* @method
|
2013-04-22 11:20:26 +00:00
|
|
|
* @returns {boolean} Fragment is a null fragment
|
Death and/or destruction
So. It turns out that the design of SurfaceFragment is a little -
shall we say - wonky.
One of the best things about ve.dm.SurfaceFragment is its magical
ability to retain the intention of its range, even as transactions
are being processed. This ability is granted by each fragment
listening to the surface's change event, and responding by using
translateRange for each transaction that gets processed. Surface
fragments also have these clever methods that allow you to get a
fragment based on another, which makes adjusting the range easy to do
inline without having to manually store multiple fragments or
modifying the original.
This sounded good, and we seemed to all be convinced it was well
designed. But if you add a console.log( 'hello' ); to the first line
of ve.dm.SurfaceFragment.prototype.onTransact, and then start using
the bold tool on various selections of text, you will find that there
may indeed be a flaw. What you will probably realize is that the
number of times that particular line of code is being called is
disturbingly large, and increases each time you do just about anything
in the editor. What's going on? How did we get here? Read on…
It turns out that fragments are immortal. We create them, they listen
to the surface's transact event, we are done with them, but the
surface keeps on emitting events to the now long forgotten about
fragments. They continue to build up over time, never go out of scope,
and bloat the hell out of our program.
The same ended up being true of toolbars - and each time the context
menu fired up a new one the old one was left in limbo, still
responding to events, still taking up memory, but not being visible to
the user.
All of this immortality was causing strange and difficult to track
down problems. This patch fixes this by introducing a destroy method.
This method unbinds events, allowing the object to finally fall out of
scope and die - and more importantly stop receiving notifications of
changes.
This is a hack, but Ed will no doubt get this situation sorted out
properly by making fragments lazy-evaluate their selections by only
storing an identifier of the most recent transaction they were based
on, see bug 47343.
Change-Id: I18bb986001a44732a7871b9d79dc3015eedfb168
2013-04-18 18:44:40 +00:00
|
|
|
*/
|
2013-04-22 11:20:26 +00:00
|
|
|
ve.dm.SurfaceFragment.prototype.isNull = function () {
|
|
|
|
return this.surface === undefined;
|
Death and/or destruction
So. It turns out that the design of SurfaceFragment is a little -
shall we say - wonky.
One of the best things about ve.dm.SurfaceFragment is its magical
ability to retain the intention of its range, even as transactions
are being processed. This ability is granted by each fragment
listening to the surface's change event, and responding by using
translateRange for each transaction that gets processed. Surface
fragments also have these clever methods that allow you to get a
fragment based on another, which makes adjusting the range easy to do
inline without having to manually store multiple fragments or
modifying the original.
This sounded good, and we seemed to all be convinced it was well
designed. But if you add a console.log( 'hello' ); to the first line
of ve.dm.SurfaceFragment.prototype.onTransact, and then start using
the bold tool on various selections of text, you will find that there
may indeed be a flaw. What you will probably realize is that the
number of times that particular line of code is being called is
disturbingly large, and increases each time you do just about anything
in the editor. What's going on? How did we get here? Read on…
It turns out that fragments are immortal. We create them, they listen
to the surface's transact event, we are done with them, but the
surface keeps on emitting events to the now long forgotten about
fragments. They continue to build up over time, never go out of scope,
and bloat the hell out of our program.
The same ended up being true of toolbars - and each time the context
menu fired up a new one the old one was left in limbo, still
responding to events, still taking up memory, but not being visible to
the user.
All of this immortality was causing strange and difficult to track
down problems. This patch fixes this by introducing a destroy method.
This method unbinds events, allowing the object to finally fall out of
scope and die - and more importantly stop receiving notifications of
changes.
This is a hack, but Ed will no doubt get this situation sorted out
properly by making fragments lazy-evaluate their selections by only
storing an identifier of the most recent transaction they were based
on, see bug 47343.
Change-Id: I18bb986001a44732a7871b9d79dc3015eedfb168
2013-04-18 18:44:40 +00:00
|
|
|
};
|
|
|
|
|
2012-08-02 00:59:38 +00:00
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Get a new fragment with an adjusted position
|
2012-08-02 00:59:38 +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} [start] Adjustment for start position
|
|
|
|
* @param {number} [end] Adjustment for end position
|
2012-08-02 00:59:38 +00:00
|
|
|
* @returns {ve.dm.SurfaceFragment} Adjusted fragment
|
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.adjustRange = function ( start, end ) {
|
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
return new ve.dm.SurfaceFragment(
|
2012-08-17 17:48:40 +00:00
|
|
|
this.surface,
|
2013-04-22 11:20:26 +00:00
|
|
|
new ve.Range( this.getRange( true ).start + ( start || 0 ), this.getRange( true ).end + ( end || 0 ) ),
|
2012-10-13 00:29:32 +00:00
|
|
|
this.noAutoSelect
|
2012-08-02 00:59:38 +00:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
The great inspector and context rewrite of 2012
ve.AnnotationAction
* Added filter to the clearAll method to allow clearing all matching annotations only
ve.dm.Document
* Some variable renaming for consistency
ve.dm.SurfaceFragment
* Added truncateRange method
* Added annotation scope to expandRange method
* Added support for passing an annotation object into annotateContent method
* Switched to using name instead of type in annotateContent method to match the ve.dm.Annotation class
* Fixed logic in annotation mode of expandSelection so that expansion only takes place if the annotation is found
ve.ui.LinkInspector
* Moved most of the functionality elsewhere
* General reorganization
* Changed setOverlayPosition to accept 2 arguments instead of an object with 2 properties and renamed it to positionOverlayBelow
* Check for annotation object before extracting target information from it
* Initialize default target as empty string to avoid undefined being cast to a string and the default target becoming 'undefined'
icons.ai, inspector.png, inspector.svg
* Added generic inspector icon which will be used when a custom icon is not specified in future inspector subclasses
ve.ui.Inspector.Icons
* Added inspector icon
* Renamed clear icon to remove to match it's actual image
ve.ui.Context
* Greatly simplified the interface, reducing the number of methods by inlining a few things and combining others
* Now always listening to resize events on the window rather than only while document is focused
* Not listening to scroll events anymore, they used to affect the top/bottom positioning of the menu which we don't do anymore
* Lots of cleanup and reorganization
* No need to fallback to empty array since getInspectorsForAnnotations does so already
* Only consider fully-covered annotations for inspectors
ve.ui.Frame
* Simplified the constructor by introducing the createFrame method
* General cleanup
* Typo fixes
ve.ui.Inspector
* Generalized lots of functionality previously located in the link inspector class which will be useful to all inspectors (such as title, clear button, saving changes, etc.)
* Added setDisabled and isDisabled methods to manage CSS changes and avoid needing to check the CSS to determine the state of the inspector (storing state in the view is evil)
* Added getMatchingAnnotations method for convenience
* Added prepareSelection stub
* Lots of cleanup and documentation
* Type pattern is now defined in base class
* Added stubs for onOpen and onClose with documentation so that subclass authors know what these methods do
* Removed checks for onOpen or onClose methods since they are now noop stubs and are always there
* Added stub and removed checks for onRemove
* Made esc key close and accept - the illusion is supposed to be that the link changes are applied instantly, even though they are only updated when you close, so all closing except for when removing should apply changes - i.e. esc is now equal to back rather than being a special function that doesn't have an associated affordance
* Only consider fully-covered annotations when getting matching annotations
ve.ui.InspectorFactory
* Depending on type pattern now since it's always there
* Added getInspectorsForAnnotations method
* Return empty array if annotation set is empty
VisualEditor, VisualEditor.i18n
* Added default inspector message
Change-Id: I1cc008445bcbc8cba6754ca4b6ac0397575980d5
2012-11-16 20:40:05 +00:00
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Get a new fragment with a truncated length.
|
The great inspector and context rewrite of 2012
ve.AnnotationAction
* Added filter to the clearAll method to allow clearing all matching annotations only
ve.dm.Document
* Some variable renaming for consistency
ve.dm.SurfaceFragment
* Added truncateRange method
* Added annotation scope to expandRange method
* Added support for passing an annotation object into annotateContent method
* Switched to using name instead of type in annotateContent method to match the ve.dm.Annotation class
* Fixed logic in annotation mode of expandSelection so that expansion only takes place if the annotation is found
ve.ui.LinkInspector
* Moved most of the functionality elsewhere
* General reorganization
* Changed setOverlayPosition to accept 2 arguments instead of an object with 2 properties and renamed it to positionOverlayBelow
* Check for annotation object before extracting target information from it
* Initialize default target as empty string to avoid undefined being cast to a string and the default target becoming 'undefined'
icons.ai, inspector.png, inspector.svg
* Added generic inspector icon which will be used when a custom icon is not specified in future inspector subclasses
ve.ui.Inspector.Icons
* Added inspector icon
* Renamed clear icon to remove to match it's actual image
ve.ui.Context
* Greatly simplified the interface, reducing the number of methods by inlining a few things and combining others
* Now always listening to resize events on the window rather than only while document is focused
* Not listening to scroll events anymore, they used to affect the top/bottom positioning of the menu which we don't do anymore
* Lots of cleanup and reorganization
* No need to fallback to empty array since getInspectorsForAnnotations does so already
* Only consider fully-covered annotations for inspectors
ve.ui.Frame
* Simplified the constructor by introducing the createFrame method
* General cleanup
* Typo fixes
ve.ui.Inspector
* Generalized lots of functionality previously located in the link inspector class which will be useful to all inspectors (such as title, clear button, saving changes, etc.)
* Added setDisabled and isDisabled methods to manage CSS changes and avoid needing to check the CSS to determine the state of the inspector (storing state in the view is evil)
* Added getMatchingAnnotations method for convenience
* Added prepareSelection stub
* Lots of cleanup and documentation
* Type pattern is now defined in base class
* Added stubs for onOpen and onClose with documentation so that subclass authors know what these methods do
* Removed checks for onOpen or onClose methods since they are now noop stubs and are always there
* Added stub and removed checks for onRemove
* Made esc key close and accept - the illusion is supposed to be that the link changes are applied instantly, even though they are only updated when you close, so all closing except for when removing should apply changes - i.e. esc is now equal to back rather than being a special function that doesn't have an associated affordance
* Only consider fully-covered annotations when getting matching annotations
ve.ui.InspectorFactory
* Depending on type pattern now since it's always there
* Added getInspectorsForAnnotations method
* Return empty array if annotation set is empty
VisualEditor, VisualEditor.i18n
* Added default inspector message
Change-Id: I1cc008445bcbc8cba6754ca4b6ac0397575980d5
2012-11-16 20:40:05 +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} limit Maximum length of range (negative for left-side truncation)
|
The great inspector and context rewrite of 2012
ve.AnnotationAction
* Added filter to the clearAll method to allow clearing all matching annotations only
ve.dm.Document
* Some variable renaming for consistency
ve.dm.SurfaceFragment
* Added truncateRange method
* Added annotation scope to expandRange method
* Added support for passing an annotation object into annotateContent method
* Switched to using name instead of type in annotateContent method to match the ve.dm.Annotation class
* Fixed logic in annotation mode of expandSelection so that expansion only takes place if the annotation is found
ve.ui.LinkInspector
* Moved most of the functionality elsewhere
* General reorganization
* Changed setOverlayPosition to accept 2 arguments instead of an object with 2 properties and renamed it to positionOverlayBelow
* Check for annotation object before extracting target information from it
* Initialize default target as empty string to avoid undefined being cast to a string and the default target becoming 'undefined'
icons.ai, inspector.png, inspector.svg
* Added generic inspector icon which will be used when a custom icon is not specified in future inspector subclasses
ve.ui.Inspector.Icons
* Added inspector icon
* Renamed clear icon to remove to match it's actual image
ve.ui.Context
* Greatly simplified the interface, reducing the number of methods by inlining a few things and combining others
* Now always listening to resize events on the window rather than only while document is focused
* Not listening to scroll events anymore, they used to affect the top/bottom positioning of the menu which we don't do anymore
* Lots of cleanup and reorganization
* No need to fallback to empty array since getInspectorsForAnnotations does so already
* Only consider fully-covered annotations for inspectors
ve.ui.Frame
* Simplified the constructor by introducing the createFrame method
* General cleanup
* Typo fixes
ve.ui.Inspector
* Generalized lots of functionality previously located in the link inspector class which will be useful to all inspectors (such as title, clear button, saving changes, etc.)
* Added setDisabled and isDisabled methods to manage CSS changes and avoid needing to check the CSS to determine the state of the inspector (storing state in the view is evil)
* Added getMatchingAnnotations method for convenience
* Added prepareSelection stub
* Lots of cleanup and documentation
* Type pattern is now defined in base class
* Added stubs for onOpen and onClose with documentation so that subclass authors know what these methods do
* Removed checks for onOpen or onClose methods since they are now noop stubs and are always there
* Added stub and removed checks for onRemove
* Made esc key close and accept - the illusion is supposed to be that the link changes are applied instantly, even though they are only updated when you close, so all closing except for when removing should apply changes - i.e. esc is now equal to back rather than being a special function that doesn't have an associated affordance
* Only consider fully-covered annotations when getting matching annotations
ve.ui.InspectorFactory
* Depending on type pattern now since it's always there
* Added getInspectorsForAnnotations method
* Return empty array if annotation set is empty
VisualEditor, VisualEditor.i18n
* Added default inspector message
Change-Id: I1cc008445bcbc8cba6754ca4b6ac0397575980d5
2012-11-16 20:40:05 +00:00
|
|
|
* @returns {ve.dm.SurfaceFragment} Truncated fragment
|
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.truncateRange = function ( limit ) {
|
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
return new ve.dm.SurfaceFragment(
|
|
|
|
this.surface,
|
2013-04-22 11:20:26 +00:00
|
|
|
this.getRange().truncate( limit ),
|
The great inspector and context rewrite of 2012
ve.AnnotationAction
* Added filter to the clearAll method to allow clearing all matching annotations only
ve.dm.Document
* Some variable renaming for consistency
ve.dm.SurfaceFragment
* Added truncateRange method
* Added annotation scope to expandRange method
* Added support for passing an annotation object into annotateContent method
* Switched to using name instead of type in annotateContent method to match the ve.dm.Annotation class
* Fixed logic in annotation mode of expandSelection so that expansion only takes place if the annotation is found
ve.ui.LinkInspector
* Moved most of the functionality elsewhere
* General reorganization
* Changed setOverlayPosition to accept 2 arguments instead of an object with 2 properties and renamed it to positionOverlayBelow
* Check for annotation object before extracting target information from it
* Initialize default target as empty string to avoid undefined being cast to a string and the default target becoming 'undefined'
icons.ai, inspector.png, inspector.svg
* Added generic inspector icon which will be used when a custom icon is not specified in future inspector subclasses
ve.ui.Inspector.Icons
* Added inspector icon
* Renamed clear icon to remove to match it's actual image
ve.ui.Context
* Greatly simplified the interface, reducing the number of methods by inlining a few things and combining others
* Now always listening to resize events on the window rather than only while document is focused
* Not listening to scroll events anymore, they used to affect the top/bottom positioning of the menu which we don't do anymore
* Lots of cleanup and reorganization
* No need to fallback to empty array since getInspectorsForAnnotations does so already
* Only consider fully-covered annotations for inspectors
ve.ui.Frame
* Simplified the constructor by introducing the createFrame method
* General cleanup
* Typo fixes
ve.ui.Inspector
* Generalized lots of functionality previously located in the link inspector class which will be useful to all inspectors (such as title, clear button, saving changes, etc.)
* Added setDisabled and isDisabled methods to manage CSS changes and avoid needing to check the CSS to determine the state of the inspector (storing state in the view is evil)
* Added getMatchingAnnotations method for convenience
* Added prepareSelection stub
* Lots of cleanup and documentation
* Type pattern is now defined in base class
* Added stubs for onOpen and onClose with documentation so that subclass authors know what these methods do
* Removed checks for onOpen or onClose methods since they are now noop stubs and are always there
* Added stub and removed checks for onRemove
* Made esc key close and accept - the illusion is supposed to be that the link changes are applied instantly, even though they are only updated when you close, so all closing except for when removing should apply changes - i.e. esc is now equal to back rather than being a special function that doesn't have an associated affordance
* Only consider fully-covered annotations when getting matching annotations
ve.ui.InspectorFactory
* Depending on type pattern now since it's always there
* Added getInspectorsForAnnotations method
* Return empty array if annotation set is empty
VisualEditor, VisualEditor.i18n
* Added default inspector message
Change-Id: I1cc008445bcbc8cba6754ca4b6ac0397575980d5
2012-11-16 20:40:05 +00:00
|
|
|
this.noAutoSelect
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2012-08-02 00:59:38 +00:00
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Get a new fragment with a zero-length selection at the start offset.
|
2012-08-02 00:59:38 +00:00
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @returns {ve.dm.SurfaceFragment} Collapsed fragment
|
|
|
|
*/
|
2013-04-23 16:05:48 +00:00
|
|
|
ve.dm.SurfaceFragment.prototype.collapseRangeToStart = function () {
|
2012-08-02 00:59:38 +00:00
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
2012-08-10 23:59:50 +00:00
|
|
|
return new ve.dm.SurfaceFragment(
|
2013-04-22 11:20:26 +00:00
|
|
|
this.surface, new ve.Range( this.getRange( true ).start ), this.noAutoSelect
|
2012-08-10 23:59:50 +00:00
|
|
|
);
|
2012-08-02 00:59:38 +00:00
|
|
|
};
|
|
|
|
|
2013-04-23 16:05:48 +00:00
|
|
|
/**
|
|
|
|
* Get a new fragment with a zero-length selection at the end offset.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @returns {ve.dm.SurfaceFragment} Collapsed fragment
|
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.collapseRangeToEnd = function () {
|
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
return new ve.dm.SurfaceFragment(
|
|
|
|
this.surface, new ve.Range( this.getRange( true ).end ), this.noAutoSelect
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
2012-08-02 00:59:38 +00:00
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Get a new fragment with a range that no longer includes leading and trailing whitespace.
|
2012-08-02 00:59:38 +00:00
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @returns {ve.dm.SurfaceFragment} Trimmed fragment
|
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.trimRange = function () {
|
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
2012-12-07 21:49:16 +00:00
|
|
|
// If range is only whitespace
|
2013-04-22 11:20:26 +00:00
|
|
|
if ( this.document.getText( this.getRange() ).trim().length === 0 ) {
|
2012-12-07 21:49:16 +00:00
|
|
|
// Collapse range
|
|
|
|
return new ve.dm.SurfaceFragment(
|
2013-04-22 11:20:26 +00:00
|
|
|
this.surface, new ve.Range( this.getRange( true ).start ), this.noAutoSelect
|
2012-12-07 21:49:16 +00:00
|
|
|
);
|
|
|
|
}
|
2012-08-02 00:59:38 +00:00
|
|
|
return new ve.dm.SurfaceFragment(
|
2013-04-22 11:20:26 +00:00
|
|
|
this.surface, this.document.data.trimOuterSpaceFromRange( this.getRange() ), this.noAutoSelect
|
2012-08-02 00:59:38 +00:00
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Get a new fragment that covers an expanded range of the document.
|
2012-08-02 00:59:38 +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 {string} [scope='parent'] Method of expansion:
|
2013-03-18 11:31:14 +00:00
|
|
|
* - `word`: Expands to cover the nearest word by looking for word breaks (see UnicodeJS.wordbreak)
|
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
|
|
|
* - `annotation`: Expands to cover a given annotation (argument) within the current range
|
|
|
|
* - `root`: Expands to cover the entire document
|
|
|
|
* - `siblings`: Expands to cover all sibling nodes
|
|
|
|
* - `closest`: Expands to cover the closest common ancestor node of a give type (argument)
|
|
|
|
* - `parent`: Expands to cover the closest common parent node
|
The great inspector and context rewrite of 2012
ve.AnnotationAction
* Added filter to the clearAll method to allow clearing all matching annotations only
ve.dm.Document
* Some variable renaming for consistency
ve.dm.SurfaceFragment
* Added truncateRange method
* Added annotation scope to expandRange method
* Added support for passing an annotation object into annotateContent method
* Switched to using name instead of type in annotateContent method to match the ve.dm.Annotation class
* Fixed logic in annotation mode of expandSelection so that expansion only takes place if the annotation is found
ve.ui.LinkInspector
* Moved most of the functionality elsewhere
* General reorganization
* Changed setOverlayPosition to accept 2 arguments instead of an object with 2 properties and renamed it to positionOverlayBelow
* Check for annotation object before extracting target information from it
* Initialize default target as empty string to avoid undefined being cast to a string and the default target becoming 'undefined'
icons.ai, inspector.png, inspector.svg
* Added generic inspector icon which will be used when a custom icon is not specified in future inspector subclasses
ve.ui.Inspector.Icons
* Added inspector icon
* Renamed clear icon to remove to match it's actual image
ve.ui.Context
* Greatly simplified the interface, reducing the number of methods by inlining a few things and combining others
* Now always listening to resize events on the window rather than only while document is focused
* Not listening to scroll events anymore, they used to affect the top/bottom positioning of the menu which we don't do anymore
* Lots of cleanup and reorganization
* No need to fallback to empty array since getInspectorsForAnnotations does so already
* Only consider fully-covered annotations for inspectors
ve.ui.Frame
* Simplified the constructor by introducing the createFrame method
* General cleanup
* Typo fixes
ve.ui.Inspector
* Generalized lots of functionality previously located in the link inspector class which will be useful to all inspectors (such as title, clear button, saving changes, etc.)
* Added setDisabled and isDisabled methods to manage CSS changes and avoid needing to check the CSS to determine the state of the inspector (storing state in the view is evil)
* Added getMatchingAnnotations method for convenience
* Added prepareSelection stub
* Lots of cleanup and documentation
* Type pattern is now defined in base class
* Added stubs for onOpen and onClose with documentation so that subclass authors know what these methods do
* Removed checks for onOpen or onClose methods since they are now noop stubs and are always there
* Added stub and removed checks for onRemove
* Made esc key close and accept - the illusion is supposed to be that the link changes are applied instantly, even though they are only updated when you close, so all closing except for when removing should apply changes - i.e. esc is now equal to back rather than being a special function that doesn't have an associated affordance
* Only consider fully-covered annotations when getting matching annotations
ve.ui.InspectorFactory
* Depending on type pattern now since it's always there
* Added getInspectorsForAnnotations method
* Return empty array if annotation set is empty
VisualEditor, VisualEditor.i18n
* Added default inspector message
Change-Id: I1cc008445bcbc8cba6754ca4b6ac0397575980d5
2012-11-16 20:40:05 +00:00
|
|
|
* @param {Mixed} [type] Parameter to use with scope method if needed
|
2012-08-02 00:59:38 +00:00
|
|
|
* @returns {ve.dm.SurfaceFragment} Expanded fragment
|
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.expandRange = function ( scope, type ) {
|
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
2012-11-21 21:22:29 +00:00
|
|
|
var range, node, nodes, parent;
|
2012-08-02 00:59:38 +00:00
|
|
|
switch ( scope || 'parent' ) {
|
2012-11-20 22:51:24 +00:00
|
|
|
case 'word':
|
2013-04-22 11:20:26 +00:00
|
|
|
if ( this.getRange( true ).getLength() > 0 ) {
|
2013-03-18 11:31:14 +00:00
|
|
|
range = ve.Range.newCoveringRange( [
|
2013-04-22 11:20:26 +00:00
|
|
|
this.document.data.getNearestWordRange( this.getRange( true ).start ),
|
|
|
|
this.document.data.getNearestWordRange( this.getRange( true ).end )
|
2013-03-18 11:31:14 +00:00
|
|
|
] );
|
2013-04-22 11:20:26 +00:00
|
|
|
if ( this.getRange( true ).isBackwards() ) {
|
2013-03-18 11:31:14 +00:00
|
|
|
range = range.flip();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// optimisation for zero-length ranges
|
2013-04-22 11:20:26 +00:00
|
|
|
range = this.document.data.getNearestWordRange( this.getRange( true ).start );
|
2013-03-18 11:31:14 +00:00
|
|
|
}
|
2012-11-20 22:51:24 +00:00
|
|
|
break;
|
The great inspector and context rewrite of 2012
ve.AnnotationAction
* Added filter to the clearAll method to allow clearing all matching annotations only
ve.dm.Document
* Some variable renaming for consistency
ve.dm.SurfaceFragment
* Added truncateRange method
* Added annotation scope to expandRange method
* Added support for passing an annotation object into annotateContent method
* Switched to using name instead of type in annotateContent method to match the ve.dm.Annotation class
* Fixed logic in annotation mode of expandSelection so that expansion only takes place if the annotation is found
ve.ui.LinkInspector
* Moved most of the functionality elsewhere
* General reorganization
* Changed setOverlayPosition to accept 2 arguments instead of an object with 2 properties and renamed it to positionOverlayBelow
* Check for annotation object before extracting target information from it
* Initialize default target as empty string to avoid undefined being cast to a string and the default target becoming 'undefined'
icons.ai, inspector.png, inspector.svg
* Added generic inspector icon which will be used when a custom icon is not specified in future inspector subclasses
ve.ui.Inspector.Icons
* Added inspector icon
* Renamed clear icon to remove to match it's actual image
ve.ui.Context
* Greatly simplified the interface, reducing the number of methods by inlining a few things and combining others
* Now always listening to resize events on the window rather than only while document is focused
* Not listening to scroll events anymore, they used to affect the top/bottom positioning of the menu which we don't do anymore
* Lots of cleanup and reorganization
* No need to fallback to empty array since getInspectorsForAnnotations does so already
* Only consider fully-covered annotations for inspectors
ve.ui.Frame
* Simplified the constructor by introducing the createFrame method
* General cleanup
* Typo fixes
ve.ui.Inspector
* Generalized lots of functionality previously located in the link inspector class which will be useful to all inspectors (such as title, clear button, saving changes, etc.)
* Added setDisabled and isDisabled methods to manage CSS changes and avoid needing to check the CSS to determine the state of the inspector (storing state in the view is evil)
* Added getMatchingAnnotations method for convenience
* Added prepareSelection stub
* Lots of cleanup and documentation
* Type pattern is now defined in base class
* Added stubs for onOpen and onClose with documentation so that subclass authors know what these methods do
* Removed checks for onOpen or onClose methods since they are now noop stubs and are always there
* Added stub and removed checks for onRemove
* Made esc key close and accept - the illusion is supposed to be that the link changes are applied instantly, even though they are only updated when you close, so all closing except for when removing should apply changes - i.e. esc is now equal to back rather than being a special function that doesn't have an associated affordance
* Only consider fully-covered annotations when getting matching annotations
ve.ui.InspectorFactory
* Depending on type pattern now since it's always there
* Added getInspectorsForAnnotations method
* Return empty array if annotation set is empty
VisualEditor, VisualEditor.i18n
* Added default inspector message
Change-Id: I1cc008445bcbc8cba6754ca4b6ac0397575980d5
2012-11-16 20:40:05 +00:00
|
|
|
case 'annotation':
|
2013-04-22 11:20:26 +00:00
|
|
|
range = this.document.data.getAnnotatedRangeFromSelection( this.getRange(), type );
|
The great inspector and context rewrite of 2012
ve.AnnotationAction
* Added filter to the clearAll method to allow clearing all matching annotations only
ve.dm.Document
* Some variable renaming for consistency
ve.dm.SurfaceFragment
* Added truncateRange method
* Added annotation scope to expandRange method
* Added support for passing an annotation object into annotateContent method
* Switched to using name instead of type in annotateContent method to match the ve.dm.Annotation class
* Fixed logic in annotation mode of expandSelection so that expansion only takes place if the annotation is found
ve.ui.LinkInspector
* Moved most of the functionality elsewhere
* General reorganization
* Changed setOverlayPosition to accept 2 arguments instead of an object with 2 properties and renamed it to positionOverlayBelow
* Check for annotation object before extracting target information from it
* Initialize default target as empty string to avoid undefined being cast to a string and the default target becoming 'undefined'
icons.ai, inspector.png, inspector.svg
* Added generic inspector icon which will be used when a custom icon is not specified in future inspector subclasses
ve.ui.Inspector.Icons
* Added inspector icon
* Renamed clear icon to remove to match it's actual image
ve.ui.Context
* Greatly simplified the interface, reducing the number of methods by inlining a few things and combining others
* Now always listening to resize events on the window rather than only while document is focused
* Not listening to scroll events anymore, they used to affect the top/bottom positioning of the menu which we don't do anymore
* Lots of cleanup and reorganization
* No need to fallback to empty array since getInspectorsForAnnotations does so already
* Only consider fully-covered annotations for inspectors
ve.ui.Frame
* Simplified the constructor by introducing the createFrame method
* General cleanup
* Typo fixes
ve.ui.Inspector
* Generalized lots of functionality previously located in the link inspector class which will be useful to all inspectors (such as title, clear button, saving changes, etc.)
* Added setDisabled and isDisabled methods to manage CSS changes and avoid needing to check the CSS to determine the state of the inspector (storing state in the view is evil)
* Added getMatchingAnnotations method for convenience
* Added prepareSelection stub
* Lots of cleanup and documentation
* Type pattern is now defined in base class
* Added stubs for onOpen and onClose with documentation so that subclass authors know what these methods do
* Removed checks for onOpen or onClose methods since they are now noop stubs and are always there
* Added stub and removed checks for onRemove
* Made esc key close and accept - the illusion is supposed to be that the link changes are applied instantly, even though they are only updated when you close, so all closing except for when removing should apply changes - i.e. esc is now equal to back rather than being a special function that doesn't have an associated affordance
* Only consider fully-covered annotations when getting matching annotations
ve.ui.InspectorFactory
* Depending on type pattern now since it's always there
* Added getInspectorsForAnnotations method
* Return empty array if annotation set is empty
VisualEditor, VisualEditor.i18n
* Added default inspector message
Change-Id: I1cc008445bcbc8cba6754ca4b6ac0397575980d5
2012-11-16 20:40:05 +00:00
|
|
|
// Adjust selection if it does not contain the annotated range
|
2013-04-22 11:20:26 +00:00
|
|
|
if ( this.getRange( true ).start > range.start || this.getRange( true ).end < range.end ) {
|
2012-11-28 01:29:09 +00:00
|
|
|
// Maintain range direction
|
2013-04-22 11:20:26 +00:00
|
|
|
if ( this.getRange( true ).from > this.getRange( true ).to ) {
|
(bug 42925) Inspector doesn't open properly
ve.Range
* Rewrote truncate so that it works as expected, truncation should always reduce the length using the start/end values, not the from/to values
ve.ui.Inspector
* Added a comment about where the name argument to onBeforeInspectorOpen comes from, since it's a little bit confusing on first read (and I wrote it!)
* Calling onInitialize, onOpen and onClose methods directly, since we need to control the before or after-ness of listeners getting in there and doing their stuff - plus it's more direct
* Removed onRemove stub, which is never actually called
* Added before/after versions of initialize, open and close events
* Got rid of recursion guard since we don't need it anymore thanks to changes made in ve.dm.Surface (see below)
ve.ui.Context
* Updated event names to deal with new before/after naming of initialize, open and close events
* Removed fade-in logic since fading in doesn't even work anymore - since now we now annotate first, then open the inspector, the menu will actually exist and be open when we open the inspector even though you don't see it because it's quickly obscured
ve.ui.LinkInspector
* Made fragments non-auto selecting, in the case of onInitialize we actually call select(), which is silly since we were using an auto-selecting fragment - it's clear that this was a mistake
ve.dm.Surface
* Moved locking (polling stop and start) to the far outside edges of the change method
* I need a lot of eyes and testing on this change, it seems OK to me, but I'm suspicious that it may have side effects
* What was happening is that selection changes were being applied and then the poll was picking them up, and then the selection was coming in again as a change, but it wasn't a change at all, it was just feedback - this change event was then closing the inspector the instant it was opened - the odd part was that this only occurred when you selected backwards, which seems to be caused by the range being normalized, so it looked like a new selection even though it wasn't
ve.dm.Document
* trimOuterSpace from Range didn't consider annotated spaces to be spaces, by using the [0] trick (first character of a plain text character string or first element in an annotated character's array both are the character's value - but elements don't have a property named '0' so it skips those safely as well) we can always get the right value for comparison
Change-Id: I0873d906c058203b83b8d4bbe5a4b274f05a26fd
2012-12-10 21:36:28 +00:00
|
|
|
range = range.flip();
|
The great inspector and context rewrite of 2012
ve.AnnotationAction
* Added filter to the clearAll method to allow clearing all matching annotations only
ve.dm.Document
* Some variable renaming for consistency
ve.dm.SurfaceFragment
* Added truncateRange method
* Added annotation scope to expandRange method
* Added support for passing an annotation object into annotateContent method
* Switched to using name instead of type in annotateContent method to match the ve.dm.Annotation class
* Fixed logic in annotation mode of expandSelection so that expansion only takes place if the annotation is found
ve.ui.LinkInspector
* Moved most of the functionality elsewhere
* General reorganization
* Changed setOverlayPosition to accept 2 arguments instead of an object with 2 properties and renamed it to positionOverlayBelow
* Check for annotation object before extracting target information from it
* Initialize default target as empty string to avoid undefined being cast to a string and the default target becoming 'undefined'
icons.ai, inspector.png, inspector.svg
* Added generic inspector icon which will be used when a custom icon is not specified in future inspector subclasses
ve.ui.Inspector.Icons
* Added inspector icon
* Renamed clear icon to remove to match it's actual image
ve.ui.Context
* Greatly simplified the interface, reducing the number of methods by inlining a few things and combining others
* Now always listening to resize events on the window rather than only while document is focused
* Not listening to scroll events anymore, they used to affect the top/bottom positioning of the menu which we don't do anymore
* Lots of cleanup and reorganization
* No need to fallback to empty array since getInspectorsForAnnotations does so already
* Only consider fully-covered annotations for inspectors
ve.ui.Frame
* Simplified the constructor by introducing the createFrame method
* General cleanup
* Typo fixes
ve.ui.Inspector
* Generalized lots of functionality previously located in the link inspector class which will be useful to all inspectors (such as title, clear button, saving changes, etc.)
* Added setDisabled and isDisabled methods to manage CSS changes and avoid needing to check the CSS to determine the state of the inspector (storing state in the view is evil)
* Added getMatchingAnnotations method for convenience
* Added prepareSelection stub
* Lots of cleanup and documentation
* Type pattern is now defined in base class
* Added stubs for onOpen and onClose with documentation so that subclass authors know what these methods do
* Removed checks for onOpen or onClose methods since they are now noop stubs and are always there
* Added stub and removed checks for onRemove
* Made esc key close and accept - the illusion is supposed to be that the link changes are applied instantly, even though they are only updated when you close, so all closing except for when removing should apply changes - i.e. esc is now equal to back rather than being a special function that doesn't have an associated affordance
* Only consider fully-covered annotations when getting matching annotations
ve.ui.InspectorFactory
* Depending on type pattern now since it's always there
* Added getInspectorsForAnnotations method
* Return empty array if annotation set is empty
VisualEditor, VisualEditor.i18n
* Added default inspector message
Change-Id: I1cc008445bcbc8cba6754ca4b6ac0397575980d5
2012-11-16 20:40:05 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Otherwise just keep the range as is
|
2013-04-22 11:20:26 +00:00
|
|
|
range = this.getRange();
|
The great inspector and context rewrite of 2012
ve.AnnotationAction
* Added filter to the clearAll method to allow clearing all matching annotations only
ve.dm.Document
* Some variable renaming for consistency
ve.dm.SurfaceFragment
* Added truncateRange method
* Added annotation scope to expandRange method
* Added support for passing an annotation object into annotateContent method
* Switched to using name instead of type in annotateContent method to match the ve.dm.Annotation class
* Fixed logic in annotation mode of expandSelection so that expansion only takes place if the annotation is found
ve.ui.LinkInspector
* Moved most of the functionality elsewhere
* General reorganization
* Changed setOverlayPosition to accept 2 arguments instead of an object with 2 properties and renamed it to positionOverlayBelow
* Check for annotation object before extracting target information from it
* Initialize default target as empty string to avoid undefined being cast to a string and the default target becoming 'undefined'
icons.ai, inspector.png, inspector.svg
* Added generic inspector icon which will be used when a custom icon is not specified in future inspector subclasses
ve.ui.Inspector.Icons
* Added inspector icon
* Renamed clear icon to remove to match it's actual image
ve.ui.Context
* Greatly simplified the interface, reducing the number of methods by inlining a few things and combining others
* Now always listening to resize events on the window rather than only while document is focused
* Not listening to scroll events anymore, they used to affect the top/bottom positioning of the menu which we don't do anymore
* Lots of cleanup and reorganization
* No need to fallback to empty array since getInspectorsForAnnotations does so already
* Only consider fully-covered annotations for inspectors
ve.ui.Frame
* Simplified the constructor by introducing the createFrame method
* General cleanup
* Typo fixes
ve.ui.Inspector
* Generalized lots of functionality previously located in the link inspector class which will be useful to all inspectors (such as title, clear button, saving changes, etc.)
* Added setDisabled and isDisabled methods to manage CSS changes and avoid needing to check the CSS to determine the state of the inspector (storing state in the view is evil)
* Added getMatchingAnnotations method for convenience
* Added prepareSelection stub
* Lots of cleanup and documentation
* Type pattern is now defined in base class
* Added stubs for onOpen and onClose with documentation so that subclass authors know what these methods do
* Removed checks for onOpen or onClose methods since they are now noop stubs and are always there
* Added stub and removed checks for onRemove
* Made esc key close and accept - the illusion is supposed to be that the link changes are applied instantly, even though they are only updated when you close, so all closing except for when removing should apply changes - i.e. esc is now equal to back rather than being a special function that doesn't have an associated affordance
* Only consider fully-covered annotations when getting matching annotations
ve.ui.InspectorFactory
* Depending on type pattern now since it's always there
* Added getInspectorsForAnnotations method
* Return empty array if annotation set is empty
VisualEditor, VisualEditor.i18n
* Added default inspector message
Change-Id: I1cc008445bcbc8cba6754ca4b6ac0397575980d5
2012-11-16 20:40:05 +00:00
|
|
|
}
|
|
|
|
break;
|
2012-08-02 00:59:38 +00:00
|
|
|
case 'root':
|
|
|
|
range = new ve.Range( 0, this.document.getData().length );
|
|
|
|
break;
|
|
|
|
case 'siblings':
|
|
|
|
// Grow range to cover all siblings
|
2013-04-22 11:20:26 +00:00
|
|
|
nodes = this.document.selectNodes( this.getRange(), 'siblings' );
|
2012-08-02 00:59:38 +00:00
|
|
|
if ( nodes.length === 1 ) {
|
|
|
|
range = nodes[0].node.getOuterRange();
|
|
|
|
} else {
|
|
|
|
range = new ve.Range(
|
|
|
|
nodes[0].node.getOuterRange().start,
|
|
|
|
nodes[nodes.length - 1].node.getOuterRange().end
|
|
|
|
);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'closest':
|
|
|
|
// Grow range to cover closest common ancestor node of given type
|
2013-04-22 11:20:26 +00:00
|
|
|
node = this.document.selectNodes( this.getRange(), 'siblings' )[0].node;
|
2012-08-02 00:59:38 +00:00
|
|
|
parent = node.getParent();
|
2012-08-17 17:48:40 +00:00
|
|
|
while ( parent && parent.getType() !== type ) {
|
2012-08-02 00:59:38 +00:00
|
|
|
node = parent;
|
|
|
|
parent = parent.getParent();
|
2012-08-17 17:48:40 +00:00
|
|
|
}
|
|
|
|
if ( !parent ) {
|
|
|
|
return new ve.dm.SurfaceFragment( null );
|
2012-08-02 00:59:38 +00:00
|
|
|
}
|
|
|
|
range = parent.getOuterRange();
|
|
|
|
break;
|
|
|
|
case 'parent':
|
|
|
|
// Grow range to cover the closest common parent node
|
2013-04-22 11:20:26 +00:00
|
|
|
node = this.document.selectNodes( this.getRange(), 'siblings' )[0].node;
|
2012-08-02 00:59:38 +00:00
|
|
|
parent = node.getParent();
|
|
|
|
if ( !parent ) {
|
|
|
|
return new ve.dm.SurfaceFragment( null );
|
|
|
|
}
|
|
|
|
range = parent.getOuterRange();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw new Error( 'Invalid scope argument: ' + scope );
|
|
|
|
}
|
2012-10-13 00:29:32 +00:00
|
|
|
return new ve.dm.SurfaceFragment( this.surface, range, this.noAutoSelect );
|
2012-08-10 23:59:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Check if the surface's selection will be updated automatically when changes are made.
|
2012-08-10 23:59:50 +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
|
|
|
* @returns {boolean} Will automatically update surface selection
|
2012-08-10 23:59:50 +00:00
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.willAutoSelect = function () {
|
2012-10-13 00:29:32 +00:00
|
|
|
return !this.noAutoSelect;
|
2012-08-02 00:59:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get data for the fragment.
|
|
|
|
*
|
|
|
|
* @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 {boolean} [deep] Get a deep copy of the data
|
2012-08-02 00:59:38 +00:00
|
|
|
* @returns {Array} Fragment data
|
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.getData = function ( deep ) {
|
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return [];
|
|
|
|
}
|
2013-04-22 11:20:26 +00:00
|
|
|
return this.document.getData( this.getRange(), deep );
|
2012-08-02 00:59:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get plain text for the fragment.
|
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @returns {Array} Fragment text
|
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.getText = function () {
|
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
var i, length,
|
|
|
|
text = '',
|
2013-04-22 11:20:26 +00:00
|
|
|
data = this.document.getData( this.getRange() );
|
2012-08-02 00:59:38 +00:00
|
|
|
for ( i = 0, length = data.length; i < length; i++ ) {
|
|
|
|
if ( data[i].type === undefined ) {
|
|
|
|
// Annotated characters have a string at index 0, plain characters are 1-char strings
|
|
|
|
text += typeof data[i] === 'string' ? data[i] : data[i][0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return text;
|
|
|
|
};
|
|
|
|
|
2012-10-24 21:56:26 +00:00
|
|
|
/**
|
|
|
|
* Get annotations in fragment.
|
|
|
|
*
|
|
|
|
* By default, this will only get annotations that completely cover the fragment. Use the {all}
|
|
|
|
* argument to get all annotations that occur within the fragment.
|
|
|
|
*
|
|
|
|
* @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 {boolean} [all] Get annotations cover some of the fragment
|
2013-03-20 22:35:05 +00:00
|
|
|
* @returns {ve.dm.AnnotationSet} All annotation objects range is covered by
|
2012-10-24 21:56:26 +00:00
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.getAnnotations = function ( all ) {
|
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
2013-03-20 22:35:05 +00:00
|
|
|
return new ve.dm.AnnotationSet( this.getDocument().getStore() );
|
2012-10-24 21:56:26 +00:00
|
|
|
}
|
2013-04-22 11:20:26 +00:00
|
|
|
if ( this.getRange( true ).getLength() ) {
|
|
|
|
return this.getDocument().data.getAnnotationsFromRange( this.getRange(), all );
|
2012-10-24 21:56:26 +00:00
|
|
|
} else {
|
2012-11-16 22:57:20 +00:00
|
|
|
return this.surface.getInsertionAnnotations();
|
2012-10-24 21:56:26 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2012-08-10 23:59:50 +00:00
|
|
|
/**
|
|
|
|
* Get all leaf nodes covered by the fragment.
|
|
|
|
*
|
2013-03-20 07:09:43 +00:00
|
|
|
* @see ve.Document#selectNodes Used to get the return value
|
2012-08-10 23:59:50 +00:00
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @returns {Array} List of nodes and related information
|
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.getLeafNodes = function () {
|
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return [];
|
|
|
|
}
|
2013-04-22 11:20:26 +00:00
|
|
|
return this.document.selectNodes( this.getRange(), 'leaves' );
|
2012-08-10 23:59:50 +00:00
|
|
|
};
|
|
|
|
|
2012-08-02 00:59:38 +00:00
|
|
|
/**
|
|
|
|
* Get nodes covered by the fragment.
|
|
|
|
*
|
2012-08-10 23:59:50 +00:00
|
|
|
* Does not descend into nodes that are entirely covered by the range. The result is
|
|
|
|
* similar to that of {ve.dm.SurfaceFragment.prototype.getLeafNodes} except that if a node is
|
|
|
|
* entirely covered, its children aren't returned separately.
|
|
|
|
*
|
2013-03-20 07:09:43 +00:00
|
|
|
* @see ve.Document#selectNodes for more information about the return value
|
2012-08-02 00:59:38 +00:00
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @returns {Array} List of nodes and related information
|
|
|
|
*/
|
2012-08-10 23:59:50 +00:00
|
|
|
ve.dm.SurfaceFragment.prototype.getCoveredNodes = function () {
|
2012-08-02 00:59:38 +00:00
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return [];
|
|
|
|
}
|
2013-04-22 11:20:26 +00:00
|
|
|
return this.document.selectNodes( this.getRange(), 'coveredNodes' );
|
2012-08-10 23:59:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get nodes covered by the fragment.
|
|
|
|
*
|
|
|
|
* Includes adjacent siblings covered by the range, descending if the range is in a single node.
|
|
|
|
*
|
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
|
|
|
* @see ve.Document#selectNodes for more information about the return value.
|
2012-08-10 23:59:50 +00:00
|
|
|
*
|
|
|
|
* @method
|
|
|
|
* @returns {Array} List of nodes and related information
|
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.getSiblingNodes = function () {
|
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return [];
|
|
|
|
}
|
2013-04-22 11:20:26 +00:00
|
|
|
return this.document.selectNodes( this.getRange(), 'siblings' );
|
2012-08-10 23:59:50 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Change whether to automatically update the surface selection when making changes.
|
2012-08-10 23:59:50 +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 {boolean} [value=true] Automatically update surface selection
|
2013-02-23 10:11:02 +00:00
|
|
|
* @chainable
|
2012-08-10 23:59:50 +00:00
|
|
|
*/
|
2012-10-05 18:07:10 +00:00
|
|
|
ve.dm.SurfaceFragment.prototype.setAutoSelect = function ( value ) {
|
2012-10-13 00:29:32 +00:00
|
|
|
this.noAutoSelect = !value;
|
2012-08-10 23:59:50 +00:00
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Apply the fragment's range to the surface as a selection.
|
2012-08-10 23:59:50 +00:00
|
|
|
*
|
|
|
|
* @method
|
2013-02-23 10:11:02 +00:00
|
|
|
* @chainable
|
2012-08-10 23:59:50 +00:00
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.select = function () {
|
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
2013-04-22 11:20:26 +00:00
|
|
|
this.surface.change( null, this.getRange() );
|
2012-08-10 23:59:50 +00:00
|
|
|
return this;
|
2012-08-02 00:59:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Apply an annotation to content in the fragment.
|
2012-08-02 00:59:38 +00:00
|
|
|
*
|
|
|
|
* To avoid problems identified in bug 33108, use the {ve.dm.SurfaceFragment.trimRange} method.
|
|
|
|
*
|
The great inspector and context rewrite of 2012
ve.AnnotationAction
* Added filter to the clearAll method to allow clearing all matching annotations only
ve.dm.Document
* Some variable renaming for consistency
ve.dm.SurfaceFragment
* Added truncateRange method
* Added annotation scope to expandRange method
* Added support for passing an annotation object into annotateContent method
* Switched to using name instead of type in annotateContent method to match the ve.dm.Annotation class
* Fixed logic in annotation mode of expandSelection so that expansion only takes place if the annotation is found
ve.ui.LinkInspector
* Moved most of the functionality elsewhere
* General reorganization
* Changed setOverlayPosition to accept 2 arguments instead of an object with 2 properties and renamed it to positionOverlayBelow
* Check for annotation object before extracting target information from it
* Initialize default target as empty string to avoid undefined being cast to a string and the default target becoming 'undefined'
icons.ai, inspector.png, inspector.svg
* Added generic inspector icon which will be used when a custom icon is not specified in future inspector subclasses
ve.ui.Inspector.Icons
* Added inspector icon
* Renamed clear icon to remove to match it's actual image
ve.ui.Context
* Greatly simplified the interface, reducing the number of methods by inlining a few things and combining others
* Now always listening to resize events on the window rather than only while document is focused
* Not listening to scroll events anymore, they used to affect the top/bottom positioning of the menu which we don't do anymore
* Lots of cleanup and reorganization
* No need to fallback to empty array since getInspectorsForAnnotations does so already
* Only consider fully-covered annotations for inspectors
ve.ui.Frame
* Simplified the constructor by introducing the createFrame method
* General cleanup
* Typo fixes
ve.ui.Inspector
* Generalized lots of functionality previously located in the link inspector class which will be useful to all inspectors (such as title, clear button, saving changes, etc.)
* Added setDisabled and isDisabled methods to manage CSS changes and avoid needing to check the CSS to determine the state of the inspector (storing state in the view is evil)
* Added getMatchingAnnotations method for convenience
* Added prepareSelection stub
* Lots of cleanup and documentation
* Type pattern is now defined in base class
* Added stubs for onOpen and onClose with documentation so that subclass authors know what these methods do
* Removed checks for onOpen or onClose methods since they are now noop stubs and are always there
* Added stub and removed checks for onRemove
* Made esc key close and accept - the illusion is supposed to be that the link changes are applied instantly, even though they are only updated when you close, so all closing except for when removing should apply changes - i.e. esc is now equal to back rather than being a special function that doesn't have an associated affordance
* Only consider fully-covered annotations when getting matching annotations
ve.ui.InspectorFactory
* Depending on type pattern now since it's always there
* Added getInspectorsForAnnotations method
* Return empty array if annotation set is empty
VisualEditor, VisualEditor.i18n
* Added default inspector message
Change-Id: I1cc008445bcbc8cba6754ca4b6ac0397575980d5
2012-11-16 20:40:05 +00:00
|
|
|
* TODO: Optionally take an annotation set instead of name and data arguments and set/clear multiple
|
2012-10-24 21:34:01 +00:00
|
|
|
* annotations in a single transaction.
|
|
|
|
*
|
2012-08-02 00:59:38 +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 {string} method Mode of annotation, either 'set' or 'clear'
|
2013-03-20 22:35:05 +00:00
|
|
|
* @param {string|ve.dm.Annotation} nameOrAnnotation Annotation name, for example: 'textStyle/bold' or
|
The great inspector and context rewrite of 2012
ve.AnnotationAction
* Added filter to the clearAll method to allow clearing all matching annotations only
ve.dm.Document
* Some variable renaming for consistency
ve.dm.SurfaceFragment
* Added truncateRange method
* Added annotation scope to expandRange method
* Added support for passing an annotation object into annotateContent method
* Switched to using name instead of type in annotateContent method to match the ve.dm.Annotation class
* Fixed logic in annotation mode of expandSelection so that expansion only takes place if the annotation is found
ve.ui.LinkInspector
* Moved most of the functionality elsewhere
* General reorganization
* Changed setOverlayPosition to accept 2 arguments instead of an object with 2 properties and renamed it to positionOverlayBelow
* Check for annotation object before extracting target information from it
* Initialize default target as empty string to avoid undefined being cast to a string and the default target becoming 'undefined'
icons.ai, inspector.png, inspector.svg
* Added generic inspector icon which will be used when a custom icon is not specified in future inspector subclasses
ve.ui.Inspector.Icons
* Added inspector icon
* Renamed clear icon to remove to match it's actual image
ve.ui.Context
* Greatly simplified the interface, reducing the number of methods by inlining a few things and combining others
* Now always listening to resize events on the window rather than only while document is focused
* Not listening to scroll events anymore, they used to affect the top/bottom positioning of the menu which we don't do anymore
* Lots of cleanup and reorganization
* No need to fallback to empty array since getInspectorsForAnnotations does so already
* Only consider fully-covered annotations for inspectors
ve.ui.Frame
* Simplified the constructor by introducing the createFrame method
* General cleanup
* Typo fixes
ve.ui.Inspector
* Generalized lots of functionality previously located in the link inspector class which will be useful to all inspectors (such as title, clear button, saving changes, etc.)
* Added setDisabled and isDisabled methods to manage CSS changes and avoid needing to check the CSS to determine the state of the inspector (storing state in the view is evil)
* Added getMatchingAnnotations method for convenience
* Added prepareSelection stub
* Lots of cleanup and documentation
* Type pattern is now defined in base class
* Added stubs for onOpen and onClose with documentation so that subclass authors know what these methods do
* Removed checks for onOpen or onClose methods since they are now noop stubs and are always there
* Added stub and removed checks for onRemove
* Made esc key close and accept - the illusion is supposed to be that the link changes are applied instantly, even though they are only updated when you close, so all closing except for when removing should apply changes - i.e. esc is now equal to back rather than being a special function that doesn't have an associated affordance
* Only consider fully-covered annotations when getting matching annotations
ve.ui.InspectorFactory
* Depending on type pattern now since it's always there
* Added getInspectorsForAnnotations method
* Return empty array if annotation set is empty
VisualEditor, VisualEditor.i18n
* Added default inspector message
Change-Id: I1cc008445bcbc8cba6754ca4b6ac0397575980d5
2012-11-16 20:40:05 +00:00
|
|
|
* Annotation object
|
|
|
|
* @param {Object} [data] Additional annotation data (not used if annotation object is given)
|
2013-02-23 10:11:02 +00:00
|
|
|
* @chainable
|
2012-08-02 00:59:38 +00:00
|
|
|
*/
|
2013-03-20 22:35:05 +00:00
|
|
|
ve.dm.SurfaceFragment.prototype.annotateContent = function ( method, nameOrAnnotation, data ) {
|
2012-08-02 00:59:38 +00:00
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
2013-05-01 18:36:32 +00:00
|
|
|
var annotation, annotations, i, ilen, tx, txs = [], newRange = this.getRange();
|
2013-03-20 22:35:05 +00:00
|
|
|
if ( nameOrAnnotation instanceof ve.dm.Annotation ) {
|
2013-04-25 23:53:25 +00:00
|
|
|
annotations = [ nameOrAnnotation ];
|
2013-03-20 22:35:05 +00:00
|
|
|
} else {
|
2013-05-01 18:36:32 +00:00
|
|
|
annotation = ve.dm.annotationFactory.create( nameOrAnnotation, data );
|
|
|
|
if ( method === 'set' ) {
|
|
|
|
annotations = [ annotation ];
|
|
|
|
} else {
|
|
|
|
annotations = this.document.data.getAnnotationsFromRange( this.getRange(), true )
|
|
|
|
.getComparableAnnotations( annotation ).get();
|
|
|
|
}
|
The great inspector and context rewrite of 2012
ve.AnnotationAction
* Added filter to the clearAll method to allow clearing all matching annotations only
ve.dm.Document
* Some variable renaming for consistency
ve.dm.SurfaceFragment
* Added truncateRange method
* Added annotation scope to expandRange method
* Added support for passing an annotation object into annotateContent method
* Switched to using name instead of type in annotateContent method to match the ve.dm.Annotation class
* Fixed logic in annotation mode of expandSelection so that expansion only takes place if the annotation is found
ve.ui.LinkInspector
* Moved most of the functionality elsewhere
* General reorganization
* Changed setOverlayPosition to accept 2 arguments instead of an object with 2 properties and renamed it to positionOverlayBelow
* Check for annotation object before extracting target information from it
* Initialize default target as empty string to avoid undefined being cast to a string and the default target becoming 'undefined'
icons.ai, inspector.png, inspector.svg
* Added generic inspector icon which will be used when a custom icon is not specified in future inspector subclasses
ve.ui.Inspector.Icons
* Added inspector icon
* Renamed clear icon to remove to match it's actual image
ve.ui.Context
* Greatly simplified the interface, reducing the number of methods by inlining a few things and combining others
* Now always listening to resize events on the window rather than only while document is focused
* Not listening to scroll events anymore, they used to affect the top/bottom positioning of the menu which we don't do anymore
* Lots of cleanup and reorganization
* No need to fallback to empty array since getInspectorsForAnnotations does so already
* Only consider fully-covered annotations for inspectors
ve.ui.Frame
* Simplified the constructor by introducing the createFrame method
* General cleanup
* Typo fixes
ve.ui.Inspector
* Generalized lots of functionality previously located in the link inspector class which will be useful to all inspectors (such as title, clear button, saving changes, etc.)
* Added setDisabled and isDisabled methods to manage CSS changes and avoid needing to check the CSS to determine the state of the inspector (storing state in the view is evil)
* Added getMatchingAnnotations method for convenience
* Added prepareSelection stub
* Lots of cleanup and documentation
* Type pattern is now defined in base class
* Added stubs for onOpen and onClose with documentation so that subclass authors know what these methods do
* Removed checks for onOpen or onClose methods since they are now noop stubs and are always there
* Added stub and removed checks for onRemove
* Made esc key close and accept - the illusion is supposed to be that the link changes are applied instantly, even though they are only updated when you close, so all closing except for when removing should apply changes - i.e. esc is now equal to back rather than being a special function that doesn't have an associated affordance
* Only consider fully-covered annotations when getting matching annotations
ve.ui.InspectorFactory
* Depending on type pattern now since it's always there
* Added getInspectorsForAnnotations method
* Return empty array if annotation set is empty
VisualEditor, VisualEditor.i18n
* Added default inspector message
Change-Id: I1cc008445bcbc8cba6754ca4b6ac0397575980d5
2012-11-16 20:40:05 +00:00
|
|
|
}
|
2013-04-22 11:20:26 +00:00
|
|
|
if ( this.getRange( true ).getLength() ) {
|
2012-11-16 22:57:20 +00:00
|
|
|
// Apply to selection
|
2013-04-25 23:53:25 +00:00
|
|
|
for ( i = 0, ilen = annotations.length; i < ilen; i++ ) {
|
|
|
|
tx = ve.dm.Transaction.newFromAnnotation( this.document, this.getRange(), method, annotations[i] );
|
|
|
|
txs.push( tx );
|
|
|
|
newRange = tx.translateRange( newRange );
|
|
|
|
|
|
|
|
}
|
|
|
|
this.surface.change( txs, !this.noAutoSelect && newRange );
|
2012-11-16 22:57:20 +00:00
|
|
|
} else {
|
|
|
|
// Apply annotation to stack
|
|
|
|
if ( method === 'set' ) {
|
2013-04-25 23:53:25 +00:00
|
|
|
for ( i = 0, ilen = annotations.length; i < ilen; i++ ) {
|
2013-05-01 18:36:32 +00:00
|
|
|
this.surface.addInsertionAnnotations( annotations[i] );
|
2013-04-25 23:53:25 +00:00
|
|
|
}
|
2012-11-16 22:57:20 +00:00
|
|
|
} else if ( method === 'clear' ) {
|
2013-04-25 23:53:25 +00:00
|
|
|
for ( i = 0, ilen = annotations.length; i < ilen; i++ ) {
|
2013-05-01 18:36:32 +00:00
|
|
|
this.surface.removeInsertionAnnotations( annotations[i] );
|
2013-04-25 23:53:25 +00:00
|
|
|
}
|
2012-11-16 22:57:20 +00:00
|
|
|
}
|
2012-08-02 00:59:38 +00:00
|
|
|
}
|
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove content in the fragment and insert content before it.
|
|
|
|
*
|
2012-08-10 23:59:50 +00:00
|
|
|
* This will move the fragment's range to the end of the insertion and make it zero-length.
|
2012-08-02 00:59:38 +00:00
|
|
|
*
|
|
|
|
* @method
|
2013-01-08 21:02:12 +00:00
|
|
|
* @param {string|Array} content Content to insert, can be either a string or array of data
|
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 {boolean} annotate Content should be automatically annotated to match surrounding content
|
2013-02-23 10:11:02 +00:00
|
|
|
* @chainable
|
2012-08-02 00:59:38 +00:00
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.insertContent = function ( content, annotate ) {
|
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
2012-08-10 23:59:50 +00:00
|
|
|
var tx, annotations;
|
2013-04-22 11:20:26 +00:00
|
|
|
if ( this.getRange( true ).getLength() ) {
|
2012-08-10 23:59:50 +00:00
|
|
|
this.removeContent();
|
|
|
|
}
|
|
|
|
// Auto-convert content to array of plain text characters
|
|
|
|
if ( typeof content === 'string' ) {
|
2013-06-05 16:30:28 +00:00
|
|
|
content = ve.splitClusters( content );
|
2012-08-10 23:59:50 +00:00
|
|
|
}
|
|
|
|
if ( content.length ) {
|
|
|
|
if ( annotate ) {
|
2013-04-22 11:20:26 +00:00
|
|
|
annotations = this.document.data.getAnnotationsFromOffset( this.getRange( true ).start - 1 );
|
2012-08-24 02:06:36 +00:00
|
|
|
if ( annotations.getLength() > 0 ) {
|
2012-08-10 23:59:50 +00:00
|
|
|
ve.dm.Document.addAnnotationsToData( content, annotations );
|
|
|
|
}
|
|
|
|
}
|
2013-04-22 11:20:26 +00:00
|
|
|
tx = ve.dm.Transaction.newFromInsertion( this.document, this.getRange( true ).start, content );
|
|
|
|
this.surface.change( tx, !this.noAutoSelect && tx.translateRange( this.getRange() ) );
|
2012-08-10 23:59:50 +00:00
|
|
|
}
|
2012-08-02 00:59:38 +00:00
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Remove content in the fragment.
|
2012-08-02 00:59:38 +00:00
|
|
|
*
|
|
|
|
* @method
|
2013-02-23 10:11:02 +00:00
|
|
|
* @chainable
|
2012-08-02 00:59:38 +00:00
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.removeContent = function () {
|
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
2012-08-10 23:59:50 +00:00
|
|
|
var tx;
|
2013-04-22 11:20:26 +00:00
|
|
|
if ( this.getRange( true ).getLength() ) {
|
|
|
|
tx = ve.dm.Transaction.newFromRemoval( this.document, this.getRange() );
|
|
|
|
this.surface.change( tx, !this.noAutoSelect && tx.translateRange( this.getRange() ) );
|
2012-08-10 23:59:50 +00:00
|
|
|
}
|
2012-08-02 00:59:38 +00:00
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Convert each content branch in the fragment from one type to another.
|
2012-08-02 00:59:38 +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 {string} type Element type to convert to
|
2012-08-10 23:59:50 +00:00
|
|
|
* @param {Object} [attr] Initial attributes for new element
|
2013-02-23 10:11:02 +00:00
|
|
|
* @chainable
|
2012-08-10 23:59:50 +00:00
|
|
|
*/
|
|
|
|
ve.dm.SurfaceFragment.prototype.convertNodes = function ( type, attr ) {
|
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
The Great ve.ui.Surface refactor of 2013
Prologue:
Farewell ve.Editor my good chap… Oh, hey there HTML frames - I didn't
see you there! In a world where iframes are outlaws, and symbols like
document and window are global, there were more than a few assumptions
about which document or window was being used. But fear not - for this
commit (probably) tracks them all down, leaving a trail of
iframe-compatible awesomeness in its wake. With the great ve.ui.Surface
now able to be used inside of iframes, let the reference editing
commence. But there, lurking in the darkness is a DM issue so fierce it
may take Roan and/or Ed up to 3 whole hours to sort it out.
Note to Roan and/or Ed:
Editing references seems to work fine, but when saving the page there
are "no changes" which is a reasonable indication to the contrary.
Objectives:
* Make it possible to have multiple surfaces be instantiated, get along
nicely, and be embedded inside of iframes if needed.
* Make reference content editable within a dialog
Approach:
* Move what's left of ve.Editor to ve.ui.Surface and essentially
obliterate all use of it
* Make even more stuff inherit from ve.Element (long live this.$$)
* Use the correct document or window anywhere it was being assumed to be
the top level one
* Resolve stacking order issues by removing the excessive use of z-index
and introducing global and local overlay elements for each editor
* Add a surface to the reference dialog, load up the reference contents
and save them back on apply
* Actually destroy what we create in ce and ui surfaces
* Add recursive frame offset calculation method to ve.Element
* Moved ve.ce.Surface's getSelectionRect method to the prototype
Bonus:
* Move ve.ce.DocumentNode.css contents to ve.ce.Node.css (not sure why it
was separate in the first place, but I'm likely the one to blame)
* Fix blatant lies in documentation
* Whitespace cleanup here and there
* Get rid of ve.ui.Window overlays - not used or needed
Change-Id: Iede83e7d24f7cb249b6ba3dc45d770445b862e08
2013-05-20 22:45:50 +00:00
|
|
|
var tx = ve.dm.Transaction.newFromContentBranchConversion(
|
|
|
|
this.document, this.getRange(), type, attr
|
|
|
|
);
|
2013-04-22 11:20:26 +00:00
|
|
|
this.surface.change( tx, !this.noAutoSelect && tx.translateRange( this.getRange() ) );
|
2012-08-10 23:59:50 +00:00
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Wrap each node in the fragment with one or more elements.
|
2012-08-10 23:59:50 +00:00
|
|
|
*
|
|
|
|
* A wrapper object is a linear model element; a plain object containing a type property and an
|
|
|
|
* optional attributes property.
|
|
|
|
*
|
2012-08-24 22:25:37 +00:00
|
|
|
* Example:
|
|
|
|
* // fragment is a selection of: <p>a</p><p>b</p>
|
|
|
|
* fragment.wrapNodes(
|
|
|
|
* [{ 'type': 'list', 'attributes': { 'style': 'bullet' } }, { 'type': 'listItem' }]
|
|
|
|
* )
|
|
|
|
* // fragment is now a selection of: <ul><li><p>a</p></li></ul><ul><li><p>b</p></li></ul>
|
|
|
|
*
|
2012-08-10 23:59:50 +00:00
|
|
|
* @method
|
|
|
|
* @param {Object|Object[]} wrapper Wrapper object, or array of wrapper objects (see above)
|
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 {string} wrapper.type Node type of wrapper
|
2012-08-10 23:59:50 +00:00
|
|
|
* @param {Object} [wrapper.attributes] Attributes of wrapper
|
2013-02-23 10:11:02 +00:00
|
|
|
* @chainable
|
2012-08-02 00:59:38 +00:00
|
|
|
*/
|
2012-10-03 23:03:33 +00:00
|
|
|
ve.dm.SurfaceFragment.prototype.wrapNodes = function ( wrapper ) {
|
2012-08-02 00:59:38 +00:00
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
2012-08-24 22:25:37 +00:00
|
|
|
if ( !ve.isArray( wrapper ) ) {
|
|
|
|
wrapper = [wrapper];
|
|
|
|
}
|
2013-04-23 16:05:48 +00:00
|
|
|
var tx = ve.dm.Transaction.newFromWrap( this.document, this.getRange(), [], [], [], wrapper );
|
|
|
|
this.surface.change( tx, !this.noAutoSelect && tx.translateRange( this.getRange() ) );
|
2012-08-02 00:59:38 +00:00
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-03-01 01:20:59 +00:00
|
|
|
* Unwrap nodes in the fragment out of one or more elements.
|
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
* // fragment is a selection of: <ul>「<li><p>a</p></li><li><p>b</p></li>」</ul>
|
|
|
|
* fragment.unwrapNodes( 1, 1 )
|
|
|
|
* // fragment is now a selection of: 「<p>a</p><p>b</p>」
|
2012-08-02 00:59:38 +00:00
|
|
|
*
|
2012-08-10 23:59:50 +00:00
|
|
|
* @method
|
2013-03-01 01:20:59 +00:00
|
|
|
* @param {number} outerDepth Number of nodes outside the selection to unwrap
|
|
|
|
* @param {number} innerDepth Number of nodes inside the selection to unwrap
|
2013-02-23 10:11:02 +00:00
|
|
|
* @chainable
|
2012-08-10 23:59:50 +00:00
|
|
|
*/
|
2013-03-01 01:20:59 +00:00
|
|
|
ve.dm.SurfaceFragment.prototype.unwrapNodes = function ( outerDepth, innerDepth ) {
|
2012-08-10 23:59:50 +00:00
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
2013-04-23 16:05:48 +00:00
|
|
|
var i, tx, innerUnwrapper = [], outerUnwrapper = [];
|
2013-03-01 01:20:59 +00:00
|
|
|
|
2013-04-22 11:20:26 +00:00
|
|
|
if ( this.getRange( true ).end - this.getRange( true ).start < innerDepth * 2 ) {
|
2013-03-01 01:20:59 +00:00
|
|
|
throw new Error( 'cannot unwrap by greater depth than maximum theoretical depth of selection' );
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i = 0; i < innerDepth; i++ ) {
|
2013-04-22 11:20:26 +00:00
|
|
|
innerUnwrapper.push( this.surface.getDocument().data.getData( this.getRange( true ).start + i ) );
|
2013-03-01 01:20:59 +00:00
|
|
|
}
|
|
|
|
for ( i = outerDepth; i > 0; i-- ) {
|
2013-04-22 11:20:26 +00:00
|
|
|
outerUnwrapper.push( this.surface.getDocument().data.getData( this.getRange( true ).start - i ) );
|
2013-03-01 01:20:59 +00:00
|
|
|
}
|
|
|
|
|
2013-04-22 11:20:26 +00:00
|
|
|
tx = ve.dm.Transaction.newFromWrap( this.document, this.getRange(), outerUnwrapper, [], innerUnwrapper, [] );
|
2013-04-23 16:05:48 +00:00
|
|
|
this.surface.change( tx, !this.noAutoSelect && tx.translateRange( this.getRange() ) );
|
2013-03-01 01:20:59 +00:00
|
|
|
|
2012-08-10 23:59:50 +00:00
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Change the wrapping of each node in the fragment from one type to another.
|
2012-08-10 23:59:50 +00:00
|
|
|
*
|
|
|
|
* A wrapper object is a linear model element; a plain object containing a type property and an
|
|
|
|
* optional attributes property.
|
|
|
|
*
|
2013-03-01 01:20:59 +00:00
|
|
|
* Example:
|
|
|
|
* // fragment is a selection of: <dl><dt><p>a</p></dt></dl><dl><dt><p>b</p></dt></dl>
|
|
|
|
* fragment.rewrapNodes(
|
|
|
|
* 2,
|
|
|
|
* [{ 'type': 'list', 'attributes': { 'style': 'bullet' } }, { 'type': 'listItem' }]
|
|
|
|
* )
|
|
|
|
* // fragment is now a selection of: <ul><li><p>a</p></li></ul><ul><li><p>b</p></li></ul>
|
|
|
|
*
|
2012-08-10 23:59:50 +00:00
|
|
|
* @method
|
2013-03-01 01:20:59 +00:00
|
|
|
* @param {number} depth Number of nodes to unwrap
|
2012-08-10 23:59:50 +00:00
|
|
|
* @param {Object|Object[]} wrapper Wrapper object, or array of wrapper objects (see above)
|
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 {string} wrapper.type Node type of wrapper
|
2012-08-10 23:59:50 +00:00
|
|
|
* @param {Object} [wrapper.attributes] Attributes of wrapper
|
2013-02-23 10:11:02 +00:00
|
|
|
* @chainable
|
2012-08-10 23:59:50 +00:00
|
|
|
*/
|
2013-03-01 01:20:59 +00:00
|
|
|
ve.dm.SurfaceFragment.prototype.rewrapNodes = function ( depth, wrapper ) {
|
2012-08-10 23:59:50 +00:00
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
2013-04-23 16:05:48 +00:00
|
|
|
var i, tx, unwrapper = [];
|
2013-03-01 01:20:59 +00:00
|
|
|
|
|
|
|
if ( !ve.isArray( wrapper ) ) {
|
|
|
|
wrapper = [wrapper];
|
|
|
|
}
|
|
|
|
|
2013-04-22 11:20:26 +00:00
|
|
|
if ( this.getRange( true ).end - this.getRange( true ).start < depth * 2 ) {
|
2013-03-01 01:20:59 +00:00
|
|
|
throw new Error( 'cannot unwrap by greater depth than maximum theoretical depth of selection' );
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i = 0; i < depth; i++ ) {
|
2013-04-22 11:20:26 +00:00
|
|
|
unwrapper.push( this.surface.getDocument().data.getData( this.getRange( true ).start + i ) );
|
2013-03-01 01:20:59 +00:00
|
|
|
}
|
|
|
|
|
2013-04-22 11:20:26 +00:00
|
|
|
tx = ve.dm.Transaction.newFromWrap( this.document, this.getRange(), [], [], unwrapper, wrapper );
|
2013-04-23 16:05:48 +00:00
|
|
|
this.surface.change( tx, !this.noAutoSelect && tx.translateRange( this.getRange() ) );
|
2013-03-01 01:20:59 +00:00
|
|
|
|
2012-08-10 23:59:50 +00:00
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Wrap nodes in the fragment with one or more elements.
|
2012-08-10 23:59:50 +00:00
|
|
|
*
|
|
|
|
* A wrapper object is a linear model element; a plain object containing a type property and an
|
|
|
|
* optional attributes property.
|
2012-08-02 00:59:38 +00:00
|
|
|
*
|
2012-08-24 22:25:37 +00:00
|
|
|
* Example:
|
|
|
|
* // fragment is a selection of: <p>a</p><p>b</p>
|
|
|
|
* fragment.wrapAllNodes(
|
|
|
|
* [{ 'type': 'list', 'attributes': { 'style': 'bullet' } }, { 'type': 'listItem' }]
|
|
|
|
* )
|
|
|
|
* // fragment is now a selection of: <ul><li><p>a</p><p>b</p></li></ul>
|
|
|
|
*
|
2012-08-02 00:59:38 +00:00
|
|
|
* @method
|
2012-08-10 23:59:50 +00:00
|
|
|
* @param {Object|Object[]} wrapper Wrapper object, or array of wrapper objects (see above)
|
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 {string} wrapper.type Node type of wrapper
|
2012-08-10 23:59:50 +00:00
|
|
|
* @param {Object} [wrapper.attributes] Attributes of wrapper
|
2013-02-23 10:11:02 +00:00
|
|
|
* @chainable
|
2012-08-02 00:59:38 +00:00
|
|
|
*/
|
2012-10-03 23:03:33 +00:00
|
|
|
ve.dm.SurfaceFragment.prototype.wrapAllNodes = function ( wrapper ) {
|
2012-08-02 00:59:38 +00:00
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
2013-02-22 20:49:13 +00:00
|
|
|
|
2013-04-23 16:05:48 +00:00
|
|
|
var tx;
|
2013-02-22 20:49:13 +00:00
|
|
|
|
2012-08-24 22:25:37 +00:00
|
|
|
if ( !ve.isArray( wrapper ) ) {
|
|
|
|
wrapper = [wrapper];
|
|
|
|
}
|
2013-02-22 20:49:13 +00:00
|
|
|
|
2013-04-22 11:20:26 +00:00
|
|
|
tx = ve.dm.Transaction.newFromWrap( this.document, this.getRange(), [], wrapper, [], [] );
|
2013-04-23 16:05:48 +00:00
|
|
|
this.surface.change( tx, !this.noAutoSelect && tx.translateRange( this.getRange() ) );
|
2013-02-22 20:49:13 +00:00
|
|
|
|
2012-08-10 23:59:50 +00:00
|
|
|
return this;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2013-01-15 23:38:49 +00:00
|
|
|
* Change the wrapping of nodes in the fragment from one type to another.
|
2012-08-10 23:59:50 +00:00
|
|
|
*
|
|
|
|
* A wrapper object is a linear model element; a plain object containing a type property and an
|
|
|
|
* optional attributes property.
|
|
|
|
*
|
2013-03-01 01:20:59 +00:00
|
|
|
* Example:
|
|
|
|
* // fragment is a selection of: <h1><p>a</p><p>b</p></h1>
|
|
|
|
* fragment.rewrapAllNodes( 1, { 'type': 'heading', 'attributes' : { 'level' : 2 } } );
|
|
|
|
* // fragment is now a selection of: <h2><p>a</p><p>b</p></h2>
|
|
|
|
*
|
2012-08-10 23:59:50 +00:00
|
|
|
* @method
|
2013-03-01 01:20:59 +00:00
|
|
|
* @param {number} depth Number of nodes to unwrap
|
2012-08-10 23:59:50 +00:00
|
|
|
* @param {Object|Object[]} wrapper Wrapper object, or array of wrapper objects (see above)
|
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 {string} wrapper.type Node type of wrapper
|
2012-08-10 23:59:50 +00:00
|
|
|
* @param {Object} [wrapper.attributes] Attributes of wrapper
|
2013-02-23 10:11:02 +00:00
|
|
|
* @chainable
|
2012-08-02 00:59:38 +00:00
|
|
|
*/
|
2013-02-25 22:32:29 +00:00
|
|
|
ve.dm.SurfaceFragment.prototype.rewrapAllNodes = function ( depth, wrapper ) {
|
2012-08-02 00:59:38 +00:00
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
2013-04-23 16:05:48 +00:00
|
|
|
var i, tx, unwrapper = [],
|
2013-04-22 11:20:26 +00:00
|
|
|
innerRange = new ve.Range( this.getRange( true ).start + depth, this.getRange( true ).end - depth );
|
2013-02-25 22:32:29 +00:00
|
|
|
|
2013-03-01 01:20:59 +00:00
|
|
|
if ( !ve.isArray( wrapper ) ) {
|
|
|
|
wrapper = [wrapper];
|
|
|
|
}
|
|
|
|
|
2013-04-22 11:20:26 +00:00
|
|
|
if ( this.getRange( true ).end - this.getRange( true ).start < depth * 2 ) {
|
2013-02-25 22:32:29 +00:00
|
|
|
throw new Error( 'cannot unwrap by greater depth than maximum theoretical depth of selection' );
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( i = 0; i < depth; i++ ) {
|
2013-04-22 11:20:26 +00:00
|
|
|
unwrapper.push( this.surface.getDocument().data.getData( this.getRange( true ).start + i ) );
|
2013-02-25 22:32:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
tx = ve.dm.Transaction.newFromWrap( this.document, innerRange, unwrapper, wrapper, [], [] );
|
2013-04-23 16:05:48 +00:00
|
|
|
this.surface.change( tx, !this.noAutoSelect && tx.translateRange( this.getRange() ) );
|
2013-02-25 22:32:29 +00:00
|
|
|
|
2012-08-02 00:59:38 +00:00
|
|
|
return this;
|
|
|
|
};
|
2013-02-21 19:20:43 +00:00
|
|
|
|
|
|
|
/**
|
2013-03-01 01:20:59 +00:00
|
|
|
* Isolates the nodes in a fragment then unwraps them.
|
2013-02-21 19:20:43 +00:00
|
|
|
*
|
2013-03-01 01:20:59 +00:00
|
|
|
* The node selection is expanded to siblings. These are isolated such that they are the
|
|
|
|
* sole children of the nearest parent element which can 'type' can exist in.
|
|
|
|
*
|
|
|
|
* The new isolated selection is then safely unwrapped.
|
2013-02-21 19:20:43 +00:00
|
|
|
*
|
|
|
|
* @method
|
2013-03-01 01:20:59 +00:00
|
|
|
* @param {string} type Node type to isolate for
|
2013-02-23 10:11:02 +00:00
|
|
|
* @chainable
|
2013-02-21 19:20:43 +00:00
|
|
|
*/
|
2013-03-01 01:20:59 +00:00
|
|
|
ve.dm.SurfaceFragment.prototype.isolateAndUnwrap = function ( isolateForType ) {
|
2013-02-21 19:20:43 +00:00
|
|
|
// Handle null fragment
|
|
|
|
if ( !this.surface ) {
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
var nodes, startSplitNode, endSplitNode, tx,
|
|
|
|
startOffset, endOffset,
|
2013-03-01 01:20:59 +00:00
|
|
|
outerDepth = 0,
|
|
|
|
factory = ve.dm.nodeFactory,
|
|
|
|
allowedParents = factory.getSuggestedParentNodeTypes( isolateForType ),
|
2013-02-21 19:20:43 +00:00
|
|
|
startSplitRequired = false,
|
|
|
|
endSplitRequired = false,
|
|
|
|
startSplitNodes = [],
|
|
|
|
endSplitNodes = [],
|
2013-04-23 16:05:48 +00:00
|
|
|
fragment = this;
|
2013-02-21 19:20:43 +00:00
|
|
|
|
|
|
|
function createSplits( splitNodes, insertBefore ) {
|
|
|
|
var i, length,
|
|
|
|
startOffsetChange = 0, endOffsetChange = 0, data = [];
|
|
|
|
for ( i = 0, length = splitNodes.length; i < length; i++ ) {
|
|
|
|
data.unshift( { 'type': '/' + splitNodes[i].type } );
|
|
|
|
data.push( splitNodes[i].getClonedElement() );
|
|
|
|
|
|
|
|
if ( insertBefore ) {
|
|
|
|
startOffsetChange += 2;
|
|
|
|
endOffsetChange += 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-01 01:20:59 +00:00
|
|
|
tx = ve.dm.Transaction.newFromInsertion( fragment.getDocument(), insertBefore ? startOffset : endOffset, data );
|
2013-04-23 16:05:48 +00:00
|
|
|
fragment.surface.change( tx, !fragment.noAutoSelect && tx.translateRange( fragment.getRange() ) );
|
2013-02-21 19:20:43 +00:00
|
|
|
|
|
|
|
startOffset += startOffsetChange;
|
|
|
|
endOffset += endOffsetChange;
|
|
|
|
}
|
|
|
|
|
2013-04-22 11:20:26 +00:00
|
|
|
nodes = this.getDocument().selectNodes( this.getRange(), 'siblings' );
|
2013-02-21 19:20:43 +00:00
|
|
|
|
|
|
|
// Find start split point, if required
|
|
|
|
startSplitNode = nodes[0].node;
|
|
|
|
startOffset = startSplitNode.getOuterRange().start;
|
2013-03-20 22:35:05 +00:00
|
|
|
while ( allowedParents !== null && ve.indexOf( startSplitNode.getParent().type, allowedParents ) === -1 ) {
|
2013-03-01 01:20:59 +00:00
|
|
|
if ( startSplitNode.getParent().indexOf( startSplitNode ) > 0 ) {
|
2013-02-21 19:20:43 +00:00
|
|
|
startSplitRequired = true;
|
|
|
|
}
|
2013-03-01 01:20:59 +00:00
|
|
|
startSplitNode = startSplitNode.getParent();
|
2013-02-21 19:20:43 +00:00
|
|
|
if ( startSplitRequired ) {
|
|
|
|
startSplitNodes.unshift(startSplitNode);
|
|
|
|
} else {
|
|
|
|
startOffset = startSplitNode.getOuterRange().start;
|
|
|
|
}
|
2013-03-01 01:20:59 +00:00
|
|
|
outerDepth++;
|
2013-02-21 19:20:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Find end split point, if required
|
|
|
|
endSplitNode = nodes[nodes.length - 1].node;
|
|
|
|
endOffset = endSplitNode.getOuterRange().end;
|
2013-03-20 22:35:05 +00:00
|
|
|
while ( allowedParents !== null && ve.indexOf( endSplitNode.getParent().type, allowedParents ) === -1 ) {
|
2013-03-01 01:20:59 +00:00
|
|
|
if ( endSplitNode.getParent().indexOf( endSplitNode ) < endSplitNode.getParent().getChildren().length - 1 ) {
|
2013-02-21 19:20:43 +00:00
|
|
|
endSplitRequired = true;
|
|
|
|
}
|
2013-03-01 01:20:59 +00:00
|
|
|
endSplitNode = endSplitNode.getParent();
|
2013-02-21 19:20:43 +00:00
|
|
|
if ( endSplitRequired ) {
|
|
|
|
endSplitNodes.unshift(endSplitNode);
|
|
|
|
} else {
|
|
|
|
endOffset = endSplitNode.getOuterRange().end;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( startSplitRequired ) {
|
|
|
|
createSplits( startSplitNodes, true );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( endSplitRequired ) {
|
|
|
|
createSplits( endSplitNodes, false );
|
|
|
|
}
|
|
|
|
|
2013-03-01 01:20:59 +00:00
|
|
|
this.unwrapNodes( outerDepth, 0 );
|
|
|
|
|
2013-02-21 19:20:43 +00:00
|
|
|
return this;
|
|
|
|
};
|