The easy part is getting the correct numbers from the InternalList
and generating the ordered list HTML. The tricky part is connecting
up the events to make sure the renumberings/list generations are
triggered when required.
InternalList can emit an update event on document transaction, which
triggers the renumbering/relisting if any references have been
added or deleted during that transaction.
ve.ce.MWReferenceListNode also listens to changes on the
InternalListNode (i.e. changes to the contents of the references)
and always triggers a rebuild.
Change-Id: I1b48ef5240e433c3b314259aa68cde13841ea98b
Also keep items in the order they appear in the document
and grouped by group and key.
Additions and removals are triggered by the new root/unroot events.
Change-Id: Ia3e90ccfdab88f352b89992b90554e5f03ff9952
The only reason it doesn't save correctly right now is because Parsoid
doesn't serialize reference edits correctly.
Change-Id: Ia0f272c07cc28ee829372eb848f23aec99eb92f0
Add merge() methods to IndexValueStore and InternalList, which merge
another store/list in to the current one and return a mapping
translating old indexes to new ones.
Also add functions that, given such a mapping, traverse a linear
model data array and remap store/list indexes using simple logic for
annotations and node type-specific functions for node attributes.
Change-Id: I1e90755ced1a87c190947c037cf151c4d17cf8b7
A document slice is a document built from a data slice of an existing
document. It's completely separate from the original document and has
its own store and internalList. The new document's data also contains
the entirety of the original document's internal list. It's possible
to create a document slice of data located inside the internal list,
in which case the resulting document will contain that data twice (one
mutable copy at the top level, and one immutable copy in the internal
list).
ve.dm.Document.js:
* Optionally take an internalList in the constructor. This allows us to
create a document with a clone of an existing internalList rather than
an empty one.
* Add edgeMetadata flag to getFullData()
ve.dm.IndexValueStore.js, ve.dm.InternalList.js:
* Make these classes cloneable
Change-Id: I93e06f764ace16aee9df941b07f8c2bff1a28e2b
The EventEmitter API we inherited from Node.js and then bastardized was
getting awkward and cumbersome. The number of uses of ve.bind was getting
out of control, and removing events meant caching the bound method in a
property. Many of the "features" of EventEmitter wasn't even being used,
some causing overhead, others just causing bloat. This change cleans up
how EventEmitter is used throughout the codebase.
The new event emitter API includes:
* emit - identical to the previous API, no longer throws an error if you
emit error without a handler
* once - identical to the previous API, still introduces a wrapper* on -
compatible with the previous API but has some new features
* off - identical to removeListener in the previous API
* connect - very similar to addListenerMethods but doesn't wrap callbacks
in closures anymore
* disconnect - new, basically the opposite of addListenerMethods
Another change that is made in this commit is mixing in rather than
inheriting from EventEmitter.
Finally, there are changes throughout the codebase anywhere
connect/disconnect could be used.
Change-Id: Ic3085d39172a8a719ce7f036690f673e59848d3a