icons, comment.*, ve.ui.Icons-*
* Added comment icon
ve.init.mw.ViewPageTarget
* Refactored editNoticeButton into being just a tool
* Added feedback tool, which shares the editNoticeButton code
* Added feedback object construction in init constructor
* Added launching code to feedback tool
VisualEditor.i18n
* Renamed editnotices-button message to editnotices-tool to match changes in code
* Added feedback tool message
VisualEditor
* Added dependency on mediawiki.feedback
* Updated changed message key
* Added reference to new message
Change-Id: I813c89a505386a9b3206bfbcb176016e28a592cb
* Made buttons use shared CSS code
* Stopped using <button> elements and got all browsers looking the same
* Fixed focus on text area issue - had to let the stack clear first
Change-Id: I6781916822b4173ba906b9bc4c341219fbf10d82
This was removed in I0873d906c058203b83b8d4bbe5a4b274f05a26fd because I had fixed another cause of the recursion - this is still needed however because the following still happens:
1. Link inspector is opened away from a word, so it goes into a mode that will insert text based on the chosen target
2. The link inspector is closed, causing a context change when the new annotated text is inserted
3. The context change event triggers the link inspector to close, leading us back to step 2
4. Browser dies in infinite loop hell
We may be able to fix this in a different way, like performing the document changes after the inspector has already closed by running it in a timeout. In any case, this works for now, and we can improve the design of this area of the code later on.
Change-Id: I7f3c17dad08521bb1ae7c2a1e8a4e21e2c4ba210
In the event the page explodes from a huge js error, prevent
the iframe from reloading to slightly reduce the confusion of the
user.
Change-Id: I0c88678437f0bad994fa97f4df63d8b288f69e7a
-Added reset and hide calls to deactivate to prevent problems
with the save dialog if the user exits to the view.
-Remove unneeded teardown routines from cancel.
-Calling deactivate without override.
Change-Id: I888019146186fb7cbc1ee2b8efee9a0c45286c23
ve.Range
* Rewrote truncate so that it works as expected, truncation should always reduce the length using the start/end values, not the from/to values
ve.ui.Inspector
* Added a comment about where the name argument to onBeforeInspectorOpen comes from, since it's a little bit confusing on first read (and I wrote it!)
* Calling onInitialize, onOpen and onClose methods directly, since we need to control the before or after-ness of listeners getting in there and doing their stuff - plus it's more direct
* Removed onRemove stub, which is never actually called
* Added before/after versions of initialize, open and close events
* Got rid of recursion guard since we don't need it anymore thanks to changes made in ve.dm.Surface (see below)
ve.ui.Context
* Updated event names to deal with new before/after naming of initialize, open and close events
* Removed fade-in logic since fading in doesn't even work anymore - since now we now annotate first, then open the inspector, the menu will actually exist and be open when we open the inspector even though you don't see it because it's quickly obscured
ve.ui.LinkInspector
* Made fragments non-auto selecting, in the case of onInitialize we actually call select(), which is silly since we were using an auto-selecting fragment - it's clear that this was a mistake
ve.dm.Surface
* Moved locking (polling stop and start) to the far outside edges of the change method
* I need a lot of eyes and testing on this change, it seems OK to me, but I'm suspicious that it may have side effects
* What was happening is that selection changes were being applied and then the poll was picking them up, and then the selection was coming in again as a change, but it wasn't a change at all, it was just feedback - this change event was then closing the inspector the instant it was opened - the odd part was that this only occurred when you selected backwards, which seems to be caused by the range being normalized, so it looked like a new selection even though it wasn't
ve.dm.Document
* trimOuterSpace from Range didn't consider annotated spaces to be spaces, by using the [0] trick (first character of a plain text character string or first element in an annotated character's array both are the character's value - but elements don't have a property named '0' so it skips those safely as well) we can always get the right value for comparison
Change-Id: I0873d906c058203b83b8d4bbe5a4b274f05a26fd
Solution: do not call update (temporary solution to prevent error - however content will never be at offset 0 - so it should never hurt)
Change-Id: I9ed6f9fbea23d5e2e55c56f8483321442049bd51
Turned saveDialog-body into slide-based swapper.
Moved footer into saveDiaog-body so that the license text doesn't
stay under the diff-slide (and move body bottom padding to foot
top)
Wrapped buttons and title in a saveDialog-header and converted
closeButton from absolutely positioned to a floated layout.
This way the title doesn't need to be repositioned but will scooch
over if the prevButton gets shown/hidden.
Update API "diff" action to include table wrapper and table
header. Without it the mediawiki CSS for diff doesn't work
properly (needs colgroups for proper width of the "-" and "+" column etc)
Renamed -saving class to -disabled for consistency.
Set prop.disabled to really lock/unlock buttons, not just visual
(otherwise the click handlers are still triggered on click, can
potentially cause actions to be triggered when not expected)
Using a ve message for "Show your changes" title instead of
re-using core tooltip-savepage in a different context.
Diff slide triggers "auto width" on dialog (inline undo of width: 29em), keeping min-width, to allow it to expand as wide as needed.
Functions that I copied as base for onShowChanges and
onShowChangeError had some incorrect argument descriptions. Fixed
in both.
Note:
* Pass function to .off(), so that only that one is unbound
instead of any "resize" handler on the page (by other extensions
or gadgets or core)
* NB: ve.bind ($.proxy) preserves internal guid, so that $.Event
can find the bound function by the original reference.
* keydown has an anonymous function, should either moved to
prototype or namespaced, did latter for now, save enough and
better than destructive .off('keydown')
Change-Id: I9d05ef6e3e2461bdcf363232f7b0fbad5e24f506
We got lucky - the fact that our alien styling choice required phantom overlays had the nice side-effect of preventing the ability to focus the aliens. Therefore, as soon as we started ignoring IE to deliver nice alien handling for standards-compliant browsers, we inadvertently solved(?) the IE alien problem. I've touched up the styling to look nice in IE 9 (solid green phantoms) and IE 10 (stripes). Shield GIF switched to PNG because IE 10 renders the transparent GIF as solid red. Yeah, red.
Change-Id: I3bc69acba9ed883a823cdf722117b90966bc332b
This solves 2 issues:
1. Paste scrolls to the top of the editable box because we temporarily moved the focus to the paste container, and then moved it back. We solve this by saving/restoring the scroll position.
2. Scroll position adjusts vertically when pasting (using key repeat) because we handle pastes with a setTimeout and multiple paste jobs will pile up before they can be finished. We solve this by disallowing paste until we are done handling the previous one. In the case of key repeat this only is observable as slowing the repeat rate.
Thank you Christian for helping me solve this the old fashioned way - by sacrificing features you don't really need!
Change-Id: I75bcf9843b57cdff0db9b6dea62d66d4d76ac011
ve.dm.Document
* 2 of the 3 paths of getSlice still returned arrays instead of ve.dm.DocumentSlice objects
ve.ce.Surface
* Translate the range using the insertion transaction and truncate it, so the cursor ends up just after the pasted content
Change-Id: If7bae5e254ec84a847c1d3527f74d9c09c2d82b4
ve.ce.Surface
* Switched to using getSlice instead of getData in copy and paste handlers
* Added try/catch which attempts to build a transaction with the unbalanced data first, but falls back on the balanced data otherwise
ve.dm.*Node
* Added default style attributes (now used by ve.dm.NodeFactory)
ve.dm.Document
* Fixed bugs in fixupInsertions where parentType was being set with an object rather than a string
* Made use of getDataElement
* Added adoption capability so that inserting a</h1><p>b into <p>c[cursor]d</p> results in <p>ca</p><p>bd</p> rather than throwing an exception
* Renamed getBalancedData to getSlice, now retuning a ve.dm.DocumentSlice object
ve.dm.DocumentSlice
* Introduced new container for balanced data and a range of the original context - useful for copy/paste
ve.dm.NodeFactory
* Added getDataElement method, which uses default attributes to create a boilerplate version of a data element
ve.dm.Document.test
* Updated getBalancedData test to be a getSlice test
demos/ve/index, VisualEditor, test/index
* Added references to ve.dm.DocumentSlice
Change-Id: Id9269a29e51ca213508de8f155d3feec5e5b0774
The fix for bug 40339 supposedly modified when we emit contextChange events so that when the node changed, even if the context was the same, we consider it a context change (such as changing the heading level).
Unfortunately I was mentally absent when I wrote the patch and all it actually does it emit more select events.
Basically cb4877b0d0 - which does indeed fix the bug - doesn't do what it's commit message describes, but this fixes it.
Change-Id: I99d74f9ab0ddec15df41320389fe83de9b8b8d1e
* Decode titles we get from Parsoid
* Encode titles we give to Parsoid
* Preserve the original encoded title if nothing meaningful changed (a.k.a. do not normalize unless we must)
Change-Id: If5d22e88904d6b2c438caac403ac2d78d440b017
* Don't show at all if user isn't logged in
* Use "watch pages I create" and "watch pages I create" prefs
* If the user is already watching it, use that
Also updated relevant onMakeGlobalVariablesScript hook,
it was using old globals still, the hook has context as
of MediaWiki 1.19.
Change-Id: Ic3daf32505a745b3cccd0663a03bbf7f3885be84
Since model.change now starts the surfaceObserver, a problem manifested where the surfaceObserver was observing the $('#paste') element (used for capturing and sanitizing pasted content from external sources). Simply switching the order of the transaction and the documentNode focus fixed the problem.
Change-Id: I1b542b546d7f3d97e2e954ca4b51ca74232b2877
* Reusing deactivate method to recover from load error
* Made deactivate resilient to some properties not being set yet (so we can call it on load error)
* Restoring save dialog state after save error
Change-Id: I6a697dc6bddeebecf4e2ab26805bee9f3754c714
Logic taken from EditPage::getCopyrightWarning, but couldn't use
it directly because it doesn't give the message keys and wraps
the html.
Using the same logic and running the same hook, we'll get the same
message keys (and message parameters therefore) as EditPage would.
Also fixed these bugs (as they were more prominent now):
* Use Message::parse() instead of Message::plain()
* Set inLanguage properly instead of using the default
(EditPage is user-localised, including this message, just like
the rest of VE).
Fixes bug 42764: minoredit/watchthis should be in user-language.
Change-Id: I84fee641162cdeed290092e56fb0e1d2562d833d
The converter was misbehaving when handling <p>s inside <span>s. This
can't be expressed in the linmod, but it would try to anyway. <span><p>
would result in too many paragraph closing elements, leading to an
exception in ve.dm.Document complaining about unbalanced input.
<span>\n<p> would result in an exception in the converter itself while
trying to perform whitespace preservation on the newline.
This change makes the converter detect these scenarios and alienate the
offending node. So <span><p>Foo</p></span> converts to a wrapper
paragraph containing an alienInline whose HTML is "<p>Foo</p>" and which
is annotated with a TextStyleSpanAnnotation.
ve.dm.Converter.getDomFromData():
* Change the criteria for alienBlock vs alienInline
** Only infer from the node type if we're in wrapping mode AND we're at
the same level where the wrapping started (wrappingIsOurs). If the
latter isn't the case, we can't split the wrapper in the block case
because we're at the wrong level.
** Use alienInline not only if the branch is a content branch, but also
if there are active annotations. This catches e.g. <li><b><p>
(and generally <span><p> on the top level).
* Before converting a child element, check that the child isn't "bad".
Bad children are non-content children in content branches, and
non-content children encountered within a wrapper that we can't split.
Only good children are converted, and bad children are alienated (cue
Santa/Sinterklaas jokes).
* Add childIsContent and rename branchIsContent to branchHasContent
Change-Id: If420ae80ab0777424a9a5517335ef9d0170e87ae
Since the link is generated by a MediaWiki message and as far as
I know, the target attribute cannot be added in wikitext.
Solution is to add the target attribute via jQuery in the
save dialog.
Change-Id: I4b6cdee64e7f8e3acb28b21c32c58254d63a8daf
Get rid of ve.ce.Surface.locked (and isLocked, lock, unlock) and instead introduce ve.ce.Surface.renderingEnabled (and isRenderingEnabled, enableRendering, disableRendering) which names are way less confusing and more specific. Also add use of isRenderingEnabled to ve.ce.ContentBranchNode.
Change-Id: I72e9e8f8dfbf43784d7e616369acc3e9649c715a
Initializing range var in SurfaceObserver to use this.range instead of null to avoid passing wrong information to onContentChange.
Change-Id: I1d4e3fa2393166dad887077529351a479401bf4b
With the introduction of ActionFactory, we lost selection restoration. I've re-added it in the HistoryAction methods.
Change-Id: I018f9a9f85f5ce081e3b56c0f52aba24bc24cec5
ContentBranchNode shouldn't rerender on update, only on childUpdate.
When deleting across an inline node, update was emitted after the splice
had occurred in the DM but before the spice event was emitted that
caused the splice to happen in CE, leading to detached nodes and
associated sadness. See the bug for more details.
Change-Id: I2d44231b6e27efdb3f12967556cff174d9364d25
ApiVisualEditor
* Reverted some of I223235a6ea8b4178c50beeaaedb709b2de7cf0b5 turned out to be full of problems - the race condition is only relevant to getting the HTML
* Fixed check for $content to be false before it was defined
ve.init.mw.ViewPageTarget
* Reverted some more of I223235a6ea8b4178c50beeaaedb709b2de7cf0b5 - wgCurRevisionId is not equal to oldid, it's equal to $title->getLatestRevId() - this was causing lots of oldid problems
* Added use of restored message
* Made save button not locked when using oldid
* Customized save buttons depending on oldid
ve.init.mw.Target
* Reverted even more of I223235a6ea8b4178c50beeaaedb709b2de7cf0b5 - we don't want to keep a copy of the wgCurRevisionId at all, we just want the oldid if it was given
VisualEditor.i18n, VisualEditor
* Added restored notification and restore save button label messages
Change-Id: I8b30c2a153911f44643e369b7c6a9b89c0fb2c5b
* Fix 404 error for ve.ui.Icons-{raster,vector}.css
Follows-up 9563f08 / I840f72426f9a.
makeStaticLoader.php:
* Clean up old code.
* Error out early for missing module.
* Put i18n stuff in the right place
(some modules access ve.msg from the global scope to
assign status variables, for standalone on demos this was
failing due to wrong load order)
Change-Id: Idbff4c5136d567da747d9ae373cd2f6c3ee7fb1c
Rewrite VisualEditorMessagesModule:
* Replace copy-paste dump of user-css module with stuff for
VisualEditor (class commend and module::$origin).
* Remove duplication between getMessages and getScript.
* Actually implement getModifiedTime so that the comment in
getMessages() about cache invalidation is actually true
Fixes bug 42670: ext.visualEditor.specialMessages cache broken
ve.init:
* Implement addParsedMessages and getParsedMessage so that we
don't mix up plain messages with raw html messages (minoredit
was previously overloaded in mw.msg storage with a parsed html
message and retrieved though ve.msg, which is documented as
retuning plain text, not raw html). This is now separated into
a different method.
* Improved documentation of the other msg methods to emphasise
their differences
* Removed redundant code in attachSaveDialog() that was
(partially) already done in setupSaveDialog() and moved the
remaining bits into it as well. Checked all callers of these and
they are both only called from ViewPageTarget.prototype.onLoad
* Also implement them in the standalone platform implementation,
with the html escaper based on mw.html.escape
* Update init.platform.getMessage to use undefined instead of
discouraged 'if-in' statement.
* Add test suite.
demos/test:
* Re-run makeStaticLoader.php on test to add ve.init.Platform.test
* Re-run makeStaticLoader.php on demos and update i18n caller
to use ve.init.platform.addParsedMessages (also moved out of the
auto-generated block for easier updating)
Change-Id: I7f26b47e9467e850c08b9c217c4f1098590de109
HTML DOM has annoying behavior for <pre>s where .innerHTML eats the
first newline in a <pre>. Work around this by explicitly adding a
newline in the data->DOM converter if the <pre> already contained a
newline.
There is a separate bug in Parsoid that causes the newline to be lost
anyway, filed as bug 42666
Change-Id: Ia26cd4a4c61afbe439b0562deb7f24ee8b8147d7
DocumentNode element loses focus when the context is opened.
When clicking out of the context into window, polling error
occurs.
Change-Id: Ie8f8af763d221c59e47e8c240653f8b817c26f64
ve.ce.Surface
* Used getModel() as per TODO
* Simplified code by pre-calculating 2 statements that were being used 4 times each
* Re-structured logic so that simple insertion and deletion are only possible if next and previous have a range, triggering complex change otherwise
* Added some documentation
ve.ce.SurfaceObserver
* Added checks for whether rangy found a branch node within the document or not before accessing it's node via .data() and made it so we are only performing DOM > document range conversion if we did
* Removed some commented out code
Change-Id: Iaaf30a5b201710ab4235e775f18808a8d512f1f9
ve.IndentationAction
* Fix incompatibility with working with multiple nodes by using surface fragments
* Bug was caused by unindent causing rebuilding, which for all groups other than the first meant their nodes were detached and broken
ve.ListAction
* Employ unindent in a loop to remove all list levels
This is all still a bit hacked together, the use of surface fragments saved us this time, but we need to refactor this code. Badly. Next year.
Change-Id: Idddef35230b04d64cf8338d53bbab730fadec2fc
This will prevent inline alien phantoms from appearing while dragging. This was a usability enhancement identified by Inez/Christian.
Change-Id: Idf046db72e25875e899f5926ab7d50d2f514586b
Detecting contextChange events was making assumptions about the previous state, and causing a mess of problems.
Solution: detect contextChange events in a smarter way.
We also now emit contextChange event when moving to a different node. This helps fix other issues because it's possible for the selection to be the same, but the node at that range to change, and that's a context change for sure. Example would be changing the heading level.
Change-Id: I99d6fa94fae76aa940077abc9b5beacd38eb7b0b
This prevents memory waste when switching between read and visual editor tabs, which happens entirely on the client.
Change-Id: I31b50accac38d72a9367b9035504552dc0150104
Which for now is just "not when creating a new page". This is
already strictly enforced in the MediaWiki backend through EditPage.php, but not reflected in the Save dialog of VE yet.
Now the checkbox for Minor edit matches the logic for EditPage.
Change-Id: I9c659845feebb3e9bbf8e13ee67be27c6adb4321
Use mw.config wgCurRevisionId for oldie instead of uri query.
That way it also set on regular views, and as a bonus it the
normalised value (e.g. if on a page with oldid in query but the id
doesn't exist or is somehow invalid, it won't use it).
Centralise page existence logic in JS and rename Target.oldId to
Target.pageRevId (to further indicate that it is always set, not
just on oldId views. To detect an oldId view, do a boolean check
on value from currentUri.query.oldid directly).
In PHP Api, move oldid logic to execute() method instead of
locally from the getHTML call. That way it is always set, avoids
hitting this bug in other methods instead of just getHTML().
Since the mw.Target constructor now retrieves the ID from
mw.config directly, the second argument was removed.
Change-Id: I223235a6ea8b4178c50beeaaedb709b2de7cf0b5
Had to make the retrieval of the Save dialog html template
asynchronous due to mw.user.getRights being asynchronous.
Entire block indented, ignore whitespace changes.
Also:
* Fixed 2 cases where ve.msg value was interpreted as HTML
instead of adding a text node directly.
* Alphabetically sorted the dependencies (after adding
user.options and mediawiki.user).
* Removed redundant inline jshint comment, multistr is already
tolerated from the central .jshintrc file.
Change-Id: Ie09bb5c8bdbfbb3ec0d4983b74d0697b941153e0