This is just a prototype - if it will be as useful as I expect
then it will get refactored (and probably get a better name +
location).
Change-Id: Ice1a2bd7d498d9d8438c35239216f01bd3db1826
Layouts
* Makes widget inherit from element
* Adds layout which also inherits from element
* Adds grid and panel layouts
* Uses grid layout in meta dialog
Other changes
* Corrects issues with several of the stand-alone files by fixing and using makeStaticLoader.php
Change-Id: I6b92c0204e176c914c26eff8c03ea417578e080c
A MetaList is a collection of MetaItems representing all of the
metadata in a ve.dm.Document, and it updates itself live as the
underlying document changes.
Currently this interface is read-only, I'll add mutators next.
Change-Id: If7bfc9563af37e22dcdca9a682d6decc2f6f1872
Rather than meta-things being special kinds of nodes, they are now a
separate class of things (MetaItems) along with Nodes and Annotations.
* Created a generic ve.dm.MetaItem that meta items inherit from.
There will be actual instances of this class as well in the upcoming
meta group code.
* Renamed MetaNode to AlienMetaItem, MWMetaNode to MWMetaItem,
'metaBlock'/'metaInline' to 'alienMeta'
* Created a MetaItemFactory, handle meta items in the ModelRegistry
* Kill ve.dm.Node.static.isMeta, now obsolete
ve.dm.Converter:
* Pass in the MetaItemFactory
* Look up data element types in the ModelRegistry rather than the
NodeFactory, because they can be either nodes or meta items
* Document createDataElement() and make explicit that modelClass can be
either a node or a meta item
* Handle meta items in getDataFromDom()
* In getDomFromData(), check the MetaItemFactory as well as the NodeFactory
Change-Id: I893709c6f3aa00f85c1b905b70f9f4e597bdeada
Replacing [a-zA-Z] with a long unicode expression which encompasses
all the characters in the unicode 'letters' category. Similarly replacing
[0-9] with an expression for 'numbers'.
Bug: 44085
Change-Id: Idd403339caa24769ce08133dda06ab6d4b9d694e
This is a major refactor of user interface context, frame, dialog
and inspector classes, including adding several new classes which
generalize managing inspectors/dialogs (which are now subclasses
of window).
New classes:
* ve.ui.Window.js - base class for inspector and dialog classes
* ve.ui.WindowSet.js - manages mutually exclusive windows, used
by surface and context for dialogs and inspectors respectively
* ve.ui.DialogFactory - generates dialogs
* ve.ui.IconButtonWidget - used in inspector for buttons in the head
Refactored classes:
* ve.ui.Context - moved inspector management to window set
* ve.ui.Frame - made iframes initialize asynchronously
* ve.ui.Dialog and ve.ui.Inspector - moved initialization to async
initialize method
Other interesting bits:
ve.ui.*Icons*.css, *.svg, *.png, *.ai
* Merged icon stylesheets so all icons are available inside windows
* Renamed inspector icon to window
ve.ui.*.css
* Reorganized styles so that different windows can include only
what they need
* Moved things to where they belonged (some things were in strange places)
ve.init.Target.js, ve.init.mw.ViewPageTarget.js, ve.init.sa.Target.js
* Removed dialog management - dialogs are managed by the surface now
ve.ui.*Dialog.js
* Renamed title message static property
* Added registration
ve.ui.*Inspector.js
* Switch to accept surface object rather than context, which conforms
to the more general window class without losing any functionality
(in fact, most of the time the surface was what we actually wanted)
ve.ui.MenuWidget.js, ve.ui.MWLinkTargetInputWidget.js
* Using surface overly rather than passing an overlay around
through constructors
Change-Id: Ifd16a1003ff44c48ee7b2c66928cf9cc858b2564
The IndentationAction was created against a version of master which
didn't have the new Surface constructor signature. This commit resolves
that conflict.
Change-Id: Ifc17f95acfa6057963d503448405355831b1ff97
Also in this commit is a minor fix to the regular expression so it
behaves as documented (the hyphen needed escaping).
Bug: 44085
Change-Id: Idc315e2dce79be8f028b5681c60f74e175b9d869
isolateAndUnwrap now unwraps to a level determined by a target type
i.e. the type you are going to convert to.
Also in this commit wrap/unwrap/rewrap have been refactored to use
getLengthDifference. unwrap now takes an inner/outer unwrap depth.
Change-Id: I3c6249de43232a9ef64f498a0aaf66b1c44973f2
Wrapper paragraphs should only be unwrapped if they are the first
element in their parent - or if there is a block level element separating
them from the previous unwrapped paragraph.
Empty paragraphs should only be unwrapped if they are empty and the
last element in their parent.
Also in this commit is a simple test for IndentationAction.decrease().
Bug: 45590
Change-Id: I1f47d12db6d57d984fd4607f667a3b62c53f3dd6
Heading and Preformatted nodes have rules that should only
exist under a document node in MediaWiki.
Two new node types have been created as has a new DropdownTool which
uses these. The MW init options have been changed to use the new
DropdownTool.
Bug: 45295
Change-Id: I3f47e1ae1f5c1415bde58a75385e4bf5f4b8fffc
The ve.Surface constructor was recently changed, but the instantiation
in the FormatAction tests was not updated accordingly.
The constructor now requires a ve.init.Target object.
Bug: 39597
Change-Id: Ia4193fbab5c63007ed057009bf9a39f1f9d18fb7
Add a static.name property to ce nodes and make sure both ce
and dm nodes always use the static.name property in constructors
and registration calls.
The result of this is that any given node type should now only
appear once in the code as a string.
Bug: 45701
Change-Id: Ibf31de16ab28ad58209c1443cd74f93dda278998
Major changes:
demos/ve/index.php
* Renamed ve-demo-content to ve-demo-editor
ve.init.mw.ViewPageTarget, ve.init.sa.Target
* Added handlers for dialog events
ve.ui.*Dialog.js
* Added skeleton classes for dialogs
ve.init.Target.js
* Create abstract class methods for Target.
ve.init.sa.Target.js
* Create Standalone target view methods.
ve.init.mw.Target.js
* Added MW specific target view methods.
* Integration action buttons are now added to the edit
view in the toolbar.
ve.Surface.js
* Simplified constructor, now requiring a target which contains the container
* Other changes include some documentation and code cleanup.
Bug: 39597
Change-Id: Iff39266bdd3052f34bda254ca407030dbbc81f26
I encountered a very difficult to track down error while working on
ve.ui.Dialog where a copy-pasted inheritClass call overwrote the
prototype of ve.ui.Widget.
By adding this check, we can ensure that 2 identical calls to
inheritClass won't silently make the system explode. This check is
lightweight and will save someone down the line a bit of time and head
scratching.
Change-Id: I014d53722fc8d941ec415462d258a79985e0e3d7
Objective:
Refactor UI widgets, improve usability and accessibility of menus, general cleanup and style improvements.
Extras:
Fixed documentation in a few other files to make descriptions of jQuery event arguments more consistent, classes inherit correctly, and made use of the @cfg functionality in jsduck.
Changes:
.docs/config.json
* Added window, HTMLDocument, HTMLElement, DocumentFragment and XMLHttpRequest to externals, so jsduck doesn't throw warnings when they are used
demos/ve/index.php, modules/ve/test/index.php, VisualEditor.php
* Moved widgets above tools (since tools use widgets)
demos/ve/index.php
* Refactored widget initialization to use options
* Renamed variables to match widget names
ve.init.mw.ViewPageTarget.css
* Adjusted text sizes to make widgets work normally
* Added margins for buttons in toolbar (since button widgets
don't have any)
* Removed styles for init buttons (button widgets now)
ve.init.mw.ViewPageTarget.js
* Switched to using button widgets (involved moving things around
a bit)
ve.ui.LinkInspector.js, ve.ui.MWLinkInspector.js
* Renamed static property "inputWidget" to
"linkTargetInputWidget" to better reflect the required base class
for the properties value
icons.ai, check.png, check.svg
* Added "check" icon, used in menu right now to show which item
is selected
ve.ui.Icons-raster.css, ve.ui.Icons-vector.css
* Added check icon
* Removed :before pseudo selectors from most of the icon classes (not need by button tool anymore, makes them more reusable now)
ve.ui.Tool.css
* Adjusted drop down tool styles so menu appears below, instead
of on top, of the label
* Adjusted paragraph font size to better match actual content
* Updated class names to still work with menu widget changes
(items are their own widgets now)
* Updated selectors as per changes in the structure of button tools
ve.ui.Widget.css
* Added styles for buttons and menu items
* Adjusted menu styles
ve.ui.*ButtonTool.js
* Added config options argument passthrough
ve.ui.ButtonTool.js
* Moved var statement to the top inside constructor
* Switched to using "a" tag to get cross-browser :active support
* Added icon to inside of button to make icon styles more reusable
* Removed disabled support (now provided by widget parent class)
ve.ui.FormatDropDownTool.js
* Updated options initialization to construct menu item objects
* Modified handling of items to account for changes in menu and
item classes
* Optimized onUpdateState method a bit, adding early exit to
inner loop
ve.ui.ButtonTool.js, ve.ui.DropdownTool.js, ve.ui.Context.js,
ve.ui.Frame, ve.ui.Tool.js, ve.ui.Widget.js
* Added chain ability to non-getter methods
ve.ui.DropdownTool.js
* Removed items argument to constructor
* Updated code as per changes in menu class
* Fixed inconsistent naming of event handler methods
* Removed item event handling (now handled by items directly)
* Made use of this.$$ to ensure tool works in other frames
ve.ui.Tool.js
* Made tools inherit from widget
* Moved trigger registry event handler to a method
ve.ui.Context.js
* Switched from using menu to contain toolbar to a simple wrapper
ve.ui.js
* Added get$$ method, a convenience function for binding jQuery
to a specific document context
ve.ui.*Widget.js
* Switched to using a config options object instead of individual arguments
* Added options
* Factored out flags and labels into their own classes
* Refactored value setting methods for inputs
ve.ui.MenuWidget.js, ve.ui.MenuItemWidget.js
* Broke items out into their own classes
* Redesigned API
* Updated code that uses these classes
* Added support for keyboard interaction
* Made items flash when selected (delaying the hiding of the menu for 200ms)
ve.ui.LinkTargetInputWidget.js, ve.ui.MWLinkTargetInputWidget
* Refactored annotation setting methods
Change-Id: I7769bd5a5b79f1ab36f258ef9f2be583ca503ce6
rewrapAllNodes is effectively the same as unwrap then wrap
except it operates as one transaction as so avoids a potentially
invalid intermediate state.
Added some more comments for unwrapAllNodes and renamed a varaible
for consistency.
Fixed a typo in Transaction.newFromWrap comment.
Bug: 45242
Change-Id: Ie752a788d087055d97c7c6f75f59c6a2680d26c7
Previously, we would translate to the right of an insertion, but for
wrapping transactions that means we end up with something like
<ul><li>|<p>...</p></li></ul>|, which doesn't make any sense. This
change changes this to <ul><li>|<p>...</p>|</li></ul>.
* Add parameter to translateOffset() that toggles the behavior for
the offset before an insertion
* In translateRange(), translate start and end differently
** In some cases this can map them across each other, fix that
Change-Id: Ia2197b08d9f6763be3f2db5a59546ddc3f74a281
We already combine consecutive operations of other types, but didn't do
that for remove. We have to do this, though, because translateOffset()
gets confused otherwise.
Change-Id: I4285a3efd9f2297398f57e2f24adb26adafdf465
I was seeing intermittent test failures caused by exceptions in
ce.SurfaceObserver (!!), seems to be caused by the FormatAction test
creating a surface but not destroying it.
Change-Id: I7ab070d3c8db934eb9781ac8a6466475144c214e
This changes the node API to work with multiple elements, so we can
support about groups. Instead of passing in and returning single DOM
elements, we use arrays of DOM elements.
ve.dm.Converter:
* Pass modelRegistry into the constructor
* Remove onNodeRegister handler and its data
* Remove getDataElementFromDomElement() and
getDataAnnotationFromDomElement(). Most logic moved into
getDataFromDom(), some into createDataElement()
* Remove createAlien(), replaced with
createDataElement( ve.dm.AlienNode, ... )
* Replace doAboutGrouping() (which wrapped about groups) with
getAboutGroup() (which returns an array of the nodes in the group)
* Put in a hack so <meta>/<link> elements with an mw: property aren't
alienated
* Remove about group wrapping behavior in favor of just outputting
multiple nodes
ve.dm.AlienNode.js:
* For multi-element aliens, only choose inline if all elements are
inline, not just the first one
ve.dm.example.js:
* Add html/0 stuff for meta nodes
* Fix test case to reflect new alien behavior
Change-Id: I40dcc27430f778bc00a44b91b7d824bfb2718be6
wrapAllNodes was calulating the new selection incorrectly. This has
been fixed and a test added.
unwrapAllNodes takes a depth as its argument and unwraps that many
elements from inside the selection.
Tests for wrap/unwrap apply also now check that applying a wrap
and then its inverse as an unwrap result in the document reverting
to its original state.
Change-Id: I7dcacdfb5894be59ffad69b369d7b32933a25b61
In our test case, offset 12 was mapped to 16, but that should be 11.
The problem here was that the offset right before the removal was
mapped to right after the removal, but that's only valid if we're
dealing with a removal, not when we're dealing with a replacement
where we're both removing and inserting data.
Change-Id: Ibf3c1463c0de009578cd50736f19bae82669ced8
This method will take a selection of siblings and ensure they
are the only chlidren in their first parent which can be placed anywhere
(for example the first parent of a tableCell which can be placed anywhere
is a table, and for a listItem is a list).
The method ensures no redundant empty tags are created, so if
the selection encompasses all siblings then no action is taken.
Also in this commit are two test cases run against ve.dm.example.isolationData.
Change-Id: I783bd5ecd9d43d61f9b2685985409b4d746cbe94
The Parsoid output will also be expected to be a full HTML document. For
backwards compatibility, we allow for the Parsoid output to be a
document fragment as well. We don't send a full document back yet, also
for b/c -- we'll change this later once Parsoid has been updated in
production.
ve.dm.Converter.js:
* Make getDataFromDom() accept a document rather than a node
** Split off the recursion (which does use nodes) into its own function
** For now we just convert the <body>. In the future, we'll want to do
things with the <head> as well
* Pass the document around so we can use it when creating elements
* Make getDomFromData() return a document rather than a <div>
ve.init.mw.Target.js:
* Store a document (this.doc) rather than a DOM node (this.dom)
* Pass around documents rather than DOM nodes
* Detect whether the Parsoid output is an HTML document or a fragment
using a hacky regex
* When submitting to Parsoid, submit the innerHTML of the <body>
ve.init.mw.ViewPageTarget.js:
* s/dom/doc/
* Store body.innerHTML in this.originalHtml
ve.Surface.js:
* s/dom/doc/
demos/ve/index.php:
* Don't wrap HTML in <div>
* Pass HTML document rather than DOM node to ve.Surface
ve.dm.Converter.test.js:
* Construct a document from the test HTML, rather than a <div>
ve.dm.example.js:
* Wrap the HTML in the converter test cases in <body> tags to prevent
misinterpretation (HTML fragments starting with comments, <meta>,
<link> and whitespace are problematic)
Change-Id: I82fdad0a099febc5e658486cbf8becfcdbc85a2d
Converts an HTML string to a brand new document using an iframe hack
(proper ways to do this exist, but don't work cross-browser).
Parsoid will serve us full HTML documents rather than document fragments
soon, so we'll need this functionality (along with some other changes
that I'm working on now) to deal with that change.
This doesn't currently work quite right in IE8 (although we have lots of
other issues in IE8) as well. It's not that hard to fix up though: we
just have to leave the iframe attached to the main document (should
probably provide a destroy function in that case) and the tests have to
deal with the fact that IE normalizes <head></head> to
<head><title></title></head> .
(For backwards compatibility, we'll have to deal with document fragments
as well; this will be implemented as an MW-specific hack in the
integration in the next commit.)
Change-Id: I15f877583c39124ba1c5e8e22585297ff3bac8d6
Have created builders for insertion, removal, and single element replacement.
In adding Document.getMetadata which is nearly identical to Document.getData,
the two functions have been refactored to use a common static method
getDataSlice, with this.data/this.metadata as an argument.
Document.spliceMetadata has been added. It is essentially spliceData with
the data/metadata synchronisation issue.
Metadata cursor position is now tracked in the TransactionProcessor. Cursor
advancement has been moved to a function so the metadata cursor can be reset
every time the data cursor is moved.
There were unhit bugs in the TransactionProcessor run test section, where
the data being loaded into the test documents wasn't always being deep-copied,
and the assert was looking at getData instead of getFulldata (which wouldn't
be able to test metadata changes).
Change-Id: Ieb20ab3e7827bc7ff04148f147da6728eb1eb666
* New! Button and InputLabel widgets
* Using new buttons in the demo
* Moved styles around to generalize input styles
Change-Id: Ic42e133f8fe0fffcb61374c09dd5668db82a4799
TODO: Use these buttons other places! (like ve.init)
This means that <p data-foo="bar"> will now be converted to a paragraph
with attributes {"html/0/data-foo":"bar"} rather than {"html/foo":"bar"}
This paves the way for multi-element node (about group) handling in the
node API: nodes representing multiple DOM elements will have html/i/attr
to represent an attribute of the i'th DOM element.
Change-Id: Iea52bdccd721942ca708c8f9f47e934524809845
When encountering an inline node (i.e. content node that's not a text
node) within a branch node that's not a content branch node, the
converter should start a wrapper. But it doesn't do this, it only opens
wrappers for text nodes and annotations.
Fixed this in the converter, added a test for it, and fixed an existing
test that asserted the broken behavior.
Change-Id: I6e143e21e68b68f0d85b8772e24a2d3a5d465410
* Introduce context object as specified for
ve.dm.Node.static.toDataElement()
* Remove wrapping variable in favor of context.wrapping
* Remove wrappingIsOurs in favor of context.canCloseWrapper
* Introduce originallyExpectingContent and use it to repopulate
context.expectingContent after closing a wrapper
* Replace most uses of branchHasContent with context.expectingContent
** Except for two cases where we need originallyExpectingContent
These changes fix a case where a metaBlock was generated in an inline
position. Updated the tests to reflect this.
Change-Id: I6baf6053f8a3a0b7d91487f812b9235a7b2b3db1
Continues where Ibb682332a6084e357104183641a104e3ae1e253f left off, adding tests and removing inconsistencies between the behavior of the document constructor, which was adding empty text nodes to empty paragraphs, and correcting other tests which expected empty text nodes to be there as well.
Change-Id: I414d061cdd494b8023f14e944eda2910a4dab0d4
Objective: Simplify the registration and use of triggers
Changes:
* Renamed ve.Command to ve.Trigger
* Renamed command demo to trigger demo
* Removed language prefixing of triggers
* Generating trigger tooltips rather than hard-coding them in i18n
* Added documentation to clarify that only 'mac' and 'pc' are supported platforms, and how the default is chosen
* Simplified trigger registry's register command
* Updated trigger registrations
Change-Id: Ibab6ad5b5c86f24707f064967dc2119a81125392
Extension-specific types are RDFa types (or type regexes) that are
registered with the ModelRegistry separately. If an element has a type
that is extension-specific, then that element can only be matched by a
rule that asserts one of its extension-specific types.
For MediaWiki, we would call
ve.dm.modelRegistry.registerExtensionSpecificType(/^mw:/ ) .
So then an element like <span typeof="mw:foobar"> would either match a
rule specifically for mw:foobar, if one exists, or no rule at all; even
the rule for <span> would not match. The consequence of this is that
elements with unrecognized mw:-prefixed RDFa types are alienated.
Change-Id: Ia8ab1fe5dffb9f813689324372a168e8e4a3e0bc
ModelRegistry registers both annotations and nodes, and performs
matching on both at the same time. It also registers annotations with
the AnnotationFactory, and nodes with the NodeFactory.
Change-Id: I5e68e506a0e573cc0afe6304ccea058ffc20d1c8
Add static properties for matching, data<->DOM conversion, and name. Use
matchTagNames, toDataElement and toDOMElement. name isn't used yet.
Change-Id: I5e7df3303bbd65e6968e931b568c23d76003a9a4
* 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
Objectives:
* Make the link inspector easier to use
* Try to resolve a few bugs (bug 43841, bug 43063, bug 42986)
* Stop using jquery.multiSuggest (which didn't really understand annotations)
* Better divide MediaWiki specifics from generic implementations
Changes:
VisualEditor.php, modules/ve/test/index.php, demos/ve/index.php
* Updated links to files
ve.Registry
* Fixed mistake where registry was initialized as an array - this didn't cause any errors because you can add arbitrary properties to an array and use it like any other object
ve.Factory
* Removed duplicate initialization of registry property
* Added entries property, which is an array that's appended to for tracking the order of registrations
ve.CommandRegistry
* Added mwLink command which opens the mwLink inspector
ve.ui.TextInputWidget
* Added basic widget class for text inputs
ve.ui.TextInputMenuWidget
* Added widget that provides a menu of options for a text input widget
ve.ui.MWLinkTargetInputWidget
* Added MediaWiki specific link target widget
ve.ui.MenuWidget
* Converted ve.ui.Menu into a widget
* Moved the body of onSelect to onMouseUp
ve.ui.LinkTargetInputWidget
* Added link target widget which adds link annotation functionality to a normal text input
ve.ui.InputWidget
* Added generic input widget which emits reliable and instant change events and synchronizes a value property with the DOM value
ve.ui.Widget
* Added base widget class
* Widgets can be used in any frame
ve.ui.Tool
* Fixed line length issues
ve.ui.InspectorFactory
* Made use of new entries property for factories to select the most recently added inspector if more than one match a given annotation
ve.ui.Inspector
* Added auto-focus on the first visible input element on open
* Moved afterClose event to after re-focus on document on close
* Added documentation
ve.ui.Frame
* Adjusted documentation
* Added binding of $$ to the frame context so it can be passed around
* Added documentation
ve.ui.Context
* Added ve.ui.Widget.css to iframes
* Updated code as per moving of ve.ui.Menu to ve.ui.MenuWidget
* Removed unused positionBelowOverlay method
* Added CSS settings to set overlay left and width properties according to context size
* Added documentation
ve.ui.DropdownTool
* Updated code as per moving of ve.ui.Menu to ve.ui.MenuWidget
ve.ui.FormatDropdownTool
* Added documentation
ve.ui.MWLinkButtonTool
* Added MediaWiki specific version of ve.ui.LinkButtonTool, which opens the mwLink inspector
ve.ui.Widget.css
* Added styles for all widgets
ve.ui.Tool.css, ve.init.sa.css, ve.init.mw.ViewPageTarget.css, ve.init.mw.ViewPageTarget-apex.css
* Updated code as per moving of ve.ui.Menu to ve.ui.MenuWidget
ve.ui.Menu.css
* Deleted (merged into ve.ui.Widget.css)
ve.ui.Menu.css
* Deleted suggest styles (no longer used)
pending.gif, pending.psd
* Added diagonal stripe animation to indicate a pending request to the API
ve.ui.MWLinkInspector
* Added MediaWiki specific inspector which uses MediaWiki specific annotations and widgets
ve.ui.LinkInspector
* Removed mw global hint (not needed anymore)
* Switched from comparing targets to annotations (since the target text is ambiguous in some situations)
* Switched to using input widget, which is configured using a static property
* Removed use of jquery.multiSuggest
* Moved MediaWiki specifics to their own class (ve.ui.MWLinkInspector)
ve.init.mw.ViewPageTarget
* Added MediaWiki specific toolbar and command options
Change-Id: I859b5871a9d2f17d970c002067c8ff24f3513e9f
Some of these stubs didn't inherit Node at all. Made them all inherit
LeafNode because their rules specify they can't have children.
Change-Id: If4afc8de350f67ee78a41307c426ec2aceeb884f
CE doesn't actually render meta nodes anymore now that we split them out
into the meta-linmod.
I took a stab at consolidating metaBlock and metaInline (into simply
'meta'), but we can't do that with the current node API unless we put a
lot of meta-specific hacks in the converter. So I'm leaving this for the
node API rewrite.
Change-Id: Ie83413df718eabcaeb504316a2db0d24a1be2226
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
This happens when the <span> is the start of unwrapped content. The
converter logic to look at the tag name in wrapping mode doesn't kick in
because we're not yet in wrapping mode at that point.
The core issue was that previously, we relied on the document
structure/state to choose between alienBlock and alienInline, and only
used the tag name where the document structure was ambiguous (wrapping).
Changed this to be the other way around: we now rely primarily on the
tag name, and if that doesn't match what we expect based on the document
structure, we work around that if possible. Specifically:
* inline tag in our wrapper --> inline alien
* block tag in our wrapper --> close wrapper, block alien
* inline tag in wrapper that's not ours --> inline alien
* block tag in wrapper that's not ours --> *inline* alien
* inline tag in structural location --> open wrapper, inline alien
* block tag in structural location --> block alien
* inline tag in content location --> inline alien
* block tag in content location --> *inline* alien
only in the fourth and the last case do we need to use the "wrong" alien type to
preserve document validity, and it will always be inline where block was
expected, which should reduce UI issues.
The condensed version of the above, which is used in the code, is:
* If in a non-wrapper content location, use inline
* If in a wrapper that's not ours, use inline
* Otherwise, decide based on tag name
* Open or close wrapper if needed
ve.dm.Converter:
* Replace isInline logic in createAlien() with the above
* Factor out code to start wrapping (was duplicated) into startWrapping()
* Call startWrapping() if createAlien() returns an alienInline and we're
in a structural location
Tests:
* Add test cases with aliens at the start and end of unwrapped content
** The first one failed prior to these changes and now passes, the
second one was already passing
* Fix about group test case, was exhibiting the bug that this commit fixes
Change-Id: I657aa0ff5bc2b57cd48ef8a99c8ca930936c03b8
Although $.toJSON optimises heavily for modern browsers (it
becomes a direct reference to JSON.stringify), we still load the
extra plugin.
JSON is specified as part of ECMAScript 5, but most browsers
supported this one before they supported the rest of ES5.
http://caniuse.com/#search=JSON
Cut off for native JSON is IE7, Firefox 3.0 (3.6 supports it) and
Safari 3. Not any of our concern as VE will most likely never
support those (certainly not at this point in time, and less
likely as time goes on).
Change-Id: I4e8f26ac94763fa38d29e41264de0247f53a21e5
I noticed this bug on [[List of Presidents of the United States]]. When
there's HTML that looks like "<td>Foo\n<meta/></td>", the converter will
collect the newline in wrappedWhitespace, then attempt to splice it out
and store it in internal data. But instead, it ends up splicing out the
/metaBlock element, which causes strange unbalanced input, which causes
an empty table in the node tree.
Change-Id: I79ed2fa9a834cc42759c7d21250d8842f563d38f
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
The converter was misbehaving when handling <p>s inside <span>s. This
can't be expressed in the linmod, but it would try to anyway. <span><p>
would result in too many paragraph closing elements, leading to an
exception in ve.dm.Document complaining about unbalanced input.
<span>\n<p> would result in an exception in the converter itself while
trying to perform whitespace preservation on the newline.
This change makes the converter detect these scenarios and alienate the
offending node. So <span><p>Foo</p></span> converts to a wrapper
paragraph containing an alienInline whose HTML is "<p>Foo</p>" and which
is annotated with a TextStyleSpanAnnotation.
ve.dm.Converter.getDomFromData():
* Change the criteria for alienBlock vs alienInline
** Only infer from the node type if we're in wrapping mode AND we're at
the same level where the wrapping started (wrappingIsOurs). If the
latter isn't the case, we can't split the wrapper in the block case
because we're at the wrong level.
** Use alienInline not only if the branch is a content branch, but also
if there are active annotations. This catches e.g. <li><b><p>
(and generally <span><p> on the top level).
* Before converting a child element, check that the child isn't "bad".
Bad children are non-content children in content branches, and
non-content children encountered within a wrapper that we can't split.
Only good children are converted, and bad children are alienated (cue
Santa/Sinterklaas jokes).
* Add childIsContent and rename branchIsContent to branchHasContent
Change-Id: If420ae80ab0777424a9a5517335ef9d0170e87ae
* Fix 404 error for ve.ui.Icons-{raster,vector}.css
Follows-up 9563f08 / I840f72426f9a.
makeStaticLoader.php:
* Clean up old code.
* Error out early for missing module.
* Put i18n stuff in the right place
(some modules access ve.msg from the global scope to
assign status variables, for standalone on demos this was
failing due to wrong load order)
Change-Id: Idbff4c5136d567da747d9ae373cd2f6c3ee7fb1c
Rewrite VisualEditorMessagesModule:
* Replace copy-paste dump of user-css module with stuff for
VisualEditor (class commend and module::$origin).
* Remove duplication between getMessages and getScript.
* Actually implement getModifiedTime so that the comment in
getMessages() about cache invalidation is actually true
Fixes bug 42670: ext.visualEditor.specialMessages cache broken
ve.init:
* Implement addParsedMessages and getParsedMessage so that we
don't mix up plain messages with raw html messages (minoredit
was previously overloaded in mw.msg storage with a parsed html
message and retrieved though ve.msg, which is documented as
retuning plain text, not raw html). This is now separated into
a different method.
* Improved documentation of the other msg methods to emphasise
their differences
* Removed redundant code in attachSaveDialog() that was
(partially) already done in setupSaveDialog() and moved the
remaining bits into it as well. Checked all callers of these and
they are both only called from ViewPageTarget.prototype.onLoad
* Also implement them in the standalone platform implementation,
with the html escaper based on mw.html.escape
* Update init.platform.getMessage to use undefined instead of
discouraged 'if-in' statement.
* Add test suite.
demos/test:
* Re-run makeStaticLoader.php on test to add ve.init.Platform.test
* Re-run makeStaticLoader.php on demos and update i18n caller
to use ve.init.platform.addParsedMessages (also moved out of the
auto-generated block for easier updating)
Change-Id: I7f26b47e9467e850c08b9c217c4f1098590de109
HTML DOM has annoying behavior for <pre>s where .innerHTML eats the
first newline in a <pre>. Work around this by explicitly adding a
newline in the data->DOM converter if the <pre> already contained a
newline.
There is a separate bug in Parsoid that causes the newline to be lost
anyway, filed as bug 42666
Change-Id: Ia26cd4a4c61afbe439b0562deb7f24ee8b8147d7
When the content rendering stuff was moved to ve.ce.ContentBranchNode the onUpdate methods being used to update the DOM wrapper in ve.ce.HeadingNode was overlooked, so heading were not rendered on update anymore.
Change-Id: I994b8c43123c3cd02b9a550d5d7eac7d5052418e