* For consistency with target.loading, target.saving should be either a boolean
false or a jqXHR, with the latter type indicating a pending save attempt.
* Rename 'DOM Retrieved' topic to 'performance.parsoid.domLoad' (and thus
inaugurate a convention of hierarchical, dot-separated topic names).
* Add a 'performance.parsoid.domSave', which is a near-mirror of domLoad, but
measures the time it takes to save a DOM.
* Remove three old ve.track events, because they are not used and because their
name and signature are not consistent with current usage.
- page-save-attempt
- page-save-success
- page-edit-impression
Change-Id: I54602394eee5d6d9229c01d868cb366c9f56b2c3
There was code in there once, but it's now empty. Removed it in favor
of adding explicit listeners in the handful of subclasses that
override it.
Change-Id: I160e55ad3c7d85c9f830a4bd7d42ec5dc18ad04f
Though the initialisation works since core has been fixed, there
are still plently of cases where we take real user input that can
genuinely be invalid.
Most notably, you couldn't make a link to [[.com]] because the
link input widget would crash on an exception from mw.Title.
Even after core was fixed (and ".com" is now valid), one still
couldn't make that link. This time because '.' is an invalid title,
and we create a Title object for that while typing ".com".
ve.ui.MWLinkTargetInputWidget#getLookupMenuItemsFromData:
* Guarded against mw.Title throwing by using newFromText
and checking it first.
ve.ui.MWLinkInspector#static.legalTitle:
* Removed in favour of checking whether newFromText returns a
truthy value.
Change-Id: I580bfccb83f86be3ad7e83d31f0834e1cde7df9c
`new mw.Title` throws on invalid input. Converting uses to
mw.Title.newFromText instead and converting try/catch to if/else.
mw.Title in general (regardless of which constructor) has been
improved in core. It will no longer crash on pages where the page
title was a false hit for invalid (e.g. we couldn't load VE on
[[.com]] because the js parser thought it was invalid).
However, though the initialisation works since core has been
fixed, there are still plently of cases where we take real user
input that can genuinely be invalid.
In cases where the code did not catch exceptions and there was
no obvious way to handle it, I left it as is (let's revisit them
in a separate commit). It would be an exception either way, and
I'd rather see "mw.Title: Parser error" than
"TypeError: null does not have method getNamespaceId".
Change-Id: I5b1b23d56d39cdb7ecb0809e3d721992e0c30f54
Fix things that 4aa86d0f8 broke:
* Update surface parameter to windowSet in all ve.ui.SurfaceDialog subclasses
* Do the same for ve.ui.SurfaceInspector subclasses
* Fix @extends documentation for SurfaceDialog
* Fix documentation for ve.ui.SurfaceInspector, copypasta from SurfaceDialog
Bonus:
* Add .getMetaList() getter to dm.Surface
Change-Id: I843e99e45e9b013cb9cb559f050384d39bbbddf2
Instead select the node and require the user to press delete
again if they really meant to delete the node.
Also test cases!
Bug: 55336
Change-Id: I66520e18740e78ce6313f9b31bb575d06b91bea8
We now initialize the surface in the dialog with a 4-element linmod
(paragraph, /paragraph, internalList, /internalList) rather than a
2-element linmod. This broke the code that disables the Insert button
in the reference dialog when the surface is empty.
Change-Id: Id733e654a628b1294e697ad4ef3f2f6fe1a9c869
Major changes:
* Create a MW specific save dialog class
* Widgetize save dialog elements
* Simplification of viewPageTarget
Minor changes:
* Added getWindow method to windowSet and setTitle methods to window class
* Add transition css properties to dialog styles
Bug: 48566
Bug: 50722
Bug: 51918
Bug: 52175
Bug: 53313
Change-Id: I8c0db01fb8477a9b3d3dfe2a6073ac67869ce40e
Objective:
* Remove surface dependencies in dialogs, inspectors, windows and window sets
* Introduce surface-specific versions of dialogs, inspectors and window sets
Change-Id: I2db59127d2085b02e173a3605e174317e419e213
After 6ec34a3de the edit notice button was no longer hidden by
default if there were no notices. The alert icon was always
visible (when clicked it would show "0 notices").
In addition, on any page (except pages with edit notices) it
would throw a fatal exception at load time because method .hide()
doesn't exist.
As a result, current master shows an incomplete toolbar (e.g. not even
a Save button!)
Change-Id: Ib6e91c4756664c25fbb7403ef54b4fffcc0f9938
Class ve-init-mw-viewPageTarget-pageTitle added various
transition settings that were never used. Meanwhile, we're doing
fadeTo which sets inline opacity css every X ms until the
animation is finished.
* Changed the inline jQuery animation to use css transitions
instead.
* Removed the inexistent and obsolete ms-transition declaration.
* Removed ":visible" from selector query. This makes the selector
more performant (since :visible is a proprietary Sizzle keyword)
and it was obsolete anyway. The classes don't affect display none/hide,
this is handled naturally by the browser now.
Change-Id: Ibdfb442ff6c743ef16b514a7696796ee27821887
When deactivating before the surface became active (e.g.
this.active is still false, as case is the case when Parsoid
isn't running), the teardown sequence was incomplete.
Most notable, the page title (h1.firstHeading) was still dimmed
after cancelling the alert for Parsoid error, eventhough
everything else was shown and restored.
* Moved call to #showTableOfContents in #deactivate up for
consistency with #activate.
* Added call to #restorePageTitle in #deactivate so that the
title is restored even if the surface didn't activate yet.
* Removed calls to various methods in #tearDownSurface that
were already called by #deactivate.
Now activate/deactivate and setUpSurface/tearDownSurface are
in balance.
Change-Id: Ibb2fbf0e5ab9b6a028d4e139c13aa7ff8c82be82
Previously we returned ElementLinearData from the converter, then
stripped out the MetaLinearData. This meant that before processing
the ElementLinearData from the converter actually contained metadata
which is confusing.
The new document constructor stores the converter results in a
FlatLinearData object and simultaneously populates element and meta
data stores.
Also in this commit I have moved various methods from ElementLinearData
to FlatLinearData, from which ElementLinearData inherits.
Change-Id: I64561bde2c31d8f703c13ac7b0a0c5f7ade9f3d4
When the editor finishes retrieving the target DOM, fire a 'DOM retrieved'
analytic event with the following properties:
* Response time in millisecond.
* Response size in bytes.
* Whether request was a cache hit.
* Value of X-Parsoid-Performance header (or null if unset).
jQuery.byteLength is now a dependency for ext.visualEditor.mediawiki.
Change-Id: I74d3964238927645e847b6e215991bd6b1ebad59
Objectives:
* Use widgets to render toolbar actions
* Remove labels next to help notices and edit notices buttons
* Add a close button to the help notices and edit notices
Overview:
* ve.ui.ButtonWidget is now abstract, use ve.ui.PushButtonWidget instead
* ve.ui.IconButtonWidget now inherits from ve.ui.ButtonWidget
* ve.ui.PopupWidget's display method no longer takes x and y arguments
* Fixup naming issues in MWCategoryPopupWidget
* Fixup naming issues with some ve-init-mw CSS classes
* Rename ve-mw/ui/styles/ve.ui.Widget.css to ve.ui.MWWidget.css
* Change uses of "callout" to "tail"
* Add hyperlink functionality to buttons
* Make buttons accessible through focusing, but make unfocusable by
clicking
* Add head option to popup for rendering a title and close button
Bug: 52386
Change-Id: Iea2c8df1be64d40f9c039873d89ee540cc56e687
This commit extracts the page and outline handling logic from
ve.ui.PagedDialog (RIP) and moves it into two layouts: ve.ui.PagedLayout
and ve.ui.PagedOutlineLayout, respectively. These layouts are now implemented
inside the dialogs that used to mixin the ve.ui.PagedDialog class. This
brings a much cleaner separation of concerns between Dialogs and Layouts
and allows the use of page handling logic without the accompanying
outline logic.
Change-Id: I5efa2f893f4b7e962438b3aff34b737573bbd5ca
We already getSlice which returns a ve.dm.DocumentSlice, so using
the word slice in this method is very confusing. What we are actually
doing is creating a ve.dm.Document from a range. Also remove argument
overloading as it's not particularly helpful and would make the new
name a lie.
Change-Id: I93da3419510410b170396e6765fbe2a87f9795be
Currently we just say 'group ""' which is a bit weird, so
instead have a specific message which talks about the
'default group'.
Bug: 51873
Change-Id: I4a17f15ee18175fac11b36b102a06cc9714426ee
This change allows for the Username to be sent in MWBetaWelcomeDialog
title so the i18n message can support {{GENDER:}} parameters.
This change arose from the need to provide GENDER support when translating
the welcome message from Change-Id: I6a3da40b286bb1abd2aff360dab3b386deb13420
Change-Id: Iae70fbaa5be822d571a0d75704cfeca4eabd2fe8
250ms after the user stops typing, we rerender the node with what they've
typed so far.
Bonus:
* When using MathJax, tell it which node to rerender
* Avoid crash when trying to unwrap wrapper paragraph
Change-Id: I623eef48e40d480cc98766cf7daf75dacd0bde19
Move the triggering of the rerender event into an overridable method
'afterRender'. Some nodes don't have the correct dimensions
immediately after rendering their DOM elements as they may need
to wait for images to load, or for a script to run (e.g. MathJax)
Change-Id: If204f665dcb2fd69d00a183279056d11188ddd74
Replaces newFromNodeReplacement(). newFromNodeReplacement was very
simplistic and didn't support metadata or internal list items, so
if you had comments or references inside of the data you were editing
(reference contents or an image caption), they'd get mangled.
With this, you can do:
newDoc = doc.getDocumentSlice( node );
// Edit newDoc
tx = ve.dm.Transaction.newFromDocumentReplace( doc, node, newDoc );
surface.change( newDoc );
and that takes care of metadata, internal list items, and things like
references that reference internal list items.
ve.dm.Document.js:
* In getDocumentSlice(), store a reference to the original document
and the number of items in its InternalList at the time of slicing
in the created slice. This is used for reconciliation when the
modified slice is injected back into the parent document with
newFromDocumentReplace().
ve.dm.InternalList.js:
* Add a method for merging in another InternalList. This provides a
mapping from old to new InternalList indexes so the linear model data
being injected by newFromDocumentReplace() can have its InternalList
indexes remapped.
ve.dm.Transaction.js:
* Replace newFromNodeReplacement() with newFromDocumentReplace()
ve.ui.MWMediaEditDialog.js, ve.ui.MWReferenceDialog.js:
* Use getDocumentSlice/newFromDocumentReplace for editing captions/refs
* Change insertion code path to insert an empty internalItem/caption, then
newFromDocumentReplace into that
* Add empty internalList to new mini-documents
ve/test/dm/ve.dm.Transaction.test.js:
* Replace newFromNodeReplacement tests with newFromDocumentReplace tests
ve-mw/test/dm/ve.dm.Transaction.test.js (new):
* Add tests for newFromDocumentReplace with mwReference nodes
ve.dm.mwExample.js:
* Add data for newFromDocumentReplace with mwReference tests
VisualEditor.hooks.php:
* Add new test file
Bug: 52102
Change-Id: I4aa980780114b391924f04df588e81c990c32983
Function was removed in eb64743436 but one caller was still left,
which caused VE to throw a JS error when opening the reference dialog
to insert a new reference.
Change-Id: I827381bfe3bdeecdbaa1fba55a09b3e8e03575a6
If you changed the contents of an alien tag extension, then tried to
use undo, the change wouldn't be undone, but the undo state would
toggle.
This was because we only kept one copy of the data-mw object for these
nodes and modified that one copy. Instead, create a new copy every time
we modify it, so we can actually go back to previous states.
Change-Id: Ib4d5d460a6fdda9c3b0968f269585d620b47fdd8
In various places in the UI code, certain properties of config objects
were overridden and in some cases the configurations were documented as
private as a strange hack to prevent them from being advertised in the
docs.
I, Trevor, have been convinced of the error of my ways, and gladly
reverse this situation, allowing all configurations to always be
overridden when desired, while still allowing default values.
Change-Id: I242e3b1902dec8e09eeea38fa64381e69ee04215
In this instance, MW(Extension|Reference|Transclusion)Nodes.
In general anything that is focusable should probably be relocatable
by default. We should considered this when we sorting out the
focusable/protected/relocatable mess in the near future.
Change-Id: Ifc55e251cba3e875798d5103540d02ad651399ad
Simply generating ':3' as the "unique" name for the 4th reference
doesn't work. Even if getUniqueListKey() had been used, that only
checks for conflicts with names that have already been encountered
(i.e. occur in <ref> tags that precede the current one), not for
conflicts with names that first occur further down in the document.
The solution is to generate names at serialization time, when we
have full knowledge of which names are in use. Internally, we use
'literal/<name>' for names that literally appeared in the source,
and 'auto/<number>' for unnamed references. Then at serialization
time, we translate 'auto/<number>' to 'literal/:<number>' if needed
(i.e. if the reference was reused).
ve.dm.MWReferenceNode.js:
* toDataElement()
** Prefix listKey with literal/ or auto/ as appropriate
* toDomElements()
** Map auto/ listKeys to unique names
** Don't try to unset the name if not present (was unsetting a property
that didn't exist anyway)
ve.dm.InternalList.js:
* Remove now-unused isUniqueListKey()
* Rewrite getUniqueListKey()
** Make prefix configurable
** Take previously generated unique keys into account
** Map the same old key (auto/N) to the same generated key (literal/:M)
* Add getNextUniqueNumber() as a source for auto/N numbers: previously
used the length of the itemHtmlQueue, but that only works during
conversion, not from the UI dialog
ve.ui.MWReferenceDialog.js:
* For new references or conflicting names, generate an auto/N key and
let toDomElements() deal with actually mapping that to name
ve.dm.InternalList.test.js:
* Rename listKeys to new style
* Split the test case into two groups so we can test multi-group cases
* Add tests for getUniqueListKey()
ve.dm.mwExample.js:
* Rename things to new style
* Modify the test case so it attempts to trigger bug 54341
Bug: 54341
Change-Id: I726fb83e6fb66ffec643d996768a854ec9474b3d
Because there's no sane wikitext to handle that case, and Parsoid
will just output garbage.
Bug: 53151
Change-Id: I9e065aa46d88f6bed9c47127b3e002ec2e1fec5a
The Parsoid team has changed their spec to always use multi-part
format even for one-part transclusions. This commit changes VE's
output format to always be multi-part, but still accepts single-part
format on the way in.
Change-Id: I6b3156b0b599ad042bb52d7f53dcdeb1c4a0954a
Cucumber 1.3.6 seems to be problematic:
gems/cucumber-1.3.6/lib/cucumber/rb_support/rb_language.rb:122: warning: redundant nested repeat operator: /^** This is a new line/
Updating the rest of the gems too.
Change-Id: Ia173312baa178a45d648fc537c8abf914144bbd5
Toolbars may want to control the target as well as the surface (spoiler alert!).
The new TargetToolbar has a pointer to its target as well as its surface.
Change-Id: I928316d9e23ac3f3de3e76c34ef0ac3d27855ab3
Objectives:
* Scroll when needed to show highlighted (with keyboard) or selected (by
any means) options in select widgets
* Allow clipping and automatic scrolling for certain elements when they
are otherwise going to be rendered partially out of view
Changes:
*.php
* Add links to new file
ve.ui.Widget.css, ve.ui.Dialog.css
* Removed unneeded x-axis overflow rules
ve.ui.ClippableElement.js, ve.ui.Element.css
* New mixin, adds visible area clipping support to an element
ve.ui.PopupToolGroup.js, ve.ui.MenuWidget.js
* Mixin clippable element
ve.ui.OptionWidget.js, ve.ui.OutlineItemWidget.js
* Add scroll-into-view configuration for option widgets
ve.ui.SearchWidget.js
* Scroll items into view when highlighting with keyboard
ve.Element.js
* Add getBorders, getDimensions, getClosestScrollableContainer and
scrollIntoView static methods
* Add getClosestScrollableElementContainer and scrollElementIntoView
methods
Bug: 53610
Change-Id: Ie21faa973a68f517c7cfce8bd879b5317f536365
Sometimes GitInfo returns a version ID of false if it can't
find the right files. In this case we should hide the whole
message as it is meaningless.
Bug: 53050
Change-Id: I71161df7588aa9311bc1fdf6b064cc6d8c155f61
CODING.md
* Document the procedure for adding a new javascript class
ve.dm.MWExternalLinkAnnotation.js
ve.dm.MWInternalLinkAnnotation.js
ve.dm.ElementLinearData.js
ve.dm.LinearData.js
* Add whitespace line before preformatted code to fix a
rendering bug
Change-Id: I54443ea3d4799328655d279f379d4ddc176c50a0
It's important in case of replacing root element ($) of a node, so new element
does have CSS class and contenteditable property set.
Change-Id: Icf14e2164e89114e6b7c10672b782d02f4c5daac
Objective:
* Make the welcome dialog work with smaller fonts by increasing its
size a bit, and also making its contents scroll vertically if needed
Changes:
ve.ui.MWBetaWelcomeDialog.js
* Move content into a scrollable and padded panel layout element
ve.ui.MWDialog.css
* Remove padding, now provided by panel layout
ve.ui.Dialog.css
* Remove min-height override, inherited value is fine
* Use max width and height instead of setting them directly
Bug: 52667
Change-Id: Ie35b041e13ef18ffcacef6d9e70439e4e1351e0a
modules/ve/ve.EventSequencer.js
* Class to sequence pre-event and post-event listening correctly
demos/ve/eventSequencer.html
* Plain HTML example page for testing EventSequencer and event sequences
Change-Id: I4ddb10a30c2f44015136a7978a185d0b13f0690b
In commit e1f8ee7 the return statement was moved into the
userPrefEnabled check, however addClass( 've-available' ) was
still unconditional. This has now been restored.
Change-Id: Ia59bfed93a8849a529cc3b9d1d2e0619d65240d4
Objective:
* Add keyboard shortcuts for paragraph, heading 1-6 and pre-formatted
Testing:
* Using [control+num] triggers appears to work well on Chrome, Safari, Firefox and Opera on Mac
Changes:
ve.init.Target.js, ve.init.mw.ViewPageTarget.js
* Add formatting commands to targets
ve.ui.MWFormatTool.js
* Add mediawiki specific format tools and commands
ve.ui.CommandRegistry.js
* Add commands for all formatting tools
ve.ui.TriggerRegistry.js
* Add triggers for formatting tools
Bug: 33512
Change-Id: I5d6176eff50aa3cea72aed226ca06512629412d4
Objectives:
* Got rid of mw prefixing in tools, inspectors and dialogs
* Simplify tool classes so they can be generically used as items in bars, lists and menus
* Add support for a catch-all toolbar group
* Simplify tool registration, leaning on tool classes' static name property
* Move default commands to command registry
* Move default triggers to trigger registry
* Get language tool working in standalone
Change-Id: Ic97a636f9a193374728629931b6702bee1b3416a
ce.MWExtensionNode
* Build up the wikitext for round-tripping using jQuery, and pass
through the attributes from data-mw
dm.MWExtensionNode
* Use a static getExtensionName to correctly get the extension
name from the dataElement (as the getMatchRdfaTypes hack won't
work for MWAlienExtensionNode's)
dm.MWAlienExtensionNode
* Implement new static getExtensionName function
Bug: 53543
Change-Id: Id4e83c14ec68c3b3970d05317477f19aaf31abe4
Currently we only offer the normalised page title from the server
so 'iPhone' only suggests 'IPhone'. With this fix we offer the typed
text as the first suggestion if it matches via mw.Title, so 'iPhone'
suggests ['iPhone', 'IPhone', ...]
Bug: 50452
Change-Id: I05cc0cd19537cbfa682d7aac0f9640decea282b5
The search index was only being built on initialization, rather than at
the time the list was being shown. By moving it to be built on open
the list will always be fresh. Also, just after building the index, we can
enable/disable the select existing button based on the number of
results.
Bug: 51689
Bug: 51848
Bug: 52000
Change-Id: Ib38b1b227edc3d61dc49fa58999358e7adf11b08
We call isRedirect to get the real language code instead of the site code.
Post-factum, lang attribute is added as well for each entry.
Bug: 53503
Change-Id: Ia6bf63a7cbe3c7b99ed05d0bd0fdd33190550c98
By passing in the information via a ResourceLoaderModule this
gets around any concerns with performance (version information
is read from the file system).
The version information is appended to the beta toolbar dialog.
Bug: 53050
Change-Id: I7836e1d4003416cbb7e18e3435aa87d82fd5c2e2
Also..
* removed an incorrrect comment referring to the old module
name (standalone didn't use the VisualEditorMessagesModule).
* made it use debug mode to determine whether to minify or
prettify the js code.
Change-Id: I493007649fba27e7faab0cf743eded5f68714c50
Also always use strings 'true'/'false' for the value, because
it is a string property (spellcheck, however, is a boolean)
and always use a capital second 'E' in the name.
Change-Id: Ia4e1f9edfd8f236fe81df190e6a68729d7b52243
This avoids problems when unnamed references were copy-pasted.
Knowing that key is always non-null simplifies a lot of logic
elsewhere.
Bug: 53365
Change-Id: I3a23123ae732d9583814d38dd880a0cdf691fd5d
This listens to change events on the surface and checks to see if
there is more than just an empty paragraph node.
Bug: 53345
Change-Id: Ic8fa84d7cdcbffd154178939d0ec8c2c4f86c415
- Added missing @inheritdoc so that generated documentation is
not empty.
- Fixed type of mw.Platform#getMessage from (implied) @property
back to @method.
- Removed notes from mw methods. They are prepended instead of
appended, thus overriding the useful single-line summary
of the method with this random note. Description should either
be replaced entirely (e.g. no @inheritdoc) or inherited.
- Rephrased a few description to be consistent with the others
(e.g. "Get .." and "Add .." instead of "Gets .." or "Adds..").
Follows-up cbe35632f1.
Change-Id: Ie55bb9e18f1524b706f0e195300170e4d552bf73
The reversed image was created by Ebraminio using
convert loading.gif -flop loading2.gif
Bug: 51401
Change-Id: I264d9368cf8fd030ff34540e50e0038aa42ece16
Objective:
* Use the MW link specifically, since the target/command system doesn't
understand the group/id/extension concept yet
Change-Id: I8b756fa0bb55468312bb30d45ac5b943ff7362b5
Objectives:
* Make it possible to add items to toolbars without having to have all
toolbars know about the items in advance
* Make it possible to specialize an existing tool and have it be used
instead of the base implementation
Approach:
* Tools are named using a path-style category/id/ext system, making them
selectable, the latter component being used to differentiate extended
tools from their base classes, but is ignored during selection
* Toolbars have ToolGroups, which include or exclude tools by category or
category/id, and order them by promoting and demoting selections of
tools by category or category/id
Future:
* Add a way to place available but not yet placed tools in an "overflow"
group
* Add a mode to ToolGroup to make the tools a multi-column drop-down style
list with labels so tools with less obvious icons are easier to identify
- and probably use this as the overflow group
Change-Id: I7625f861435a99ce3d7a2b1ece9731aaab1776f8