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
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
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
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
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
* 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
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
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
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
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