Add prepareCacheKey() which submits HTML for serialization and saves
the resulting cache key, and tryWithPreparedCacheKey() which uses that
cache key (if available; if pending, it waits for it) for API requests.
Implemented save(), serialize() and showChanges() in terms of
tryWithPreparedCacheKey().
When opening the save dialog, run the conversion, cache it, and fire
off a prepareCacheKey(). Then use the cached conversion for save/diff/
serialize. This means we don't convert multiple times, and it causes
the prepared wikitext to be used.
Bug: 55979
Bug: 56011
Change-Id: I1d56fe88d312e9810a57d56a285ccdf4f1facf42
initialize() is currently called synchronously, but once the CSS
transplantation code is fixed and it goes back to being async, that'll
cause problems.
* Add this.setupDeferred and use it to defer setupCheckboxes() until
after initialization
* Move code populating the edit summary from ViewPageTarget into
MWSaveDialog and use .setValue() rather than manipulating the
TextInputWidget's DOM. Defer this until after init as well
* Move clearing of the diff from ViewPageTarget into MWSaveDialog,
and don't connect it to the transact event at startup, only when
we've actually shown a diff
* Remove swapPanel( 'save' ) from ViewPageTarget, instead do this
on setup in the dialog itself
Bonus:
* Document events
* Get rid of onFooButtonClick handlers in favor of array syntax
Change-Id: Idcdae5e013340f4519db4387bab507e714d47941
* Use 'this' instead of 'viewPage' in setupSaveDialog()
* Unwrap unnecessary .each() in restoreEditSection()
Change-Id: I45d0c9714d59e195d0c4413ed3dbe9cbabe45e9d
Previously was failing for two reasons:
1. FF requires the form to be attached before submitting
2. options.watch failed because of FF's annoying Object.prototype.watch
Bug: 56767
Change-Id: I7b3d349f057f5b87f823ce788b4143f817af5303
Changes:
* Cleanup the window API to use more consistent and intuitive methods - we
now use initialize/setup/teardown instead of
initialize/onSetup/onOpen/onClose as methods which are overridden, and
use open/close methods to control the window
* Change events around to have opening/open and closing/close events which
act as before/after points during the opening/closing process
* Make WindowSet and Context respond to windows being opened, rather than
opening them directly
* Fix a LinkInspector creation mode bug where the initial text doesn't get
reset
* Move inspector, a VisualEditor concept, back to VE
* Cleanup naming of SurfaceDialog, SurfaceToolbar, etc. to use shorter
names, they were given Surface* names when the generic ones were also in
VE, but now the generic ones are in OO, so they can return to their
original names
Change-Id: I82c4fed8bcb3fb5630938c8bc4dd9b2d5f1a8c1d
Renamed events:
* performance.domLoad --> performance.system.domLoad
* performance.domSave --> performance.system.domSave
New events:
* performance.system.activation: total load time
* performance.system.domDiff: timing of paction=diff; like .domSave
* performance.system.domSerialize: timing of paction=serialize; like .domSave
* behavior.lastTransactionTillSaveDialogOpen: time from last transaction
until user opened save dialog
* behavior.saveDialogOpenTillSave: time from save dialog opening to user
clicking save
* behavior.saveDialogOpenTillReview: time from save dialog opening to user
clicking review (skipped when a cached diff is shown)
* behavior.saveDialogClose: when user closes save dialog; duration is time
* performance.user.saveComplete: time from user clicking save to successful
save completion; 'retries' indicates # of badtoken retries
* performance.user.saveError.*: time from user clicking save to failure;
'retries' indicates # of badtoken retries
** performance.user.saveError.abusefilter
** performance.user.saveError.badtoken: token was bad and we prompted the user
** performance.user.saveError.captcha
** performance.user.saveError.editconflict
** performance.user.saveError.empty
** performance.user.saveError.spamblacklist
** performance.user.saveError.unknown
* performance.user.reviewComplete: time from user clicking review to diff showing
* performance.user.reviewError: time from user clicking review to diff failure
since dialog was opened
Change-Id: I9815fa637d34c766c163e181d2f9527d3f32a7c3
Some 've-ui-toolbar-bar' classes hadn't been converted to OO.ui so the
toolbar had no border. Also removed a useless rule in mw.ViewPageTarget.css.
SA platform didn't override OO.ui.msg to use the ve.msg so no messages
were getting through.
Change-Id: Ieb5bc3c98d1c435ec194b201b517a688cd9b02b9
Objectives:
* Rename this.$ to this.$element
* Rename this.$$ to this.$
* Get rid of the need to use this.frame.$$
* Rename OO.ui.Element.get$$ to OO.ui.Element.getJQuery
Changes: (using Sublime Text regex patterns)
* Replace "get$$" with "getJQuery"
* Replace "\.(\$)([^\$a-zA-Z])" with ".$element$2"
* Replace "\.(\$\$)" with ".$"
* Replace "'$$'" with "'$'"
* Set this.$ to null in constructor of OO.ui.Window
* Set this.$ to this.frame.$ in initialize method of OO.ui.Window
* Replace "\.(frame.\$)([^\$a-zA-Z])" with ".\$$2"
Bonus:
* Use this.$() in a bunch of places where $() was erroneously used
Change-Id: If3d870124ab8d10f8223532cda95c2b2b075db94
By serialising the current DOM, and injecting it into a form we can
end up in the source editor with our VE changes converted.
Bug: 50687
Change-Id: Iafcc02a737d9c6c3a59dce1caff130d47ca25650
Calculate and store the two inner whitespace values of the body in the
dm.Document. When converting back, make sure the first/last nodes
pre/post outer whitespace matches the inner left/right whitespace
of the body.
Bug: 54964
Change-Id: I45f1ffd63669f25a6cae878400bfe21719ed58ee
Objectives:
* Hamburger menu in actions area of toolbar
* Add tools that open specific pages in the meta dialog
* Fix support for using setPage in ve.ui.PagedOutlineLayout
* Allow passing setup config objects through window open calls
* Add dialog action, similar to inspector action
* Fix incorrect or missing documentation
Change-Id: I2d2c9b87554fb2a0c90ed6944a58b38a37efa712
* Move and rename generic parts of ve.ui to OO.ui
* We now have a UI test suite because ve.Element (outside ve.ui)
is now part of oojs-ui, so it needs a test suite.
* Added to the MW test run (just like we do for unicodejs).
* Updated csslint config (also added ve-mw and syntaxhighlight
which were missing).
oojs-ui still depends on the TriggerRegistry in VE, this is addressed
in a follow-up commit.
Change-Id: Iec147155c1ddf20b73a4d15d87b8742207032312
Make every module that was formerly part of the experimental module its own
Beta Feature. For now, all of them are commented out except for formulæ editing
(mwmath). The "experimental" Beta Feature bucket is no more, but the preference
remains so that it can be set to both true and hidden on MediaWiki.org to let
all the different experimental flags.
The feature icons, previous mis-named "logo" and mis-identified as "screenshots"
are now renamed. One for the mwmath Beta Feature has been added (the rest need
creating before those can be enabled). The i18n descriptions now each identify
that the feature is an experimental one, and that caution is needed.
Change-Id: I28862f3e62f5c78aca33f11265aced1db67f4725
* changes:
Get rid of dmRendering hack in ve.ce.MWInternalLinkAnnotation
Render resolved URLs for href and src attributes in CE
Give ce.Annotations a reference to their ce.ContentBranchNode
Track the original HTMLDocument in ve.dm.Document
Create CE nodes and annotations with the correct $$
Add ve.resolveUrl for URL resolution
Don't render href as src in MWBlockImageNode
Rename 'html' to 'body' in converter tests
Add it as an optional parameter to the constructor, and create a new
one if omitted.
This is going to be used to resolve URLs according to the right <base>,
but really that's a hack and we should come up with a better way to
track metadata from the <head>.
Change-Id: I49dfc81ff793d73e08a20e502d681a15613d23f7
* Replace surface 'transact' event with 'documentUpdate' event
* Have surface listen for all document transactions and update selection
as appropriate (as well as emitting 'documentUpdate')
* Implement change() in terms of setSelection()
** Queue 'contextChange' events so contextChange is only emitted once
** Use this.transacting flag to prevent setSelection() (which is called
because the model emits transact events) from doing too much
** Behavioral change: lock/unlock now emitted separately for
transaction and selection changes
Change-Id: I44425d260ec70758f99d13f99e41f5c993d260c2
Binding ve.init.mw.Target#onLoad and the anonymous function which calls ve#track
with timing data to the resolution of the same deferred makes the timing
measurement sensitive to how long it takes ve.init.mw.Target#onLoad to yield,
which in turns depends on whether the requisite ResourceLoader modules for
setting up the editing surface are ready. This muddles the definition of what
we're actually measuring, making it dependent on a race condition.
This patch moves the tracking call to a filter function through which the jqXHR
deferred is threaded. This ensures that the 'duration' datapoint on the domSave
and domLoad events captures just the time spent talking with the API.
Change-Id: I6e162014a4043d4ff9422131ae87fb25d0ab4c29
Instead, listen to 'select', or to 'transact' on the dm.Document.
This commit only fixes uses outside of the dm/ce.Surface ecosystem.
ce.Surface still listens to 'change'.
ve.init.mw.ViewPageTarget.js:
* Rename onSurfaceModelTransact to clearSaveDialogDiff and bind it to
the document's transact event instead
* Rename onSurfaceModelChange to checkForWikitextWarning and bind it
to the surface's transact event. This is needed because the function
inspects the surface's selection, which isn't yet in a consistent
state when the document's transact event fires
ve.ui.MWReferenceDialog.js:
* Rename onSurfaceChange to onDocumentTransact and rebind accordingly
ve.ce.ProtectedNode.js:
* Get rid of onSurfaceModelChange
* Instead, bind positionPhantoms to the document's transact event
directly, and only bind it while phantoms are visible
ve.ui.Context.js:
* Rename onChange to onModelSelect and rebind accordingly
* Rename afterChange to afterModelSelect
* Drop check for undefined selection, no longer needed now that we're
listening to a finer-grained event
ve.ce.Surface.test.js:
* Listen to 'select' instead of 'change'
Change-Id: Ifeb1a1fc5427696f2aae5441d4b54dde366793e0
Instead of using @emits in both, use our custom @fires in
production (JSDuck 4), and in the future it'll just naturally
use the native one.
This way we can also index oojs without issues, which seems to
have started using @fires already.
Change-Id: I7c3b56dd112626d57fa87ab995d205fb782a0149
If there was an error loading the HTML from Parsoid, ViewPageTarget
would try to tear down the save dialog, which caused a crash because
the save dialog doesn't exist yet at that point.
Change-Id: Ia50756a19cb775be96b90e87b642eb2a38f254ce
Using the MW APIs get a resized version of the image and use
GeneratedContentNode to cache the url.
Bug: 55697
Change-Id: I418f7e1464663f447d46de7ffc29aa5f52d23b12
* 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
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
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
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
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
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
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
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
- 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
Return an array of languages instead of a single language. Languages
containing hyphens return themselves along with the root code e.g.
'en-GB' => ['en-GB', 'en']
Change-Id: I840b689d0021d865f93d16d075473a2ed0a9f0d8
This patch rounds off change I29740fa7a by replacing calls to EventLogging's
eventLog.logEvent with calls to VisualEditor's ve.track. ve.track publishes
events by providing an interface, ve.trackRegisterHandler, which event handlers
use to subscribe to VisualEditor events. By making it the responsibility of the
web analytics framework to register itself as a handler, VisualEditor can
remain decoupled from (and indeed ignorant of) any particular event logging
implementation. This allows VisualEditor to be integrated with many different
web analytics platforms with nothing more than a bit of glue code for mapping
ve's event semantics to those of the target platform.
The practical difference that this makes is that it frees VisualEditor from
having to know about EventLogging or from having to load EventLogging
components, which means we can remove quite a lot of gnarly code. My current
plan is to migrate the code for registering and loading the 'Edit'
schema module to Extension:CoreEvents, which is also where I'll commit the
handler for VE events. (CoreEvents exists precisely to provide an organized
place for persistent but WMF-particular instrumentation.)
Once this patch is merged and deployed, the following two configuration
variables may be removed from mediawiki-config:
- $wgVisualEditorEnableSplitTest
- $wgVisualEditorEnableEventLogging
Change-Id: Idfdf692668d2adfbe029e8f0c4ff9e96c60ff741
Mostly as a demonstration of how easy this is with MWExtensionNode.
The icon was chosen with the following criteria:
1. Recognisable (the ankh is quite common in popular culture, right?)
2. Doesn't look idiotic to academics (I've consulted an Egyptology
PhD and they can confirm it's not the glyph for penis)
3. Renders well at <16x16
That said it does look a little like a stick man...
Bug: 43118
Change-Id: I9f9e8af501401866bfeecf0eec3690a705fbd4db
Objectives:
* Use a class for toolbar groups to add more functionality later
* Rename addTools method to setup
Changes:
*.php
* Add link to new file
* Move ui element classes up for more general use
ve.init.mw.ViewPageTarget.js, ve.init.sa.Target.js, ve.ui.Context.js,
ve.ui.SurfaceWidget.js
* Update use of addTools method
ve.ui.Tool.css, ve.ui.Toolbar.css
* Move styles between sheets
ve.ui.Toolbar.js
* Rename addTools to setup
* Use ve.ui.ToolGroup objects when building tools
ve.ui.ToolGroup.js
* New class, encapsulates tools
Change-Id: Ic3a643634a80a8ac7d6f6f47f031d001c7efaee7
Objective:
* Make it possible to make a toolbar without a surface
Changes:
*.php
* Links to new file
ve.ui.Toolbar.js, ve.ui.SurfaceToolbar.js
* Split toolbar into generic and surface specific classes
*.js
* Update symbol names
Change-Id: Ice063a2fb67b5ce5155cdc96a0d47af49eee48cb
Follows-up ced2a8a which moved the tab layout to the server-side
and changed it to set up "source" tab and section links always
everywhere (even if VE would not be availabe in the namespace
or browser).
The JS logic (which continues to exist to take care of pages
cached before we moved it to PHP and/or to fix up pages cached
with a different configuration in the future) didn't do this yet
causing the "Edit source" tab to inconsistently appear on pages
for anonymous users viewing pages where VE is not available.
Change-Id: Ic575b3fcef17e636adaa338abc7748a4388ed9a9
For configured wikis, show a dialog that welcomes the user to the
amazing and fantabulous world of VisualEditing, which is not only full of
wonderment and joy but also may lead to increased popularity and love.
The dialog only shows up once (uses a cookie).
Change-Id: I8e7c4dc2c63b36594378a543b9d66291395eebcf
* Generate the edit tabs and the section edit links in PHP, with a
fallback in JS for cases where we don't have them yet due to
caching. But only change things if VE is enabled, and have the JS
correct the state if the wrong cached HTML comes through.
* Make the order of the tabs/links and the messages to use as captions
configurable
* Make the edit tabs and section edit links always be present in the
page (regardless of namespace, user prefs, etc.) but be hidden and
have JS unhide them (using html.ve-available) if appropriate
* Add appendix messages so we can do a superscript "beta" even in places
where we can't use HTML in the message
VisualEditor.php:
* Add new hook registrations
* Remove edit link caption messages from the init init module because
they're now added dynamically in VisualEditor.hooks.php
* Add a noscript CSS module so we can hide some things in JS-less
environments
* Remove $wgVisualEditorTabLayout and replace it with
$wgVisualEditorPosition
* Add config vars for link captions, with null causing us to use
the default caption
* Add config vars for link caption appendices. Too many config vars
but we'll clean that up later
VisualEditor.hooks.php:
* Dynamically add tab messages to the init init module
* Remove unused globals in onBeforePageDisplay()
* Add noscript CSS module
* Add a SkinTemplateNavigation hook that changes and reorders the edit
tabs as appropriate
* Add a DoEditSectionLink hook that overwrites the edit section links
* Export the new config variables to JS
VisualEditor.i18n.php:
* Add beta appendix message
* Add a message for the default VE edit section link
ve.init.mw.ViewPageTarget.init.css:
* Remove the animation on the edit section links
* Darken the color of the brackets and the pipe from #ccc to #555
* Style the beta message to be superscript-like (but not real <sup> to
avoid moving the baseline)
ve.init.mw.ViewPageTarget.noscript.css:
* Hide the VE edit tab, the pipe and the VE edit section link initally
unless and until JS unhides
ve.init.mw.ViewPageTarget.init.js:
* Toggle .ve-not-available / .ve-available
* Edit tabs
** Only generate the the edit tabs if they're not already there from PHP
** Rewrite the edit tab generation to mirror what's being done in PHP
* Section edit links
** Same as for edit tabs
** Also add mw-visualeditor-expanded to pad the brackets
ve.init.mw.ViewPageTarget.js:
* #ca-ve-edit is now always the VE tab (and #ca-edit always the
edit source tab) so update the .selected behavior accordingly
Change-Id: Idcb15faea7fabe5fe7578b1508079969b27d2469
Added wgIsArticle to isViewPage checks, otherwise we were attempting
to load VE dynamically on Special:Move/Delete, which resulted in a
broken h1 title and odd behavior off the 'Read' tab.
Also added !wgIsArticle to pageExists. This is a bit of a hack because
we don't have any info on page existence in the JS on these pages
(I think?). But it's better to display 'Edit' for a page that doesn't
exist, than 'Create' for a page that does.
Bug: 49000
Change-Id: Ib47e5524d41e6066b362e0f5645750c769de5193
mw.ViewPageTarget is currently getting events from both the
platform target toolbar and context menu toolbar because the
event is emitted from within the toolbar to the surface.
Instead we're now emitting it on the toolbar itself and it is up
to the binder to access the correct one and listen to its events.
Bug: 52317
Change-Id: Ibd8053768e82b1df91081bd77a172628ea855db7
Though this is already handled by Ie50b63ba5064e85d26 for the
server-side, and that should automatically reflect to the
client-side. Since we're dealing with cache conditions in
wmf-production where the user.options manifest does not yet
contain an entry for these relatively new preferences, lets
transfer the default value here as well. This does not affect
logged-in users (since their user options are always up-to-date
and embedded in the page).
Also made ve.support.es5 be casted to boolean. Previously it
would be a reference to JSON.stringify (if supported), or the
bottom value of whichever feature the browser didn't support.
Doesn't change any behaviour but should make things slightly
more performant when this value is evaluated.
Change-Id: I9ca430051ae6f4e603c2d89982e540e455055255
On browsers that implement the Navigation Timing API, performance.now()
provides values with microsecond precision that are guaranteed to be monotonic
(i.e., they are not subject to skew due to changes to the system clock).
This patch adds a `ve.now` utility function that will use this API when it is
available and fall back gracefully to `Date.now` when it is not.
Change-Id: I377025fcb23cb26399b9e437e33c8afa138916af
In target#setUpSurface, both target#setUpToolbar and
target.surface#initialize are called. #setUpToolbar does an
asynchronous animation.
After that animation is completed we call target.toolbar.initialize
and target.surface.context.update.
Right now ce.ProtectedNode needs to update the position of its
shields when the CE Surface changes position (which it does when
the UI Surface changes position because of the UI Toolbar changing
position), and does so by listening to toolbarPosition.
Adding this event to allow it to listen to that instead.
Change-Id: I826986794630c04c34cef6da36ccb15ff7dde49a
The 'ext.visualEditor.genderSurvey' module was introduced in I2b4aba6a9
for the purpose of instrumenting a short-lived microsurvey that would be
concomitant with the deployment of VisualEditor. The survey has now run
its course; this patch removes its code.
Change-Id: I8be6198a66957d792757a5312e9e71b3c8cdd1e3
This code caught badtoken errors on load, but we can't get those
any more since the API module was split and we no longer send a token
on load. badtoken handling on save is done in mw.ViewPageTarget.
Bug: 51253
Change-Id: Idb172ee46b7142681d41e593eacd9600b8f11a9a
7557dd39ed make the badtoken handling code unreachable. Revert that
change, and fix the rest of the function to deal with the possibility
that editApi is undefined. Let handling of the read-only mode error
and any other errors fall through to the bottom of the function.
Change-Id: I0673f2bb629e5cc9449675c1074d283e3926e1d5
VisualEditor.php
* Add CSS file
ve.ce.MWMathNode.js
* Wrap the image in a span, so GenerateContentNode doesn't
try to nest an image inside an image
* Remove unnecessary attribute setting
* Only pass unwrapped image to deferred.resolve
* Retrigger MathJax rendering
ve.ce.Node.css
* Use inline-block for image wrapper
ve.dm.MWMathNode.js
* Mixin GeneratedContentNode and implement getHash
* Copy over functionality of MWTransclusionNode:
+ Just store data-mw for attributes
+ Store orignal(DomElement|MW|Index) for selser
ve.init.mw.ViewPageTarget.js
* Add mwMath to the toolbar
ve.ui.MWMathInspector.js
* Remove static.InputWidget, not required in this architecture
* Use multiline TextInputWidget
* Only update mw attribute
* Allow creation of new math nodes
ve.ui.MWInspector.css
* Set height of TextInputWidget
Change-Id: I520f8ccc9f89a2ce70aa1d9e02ed0c6cacbecc2f
Now Ctrl+\ (Cmd+\ on Mac) will trigger the 'clear annotations' button
on the current context. Ideally we'd also bond to the 'clear' keyboard
button (ASCII 12) but it does not seem possible to do that yet.
Bug: 51507
Change-Id: I300ec1ffa237e51418ec429be39001f820f053ae
== Renamed methods ==
* enableFloating -> enableFloatable
* disableFloating -> disableFloatable
* setPosition -> float
* resetPosition -> unfloat
== Scroll and resize event ==
Timeline for scroll event reduced from about half a dozen
"Recalculate style" and various forced "Paint" down to 0.
New timeline for scroll is clean (for me: from ~35 to ~59 fps):
* 1 Event (scroll)
* 1 Composite Layer
The composite layer action is the browser changing the viewport
to a different portion of the document drawing. Exactly the one
thing a simple scroll should do.
Timeline for resize event is still pretty crowded and low fps,
but it has improved. Further improvement would likely be around
using requestAnimation and going outside ve.ui.Toolbar.
== Changes ==
* New: ve.ui.Toolbar#initialize.
Similar to what surface has. Users of Toolbar should decide
whether to call enableFloatable, append it to the DOM at some
point and then call initialize() once.
* Don't compute offset() every time.
Eliminated by doing it once in #initialize. These 'top' and
'left' offsets do not change.
* Don't compute outerWidth() and $window.width() every time.
Reduced by doing it once in #initialize to compute the 'right'
offset. Updating it only on resize.
* Don't set 'top' every time.
This is already in the stylesheet. It was never set to anything
else so the abstraction for it in #float has been removed.
This also made it obvious that code for "ve-ui-toolbar-bottom"
was unused and left behind. Tha class was only ever being
removed from something (never added).
The one addClass call for it was in a condition that is always
false ("if top > 0").
* Don't set 'left' every time.
Eliminated by doing it once in #float.
* Don't set 'right' every time.
Reduced by no longer doing it on scroll. Done once in #float,
and on resize after computing the new value for it.
* Remove no-op style operations.
Wrapped methods in if-floatable, if-floated etc. to reduce a
fair amount of easily avoided re-paint overhead.
* Avoid double re-paint in mw.ViewPageTarget.
Though we prevent a lot of redundant re-paints now, whenever
we do repaint we want to do it in 1 repaint instead of 2.
ve.ui.Toolbar emits #toolbarPosition, which tells
mw.ViewPageTarget to update toolbarTracker which would read
the new $bar style properties and copy them over to the
$toolbarTracker. However, this read operation forces the browser
to do an immediate re-paint half-way just for $bar.
Browsers only repaint when style properties are changed and
JS has yielded. The exception to this is JS reading style
properties: in that case the browser is forced to do those
deferred repaints directly and reflect the new values.
We can avoid this double repaint by passing the updated values
as data instead of requiring the receiver to read the DOM (and
thus a keep the deferred repaint). Now toolbarTracker can use
them directly whilst the browser hasn't even repainted $bar yet.
== Clean up ==
* Redundant "border-radius: 0". This would reset something, but
it never does. None of the things it inherits from set a
border-radius. There is one subclass where toolbar is used
with a border-radius (".ve-ui-surfaceWidget .ve-ui-toolbar-bar"
sets a border-radius) which overrides this on purpose, so the
default of 0 is redundant.
* Pattern "if ( .. ) addClass() else removeClass()" changed to:
"toggleClass( , .. )"
Bug: 52014
Change-Id: I9be855148962eee068a77fe83e98eb20bbdcfeec
These have been pointing to the same method for a while now,
we can safely remove these obsolete aliases and just use it
as generic copy.
* Each file touched by my editor had its new line at EOF fixed
where absent
* Don't copy an otherwise unused empty object
(ve.dm.Converter)
* Use common ve#copy syntax instead to create a link
(ve.dm.Document, ve.dm.example)
* Remove redundant conditionals for isArray/copyArray/copyObject
(ve.dm.example)
Change-Id: If560e658dc1fb59bf01f702c97e3e82a50a8a255
The core changes to postedit in I778b18b that this depends on were
deployed to the cluster as part of 1.22wmf11.
Bug: 39632
Change-Id: Id4a8bc22c09a552ef79670b0d4fc4a70df07ec33
Opera 12 seems to work well enough, but I'm not confident enough to
whitelist it just yet.
Opera 15 is basically Chrome with a different interface, so it should
work perfectly, but it's barely out of beta and untested right now.
Bug: 36000
Change-Id: Ia80a6f53f8c128ef52d0bfde1828fdc132046afb
This is the language inspector UI engine with ULS core.
The Language Inspector works alongside ULS to choose and change language
blocks in text. The inspector was based on ve.ui.TextInputWidget and
now changed to inherit ve.ui.Widget and display details in a table
instead of an input textbox.
Added jQuery.ULS module:
* Repository: https://github.com/wikimedia/jquery.uls
* Latest Commit 728f112ffc90b03b50c0109487886a2647f12020
* Taken 'src' / 'images' and 'css' folders into modules/jquery.uls
Bug: 47759
Change-Id: I3c9fd6c135c05a54f6c7fc28c5962fc0a6677806
Previously, we'd clone the data but convert it in the context of
the existing dm.Document, whose nodes had pointers to elements in the
old data array, not to the cloned ones. Because dm.MWReferenceNode
has logic like if ( something === dataElement ), this caused the sanity
check conversion to behave slightly differently compared to the real
conversion that happens on save, and so a references corruption
bug went unnoticed.
Change-Id: I79a42ae21f91cb8eb410ae26ea638036db19e217
Pretty straightforward, although we should start thinking about
grouping/hiding 'advanced' formatting options in the toolbar.
Making this button experimental for now until we've come up with
a way to deal with this problem.
Bug: 51590
Change-Id: Ieb1935b742aced4b883d8a194e6cb69be68473d0
Server-side, plugins can register themselves by adding to
$wgVisualEditorPluginModules. This is the recommended way for
MW extensions to extend VE. Client-side, plugins can register
themselves through mw.libs.ve.addPlugin(), which takes a string
(RL module name) or a callback.
When VisualEditor loads, we load the registered plugin modules in
parallel with ext.visualEditor.core. Note that they're loaded in
parallel, not after, and so the plugins should explicitly depend
on ext.visualEditor.core if they use or extend classes in VE core.
Once the modules finish loading and user and site scripts have run,
we execute the registered plugin callbacks. These callbacks can
optionally return a promise. We gather these promises and wait for
all of them to be resolved, then initialize the editor.
This allows Gadgets to extend VE by top-loading a small module that
depends on ext.visualEditor.viewPageTarget.init and calls
mw.libs.ve.addPlugin( 'ext.gadget.bottomHalfGadget' ); , the bottom
half being a hidden Gadget that depends on ext.visualEditor.core and
contains the actual code. The addPlugin() call needs to be in a
top-loading module because otherwise there's no guarantee that the
plugin will be registered before the user clicks edit and VE loads.
User and site scripts can extend VE by simply calling addPlugin()
directly, as mw.libs.ve is already present when user scripts run (since
it's top-loaded) and VE waits for 'user' and 'site' to run before
executing plugins.
If user/site scripts need to load additional JS files, they can load
these with $.getScript() and return the corresponding promise:
mw.libs.ve.addPlugin( function() { return $.getScript( 'URL' ); } );
For a diagram of all this, see
https://www.mediawiki.org/wiki/File:VE-plugin-infrastructure.jpg :)
VisualEditor.php:
* Add $wgVisualEditorPluginModules
VisualEditor.hooks.php:
* Expose $wgVisualEditorPluginModules in JS
ve.init.mw.ViewPageTarget.init.js:
* Add mw.libs.ve.addPlugin function that just stores the registered
values in an array and passes them into the mw.Target when it's
being initialized
ve.init.mw.Target.js:
* Add $wgVisualEditorPluginModules to the set of modules to load when
initializing VE
* Add a Deferred (this.modulesReady) to track module loading
* Add addPlugin() and addPlugins() methods that add to either
this.modules or this.pluginCallbacks
* In load(), instead of mw.loader.load()ing this.modules, use using()
to load this.modules plus user and site, and fire onModulesReady()
when they're loaded
* In onModulesReady(), execute the registered callbacks, gather the
returned promises, wait for all of them to be resolved, then resolve
this.modulesReady
* Fire onReady based on this.modulesReady being resolved, rather than
using a second using() call
Bug: 50514
Change-Id: Ib7d87a17eaac6ecdb8b0803b13840d7ee58902df
We already correctly show the read only error if the user tries
to load VE which the database is locked, but if the database gets
locked after they've loaded VE, we also need to show the error
when they try to save.
Bug: 51636
Change-Id: I7a56f1b4387e7ea594a2a7f939c81626c9eee834
EditPage has a lovely getCheckboxes() function which includes the
minor and watch checkboxes as rendered by MW core, as well as any
checkboxes extensions like FlaggedRevs might have added. Output
these in the API, render them, and send their values back.
ApiVisualEditor.php:
* Build a fake EditPage, get its checkboxes, and return them
ApiVisualEditorEdit.php:
* Pass through posted request data to ApiEdit, which passes it
through to EditPage thanks to Idab5b524b0e3 in core
ve.init.mw.ViewPageTarget.js:
* Remove minor and watch checkboxes from the save dialog template
and replace them with a generic checkbox container
* Have getSaveOptions() pull the state of all checkboxes in
** Special-case minor and watch, and pass the rest straight through
** Move normalization from true/false to presence/absence here, from
ve.init.mw.Target.prototype.save(), because here we know which ones
are checkboxes and we don't know that in save() without
special-casing
* Remove getSaveDialogHtml(), we don't need to hide checkboxes based on
rights anymore because in that case the API just won't send them to us.
** Moved logic for checking the watch checkbox down to where the same
logic for the minor checkbox already is
* Unwrap getSaveDialogHtml() in setupSaveDialog()
* Access minor and watch by their new IDs throughout
ve.init.mw.Target.js:
* Get and store checkboxes from the API
* Pass all keys straight through to the API
Bug: 49699
Change-Id: I09d02a42b05146bc9b7080ab38338ae869bf15e3
Previously it was faded out to 60%. contentSub contains FlaggedRevs
stuff we don't want around in the editor, and contains the revision
navigation when editing an oldid, which James decided also shouldn't
be visible when editing.
Change-Id: Icdef98f756ce92a32d276d6eeb22c9de04640d8b
This preference will allow users to opt-out of VisualEditor during the beta
if they so choose. We do not re-use the alpha enablement flag because (a) this
would lead to a confusing preference description, and (b) because opting in
and then out of the alpha is not the same user choice as opting out of the
beta period.
Change-Id: I0f0a1b5eb21703ad422d007cab65c75ac1aa6fd8
Load the module always and have the conditionals on the
client-side so that we can change these without running into
problems with the new conditions not being rolled-out quickly
for anonymous users because the load queue is in the HTML
and cached for 30+ days.
This also allows us to fix above problem retroactively in wmf
production by just adding a mw.loader.load for this module
in something like MediaWiki:Common.js or something else that is
already in the cached load queue (temporarily, until the cache
has rolled over).
Removed unreachable code for loading ext.visualEditor.splitTest.
Change-Id: I21114960a88d224747447f2dc83d17d160f5f066
Refactor a few things to make it easier for scripts to see
not just whether mw.libs.ve is present but also whether it
allows the user to activate VisualEditor.
Change-Id: I50da8d9a260207d4ec1c43254dfe738f91386a9e
Objectives:
* Merge reference insert and edit dialogs
* Change workflow to put editing/creating a new reference first
* Add secondary page in dialog for selecting an existing reference
Changes:
*.php
* Cleanup unused files/messages
ve.ui.Dialog.css
* In the footer; make primary, constructive and destructive buttons
appear on the right; all others on the left
ve.ui.MWReferenceSearchWidget.js
* Fix documentation
* Remove create option and reuse section header items
ve.ui.MWReferenceInsertButtonTool.js,
ve.ui.MWReferenceEditButtonTool.js,
ve.ui.MWReferenceButtonTool.js
* Merge reference button tools
ve.ui.MWDialog.css
* Remove body styles, use padded option of layout instead
* Update selectors as per merging of dialogs
ve.ui.MWReferenceInsertDialog.js
ve.ui.MWReferenceEditDialog.js
ve.ui.MWReferenceDialog.js
* Merge reference dialogs
* Add buttons to switch between edit and select mode
ve.init.mw.ViewPageTarget.js
* Update reference button name as per merging of tools
ve.ui.SurfaceWidget.js
* New widget!
* Encapsulates a "sub-surface"
Bug: 51152
Bug: 50458
Change-Id: I8265febf4fd8f64d2ac40470ff033bac68b24d99
Misc:
* Updated signature of #showMessage to include allowing
an array of nodes to be passed. We pass this to jQuery#append
so we're just extending the explicitly documented subset of
things it could already do due to passing to jQuery#append.
Bug: 50472
Change-Id: I3f56820a4f14b0684bfa265e3eb5e3820f2a3513