The normalize method doesn't need to be explicitly called anymore because there's not any code that changes the properties of a range directly anymore.
A good way to prove it's not needed anymore is to move the normalization logic to the constructor and then add "console.log(this.from <= this.to );" to the normalize method - you will find that it's never actually doing anything at all because the range was normalized by the constructor.
ve.Range
* Moved normalization logic to constructor
* Removed calls to normalize method
* Removed normalize method
* Simplified documentation for flip method
* Whitespace fixes
ve.Document, ve.dm.Transaction, ve.dm.Surface, ve.dm.Document, ve.ce.Surface
* Removed calls to range.normalize
* Switched to using range.isCollapsed instead of comparing properties directly
Change-Id: I80bfd06f88579c34dce2083c2b70d63ab92f1275
* Made method descriptions imperative: "Do this" rather than "Does this"
* Changed use of "this object" to "the object" in method documentation
* Added missing documentation
* Fixed incorrect documentation
* Fixed incorrect debug method names (as in those VeDmClassName tags we add to functions so they make sense when dumped into in the console)
* Normalized use of package names throughout
* Normalized class descriptions
* Removed incorrect @abstract tags
* Added missing @method tags
* Lots of other minor cleanup
Change-Id: I4ea66a2dd107613e2ea3a5f56ff54d675d72957e
Follow up for I6a7c9e8ee8f995731bc205d666167874eb2ebe23
The first pass that Timo took missed the following cases
* "{Array|String}": string is just one of the values
* "{String[]}": string is followed by [] to indicate an array of strings
Change-Id: I65e595e8d37fb624802d84af9536a2d3c5d73c7d
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
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
ve.dm.Document
* 2 of the 3 paths of getSlice still returned arrays instead of ve.dm.DocumentSlice objects
ve.ce.Surface
* Translate the range using the insertion transaction and truncate it, so the cursor ends up just after the pasted content
Change-Id: If7bae5e254ec84a847c1d3527f74d9c09c2d82b4
ve.ce.Surface
* Switched to using getSlice instead of getData in copy and paste handlers
* Added try/catch which attempts to build a transaction with the unbalanced data first, but falls back on the balanced data otherwise
ve.dm.*Node
* Added default style attributes (now used by ve.dm.NodeFactory)
ve.dm.Document
* Fixed bugs in fixupInsertions where parentType was being set with an object rather than a string
* Made use of getDataElement
* Added adoption capability so that inserting a</h1><p>b into <p>c[cursor]d</p> results in <p>ca</p><p>bd</p> rather than throwing an exception
* Renamed getBalancedData to getSlice, now retuning a ve.dm.DocumentSlice object
ve.dm.DocumentSlice
* Introduced new container for balanced data and a range of the original context - useful for copy/paste
ve.dm.NodeFactory
* Added getDataElement method, which uses default attributes to create a boilerplate version of a data element
ve.dm.Document.test
* Updated getBalancedData test to be a getSlice test
demos/ve/index, VisualEditor, test/index
* Added references to ve.dm.DocumentSlice
Change-Id: Id9269a29e51ca213508de8f155d3feec5e5b0774
ve.ce.Surface
* Added ve.ce.Surface.adjustCursor, which replaces repetitive and buggy code that was handling left and right arrow key presses
* New method only affects the selection target, so it won't collapse the selection on you - this was what caused bug 42401
* Made hasSlugAtOffset() actually return a boolean
ve.dm.Document
* Fixed turn-around issue in ve.dm.Document.getRelativeOffset - if the offset is already valid and we can't move in the direction we want, we should just leave it be, not turn around
* Since this method was being used by ve.ce.Surface to correct the cursor position on arrow key presses, it was causing the strange cursor jumping when you pressed an arrow key while at the edge of a document
ve.dm.SurfaceFragment
* Fixed typo where getAnnotationRangeFromSelection was preserving selection direction, but checking the wrong properties
ve.dm.Document.test
* Added tests that verify turn-around issue is fixed
Change-Id: Iba55cfc3d531e7d1333b78c94912ff22179aace8
This is cleaner than passing around the attributes separately, and it
allows us to access the annotations in dm.LeafNode as well.
Change-Id: Ie5b90988114835831cbe5cdccf63c7cd45719e31
ve.dm.SurfaceFragment
* Removed flawed implementation of word mode for expandRange method and made use of new getNearestWordBoundary method in the document model
ve.dm.Surface
* Got rid of useInsertionAnnotations, which allowed disabling and enabling of insertion annotations - this isn't needed anymore because it was just a dirty hack around the improper starting and stopping of surface observer that's now solved more elegantly by emitting lock and unlock before committing or rolling back transactions
* Get annotations from the first character of the selection if the selection is not collapsed
* Only emit annotationChange events if it really changed
ve.dm.Document
* Added getNearestWordBoundary method which performs the work behind the surface fragment expandRange word method
ve.ce.SurfaceObserver
* Allow using an initial selection to avoid the observer thinking the selection has changed just because it started out with null
* Only emit selectionChange event if there was a meaningful change
ve.ce.Surface
* (bug 42279) Only annotate characters if insertion annotations are not empty
* Remove manual locking and unlocking, this is now done inside the change method of surface model
* Provide an initial selection to surface observer when we clear it
* Remove enabling and disabling of insertionAnnotations, this isn't needed anymore
* Stop/start observer on key presses that execute actions as well as those that have no special handling
ve.ce.Document
* Make getNodeFromOffsetand getSlugAtOffset return null when given -1 as an offset
Change-Id: Ibf6b26de299e54ae8688a2653bf5d5538927f8c3
AnnotationAction and SurfaceFragment now use insertAnnotations.
ve.dm.Surface.test
* Removed test for annotate method (not needed anymore)
ve.dm.SurfaceFragment
* Now using getInsertionAnnotations method
* Added support for modifying insertion annotations when annotating a zero-length selection
ve.dm.Surface
* Moved in insertion annotations state from document model
* Added insertion annotation interface (enable, disable, areEnabled, get, set, add, and remove)
* Simplified handling of annotations on change
* Removed annotate method (not used anymore)
ve.dm.Document
* Removed insertion annotations (moved it to surface model)
ve.ce.Surface
* Cleaned up handleInsertion and changed it to use the insertion annotations interface on the surface model
ve.AnnotationAction
* Moved insertion annotation handling out of here since it's now included in the surface fragment
Change-Id: I047d656acf7fa1c63f726ca2b0801e1476f84f96
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
* ve.dm.Converter still generates metaInline/metaBlock elements as
before, it's not affected by this change
* ve.dm.Document constructor splits its input into "real" data and
metadata
** Metadata is stored in this.metadata (the meta-linmod) as a sparse
array of arrays, with an element for each offset in this.data
** this.data itself does not contain the metadata
** This means the node tree also doesn't contain the metadata
** Which means CE doesn't know about it at all
* All splice operations on the linear model are sent through
ve.dm.Document.spliceData(), which performs the splice and syncs the
meta-linmod
** Metadata in the removed range is reaped and added to the metadata for
the offset immediately following the removal
* ve.dm.Document.getFullData() splices the linmod and meta-linmod back
into each other; this "full data" is then fed back to ve.dm.Converter
Change-Id: Ief6dfd5b59cc13a8457993ed85c725413029c4fb
* Allow inspector to open with 0 length selection.
* Allow context menu to open with 0 length selection.
* Fixed bug in doc.getAnnotationsFromRange on zero length selection:
Method now returns annotations from start vs empty annotation set.
Change-Id: I3937c5c2824c7396d0c3ee11c13ffecdbed6052a
The data array is now taken by reference, and the caller must perform
any copying required.
Changed tests to make a deep copy of shared data sets (mostly
ve.dm.example) before passing them to ve.dm.Document().
Change-Id: Iedc64f9fd9cd689640de9a19379cf5f3db94a2bb
There's no use case for keeping a deep copy of the 'internal' property
in the node tree, and it was breaking some of my new tests concerning
change markers. We could keep internal data in the node tree if we
wanted to, but to be correct we'd have to synchronize every time we
changed it, which is a pain.
Change-Id: I024de1ff8b6b6154da82c103c4bb21db8ff2ec14
* Added comments to classes and methods
* Quieted a jshint warning
* Broke some long lines
* Replaced instances of "var\t" with "var "
Change-Id: I1d617ed9e5180f1a3dff42078fb5debb5d718407
We were populating empty content nodes with zero-length text nodes to
make round-trip tests in the test suite work (otherwise blanking a
paragraph leaves behind a zero-length text node whereas creating an
empty paragraph does not), but the empty nodes are causing problems in
CE apparently.
* Do not create empty text nodes when constructing a node tree
* Be more careful with text-only replacements:
** Don't resize a text node to zero, remove it instead
** There may not be a text node to resize at all, build it in that case
** Switch nodeRange to nodeOuterRange, this was probably broken before
Tests:
* Change test case for zero-length text node to assert that there is
*no* zero-length text node :)
* Remove a test case concerning an empty text node from the
ve.ce.TextNode suite
Change-Id: Ie677457f2f0a7823a517ba3077b844ef52a20fcc
* Commands for Sublime:
Find*: "(\* @[a-z]+) ([^{].*) \{(.*)\}"
Replace: "$1 {$3} $2"
Save all && Close all
Find: " function("
Replace: " function ("
Save all && Close all
Find: "Intialization"
Replace: "Initialization"
Save all && Close all
* Consistent use of types (documented in CODING.rm):
- Merged {Integer} into {Number}.
- Merged {DOM Node} into {DOMElement}.
* Remove work-around /*jshint newcap: false */ from ve.js
Calling Object() as a function to to use the internal
toObject no longer throws a newcap warning in JSHint.
It only does that normal functions now .
(e.g. var a = Cap(); or var a = new uncap();)
* Add missing annotations (@static, @method, ..).
* Remove unused variables
* Remove null-assignments to variables that should just be
undefined. There's a few variables explicitly set to null
whereas they are set a few lines under and not used otherwise
(e.g. 'tx' in ve.ce.Surface.prototype.onPaste)
Change-Id: I0721a08f8ecd93c25595aedaa1aadb0e08b83799
Detecting page status in a similar way as WikiEditor inspector.
Disabled accept button now behaves appropriately.
Accept button status is now evaluated on enter or submit.
Change-Id: Ibfef6ffd87cb9a71e37242d6214d0f8e3af2e2c0
Icon appears when scrolling and resizing window.
Instead of always setting the context on scroll and resize, bind to the
updateContextIcon method.
Icon appears when selecting a non content data offset.
Changed logic to show icon changed to content length vs range difference.
Move Link inspector getSelectionText to ve.dm.document getText.
Rationale, more bits of the code depend on evaluating content.
Added new ve.Range truncate method.
Remove getSelectionText, using truncate range & document.getText instead.
Change-Id: Ibd3e99c923f18d2c96a86d92e74e2e9ebd49c85f
* For the most common case:
- replace ve.extendClass with ve.inheritClass (chose slightly
different names to detect usage of the old/new one, and I
like 'inherit' better).
- move it up to below the constructor, see doc block for why.
* Cases where more than 2 arguments were passed to
ve.extendClass are handled differently depending on the case.
In case of a longer inheritance tree, the other arguments
could be omitted (like in "ve.ce.FooBar, ve.FooBar,
ve.Bar". ve.ce.FooBar only needs to inherit from ve.FooBar,
because ve.ce.FooBar inherits from ve.Bar).
In the case of where it previously had two mixins with
ve.extendClass(), either one becomes inheritClass and one
a mixin, both to mixinClass().
No visible changes should come from this commit as the
instances still all have the same visible properties in the
end. No more or less than before.
* Misc.:
- Be consistent in calling parent constructors in the
same order as the inheritance.
- Add missing @extends and @param documentation.
- Replace invalid {Integer} type hint with {Number}.
- Consistent doc comments order:
@class, @abstract, @constructor, @extends, @params.
- Fix indentation errors
A fairly common mistake was a superfluous space before the
identifier on the assignment line directly below the
documentation comment.
$ ack "^ [^*]" --js modules/ve
- Typo "Inhertiance" -> "Inheritance".
- Replacing the other confusing comment "Inheritance" (inside
the constructor) with "Parent constructor".
- Add missing @abstract for ve.ui.Tool.
- Corrected ve.FormatDropdownTool to ve.ui.FormatDropdownTool.js
- Add function names to all @constructor functions. Now that we
have inheritance it is important and useful to have these
functions not be anonymous.
Example of debug shot: http://cl.ly/image/1j3c160w3D45
Makes the difference between
< documentNode;
> ve_dm_DocumentNode
...
: ve_dm_BranchNode
...
: ve_dm_Node
...
: ve_dm_Node
...
: Object
...
without names (current situation):
< documentNode;
> Object
...
: Object
...
: Object
...
: Object
...
: Object
...
though before this commit, it really looks like this
(flattened since ve.extendClass really did a mixin):
< documentNode;
> Object
...
...
...
Pattern in Sublime (case-sensitive) to find nameless
constructor functions:
"^ve\..*\.([A-Z])([^\.]+) = function \("
Change-Id: Iab763954fb8cf375900d7a9a92dec1c755d5407e
Introduced the ve.AnnotationSet class to manage sets of annotations. This
is a generalization of ve.OrderedHashSet, a class that manages a set
using an array and an object keyed by hash.
Converted everything that stores, tracks or passes around annotations to
use ve.AnnotationSet. In particular, this means the linear model now
contains AnnotationSets instead of hash-keyed objects.
This allows us to maintain the order of annotations in the linear model,
and will help fix bugs with annotation ordering and splitting.
Change-Id: I50975b0a95f4cc33017a0b59fdede9ed1eff0124
[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
* Replaces c8b4a28936
* Use Object() casting to detect objects instead of .constructor
(or instanceof). Both .constructor and instanceof compare by reference
the type "Object" which means if the object comes from another window
(where there is a different "Object" and "Object.prototype") it will
drop out of the system and go freewack.
Theory: If a variable casted to an object returns true when strictly compared
to the original, the input must be an object.
Which is true. It doesn't change the inheritance, it doesn't make it inherit
from this window's Object if the object is from another window's object. All it
does is cast to an object if not an object already.
So e.g. "Object(5) !== 5" because 5 is a primitive value as opposed to an instance
of Number.
And contrary to "typeof", it doesn't return true for "null".
* .constructor also has the problem that it only works this way if the
input is a plain object. e.g. a simple construtor function that creates
an object also get in the wrong side of the if/else case since it is
an instance of Object, but not directly (rather indirectly via another
constructor).
* Added unit tests for basic getHash usage, as well as regression tests
against the above two mentioned problems (these tests fail before this commit).
* While at it, also improved other utilities a bit.
- Use hasOwnProperty instead of casting to boolean
when checking for presence of native support.
Thanks to Douglas Crockford for that tip.
- Fix documentation for ve.getHash: Parameter is not named "obj".
- Add Object-check to ve.getObjectKeys per ES5 Object.keys spec (to match native behavior)
- Add Object-check to ve.getObjectValues to match ve.getObjectKeys
- Improved performance of ve.getObjectKeys shim. Tried several potential optimizations
and compared with jsperf. Using a "static" reference to hasOwn improves performance
(by not having to look it up 4 scopes up and 3 property levels deep).
Also using [.length] instead of .push() shared off a few ms.
- Added unit tests for ve.getObjectValues
Change-Id: If24d09405321f201c67f7df75d332bb1171c8a36
When a document is created, it should take it upon itself to make sure it has a new reference to the data using slice, not place this on the caller. Callers that do not use slice will often find strange and mysterious things going on and not know why. The real reason is that multiple documents sharing a reference to the same data array leads to seriously messed up behavior.
Change-Id: Ic4e25fcd9bf3f41a805003520a8f38e2768f5dbf
This allows us to put other internal data in there in the future. Also
passing it through the Node constructor properly now.
* ve.dm.Node
** Rename fringeWhitespace property to internal
** Add internal parameter to constructor
** Remove setFringeWhitespace()
* Increase the number of parameters passed through by ve.Factory to 3
* Pass through .internal from linmod to nodeFactory in ve.dm.Document
* ve.dm.Converter
** Rename .fringeWhitespace to .internal.whitespace and make it an array
** Store a temporary reference to .internal in domElement.veInternal
* Add internal to all node constructors except TextNode
Tests:
* Update for fringeWhitespace->internal rename
* Add third parameter to ve.Factory tests
* Add .internal to getNodeTreeSummary
Change-Id: If20c0bb78fee3efa55f72e51e7fc261283358de7
Refactor:
* ve.indexOf
Renamed from ve.inArray.
This was named after the jQuery method which in turn has a longer
story about why it is so unfortunately named. It doesn't return
a boolean, but an index. Hence the native method being called
indexOf as well.
* ve.bind
Renamed from ve.proxy.
I considered making it use Function.prototype.bind if available.
As it performs better than $.proxy (which doesn't use to the native
bind if available). However since bind needs to be bound itself in
order to use it detached, it turns out with the "call()" and
"bind()" it is slower than the $.proxy shim:
http://jsperf.com/function-bind-shim-perf
It would've been like this:
ve.bind = Function.prototype.bind ?
Function.prototype.call.bind( Function.prototype.bind ) :
$.proxy;
But instead sticking to ve.bind = $.proxy;
* ve.extendObject
Documented the parts of jQuery.extend that we use. This makes it
easier to replace in the future.
Documentation:
* Added function documentation blocks.
* Added annotations to functions that we will be able to remove
in the future in favour of the native methods.
With "@until + when/how".
In this case "ES5". Meaning, whenever we drop support for browsers
that don't support ES5. Although in the developer community ES5 is
still fairly fresh, browsers have been aware for it long enough
that thee moment we're able to drop it may be sooner than we think.
The only blocker so far is IE8. The rest of the browsers have had
it long enough that the traffic we need to support of non-IE
supports it.
Misc.:
* Removed 'node: true' from .jshintrc since Parsoid is no longer in
this repo and thus no more nodejs files.
- This unraveled two lint errors: Usage of 'module' and 'console'.
(both were considered 'safe globals' due to nodejs, but not in
browser code).
* Replaced usage (before renaming):
- $.inArray -> ve.inArray
- Function.prototype.bind -> ve.proxy
- Array.isArray -> ve.isArray
- [].indexOf -> ve.inArray
- $.fn.bind/live/delegate/unbind/die/delegate -> $.fn.on/off
Change-Id: Idcf1fa6a685b6ed3d7c99ffe17bd57a7bc586a2c
This makes things like
== Foo ==
* Bar
render without the leading and trailing spaces, while still
round-tripping those spaces.
* Added a .fringeWhitespace property to the linear model and ve.dm.Node
** Object containing innerPre, innerPost, outerPre, outerPost
** Only inner* are used right now, outer* are planned for future use
** Like .attributes , it's suppressed if it's an empty object
* In getDataFromDom():
** Store the stripped whitespace in .fringeWhitespace
** Move emptiness check up: empty elements with .fringeWhitespace have
to be preserved
** Move paragraph wrapping up: .fringeWhitespace has to be applied to
the generated paragraph, not its parent
** Add wrapperElement to keep track of the element .fringeWhitespace has
to be added to; this is either dataElement or the generated paragraph
or nothing, but we can't modify dataElement because it's used later
* In getDomFromData():
** When processing an opening, store the fringeWhitespace data in the
generated DOM node
** When processing a closing, add the stored whitespace back in
* In the ve.dm.Document constructor, pass through .fringeWhitespace from
the linear model data to the generated nodes
Tests:
* Change one existing test case to account for this change
* Add three new test cases for this behavior
* Add normalizedHtml field so I can test behavior with bare content
Change-Id: I0411544652dd72b923c831c495d69ee4322a2c14
* Restricting "camelcase":
No changes, we were passing all of these already
* Explicitly unrestricting "forin" and "plusplus"
These are off by default in node-jshint, but some distro of jshint
and editors that use their own wrapper around jshint instead of
node-jshint (Eclipse?) may have different defaults. Therefor
setting them to false explicitly. This also serves as a reminder
for the future so we'll always know we don't pass that, in case
we would want to change that.
* Fix order ("quotemark" before "regexp")
* Restricting "unused"
We're not passing all of this, which is why I've set it to false
for now. But I did put it in .jshintrc as placeholder.
I've fixed most of them, there's some left where there is no clean
solution.
* While at it fix a few issues:
- Unused variables ($target, $window)
- Bad practices (using jQuery context for find instead of creation)
- Redundant /*global */ comments
- Parameters that are not used and don't have documentation either
- Lines longer than 100 chars @ 4 spaces/tab
* Note:
- ve.ce.Surface.prototype.onChange takes two arguments but never
uses the former. And even the second one can be null/undefined.
Aside from that, the .change() function emits
another event for the transaction already. Looks like this
should be refactored a bit, two more separated events probably
or one that is actually used better.
- Also cleaned up a lot of comments, some of which were missing,
others were incorrect
- Reworked the contentChange event so we are no longer using the
word new as an object key; expanded a complex object into multiple
arguments being passed through the event to make it easier to work
with and document
Change-Id: I8490815a508c6c379d5f9a743bb4aefd14576aa6
Stack traces, line numbers, etc. All the approaches I've seen are bad hacks. This is the best way to go.
Change-Id: Ib12e9d2ecfe610bcc89d046005e35cc13efa3d99
Throwing strings is bad because it doesn't include a lot of important
information that an error object does, such as a stack trace or where
the error was actually thrown from.
ve.Error inherits directly from Error. In the future we may create
more specific subclasses and/or do custom stuff.
Some interesting reading on the subject:
* http://www.devthought.com/2011/12/22/a-string-is-not-an-error/
Change-Id: Ib7c568a1dcb98abac44c6c146e84dde5315b2826