Added return boolean to ve.dm.Surface#breakpoint to indicate if
and transactions were pushed to the big stack. Use this value in
MWMetaDialog to see if we need to undo on close.
Added tests for ve.dm.Surface#breakpoint.
Bug: 49630
Change-Id: Ieb2e9e361afe057af93c4d374acc85df58bfb4c3
Slightly more efficient way of seeing if the template has changed,
and results in a cleaner set of data element attributes.
Change-Id: I1507520005bfb8a88bfa6038dac5c3b15506425d
These kinds of empty nodes shouldn't occur since the converter fills
them with empty paragraphs, but selectNodes() should still behave
correctly for them.
Change-Id: Ia37f3db1c2a84b842e2311cf70642fa66af04d91
* Move them from ve.example.js to ve.dm.example.js
** Also move lookupNode() and createDomElement() there
** Delete ve.example.js because there's nothing left in it
* Make main example document implicit, but allow override
* Specify nodes as arrays and do the lookup later
* Specify range and mode separately rather than calling selectNodes()
during construction
* Construct statically rather than in a function
* Use expect( cases.length );
Change-Id: I620e949c5e612b32eaa57c5d9b60cc91f9ddbf02
Otherwise fun exceptions occur when you have a <references /> tag
with no <ref>s, for instance.
Also disregard the internalList in the data->DOM conversion, to prevent
a nasty interaction where the whitespace information on the last element
is considered invalid because it doesn't match the internalList's.
Plus test updates from hell because this touches ve.dm.example.data
Change-Id: I62881d9fc27fa081123856d1b35a6021af469271
unicodejs.graphemebreak.js
* New file: singleton class with splitClusters method
* On load, builds graphemeBreakRegexp from unicodejs.graphemebreakproperties.js
unicodejs.js
* Remove old splitClusters method (was just a placeholder)
* Change "conjunction" -> "disjunction", for consistency and correctness
unicodejs.textstring.js
* Use new splitClusters method
modules/ve/ve.js
* Use new splitClusters method
unicodejs.wordbreak.text.js
* Add new splitClusters test
* Refactor charRangeArrayRegexp test to use splitClusters
PHP files
* add unicodejs.graphemebreak.js, unicodejs.graphemebreakproperties.js
.docs/categories.json
* add unicodeJS.wordbreak class
Change-Id: I8f512e2fc2c46eb4b5f00994a8dac88f3c8f7dd2
Objective:
* Allow editing reference groups and names in the reference dialog
Bonus:
* Modify attribute transaction builder to support multiple attribute
changes in a single transaction
Changes:
ve.ui.MWReferenceDialog.js
* Load ref name and group from model
* Save ref name and group, if changed, to model
ve.ui.ListAction.js, ve.ui.Transaction.test.js, ve.ce.ResizableNode.js
* Update use of newFromAttributeChange to newFromAttributeChanges
ve.dm.SurfaceFragment.test.js
* Add test for new changeAttributes method
ve.dm.InternalList.js
* Missing new line at end of file
ve.dm.Transaction.js
* Change newFromAttributeChange to accept an list of attribute changes and
produce a single transaction that applies one or more attribute changes
at once
ve.dm.SurfaceFragment.js
* Fix bug in getCoveredNodes where the wrong mode name was being used
* Add changeAttributes method, which applies attributes to all covered
nodes and allows filtering of which types of nodes the attributes are
applied to
ve.dm.MWReferenceNode.js
* Actually write key and group back to DOM
* Separate onRoot functionality into addToInternalList so it can be called
separately (similarly onUnroot/removeFromInternalList)
ve.ce.MWReferenceListNode.js
* Clone internal item CE node before appending to avoid rendering bug.
*.php
* Add links to messages and sort them
Change-Id: Ic4121e4fcfc09265d5863af6f078cdeb77926c8e
Objectives:
* Allow reordering items in outline widgets using an outline control
widget
* Use an outline control widget to reorder transclusion parts
Changes:
ve.ui.SelectWidget.js
* Emit add and remove events
ve.ui.OutlineItemWidget.js
* Add movable config options
* Add isMovable method
ve.ui.OutlineControlsWidget.js
* New class
* Displays move up/down buttons which are synchronized with an outline
widget
* Doesn't actually move items (since an outline widget is probably
data-driven) just emits events
ve.ui.Widget.css
* Add disabled style for icon button widgets
* Add styles for outline controls widget
ve.ui.Icons*.css
* Add missing icon styles
ve.ui.Dialog.css
* Add styles for outline and controls in editable paged dialogs
ve.ui.GroupElement.js
* Fix bug where items are insertions are in the wrong place when "moving"
them
ve.ui.PagedDialog.js
* Add editable config option which shows outline controls under the
outline
* Pass through movable config option when creating pages
ve.ui.MWTranclusionDialog.js
* Configure paged dialog outline as editable
* Add initialize method to connect outline controls widget events
* Make addPart method automatically add parameters when templates are
added
* Add handler for outline controls move event which re-orders parts
* Make parts movable (params are automatically ordered, so they aren't
movable)
ve.dm.MWTransclusionModel.js
* Add addPart method and use it within the addContent and addTemplate
methods
* Fix documentation lies
* Add getPartFromId method
*.php
* Add links to new files and messages
Change-Id: I919d4c3e9b85d07a97a99c0b2e8739a859bdf2b1
Per the bug report, it's useless because Firefox does not preserve order
in the .attributes array (but sorts it alphabetically instead), and so we
actually get the same exact behavior regardless of whether we use ordering
cleverness or just a straight-up plain object: order is preserved in Chrome,
and alphabetized in Firefox.
Bug: 48980
Change-Id: I1463d06db4900083dd4c565292bbabef09194b43
Objectives:
* Rename just about every use of "template" to "transclusion"
* Make a proper data structure for transclusions
* Abstract away template data
* Use more template data in the user interface
* Allow adding parameters
* Allow removing templates, parameters and content
Changes:
ve.ui.Dialog.css
* Add rule to place add param controls on a single line
ve.ui.MWTemplateDialogs.js
* Move template spec loading into transclusion class
* Add remove button for parts and parameters
* Add parameter adding form
* Use template data for labels and descriptions
ve.dm.*
* Add new transclusion data structures
*.php
* Add links to new files
*.*
* Rename all things "template" to "transclusion"
Bug: 39598
Bug: 49403
Change-Id: I3bcf924a3e179cb65f19e833277a39dfd3dad8bd
Media item dialog for settings; drag-and-drop placement; caption
editing still to come.
Bug: 37870
Change-Id: I547e06dcdb92e19f0159660314187c4f1a62f3ed
We don't need to decompose and rebuild alien meta items
as they are uneditable, so just store the dom node and return that
in toDomElements.
Update test cases and several tests now need to use
assert.deepEqualWithDomElements.
Change-Id: I4d2eed267dac7855cb929a17d7aef566eaf0e287
unicodejs.js:
* charRangeArrayRegexp to write surrogate-aware regexps
* private helper functions
unicodejs.wordbreak.test.js:
* test charRangeArrayRegexp
* corrected tests for non-BMP wordbreaks
unicodejs.wordbreak.js:
* use new surrogate-aware regexps
unicodejs.wordbreakproperties.js:
* generated from Unicode data
unicodejs.graphemebreakproperties.js:
* generated from Unicode data
unicodejs.wordbreak.groups.js:
* delete as no longer used
unicodejs-properties.py:
* generate unicodejs.wordbreakproperties.js from Unicode data
* generate unicodejs.graphemebreakproperties.js from Unicode data
index.php:
* update script tag links
/VisualEditor.php:
* update script tag links
/demos/ve/index.php:
* update script tag links
/maintenance/makeStaticLoader.php:
* update script tag links
Change-Id: I39c0386a85b0cf21d68d3385b84018a5d7648de5
Objective:
* Allow opening reference dialog with arbitrary selection
* Auto-insert reference when selection is not a reference node
Changes:
ve.init.mw.ViewPageTarget.js
* Added reference button to toolbar
ve.init.Target.js
* Add getToolbarSubset so we can exclude the reference button from
the toolbar in the reference dialog (nested references are not
allowed).
ve.ui.MWReferenceDialog.js
* Stop storing referenceNode (not needed)
* Only store internalItem on open if there's a focused node that's a
reference
* Use wrapper paragraph when creating a new reference
* Create new reference on dialog close if required
ve.dm.InternalList.js
* Major rewrite to support key less references.
* Add new method for creating a transaction to insert a new iternal
item. Also returns the index of the new item to be passed to the
reference node.
Change-Id: I839ae165c299248484ce93d4ab087318a95fbb94
Previously we populated the reference body into all <ref> tags
with the same key. Now we store an internal attribute marking
which element originally had the data.
If that tag is deleted the body is moved to the first <ref> tag
with that name.
Change-Id: If9f12bfb699e6ce85bb8f7d2ea9e6df528610a3d
Objective:
* Make all text inputs have the ability to be "pending", not just ones
with a special mixin
Changes:
* Delete pending input widget
* Move pending input widget implementation to text input widget
* Update all uses of pending input widget
* Make pending image a reusable "texture"
* Update styles of text input widget for pending state
* Get rid of checking for mixin since all text inputs can be pending now
Bonus:
* Get rid of unused images, including .psd and .ai files
* Add transparency texture
* Fix input widget not using documented config value
* Fix documentation in select widget (lies!)
Change-Id: Ib46ab01dc39d706e5c25fd473dee0edce51b7e44
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
Follows-up 2e76271 and 231a50f which made manual changes to
the static-loading files without updating makeStaticLoader
(thus causing the load order and if-statement to be out of
sync between different index.php files).
Updating makeStaticLoader to include those changes and applying
it to the other index.php file.
Change-Id: I9bbe97d85f663b1cffeb384d52b5cc54e2f6601b
Due to the "es5: true" jshint option we enabled, these
warnings were surpressed. I've disabled the option since
we no longer require it. It was enabled in 07c86fc to fix
a bug with jshint. This bug has now been fixed.
Change-Id: I55b7d031eb5581af5f733f050cf2ea98dacb2af6
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
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
Getting & setting the cursor is done with byte offsets
instead of data model offset (characters) so we need to
be able to convert between the two as well as splitting
characters.
TODO: The regex only works on surrogate pairs, not
yet combining accents.
fixupInsertion will combine a combining mark with the
character to its left it it can.
Bug: 48630
Change-Id: I8d936fb15d82f73cd45fac142c540a7950850d55
Right now the internal list is very much HTML-based, so it's not
populated at all when creating a document from data. So hack this in by
specifying what should be in the internal list as a property of the
example document's data array.
Change-Id: I51c7b7b4dcd9fd3333777c1287b7ba544887aa32
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
* VisualEditor.hooks.php
** export URL to magnify clip as a configuration variable so thumbnail image can render correctly
* ve.ce.Surface.css
** add CSS styling to make image captions look the same way in edit mode as they look in the view mode
* ve.ce.ParagraphNode.js
** add CSS class ve-ce-generated-wrapper if it is a generated wrapper
* ve.ce.MWImageCaptionNode.js
** make image caption rendering match the view mode
Change-Id: I0cd1b25e8f8355e0500aabc90e7c4cdf591545f3
Previous check wouldn't make sense, cause the last offset in the data
could be that one that makes data balanced (and j is increased always
after iteration).
Change-Id: Ie9498d0ac9e3417d09b8b3043bf3281e7dfbf9db
Rather than using namespaced linmod attributes, store the preserved
HTML attributes in the .htmlAttributes property of the linear model
element, in a nested structure to allow for easier treatment of child
nodes. Also added attribute order preservation by storing attributes
as an object plus an array of keys.
ve.ce.Node.js:
* Remove html/* attribute synchronization. Doesn't make sense any more
because these things aren't in the attributes object any more. I don't
think it ever made sense because these attributes were never supposed
to be changed anyway.
ve.ce.View.js:
* Replace renderAttributes() with a simple wrapper around
renderHtmlAttributeList()
ve.dm.Converter.js:
* Add buildHtmlAttributeList() and renderHtmlAttributes() for building
and rendering HTML attribute lists
ve.dm.Model.js:
* Add getter for .htmlAttributes
ve.dm.Node.js:
* Drop .htmlAttributes on clone, and remove logic dropping html/*
ve.ui.MWCategoryWidget.js:
* Remove html/0/about hack, was already unnecessary and now doesn't
work any more
tests/:
* UPDATE ALL THE TESTS
Change-Id: I620573afd70d36ade6b80413075b6e1f4a435abe
Escapes }} and | by wrapping them in <nowiki> tags, and steps around
<nowiki> tags so as to not double-wrap things.
Change-Id: Ia50906524c1fcf55c9f390a114856bc7f20b2d3a
Objective:
* Add button to launch template dialog
* Add template dialog
Changes;
*.php
* Add messages and links to files
ve.ce.Node.css
* Make inline templates display as inline-block to contain their
contents (allowing shields to work properly)
ve.ui.MWTemplateDialog.js
* New empty dialog for templates
ve.ui.MWTemplateButtonTool.js
* New template button, appears in context and launches dialog
Change-Id: I9174ed7c9012522246a6defc859276bf36763f5b
Objectives:
* Split ve.Surface into ve.Editor and ve.ui.Surface
* Move actions, triggers and commands to ve.ui
* Move toolbar wrapping, floating, shadow and actions functionality to configurable options of ve.ui.Toolbar
* Make ve.ce.Surface and ve.ui.Surface inherit ve.Element and use this.$$ for iframe friendliness
* Make the toolbar separately initialized so it's possible to have a surface without one, as well as control where the toolbar is
Some change notes:
VisualEditor.php
* Added standalone module for mediawiki integrated unit testing
ve.ce.Surface.js
* Remove requirement to pass in an attached container to construct object
* Inherit ve.Element and use this.$$ instead of $
* Make getSelectionRect iframe friendly
* Move most of the initialize stuff to a new initialize method to be called after the surface is attached to the DOM
ve.init.mw.ViewPageTarget.js
* Merge toolbar functions into setup/teardown methods
* Add toolbar manually (since it's not added by the surface anymore)
ve.init.sa.Target.js
* Update new init procedure for editor, surface and toolbar separately
* Move toolbar floating stuff to ve.Toolbar
Change-Id: If91a9d6e76a8be8d1b5a2566394765a37d29a8a7
Objectives:
* Move ve.ui.Element to ve.Element
* Make CE nodes inherit from ve.Element
Changes:
ve.ui.Element.js, ve.Element.js
* Move and rename
* Move ve.ui.get$$ to ve.Element.static.get$$
* Add static getDocument and getWindow methods
* Add instance getElementDocument and getElementWindow methods
* Add getTagName method, which by default reads the static tagName property, but when overridden can return a tag name based on other factors
*.php
* Updated file link
ve.ce.*Annotation.js, ve.ce.*Node.js, ve.ce.View.js, ve.ce.Document
* Added config options pass through
* Replaced passing elements through constructor with defining static tag names
* Added getTagName overrides where needed that derive tag name from model
* Refactore dom wrapper methods, now consistently using getTagName
ve.ce.Surface.js
* Removed static initialization (not needed)
ve.dm.Model.js, ve.ui.Window.js
* Added missing docs
ve.ui.GroupElement.js, ve.ui.Layout.js, ve.ui.Widget.js,
* Updated class name for elements
ve.ui.Frame.js, ve.ui.LookupInputWidget.js
* Updated location of get$$
ve.ui.js
* Move get$$ to ve.Element
ve.js
* Add auto-init of static properties to mixinClass
Change-Id: I39ae14966456903728e4d9e53f806ddce9ca2b70
Objective:
Add a basic (empty) dialog for mediawiki references. Editor to follow.
Changes:
*.php
* Added file links and messages
ve.ui.MWMetaDialog.js
* Moved initialize method to the top (for consistent ordering)
ve.ui.MWReferenceDialog.js
* New class, basic empty dialog for references
ve.ui.LinkInspector.js, ve.ui.MWLinkInspector.js, ve.ui.MediaButtonTool.js
* Cleanup documentation
* Whitespace
icons.ai, reference.png, reference.svg
* Switch to reference icon being 3 books on a shelf
ve.ui.MWReferenceButtonTool.js
* New class, basic dialog button for references
Change-Id: Ia4e30e9239fa1e3b28c0a1ef1ca0a6515a8103ef
This is caused by a limitation of surface fragments in that they
always expand to include insertions touching them. In this case
we build surface fragments contain adjacent listItems, so when
the first listItem is de-listed a transaction is first created to
split the list. This insertion of ('/list', 'list') is adjacent
to the second surface fragment and so becomes part of that fragment.
This then causes the wrong node to be passed to unindentListItem.
The workaround is to use the inner range of the listItem, not
the outer range.
Bug: 48390
Change-Id: I7418910412d292ef4953e294a97f66e48d6f776f
Objective:
* Add default sort key field to meta dialog
* Replace PagePanelLayout with a generic panel containing one or more FieldsetLayout elements
Changes:
*.php
* Added/removed file links
ve.dm.MWDefaultSortMetaItem.js
* Added getContent method
ve.dm.MetaItem.js
* Added replaceWith method
ve.dm.MetaList.js
* Allow insertion at the end by omitting offset and index
ve.dm.MWMetaDialog.js
* Added default sort key field
* Put category and default sort fields inside fieldsets
* Added loading/saving default sort key
ve.ui.PagedLayout.js
* Changed class used for pages to generic panel layout
ve.ui.PagePanelLayout
* Moved title/icon stuff to field set
ve.ui.FieldsetLayout.js
* New class, adds fieldset with legend
ve.ui.StackPanelLayout.js
* Moved up to the layouts directory
ve.ui.Dialog.css
* Moved style for paged panel from layout stylesheet
ve.ui.Layout.css
* Added styles for fieldsets
ve.ui.Widget.css
* Adjusted margins of input label widgets
ve.ui.MWCategoryWidget.js, ve.ui.MWCategoryPopupWidget.js
* Added setDefaultSortKey method
Change-Id: I979f5e3f08a688790c9f54086206ed1999af13ea
In stopWrapping we assign any left over whitespace to the paragraph
in position 3, however we weren't clearing this whitespace buffer
if an inline content node followed it.
Change-Id: I8b3ee3915044abd6bafda386430bf7f992ca4aa8
The way it operated was evil. It did a depth-first search from the root,
finding the node using reference equality. For documents with deep
structures, this could take a long time. Inez did some profiling and
found it was called tens of millions of times on a complex document.
Kill getOffsetFromNode() and move its functionality to getOffset().
The logic has been completely rewritten: getOffset() now traverses
up from the node rather than down from the root, and pretty much does
the reverse of what getNodeFromOffset() does. This should be much more
efficient even without offset caching in the node objects (which we may
still implement later).
Change-Id: I125f9fa423c40db6472e2c4a7c94214218ba3bc7
For nodes that handle their own children (as well as leaf nodes and
meta items), store the first child's attributes in html/0-0/*, the
second child's attributes in html/0-1/*, the second element's third
child's fourth child's attributes in html/1-2-3/* , etc.
This obsoletes the ad-hoc code that basically did the same thing in
MWInlineImageNode.
Change-Id: If5abd2d5d9c361b359617ff4b0f3d6ba4c9b0142
We already do this in unit test so moving getDomElementSummary
and convertDomElements from ve.qunit.js to ve.js.
Apply ve.convertDomElements to report data before serialising.
Bug: 47948
Change-Id: Id807ccc6ff31d063be815ed4988cb35684adb76a
Store the HTML as a domElements array like everywhere else, rather than
as a string. Also disable HTML attribute preservation because there's
no point doing that when we're already preserving all of the HTML.
Also fixed a misnamed attribute (<li li="foo"> --> <li id="foo">) in
the test case.
Change-Id: I36bf8bade8118e07a75eb6f3a2427a00ef4915d7
We've housed these utilities for a while and changed some of
them quite a bit. Importing them to avoid regressions and
ensure we keep them in sync with our fork of it.
Removed references back through `@source`. They are sufficiently
different that the reference no longer adds any value.
Imported from https://github.com/Krinkle/K-js/blob/v0.1.2/test/K.test.js.
Change-Id: I9e71297246b7c248c1f032ba6b6ae1123519f3c1
It now allows you to specify which attributes to preserve in various
ways rather than just setting true or false.
Removed unused factory methods that exposed the old value.
Change-Id: I914164adcf1f0e48fa3fa85277e68c72dbad393e
* It returned undefined instead of false if the subject
didn't have a 'mixins' property. This is because '&&'
is a DEFAULT operator, not an AND operator, it returns the
value, not a boolean per se.
* The logic of traversing to the constructor property was
broken since all objects in javascript have a constructor
property, and functions/constructors are also objects.
Follows-up Ic3e4472b9e694.
Change-Id: I462e7ce270c8cfc7e1970e359894ee4b7d90b881