Rather than setting the wgPostEdit configuration variable when the
user uses VisualEditor, i.e. communicating via mutable global
state, include whether or not the user edited the page in the
ve.deactivationComplete event.
Bug: 52955
Change-Id: I0f5067550921008f74221d6c92882adfe404b3a5
Changes in MediaWiki core to the padding of div#content in Vector
(see 9d988924a0350228745375e074420a0e1214f7e3 ) made the toolbar in
VisualEditor's ViewPageTarget integration for Vector render incorrectly.
This adjusts the toolbar margins to match the changes in content padding.
Bug: 61224
Change-Id: Ie6b47f5d1929533669118ba51202c1fccda4a0d6
.then() removes the .abort() method from the promise, even though
we had return jqxhr; in the then() callback. So store xhr in
a variable and put the abort method back.
This fixes a JS error upon calling this.loading.abort();
Change-Id: I50460782e58399198bacc02d028984682ddbed56
* Use correct class name for setUpToolbar() in MobileViewTarget
* Move shared setUpToolbar() code into ve.init.mw.Target
* Fix iconModuleStyles documentation, remove leading space
Change-Id: Icf5ed36fd817837c0434db8202bef8a78e6cb898
The selector is too weak and results in the toolbar being placed
in positions it shouldn't be! Whoopsy!
Change-Id: I63540130e4de01f9326fe110d606985fea70b644
The toolbar in very desktop vector skin specific
In mobile we want to have more control over the toolbar,
and its placement.
* Thus make setUpToolbar abstract
And move the function to ViewPageTarget
* Introduce ve.init.mw.Target.static.iconModuleStyles to
allow the use of different icons
* Update the mobile toolbar to only have B and I tools
Change-Id: I4c72b4b9128b3a74de8b8b5bce7664fbb315216b
The jqXHR parameter is optional, so handle the case where it's null
gracefully.
Also fix the documentation for this method, it was full of lies.
Change-Id: I6ab799846a4d4b0d10cc5fd4d8c47264b1845bdf
Extend default paste rules to prevent lists/tables/references/headings
as applicable.
Also update submodule to master (76ff210).
New changes:
f1a927f Internal paste rules and type conversions
Bug: 59603
Change-Id: I952f98477219a55d25a2bd817344bde58a4862d4
In HD mode, the left margin was 0.25em off.
In narrow mode, the margins were completely wrong.
Bug: 51000
Change-Id: I7fd9cbc925b828fd780adb9ab2c71bcf15dc7284
New changes:
* e7e2833 - Update uses of Push/IconButtonWidget to ButtonWidget
* d9d9eb5 - Update OOjs UI to v0.1.0-pre (d9bab13)
* d9bab13 - The Great Button Refactor of 2014
* 22b93ef - Update OOjs UI build (88b2871)
* 88b2871 - Fix png transparency on required.png
* 670c468 - Add i18n
Also:
* Update uses of Push/IconButtonWidget to ButtonWidget as there
is a breaking change in new OOjs UI version.
This was separated from commit I325a4dcc316d0.
Change-Id: I82220d15221c52be03feafcfc85c2bd6c12ba462
When running in the context of MediaWiki, VisualEditor should tee its event
stream to MediaWiki's main event bus, mw.track(), so that MediaWiki event
subscribers have a unified interface for subscribing to events. Each
VisualEditor event topic is prefixed with 've.'
To test this patch, you can use this snippet:
mw.trackSubscribe( 've', function ( topic, data ) {
console.log( this, topic, data );
} );
Change-Id: I6b3f10b0dd0aa7fa47c3b35e2fc554622960ce52
The down arrow is no longer default, so it needs to be specified
explicitly.
Updates submodule to include indicator changes
(see I0a1faef11a1e7e6ea3e44275c85f2efafae4dc9a)
Change-Id: I32aef3ea2e66fd823aeb07dac06cfefba9954270
It is treated specially which results in it being set to opacity=0 instead
of hidden, and leaves a large space at the top of the document. Removing
special treatment of it results in it being hidden properly.
Bug: 52243
Bug: 54325
Change-Id: I2d6157708bd7b4c3a7c6474b1612862120f963b7
Instead of having a hard-coded array of preference-triggered modules
that we need to maintain in multiple places, manage this data in one
place in a configuration variable, and explicitly declare the preference
and module names rather than interpolating both of them from a name.
This allows extensions to add preference-triggered modules, and it
allows them to have preference names and module names that aren't
prefixed with 'visualeditor-enable-' and 'ext.visualEditor.' respectively.
Change-Id: I9eb14349cd39125d5c11ffb44c962cc5febb6ba0
This creates a new panel in the meta dialog, "Page settings", where page-
level settings will be, err, set. For now, this exposes just the
behavioural switches for the presence/absence of the Table Of Contents –
__NOTOC__ and __FORCETOC__.
As part of this change, the meta dialog is renamed to "Options" to be
less confusing, and the icon for the meta dialog is changed to the
generic one for dialogs, which was previously unused. The page settings
pane is provided first in this list, given that the categories pane
(amongst others) is now directly accessible through the toolbar menu.
Bug: 56866
Bug: 56867
Change-Id: I33ce05c19d2e19b249e1cefd26fd0e3697d0085d
This commit switches from using hard-coded media source urls to utilizing
MediaWiki's API call for meta=filerepoinfo. The API call is done only if
needed when the media insertion dialog is loading, and is done only once
per session.
Bug: 50673
Change-Id: Ia5ad9a8c00cca6cbbbc890359dc529e29e1a6be7
Move target.surface from mw.Target to Target
* All targets use this, let's standardise it.
Move target.$document from mw.ViewPageTarget to Target
* It was initialised with null in mw.ViewPageTarget, but the
assignment happened in mw.Target. So it should be moved up
at least to mw.Target.
* Since it is useful to have in sa.Target as well, moved it up
to the abstract Target, and implemented in sa.Target and
immediately used in the standalone demo where we were already
duplicating the find( '.ve-ce-documentNode' ).
Add missing target.setupDone = false; in sa.Target
Add missing target.toolbar to Target
* Was used in all subclasses, but never initialised in any of
the constructors. Let's standardise this property name as well
(instead of initialising it in three places).
Move target#event-surfaceReady from mw.Target to Target
* sa.Target uses it as well, and considering Platform#initialize
is already standardised in the abstract class, Target#setup
being deferred is most likely to happen in each target as well
so let's avoid different events being invented for the same
thing and consistently use 'surfaceReady'.
Change-Id: Ia8bde188a4cde7e1615c2ae9c5b758eefc5d9cb7
* Split files according to ve / ve-mw paths
* Split messages according to msgs-ve / msgs-ve-mw
* Update dependencies accordingly
* Remove ve-mw/ hack in makeStaticLoader.php, no longer needed
Bug: 45342
Change-Id: I6cb89606c307e27e237a1e9b56b94dfdcd310f41
The duplication of the toolbar definition is ugly but we don't
have a better system to say "give me the same except demote this
one thing" right now.
Change-Id: Id74ed1a18aee4a947992bdd626702f578bbace14
Follows-up I55ef2622c9eacc which activated code introduced in
mw.Target in commits before that one that caused a change in the
execution order.
Hiding of page content (regular wiki page content provided by
original view request) must happen before the surface document is
focussed.
We used to hide the content from mw.ViewPageTarget#setUpSurface,
which is called from #onReady, which focusses the document after
setUpSurface is done.
Most of this code was moved to mw.ViewPageTarget#onSurfaceReady
which is the listener for the surfaceReady event emitted from
If our surface document gets focus while the original wikipage
content container is still there, the view port is forced to
scroll down because our surface is the next element sibling after
the wikipage container in the DOM.
And browsers (apparently Chrome is not affected) naturally retain
scroll position even if the elements above the one you "scrolled to"
disappear.
We can't (and shouldn't) move the hidePageContent call because
that's the responsibility of the Target subclass, so instead
moved the document focus to below the hidePageContent which is
now also part of the responsibility of the Target subclass.
Also:
* Removed target.surfaceOptions reference because that property
does not exist. We never passed a second argument here, and
whatever this was intended for, doesn't exist.
Bug: 58089
Change-Id: I230fbd5401cbd6e3b9450c7f156650409be8ef16
Let's experiment with this via our local Gruntfile. If it works
fine we can install it in Jenkins (similar to node-csslint).
Verify through $ npm install && npm test;
Fixed all outstanding violations.
Also:
* Added syntaxhighight to ignore.
* Added imetests (which contain unformatted JSON) to ignore.
* In ve.dm.ModelRegistry#matchTypeRegExps, removed redundant
!! cast from the [+!!withFunc] statement which was hitting
a bug in node-jscs. All callers to this local private function
pass a literal boolean true/false so no need to cast it.
* Removed "/* key .. , value */" from ve.setProp, though this
wasn't caught by node-jscs, found it when searching for " , ".
* Made npm.devDependencies fixed instead of using tilde-ranges.
This too often leads to strange bugs or sudden changes. Fixed
them at the version they were currently ranging to.
Bug: 54218
Change-Id: Ib2630806f3946874c8b01e58cf171df83a28da29
Following on from getDomFromModel, this returns a document model
instead of element linear data. The only instance that hasn't been
replaced is in rich paste, where we need to sanitize the converted
data before constructing the document model.
This should be cleaned up in a later commit.
Change-Id: I37a2b641632af2cb515e3409deed5cd1fa358af5
Was already implemented in the parent class. Moved setPasteRules() so it
would still get run, everything else had already been moved.
Change-Id: I55ef2622c9eacc8b46bd3487919165bccfc347d5
Currently it takes 4 arguments which are all properties
of the document model, so just pass the model instead and
access the properties later. Rename to getDomFromModel.
Change-Id: I0c378a04dc08b9b90bdc3984f8fa8c4acfe0b667
Sometimes a save is not a save, but a switch to the wikitext editor; in this
case, the save dialog doesn't exist, so don't assume that it does.
Bug: 57947
Change-Id: Ic2df7d2066ba03564ed531e1d31351cd27441abe
Also:
* Added modules/syntaxhighlight to csslintignore because
it is broken right now, so it's hard to fix those warnings
without being able to verify it.
* Fixed a typo in the grunt-watch config that accessed an
inexistent property.
Change-Id: Ib81572506786b6a1203c454d1b2b91bb6ae2a3de
That's where they belong IMO, since ViewPageTarget is the one that
has .activate() and .deactivate(), and mw.Target doesn't retain any
state (apart from some caching things).
Change-Id: Ia6cf5bac9054163d54ab492d691d8ce9d6a3bb90
* changes:
Split apart onSaveError logic for other mw targets
mw.ViewPageTarget: Remove unused onTokenError handler covered in onSaveError
Create base MobileView config and target refactor
Changes include:
* Target mobile for ve dependencies
* Create mobile view constructor
** Some tools like dialogs are excluded for now
* Refactor mw.target to permit code reuse
** Split out pageTarget view functionality from core init methods
Change-Id: I786b63ab57518fc6af7761501259ed66592f70e3
Otherwise the old save dialog will still be around if the user sets up
another surface (e.g. a second edit), but won't be attached to the DOM.
Bug: 57654
Change-Id: I23c10849a212534bdd0600637d8ad4fa3ebc4fb7
* changes:
Plain text paste with paste special
Use rare unicode characters for paste placeholders
Rich paste
Add fixUpInsertion to newFromDocumentReplace
This allows things outside of VisualEditor to style themselves
differently while the editor is active.
Bug: 57555
Change-Id: Ief6b5f53096dd5eeb43a72a7bb182a2c04ec97ca
Allow pasting of rich (HTML) content.
ve.ce.Surface
* Use a sliced document clone for converting to DM HTML (copy)
* Add full context to pasteTarget before copying
* Add ve-pasteProtect class to spans to prevent them being dropped
* Implement external paste by converting HTML to data and inserting
with newFromDocumentInsertion
* Remove clipboard key placeholder after read so they aren't picked
up by rich paste. Hash no longer includes the placeholder.
* Detect the corruption of important spans and fallback to clipboard
data HTML if available.
ve.dm.LinearData
* Add clone method for copy
ve.dm.ElementLinearData
* Add compareUnannotated for use by context diffing.
* Add sanitize method for cleaning data according to a set of rules.
ve.dm.Transaction
* Add range parameter for inserting a range of a document only,
e.g. stripping the paste context.
ve.dm.Document
* Implement sliced document clone creation so that DM HTML
is generated correctly in onCopy
ve.dm.DocumentSlice
* Replaces LinearDataSlice. Now has two ranges for balanced data
and data with a full context.
ve.init.Target.js
* Define default, loose, paste rules (just remove aliens).
ve.init.mw.ViewPageTarget
* Define strict MW paste rules:
+ no links, spans, underlines
+ no images, divs, aliens
+ strip extra HTML attribues
ve.init.sa.Target, ve.init.mw.ViewPageTarget, ve.ui.Surface
* Pass through and store paste rules.
Bug: 41193
Bug: 48170
Bug: 50128
Bug: 53828
Change-Id: I38d63e31ee3e3ee11707e3fffed5174e1d633b42
We were using it for the pop-out save dialog, but now that the save
dialog is real dialog, we don't need it any more.
Change-Id: I72697b5502d5f3fd19f2369a754a62d614af715b
Move the userPrefEnabled check out of isAvailable and instead check
it in-line with isAvailable for setting up the tabs with CSS, but
not for the veaction=edit function.
Bug: 55900
Change-Id: I23984e377ff3fc797e921546492b8c73a5101235
* Don't use setTimeout() within a change event, because change fires
after the text has already changed
* Don't use .$input.val(), use .getValue() instead
* Don't use .placeholder()
** Reaching into .$input is bad
** Any use of .placeholder() is TextInputWidget's responsibility
** All browsers we support also support placeholder natively
* Remove .editSummaryByteLimit from ViewPageTarget, unused
* Remove ve.bind() wrapping, we already have var saveDialog = this;
Change-Id: I380575fec8d02d1191bfc1f3f235b94c64cd23b6
The save dialog DOM is pretty big, so building it on demand
like every other dialog out there seems like a good idea.
Change-Id: I02077c3e45f01d3467d41616eb879bd1d608a82b
Each used their own implementation of building a form and submitting it.
The edit source one wasn't passing in the oldid, which caused edit
conflicts.
Also introduced a separation between form fields (for the action=edit UI)
and API options, building one from the other.
Bug: 56835
Change-Id: I38547b4ba1827f4028a2255109cba2a57cd59e8a
It looks like it also came from there originally, because it uses
this.pageExists which doesn't even exist in MWSaveDialog. This caused
all pages, even existing pages, to be watched when 'watchcreations'
was set.
This logic really belongs server-side, though.
Bug: 56206
Change-Id: Idf500383b27a93136dc0cfdd60a2e7b2607af95c
Move generation of initial edit summary from setupSaveDialog() to
restoreEditSection().
This allows us to get rid of the properties tracking whether both
halves of the edit section handling had happened, because they're
now in the same method.
Moving setupSaveDialog() down so it runs after restoreEditSection();
this is needed for the communication via this.initialEditSummary
to work correctly.
Change-Id: I06a9c5cf5c752acea8a2ac25d0ffb6ac61cfe986
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
Point out that the software may have issues, and point users to the "Edit source"
link explicitly.
Change-Id: Id84d76887038a3a6a9e11a203f19dc3db7703e6a
This way if both are the case, the user (or VE, if possible)
will deal with badtoken first instead of potentially having to
solve the captcha twice (as each handling of the error does - and
should - end with an early return).
Change-Id: I9e4264a7001ffa9654bfab02cc955aa36ff5b6aa
Previously we only looked at error info/code from the root of
the API response, not the ones from the root of the response
that action=visualeditoredit forwards from action=edit.
This changes the message for e.g. AbuseFilter from:
> Error: Invalid error code
to:
> Error: Hit AbuseFilter: [name of triggered filter]
Also changed default error for other reasons (e.g. hooks of other
extensions that we don't yet have specific support for) to "Unknown error"
instead of "Invalid error code".
Bug: 50472
Change-Id: I3b32eddafd8fff83f323606f9922ac60b5d3b58e
* Rephrased visualeditor-savedialog-error-badtoken to emphasise
that it is the old session that become invalid, not the one
the user started browsing with since in a different window.
* If the session changed, the user will be asked whether they
agree to save with this new session instead.
* We explictly update mw.config so that future save attempts
in the same window compare against the correct environment.
Without this there are two problems when saving and then
making a second edit in the same window and saving that:
- It will bring up the same question again (user A -> user B),
which is annoying.
- If the user logged back in again (new session, but for
user A again) it would silently try with that new token
without asking, thus saving as user A when the user still
thinks it switched to user B. It switching back automatically
is not obvious since we asked them from A->B, so we should
also ask the other way around.
This can be reproduced by opending ve-edit logged-in, then
logging out in a new window, save, confirm anon, save,
open edit again, log back in in a new window, save open edit
in the old window, confirm new logged-in, save.
Bug: 50424
Change-Id: Id055eca1886f85aeaf615f645de29898afc0373c
Without making the code much more complex (and possibly create
performance issues) the warning will fire on pages which already
contain escaped wikitext (when that text is edited). I think this
should be a small enough minority that it won't be an major annoyance.
Bug: 49820
Change-Id: I0f67ec04b890f4add9247be6126bdc086b6ae72f
Previously all it did was surface api response error.info,
which surfaced underneath the edit summary form as mere:
"Error: Invalid token".
Bug: 50424
Change-Id: I60169b42701ae3b88e54626c4ff7050549e6ef55
This allows us to make the token no longer a requirement
for non-save actions while still using the built-in system
for token verification.
Update documentation for "oldid" since it is not required even
outside (paction=save). In fact, if we require it VE loading
fails because it doesn't pass oldid unless it has to when
restoring a specific version.
Bug: 50424
Change-Id: I7b1b50a43648b1cc40a984340846efdb0ba2ecc9
The presence check used to be against the VE global, but we
recently made that impossible without providing an alternative.
Though by accident, mw.libs.ve has become the new way to check
for presence.
Change-Id: If85695525777a71dde467675052d2ede4e52c9b7
* Hooks for activation, deactivation, save dialog state change,
and tab setup.
* Class for save button (needed to point to it in a clean way).
Also done for cancel button to be consistent, though GuidedTour
doesn't currently use this.
Change-Id: I4a0e0631d513fb09c3408f2f36a0de0bd51e1a37
Follows-up Ic0c6d190c9b78 which introduced a full linmod copy in a
scope that is also accessible by other closures (namely the
callbacks to jQuery.Deferred #done and #always, and setTimeout).
Though in theory engines may be able to garbage collect it,
I doubt it. Though browsers probably destruct the setTimeout
callback I know at least the closures pass to jQuery.Deferred
are not released by jQuery, so an engine would have to
understand these other functions well enough to know it doesn't
access the `data` variable.
Let's release explicitly to be safe.
Change-Id: I11000edcad4690dcce53b6e9d1a45bf2ab82fbcb
Objective:
* Prevent input while the inspector is animating open
Changes:
ve.ui.LinkInspector.js
* Disable and then re-enable the surface while the inspector is opening
ve.ce.DocumentNode.js
* Remove opacity changes on disable/enable
ve.init.mw.ViewPageTarget.js
* Change the opacity of the document when save dialog is open
Bug: 51075
Change-Id: Ic7910a666b33b41b57b035a15cf1f8c9264e7111
We previously manually loaded CSS into these frames, which is flawed
because it completely bypasses ResourceLoader (so CSSJanus didn't flip
them, necessitating a bunch of hacks for RTL), and doesn't pull in
MediaWiki styles (so templates inside references don't render correctly).
Instead, this commit copies all styles from the main document into each
frame's document, inlining what it can.
Loading all styles in dialogs and inspectors caused some problems,
initially. We didn't namespace our styles for dialogs vs. inspectors
at all; the only reason inspector styles weren't being applied to dialogs
and vice versa was because we controlled which files were being loaded
in which context. This commit namespaces the inspector and dialog styles
where needed so they don't conflict and try to override each other.
Tested in Vector and Monobook, but not in Apex and not in RTL.
ve.init.mw.ViewPageTarget*.css:
* Namespace styles that are only intended for the main document
* Undo Monobook's font-size: x-small; in frames
*Dialog.js:
* Remove addLocalStylesheet() calls, we don't need those any more
** ve.ui.MWDialog seems to be unneeded now, we may want to remove it
*.css:
* Remove @noflip-ped RTL rules where they were just flipped versions of
their LTR counterparts
ve.ui.Dialog.css, ve.ui.Inspector.css:
* Namespace styles with .ve-ui-dialog-content / .ve-ui-inspector-content
ve.ui.Frame.css:
* Move the margin:0 and padding:0 here (were in the frame <body>'s style
attribute) and add background:none to prevent frames from getting
the skin's background (grey in Vector, a book in Monobook)
ve.ui.Dialog.js, ve.ui.Inspector.js:
* Add ve-ui-dialog-content / ve-ui-inspector-content class to the
frame's content <div> so we can restrict styles to only apply in
dialogs / inspectors
ve.ui.Frame.js:
* Replace infrastructure for @import-ing stylesheets with transplantation
* Remove code polling to see when the stylesheets were loaded
** We can't do this in the new approach AFAIK, since all styles in the
frame are either inlined or inaccessible due to the same-origin policy
** We also shouldn't need it because the browser should have cached the
styles when it loaded the main document
* Apply ve-ui-frame-body class to the frame's <body> so we can style it
** Move inline padding:0;margin:0; into ve.ui.Frame.css
** Move the ve-ltr/ve-rtl class up to the <body>
ve.ui.Window.js:
* Remove infrastructure registering stylesheet URLs to load
Change-Id: I4a37115301811ad860f4578344a04873ea8c2b69
Conversion is apparently pretty slow on large articles, so put it inside
the setTimeout(). We still need to copy the data array synchronously
though.
Change-Id: Ic0c6d190c9b782f8c643d00d335f0e004d860bcf
Firefox 13 and 14 were the cause of links magically turning into [[./Foo]].
Once the immediate rush of deployment is over, we'll want to investigate as
to why and hopefully find a way to unblacklist FF.
Bug: 50720
Change-Id: I7a9dddb693091fa1e44b4325e77b9e4f55e5c193
The handler for the Edit tab already is in this conditional,
for edit section we were making the assumption that they only
ever appear on a view page, but that's wrong. They're also shown
on a diff against the latest revision of the page.
Bug: 50925
Change-Id: I802e548cbcdc03cfca66129466668854604bc3e7
* Only pass the oldid to the API from #load if we restoring from
oldid in the url. Otherwise load the latest version.
* Setting 'restoring' from mw.Target instead of mw.ViewPageTarget
so that we don't rely on mw.ViewPageTarget in mw.Target#load.
* Fix the API to not require 'oldid' to be passed.
* Fix the API to actually return the 'newrevid' property. It
was doing a no-op on a $result that is never used due to the
same variable being overwritten with the result of parseWikitext.
* Moved updating of wgCurRevisionId to mw.ViewPageTarget as it
belongs there (possible future inline editors probably act
on a different page than the main one). Also made it only
update if it isn't undefined, so that a null edit doesn't
result in wgCurRevisionId being unset.
Bug: 49943
Bug: 50441
Change-Id: I221e5038f95eadf6d87013e80f12394f0376a293
Since we're now only loading the light-weight init on page load,
the section editing wasn't just deferred to after page load (like
it was before), but wasn't happening at all until you clicked
"Edit" (at which point the library loads). It only worked when
going back to "View" after "Edit".
Contrary to tab layout, edit section handling needs to be
accessible both in the top init and in the main target class
because we need to run it both at run time and after the user
has saved a page when we show them the updated page without
refresh. This is why we need to transfer the method at run time
and give the main class access to it as well.
Can't wait for bug 50707 to get rid of this mess...
Bug: 50731
Bug: 49993
Change-Id: Iab9c81222df7f1084179c3643d158374a89ca14b
Initialisation initialisation? It's time to rename ve.init
to ve.platform and ve.init.Platform to ve.platform.Environment,
but that'll come later.
* Moved support detection and skin set up to separate class-less
file.
* Swapped usage of ve.msg for mw.msg.
* Callback of edit tab now does an mw.loader call to fetch
the actual VisualEditor libraries.
Though mw.loader won't load the same thing twice, we would
bind a callback each time. To avoid instantiating ViewPageTarget
more than once we use a Deferred.
Bug: 50542
Bug: 50608
Bug: 50612
Change-Id: Ic8b0004ab5288fa91bb29d496485b93ffd8d977e
Move all MW-specific files into the ve-mw directory, in preparation
for moving them out into a separate repo.
All MW-specific files were moved into a parallel directory structure
in modules/ve-mw . Files with both generic and MW-specific things were
split up. Files in ve/init/mw/ were moved to ve-mw/init/ rather than
ve-mw/init/mw ; they're still named ve.init.mw.* but we should change
that. Some of the test files for core classes had MW-specific test cases,
so those were split up and the test runner was duplicated; we should
refactor our tests to use data providers so we can add cases more easily.
Split files:
* ve.ce.Node.css
* ve.ce.ContentBranchNode.test.js (MWEntityNode)
* ve.ce.Document.test.js (some core test cases genericized)
* ve.dm.InternalList.test.js (uses mwReference test document)
* ve.dm.SurfaceFragment.test.js, ve.ui.FormatAction.test.js
** Made core tests use heading instead of mwHeading
** Updated core tests because normal headings don't break out of lists
** Moved test runners into ve.test.utils.js
* ve.ui.Icons-*.css
* ve.ui.Dialog.css (MW parts into ve.ui.MWDialog.css)
* ve.ui.Tool.css
* ve.ui.Widget.css (move ve-ui-rtl and ve-ui-ltr to ve.ui.css)
ve.dm.Converter.test.js: Moved runner functions into ve.test.utils.js
ve.dm.example.js:
* Refactored createExampleDocument so mwExample can use it
* Removed wgExtensionAssetsPath detection, moved into mw-preload.js
* Genericized withMeta example document (original version copied to mwExample)
* Moved references example document to mwExample
ve.dm.mwExample.js:
* Move withMeta and references example documents from ve.dm.example.js
* Add createExampleDocument function
ve-mw/test/index.php: Runner for MW-specific tests only
ve-mw/test/mw-preload.js: Sets VE_TESTDIR for Special:JavaScriptTest only
ve.ui.Window.js:
* Remove magic path interpolation in addLocalStyleSheets()
* Pass full(er) paths to addLocalStyleSheets(), here and in subclasses
ve.ui.MWDialog.js: Subclass of Dialog that adds MW versions of stylesheets
ve.ui.MW*Dialog.js:
* Subclass MWDialog rather than Dialog
* Load both core and MW versions of stylesheets that have both
ve.ui.PagedDialog.js: Converted to a mixin rather than an abstract base class
* Don't inherit ve.ui.Dialog
* Rather than overriding initialize(), provide initializePages() which the
host class is supposed to call from its initialize()
* Rename onOutlineSelect to onPageOutlineSelect
ve.ui.MWMetaDialog.js, ve.ui.MWTransclusionDialog.js:
* Use PagedDialog as a mixin rather than a base class, inherit MWDialog
bullet-icon.png: Unused, deleted
Stuff we should do later:
* Refactor tests to use data providers
* Write utility function for SVG compat check
* Separate omnibus CSS files such as ve.ui.Widget.css
* Separate omnibus RL modules
* Use icon classes in ViewPageTarget
Change-Id: I1b28f8ba7f2d2513e5c634927a854686fb9dd5a5