Summary:
Instead of having a button "Review and save" that opens with a
diff and leads the user to the "Report a bug" and "Save page"
slides respectively, make it more like the default EditPage.
There is now a "Save page" button that opens with the save
form with a button to "Review changes" (diff) or "Save page".
The "Report a bug" slide has been unlinked from the UI and is
no longer accessible for now.
As a result of the UI no longer requesting a diff upfront this
also means we will no longer detect "nochanges" event (when it
turns out the submittted revision matches the latest version).
This is unfortunate as it was a nice feature to detect it
before the user spends time writing the edit summary) but it
is the same as how the default EditPage works.
Changes:
Improved interface messages.
Adapted "nochanges" caption to the new context (it is no
longer shown when clicking "Save page", it is now shown as a
result of clicking "Show changes").
Now that the "save" slide is accessible from multiple paths
it is needed to keep track of slide changes in a history
array. Previously the slide tree was 1 level deep with
everything descending from "review". Now it starts at "save"
and can go in multiple directions including a loop from
save>review>save. We also need to toggle the "Prev" button
based on history instead of based on whether or not we are
on the "first" slide.
Hid the "saveDialogReviewWrongButton" from the review slide.
We're approaching wider launches and this will not scale to
a wider audience.
Bug: 49258
Change-Id: I90de95f6337eeddd794b75d56543d8d152421a6f
Allow block images to be resized by mixing in ResizableNode.
Made transitioning optional, and disabled it for block image nodes.
Change-Id: If89948d285ffb5efb104c44cbc9553a3d56f52e7
Objective:
* Allow inserting images from local wiki and commons
Changes:
ve.init.mw.ViewPageTarget.js
* Add media insert button to toolbar
ve.init.mw.Platform.js
* Add getMediaSources method - defaults to local wiki and commons
ve.ui.MWMediaInsertDialog.js
* New dialog for inserting media
* Uses a media select widget and inserts block images
ve.ui.Dialog.css
* Added styling for media select widget in media insert dialog
ve.ui.Widget.css
* Added styles for media select widget and media select item widget
ve.ui.MWMediaInsertButtonTool.js
* New tool for inserting media
ve.ui.MediaSelectItemWidget.js
* New item widget for media select widgets
ve.ui.MediaSelectWidget.js
* New widget for searching for and selecting media items
ve.ui.TextInputWidget.js
* Added isPending method
VisualEditor.i18n.php
* New messages for media insert dialog
VisualEditor.php
* Added links to new files and messages
PhantomJS--
Change-Id: Ia803ff3ef518782ce76802d2dab7559686a1bb0a
ce.ProtectedNode doesn't like to be torn down when it's detached,
and this was happening to CE nodes created in the MWReferenceList.
Hack around this by attaching the CE nodes generated by the
MWReferenceList to the ce.MWReferenceListNode (so they have a
parent and a way of getting to the surface), and by guarding against
multiple successive setups/teardowns in ce.ProtectedNode.
Change-Id: If00e75b939ccbdbaf681bbb6609fec54805bf9a0
It is easy to exit the list at any given point by using the toolbar
button or pressing enter twice while at the end of the list.
Change-Id: Ie34300fc13a4548e283348ef58c88ce420fbe0c1
ce.GeneratedContentNode had an interesting bug where it called .append()
directly on DOM elements stored in the store. They weren't cloned,
which meant the previous rendering of the same node would just disappear,
and they also weren't adopted into the correct document which would
probably have caused other issues as well.
Properly clone and transplant the nodes from the store before attaching
them to the DOM.
Change-Id: I423db85cb7c3851a9bf68de03c72aa22994d9474
Because scroll events cannot be canceled or prevented from bubbling
up, the only way to prevent the scrolling is to cancel the actual key
and mouse wheel events.
PhantomJs -= 2
Change-Id: I540738459181c37d11caf5db07345703e7000ef9
This is mainly used for testing blacklisted browsers, so we just need
one parameter ('vewhitelist') which sets whitelist to true and
blacklist to false.
Change-Id: I38771ba7a49657d67c4d94ace1f30b5e41904df6
Objective:
* Make all text inputs have the ability to be "pending", not just ones
with a special mixin
Changes:
* Delete pending input widget
* Move pending input widget implementation to text input widget
* Update all uses of pending input widget
* Make pending image a reusable "texture"
* Update styles of text input widget for pending state
* Get rid of checking for mixin since all text inputs can be pending now
Bonus:
* Get rid of unused images, including .psd and .ai files
* Add transparency texture
* Fix input widget not using documented config value
* Fix documentation in select widget (lies!)
Change-Id: Ib46ab01dc39d706e5c25fd473dee0edce51b7e44
Browser history state:
* Listen for popstate, if veaction is different, act on it
(by calling activate or deactivate).
* When switching to edit mode, push veaction=edit.
When switching to view mode, push non-veaction.
Except if the switch was made by the popstate listener in
which case we don't want to push again.
Clean up:
* Use document.location.href instead of odd location.toString
Don't pass it to mw.Uri from the original one since it
takes the current url by default.
Bug: 43844
Change-Id: I5c345c1526852a84b04436955845bf1b56d94402
Merge methods:
* transformPage: transformSkinTabs + hideSiteNotice
* restorePage: restoreSkinTabs + restoreSiteNotice
Callers now consistently do both (e.g. #tearDownSurface only
called #restoreSkinTabs). This is also in preparation for
bug 43844.
Removed call from #tearDownSurface as that method is only
called from #deactivate which already calls #restorePage.
Clean up support check:
* Rename supportsStrictMode to supportsES5. Though the feature
test asserts strict mode, we use it to check support for
ES5. VisualEditor doesn't particularily care about strict
mode itself.
* Reverse support if-statemement to return early instead of
wrapping everything that follows. This makes it easier to
see that we intent to abort if the current environment is
known to be problematic. Also easier for code later on
by not accidentally falling outside this block
* Follows-up aaa5ad254b.
Change-Id: Ia4b949d9c066a3f7b07217aa3d51de9908734e85
This makes the 'category' section of the meta-data panel less lonely, and
prompts us to actually do this at some point quite soon (or encourage others
so to do).
Bug: 48814
Change-Id: I5b8fdfb78a2117839277a683db47fe97107d87b0
The update() method wiped out the entire contents of the node, including
the shield that makes ce.ProtectedNode work. Fixed by only wiping out and
reconstructing the contents of the <ol>
Change-Id: Ib2978a72939884be67964ce8a3d89a570f70bfa3
The previous fix didn't really work, because the notices are expected to
be an array elsewhere too. Better to just convert it to an array on the
spot. getObjectValues works with any kind of object (including an array)
so it's safe to use with either data type.
Change-Id: I03237b8624a0b980e5f70d54d55c662ffa460373
The easy part is getting the correct numbers from the InternalList
and generating the ordered list HTML. The tricky part is connecting
up the events to make sure the renumberings/list generations are
triggered when required.
InternalList can emit an update event on document transaction, which
triggers the renumbering/relisting if any references have been
added or deleted during that transaction.
ve.ce.MWReferenceListNode also listens to changes on the
InternalListNode (i.e. changes to the contents of the references)
and always triggers a rebuild.
Change-Id: I1b48ef5240e433c3b314259aa68cde13841ea98b
We now have three stages:
1. Browser feature tests. Dies silently if any fail.
2. Browser blacklist. Dies silently if match found.
3. Browser whitelist. Shows warning if no match found.
Previously we were treating the remotely generated
edit notices as if they were in an object when
in fact they were in an array - the code has been
fixed to reflect that fact.
As locally generated notices will typically require
parsed messages, we've also moved the notice rendering
to after onReady is fired.
Updated jquery.client to latest master from MediaWiki core
(needed for proper detection of Iceweasel, Android and Safari)
Bug: 38128
Change-Id: Idc5f4a23a2709264d869a91d00873c4e187bc470
Follows-up 2e76271 and 231a50f which made manual changes to
the static-loading files without updating makeStaticLoader
(thus causing the load order and if-statement to be out of
sync between different index.php files).
Updating makeStaticLoader to include those changes and applying
it to the other index.php file.
Change-Id: I9bbe97d85f663b1cffeb384d52b5cc54e2f6601b
This has no influence on Jenkins but can be used locally to
easily run certain tools. Since we already had `.jshintrc` in
our repo it was already possible to easily run JSHint from
the command-line locally. Taking that as a base the following
are new features:
* `grunt csslint`: Runs CSSLint on all css files
* `grunt qunit`: Runs QUnit (standalone) tests in PhantomJS
* `grunt test`: Runs jshint/csslint/qunit
* `grunt watch`: Runs the "test" command automatically whenever
a file is changed. You can keep this in the background so
whenever you save a file in your editor (e.g. Sublime Text)
it'll run the tests and if there is a failure, it'll throw a
bash error code causing your Terminal application to beep you
in whatever way your operating system does so (e.g. for
Mac OS X a red badge + jumping icon in the Dock). It will
continue to run in the background even after a failure so no
need to re-start watch after a failure.
* `grunt`: Runs the default task, which is 'test'.
Previously to use `jshint .` you had to:
* One-time install:
* install package -- nodejs npm
* npm install -g jshint
* Usage:
* cd VisualEditor; jshint .
Now, for grunt:
* One-time install:
* install package -- nodejs npm
* npm install -g grunt-cli
* cd VisualEditor; npm install
* Usage:
* cd VisualEditor; grunt
Change-Id: I7a4fdf4b6bf3f00cef15dc3e2c81eceb595aec7c
Adding a fairly loose .csslintrc file so that our code
passes it.
The following options cause warnings in our code and have been
disabled for now:
* adjoining-classes
> Don't use adjoining classes.
> .ve-ui-widget-disabled.ve-ui-textInputWidget textarea:focus {
* box-sizing
> The box-sizing property isn't supported in IE6 and IE7.
> box-sizing: border-box;
* box-model
> Using width with border can sometimes make elements larger than you expect.
> border: solid 1px #ccc;
> Using width with padding can sometimes make elements larger than you expect.
> padding: 0 0.75em 0 0.75em;
> Using width with border-right can sometimes make elements larger than you expect.
> border-right: 1px solid #eee;
* fallback-colors
> Fallback background-color (hex or RGB) should precede RGBA background-color.
> background-color: rgba(104,171,255,0.1);
* important
> Use of !important
> position: relative !important;
* outline-none
> Outlines shouldn't be hidden unless other visual changes are made.
> .ve-ce-documentNode[contenteditable="true"]:focus {
* qualified-headings
> Heading (h1) should not be qualified.
> .ve-ce-branchNode h1:empty:before,
* universal-selector
> The universal selector (*) is known to be slow.
> .ve-ce-protectedNode * {
* unqualified-attributes
> Unqualified attribute selectors are known to be slow.
> .ve-ce-documentNode[contenteditable="true"]:focus {
Fixes made:
* modules/ve/ce/styles/ve.ce.Surface.css:
[L66:C2] margin can't be used with display: inline.
* modules/ve/ui/styles/ve.ui.css: Unknown @ rule: @-ms-keyframes
Internet Explorer < 10 doesn't support keyframes. IE10+ supports
the standard property. I don't think ms-keyframes ever existed
http://caniuse.com/css-animation. ms-transform did exist
http://caniuse.com/transform.
Change-Id: I728a48e489c079e1c94a506bb00c245de9551eb6
Due to the "es5: true" jshint option we enabled, these
warnings were surpressed. I've disabled the option since
we no longer require it. It was enabled in 07c86fc to fix
a bug with jshint. This bug has now been fixed.
Change-Id: I55b7d031eb5581af5f733f050cf2ea98dacb2af6
Also keep items in the order they appear in the document
and grouped by group and key.
Additions and removals are triggered by the new root/unroot events.
Change-Id: Ia3e90ccfdab88f352b89992b90554e5f03ff9952
Clean up of logic implemented during the template-sprint:
* Store spec inside the content model, directly associated
with the content-part. This allowed fixing the bug where
two spec-less template invocations overwrote each other's
made-up template data due to it using "target.wt" as key.
The opener now provides the fetcher with a "specId" which
is set to "part/<id>" for wt-generated template targets.
* Batching is now implemented inside the fetcher instead
of outside. This allows calling "getTemplateSpecs" inside
the loop with a dedicated callback for each spec to store
it in the content.parts[i] object passed by reference.
It also makes it easier to use by different code paths.
You call it as much as you like and it will queue up
naturally through javascript yielding and then make a batch
request. This is based on the pattern I used in MediaWiki core
for mw.loader#addEmbeddedCSS.
Follows-up e7af635, da679b7.
Change-Id: I4d7121229d060a96d927585c987a1a81a474b922
This is a hack, in the future Parsoid will have a template re-expansion
API that will produce the correct result.
Change-Id: I328c11330fb3db71c51882717d6b84099c9270d1
unicodejs.js:
* add splitClusters(text) and splitCharacters(text) methods
unicodejs.textstring.js:
* change internal representation from a char string to a list of grapheme
clusters
unicodejs.wordbreak.js:
* change getGroup to work on the first character of a grapheme cluster
ve.js:
* Use new unicodejs.splitClusters function
Bug: 48975
Change-Id: I202b98199d2780534d1e02519b72579ba796f08f
Changes:
ve.ui.Widget.css
* Add styles for decorated text input widgets and their icon elements
ve.ui.TextInputWidget.js
* Add icon option which adds an icon before input text
Change-Id: Ib48d795391cb5d110e7dc05658d51129792dfc33
Objectives:
* Break template page creation into it's own method
* Get rid of styling being applied in JavaScript
* Fix styling issues
Changes:
ve.ui.MWTemplateDialog.js
* Add method for adding a template page
* Replace css calls with addition of classes for styling
* Cleanup of append calls
ve.ui.Dialog.css
* Make inputs in the template dialog full width and a reasonable height
ve.ui.Widget.css
* Swap margins with padding in labels to prevent layout issues
* Prevent textareas from being resized in safari/chrome
Change-Id: I4030d8605aad865251ecd0aeb8cc72d333bed6a4
Objectives:
* Refactor template dialog to support loading template data for, and
editing multiple templates and interleaved content in a template node
* Update template node model to generate multi-template wikitext
Changes:
ve.dm.MWTemplateNode.js
* Rewrite getWikitext method to work with multi-template formats
ve.dm.MWTemplateDialog.js
* Retain information about the node and template calls
* Break AJAX handler into its own method
* Attach event handlers to inputs directly so template values are
edited directly on the fly
* Refactor page building to support multiple templates
* Add multi-template support for template data API call
* Add support for editing plain text content
Change-Id: I92ff8a9e186701a3f8da88def92a5b7dcb607897
Objectives:
* Fix compareObjects so it doesn't break when given arrays
* Remove compareArrays
* Rename compareObjects to compare and update callers of both methods
Changes:
ve.js
* Loosen check for whether to recurse so both arrays and objects qualify
* Remove compareArrays
* Rename compareObjects to compare
ve.dm.MWTemplateNode.js, ve.dm.AnnotationSet.js, ve.dm.Document.js,
ve.dm.Transaction.js
* Update uses of compare(Arrays|Objects) to use compare
Change-Id: I7d4f7ceb28c0389f0157b7598e291f21393b5b85
* In getDataElementOrSlice(), we were slicing one too far
* When encountering a closing for an internal node, don't traverse
up. Doing this caused weird bugs, like inserting text where it didn't
belong in some cases an exceptions in others, but these issues were
parly masked by the off-by-one error in the data slice.
Change-Id: Ieda9afa95b7c1953d09e391774350a9b4148c2fe
Objectives;
* Cleanup the addPage API
* Add optional index param to addPage method
Changes:
ve.ui.MWMetaDialog.js, ve.ui.MWTemplateDialog.js
* Update uses of addPage
ve.ui.PagedDialog.js
* Bundle existing optional arguments into object
* Add index option for inserting a specific index
Change-Id: Idcef4d0a52fb817c7d888990920b2c12224a3392
This will make sure the marker moves correctly (backwards/forward)
in RTL languages as well as LTR languages, judging from the wiki pageLanguage.
This can be a quickfix until the movement can be decided per the direction
of the specific element (span/paragraph/div) the marker is in.
Bug: 38546
Change-Id: Ic01e110a5e6094cd275327a2e8cea90c900f1bd1
Making sure resize handle events are bound and unbound on focus, and that elements are created in the right window.
Change-Id: Ie90bb82aa6c81c372d76278dab3665bd49bf573c
Trevor tweaked the pixel grid snapping on my previous commit
but it appears that introduced some errors as well. The horizontal
lines in underline-a and strikethrough-s no longer have integer
x-coordinates, and on underline-u the whole object is offset
by (0.166, 0.166).
Bug: 47780
Change-Id: I51f2605e7d8e2bab1d641f02244d5cd24f505676
When you typed after a ProtectedNode that was previously at the end of
a paragraph, then moved the mouse, you'd get a JS error.
What happened was the typing caused a new TextNode to be created after
the ProtectedNode, which caused the ParagraphNode to be rebuilt,
detaching the original ProtectedNode and creating a new one. The
detached ProtectedNode was still bound to mousemove on the body, and
when that event fired it would try to remove its phantoms from the
surface and fail because detached nodes can't get to the surface.
Change-Id: I9f38776f0267645b14d7b26e2a25007cf3be8ec7
The only reason it doesn't save correctly right now is because Parsoid
doesn't serialize reference edits correctly.
Change-Id: Ia0f272c07cc28ee829372eb848f23aec99eb92f0
Add merge() methods to IndexValueStore and InternalList, which merge
another store/list in to the current one and return a mapping
translating old indexes to new ones.
Also add functions that, given such a mapping, traverse a linear
model data array and remap store/list indexes using simple logic for
annotations and node type-specific functions for node attributes.
Change-Id: I1e90755ced1a87c190947c037cf151c4d17cf8b7
A document slice is a document built from a data slice of an existing
document. It's completely separate from the original document and has
its own store and internalList. The new document's data also contains
the entirety of the original document's internal list. It's possible
to create a document slice of data located inside the internal list,
in which case the resulting document will contain that data twice (one
mutable copy at the top level, and one immutable copy in the internal
list).
ve.dm.Document.js:
* Optionally take an internalList in the constructor. This allows us to
create a document with a clone of an existing internalList rather than
an empty one.
* Add edgeMetadata flag to getFullData()
ve.dm.IndexValueStore.js, ve.dm.InternalList.js:
* Make these classes cloneable
Change-Id: I93e06f764ace16aee9df941b07f8c2bff1a28e2b
Getting & setting the cursor is done with byte offsets
instead of data model offset (characters) so we need to
be able to convert between the two as well as splitting
characters.
TODO: The regex only works on surrogate pairs, not
yet combining accents.
fixupInsertion will combine a combining mark with the
character to its left it it can.
Bug: 48630
Change-Id: I8d936fb15d82f73cd45fac142c540a7950850d55
Add teardown call to surface destruction in mw target, and
teardown listener to resizeable node.
Bug: 48530
Change-Id: I807a0f32d3d1eb490456d887f7bf867bdb896df4
MW meta is close to being moved out of experimental, but language
editing is not in line for the beta release.
Bug: 48561
Change-Id: Ie87a3c7dde2f29c3898c08d4cade5c0ba2f937dd
Also remove the exception thrown when we try to add an non-existent
toolbar button, as it may just be experimental and not loaded.
Change-Id: I0a60421f45d7a3941c510defc60d1fbf9469e784
Right now the internal list is very much HTML-based, so it's not
populated at all when creating a document from data. So hack this in by
specifying what should be in the internal list as a property of the
example document's data array.
Change-Id: I51c7b7b4dcd9fd3333777c1287b7ba544887aa32
Prologue:
Farewell ve.Editor my good chap… Oh, hey there HTML frames - I didn't
see you there! In a world where iframes are outlaws, and symbols like
document and window are global, there were more than a few assumptions
about which document or window was being used. But fear not - for this
commit (probably) tracks them all down, leaving a trail of
iframe-compatible awesomeness in its wake. With the great ve.ui.Surface
now able to be used inside of iframes, let the reference editing
commence. But there, lurking in the darkness is a DM issue so fierce it
may take Roan and/or Ed up to 3 whole hours to sort it out.
Note to Roan and/or Ed:
Editing references seems to work fine, but when saving the page there
are "no changes" which is a reasonable indication to the contrary.
Objectives:
* Make it possible to have multiple surfaces be instantiated, get along
nicely, and be embedded inside of iframes if needed.
* Make reference content editable within a dialog
Approach:
* Move what's left of ve.Editor to ve.ui.Surface and essentially
obliterate all use of it
* Make even more stuff inherit from ve.Element (long live this.$$)
* Use the correct document or window anywhere it was being assumed to be
the top level one
* Resolve stacking order issues by removing the excessive use of z-index
and introducing global and local overlay elements for each editor
* Add a surface to the reference dialog, load up the reference contents
and save them back on apply
* Actually destroy what we create in ce and ui surfaces
* Add recursive frame offset calculation method to ve.Element
* Moved ve.ce.Surface's getSelectionRect method to the prototype
Bonus:
* Move ve.ce.DocumentNode.css contents to ve.ce.Node.css (not sure why it
was separate in the first place, but I'm likely the one to blame)
* Fix blatant lies in documentation
* Whitespace cleanup here and there
* Get rid of ve.ui.Window overlays - not used or needed
Change-Id: Iede83e7d24f7cb249b6ba3dc45d770445b862e08
The spec you link to appears to not correlate to the real world.
Firefox has a value of 0x2E (46 in decimal) store for this, and
both FF & Chrome report that value in my tests.
Change-Id: I4b0d4d27448587ca7381c640d6d3949402305656
* VisualEditor.hooks.php
** export URL to magnify clip as a configuration variable so thumbnail image can render correctly
* ve.ce.Surface.css
** add CSS styling to make image captions look the same way in edit mode as they look in the view mode
* ve.ce.ParagraphNode.js
** add CSS class ve-ce-generated-wrapper if it is a generated wrapper
* ve.ce.MWImageCaptionNode.js
** make image caption rendering match the view mode
Change-Id: I0cd1b25e8f8355e0500aabc90e7c4cdf591545f3
On wikis where certain "topicons" exist the toolbar showed a
weird blank space pushing the entire toolbar down and
ve-ui-toolbar-actions to the left.
Bug: 48734
Change-Id: Ic5f73ac1eb8c41b891dd1c67b71795cb6c456141
Previous check wouldn't make sense, cause the last offset in the data
could be that one that makes data balanced (and j is increased always
after iteration).
Change-Id: Ie9498d0ac9e3417d09b8b3043bf3281e7dfbf9db
Relying on any native implementation of window.KeyEvent is
unreliable. The two specs listed in the comments for this method
are not the same and Firefox now has DOM_VK_ENTER and
DOM_VK_RETURN which are equivalent to 13 and 14 respectively.
The key on the right side of my home row triggers 14 using
native window.KeyEvent in Firefox, where Chrome uses our
defined constants and returns 13. This fix ensures the same
values for all browsers.
Change-Id: I12b2f5d674bdf13526577cb81d0505b608f2846c
Don't suggest a "new page" (redlink) for values that are
strictly different but the same as a suggestion according
to mw.Title (e.g. input "foo" with an existing "Foo" page
should not suggest a redlink to inexistant page "foo").
Bug: 48476
Change-Id: I66f5fc56554984af58d6223dc6cd76b3ab9940bd
Fetch
* Added basic name expansion logic since bug 48663 is not yet
resolved in Parsoid.
* Fetch info from template data API.
Clean up (follows-up 97157a1c, de203cb8, 718db58)
* Remove redundant initialize method.
* Pass the entire target object to #getTemplateData
because `target.wt` is *not* the template name.
* Reorganise #createPage to be more logical and rename
to #createParamPage.
* Add todo comments for things currently missing.
* Implement error handling of promise to prevent UI from
going stale if the promise is not resolved.
* Fix documentation in ve.ui.MWCategoryInputWidget.
Change-Id: Ie0114a81eead86d7a3b3e3a7a5b10d25c457b524
If the commit message is empty we show a warning, and if the warning
is already visible we allow the user to proceed.
Bug: 47752
Change-Id: Idba707abaea8b08a94f7fa4d5bc5b1e35261a572
We need to listen to the same events as bytelimit. Specifically
we were missing keyup, which meant the counter could get stuck on
-1.
Bug: 47718
Change-Id: I3d4f3f8cd451bfb6acea19ee9baae7be60adcf15
Rather than using namespaced linmod attributes, store the preserved
HTML attributes in the .htmlAttributes property of the linear model
element, in a nested structure to allow for easier treatment of child
nodes. Also added attribute order preservation by storing attributes
as an object plus an array of keys.
ve.ce.Node.js:
* Remove html/* attribute synchronization. Doesn't make sense any more
because these things aren't in the attributes object any more. I don't
think it ever made sense because these attributes were never supposed
to be changed anyway.
ve.ce.View.js:
* Replace renderAttributes() with a simple wrapper around
renderHtmlAttributeList()
ve.dm.Converter.js:
* Add buildHtmlAttributeList() and renderHtmlAttributes() for building
and rendering HTML attribute lists
ve.dm.Model.js:
* Add getter for .htmlAttributes
ve.dm.Node.js:
* Drop .htmlAttributes on clone, and remove logic dropping html/*
ve.ui.MWCategoryWidget.js:
* Remove html/0/about hack, was already unnecessary and now doesn't
work any more
tests/:
* UPDATE ALL THE TESTS
Change-Id: I620573afd70d36ade6b80413075b6e1f4a435abe
Intercept badtoken errors, refetch the edit token from the
action=tokens API, and retry the request again. If this fails too,
show the error to the user.
Right now this just shows the good old confirm() dialog if the token
refetch fails; we should probaby give the user a clearer error message
telling them to refresh the page or something.
Bug: 42984
Change-Id: Ib43d1938ffa24bc8d1dc76a300e16e486dabd928
Add checks to make sure parts of the target are acutally
active before trying to tear them down or use them.
This fixes a couple of issues which appeared when the VE was
closed before it had a chance to finish loading.
Bug: 48520
Bug: 47813
Change-Id: Ide5def0e983bab49108b40008fc170957c7fc2a2
Objective:
* Context popup would stop opening sometimes "mysteriously" which ended
up having to do with the automatic closing on blur functionality
added to popups for use in the category popup widget
* Mousedown event canceling was being applied a little too widely, and
was causing popup widgets to not allow child elements to be focused
(unless they contained an iframe, like an inspector)
Changes:
ve.ui.Context.js
* Make use of the popup's show and hide methods within the inspector
ve.ui.MWCategoryPopupWidget.js
* Override autoClose option for category popup widgets
ve.ui.PopupWidget.js
* Add autoClose option to popup widgets
* Move event handler to the top of the methods (convention)
* Only bind blur event if autoClose is enabled
* Inline the getFocusedChild method
Change-Id: I22aedb5fbd51b327ea7ce2ecdd6123e79cbebb9c
Objectives:
* Make the context menu display in the top right corner of the currently
focused inspectable node (if there is one)
* Prevent clicking on anything to do with the toolbar or popup from doing
anything at all, ever
Bonus:
* While we are using the clever feature in jQuery's on method which allows
passing boolean false to cancel the event - may as well do that in
ve.ui.Dialog as well
Changes:
ve.ui.FocusableNode
* Add ability to specify the focusable element so that dimensions can be
derived from it
ve.ce.Surface
* Add quotes to object keys
ve.ui.MediaDialog
* Change association from being MW specific to handling images in general
ve.ui.Context
* Add embedded styles for context
* Add embedded mode, which is triggered when the context is a single
focusable node, and the node is large enough to fit the context
reasonably
ve.ui.Dialog
* Inline mousedown handler
ve.ui.Toolbar, ve.ui.PopupWidget
* Cancel stray mousedown events
Change-Id: I4b25d33f64b4bcb8a3ecfd7e9728f54a2d4886f3
When loading an image block node in the demo, there are no classes on the figure, which caused the code to crash because it was assuming that jQuery's attr method would always return a string.
Change-Id: Ib13e7bfa3fb2bd76ac71dfef085bed209d880b4a
Escapes }} and | by wrapping them in <nowiki> tags, and steps around
<nowiki> tags so as to not double-wrap things.
Change-Id: Ia50906524c1fcf55c9f390a114856bc7f20b2d3a
Objective:
* Add multiline option to text input widget which uses a text area instead of a text input
Changes:
ve.ui.Widget.css
* Add text area support for styles otherwise only targeting input elements
ve.ui.InputWidget.js
* Initialize input element using a method, so it can be fully customized (like making a text area or select input
* Use val() to set the initial value, using jQuery's abstraction around inputs of various types
ve.ui.TextInputWidget.js
* Add multiline option which uses a text area instead of an input
Change-Id: I1bf17c8c76b7f1708c57ee5e95160c071ddd00e9
The existing default sort key was being cached when the dialog was
constructed, but on the 2nd time launching it the reference was broken.
This change gets rid of the caching and always grabs a fresh copy when
we need one.
Also, the flag indicating the default sort key has changed wasn't being
reset properly.
Change-Id: I8fb3b088f25212b8c542df65bb5a248550ff6f27
Objective:
* Add button to launch template dialog
* Add template dialog
Changes;
*.php
* Add messages and links to files
ve.ce.Node.css
* Make inline templates display as inline-block to contain their
contents (allowing shields to work properly)
ve.ui.MWTemplateDialog.js
* New empty dialog for templates
ve.ui.MWTemplateButtonTool.js
* New template button, appears in context and launches dialog
Change-Id: I9174ed7c9012522246a6defc859276bf36763f5b
Surface can be deep inside a skin layout of which it is not
unlikely for one or more of the parents to have position
relative.
Change-Id: Ie202fa43b837650fd296fa6804d035622e2599e1
Objectives:
* Split ve.Surface into ve.Editor and ve.ui.Surface
* Move actions, triggers and commands to ve.ui
* Move toolbar wrapping, floating, shadow and actions functionality to configurable options of ve.ui.Toolbar
* Make ve.ce.Surface and ve.ui.Surface inherit ve.Element and use this.$$ for iframe friendliness
* Make the toolbar separately initialized so it's possible to have a surface without one, as well as control where the toolbar is
Some change notes:
VisualEditor.php
* Added standalone module for mediawiki integrated unit testing
ve.ce.Surface.js
* Remove requirement to pass in an attached container to construct object
* Inherit ve.Element and use this.$$ instead of $
* Make getSelectionRect iframe friendly
* Move most of the initialize stuff to a new initialize method to be called after the surface is attached to the DOM
ve.init.mw.ViewPageTarget.js
* Merge toolbar functions into setup/teardown methods
* Add toolbar manually (since it's not added by the surface anymore)
ve.init.sa.Target.js
* Update new init procedure for editor, surface and toolbar separately
* Move toolbar floating stuff to ve.Toolbar
Change-Id: If91a9d6e76a8be8d1b5a2566394765a37d29a8a7
Previously it was just being returned as the diff html, which
looked weird becacuse 1: it was the wrong width and 2: the
save buttons were still there.
Bug: 43754
Change-Id: I537bcae91f51a3f30ca4736c41f7a5619bbf321d
converter.documentData contains the full data with metadata interleaved,
but it was being sliced using offsets relevant to the element data.
Change-Id: Iddbef23212da818a2a399b4abdc223aad130eb4e
See: I6daff5c5969e5fdc871f8f346cf790b4302ae080
Objectives:
* Move ve.ui.Element to ve.Element
* Make CE nodes inherit from ve.Element
Changes:
ve.ui.Element.js, ve.Element.js
* Move and rename
* Move ve.ui.get$$ to ve.Element.static.get$$
* Add static getDocument and getWindow methods
* Add instance getElementDocument and getElementWindow methods
* Add getTagName method, which by default reads the static tagName property, but when overridden can return a tag name based on other factors
*.php
* Updated file link
ve.ce.*Annotation.js, ve.ce.*Node.js, ve.ce.View.js, ve.ce.Document
* Added config options pass through
* Replaced passing elements through constructor with defining static tag names
* Added getTagName overrides where needed that derive tag name from model
* Refactore dom wrapper methods, now consistently using getTagName
ve.ce.Surface.js
* Removed static initialization (not needed)
ve.dm.Model.js, ve.ui.Window.js
* Added missing docs
ve.ui.GroupElement.js, ve.ui.Layout.js, ve.ui.Widget.js,
* Updated class name for elements
ve.ui.Frame.js, ve.ui.LookupInputWidget.js
* Updated location of get$$
ve.ui.js
* Move get$$ to ve.Element
ve.js
* Add auto-init of static properties to mixinClass
Change-Id: I39ae14966456903728e4d9e53f806ddce9ca2b70
Objective:
Move toolbar floating functionality to ve.init and clean it up
As a bonus:
demo.css
* Fix CSS path to set width of inputs properly
Changes:
demos/ve/index.php
* Allow ve.init.sa.Target to construct it's own surface object
ve.ce.Surface.js
* Move object resizing and table editing disabling commands from ve.Surface
* Add method for getting the currently focused node
ve.init.mw.ViewPageTarget.js
* Remove initializing surface property (now done in parent class)
* Normalize all uses of "setup" to "setUp"
* Replace uses of getDocumentModel with getModel().getDocument()
* Add calls to set up and tear down for toolbar floating
ve.init.mw.Target.js
* Replace uses of getDocumentModel with getModel().getDocument()
ve.init.sa.Target.js
* Move example from ve.Surface
* Change constructor to accept document model
* Create ve.Surface object in constructor
* Add set up for toolbar floating
ve.ui.init.Target.js
* Initialize surface property
* Move and cleanup toolbar floating functionality from ve.Surface
ve.ui.Surface.js
* Remove example now that init.sa creates it's own surface (moved)
* Document options
* Simplify toolbar options and remove the concept of multiple toolbars
* No longer cache the options object
* Move toolbar initialization to constructor
* Change setupCommands to addCommands, making it useful after construction
* Inline selection initialization
* Move and cleanup toolbar floating functionality to ve.ce.Surface
* Reorganize a few methods
* Move toolbar floating to ve.init.Target.js
Change-Id: I393a426e35567d57c048122bf64a83c1ef45e6e8
We previously tried Rangy 1.3 alpha but rolled back due to a bug
with getting cursor position in IE. Rangy developer Tim Down fixed
the issue here:
https://code.google.com/p/rangy/source/detail?r=780
Both 1.2 (filenames without file versions) and 1.3 in the repo
for now.
Change-Id: I26263fc1d10e3c2bdda7f1c9135544ca3bc05d97
Objective:
Add a basic (empty) dialog for mediawiki references. Editor to follow.
Changes:
*.php
* Added file links and messages
ve.ui.MWMetaDialog.js
* Moved initialize method to the top (for consistent ordering)
ve.ui.MWReferenceDialog.js
* New class, basic empty dialog for references
ve.ui.LinkInspector.js, ve.ui.MWLinkInspector.js, ve.ui.MediaButtonTool.js
* Cleanup documentation
* Whitespace
icons.ai, reference.png, reference.svg
* Switch to reference icon being 3 books on a shelf
ve.ui.MWReferenceButtonTool.js
* New class, basic dialog button for references
Change-Id: Ia4e30e9239fa1e3b28c0a1ef1ca0a6515a8103ef
To do this, we take the document generated by the converter and
transplant things from the original Parsoid document into it.
Change-Id: I2f5058220669526130a360cec3389c3f42b41771
Fixes change made in I7a8d6c474ecca5af02b72b6453c900ed61acea58 by using
DOM_VK_ENTER instead of DOM_VK_RETURN (which is not defined anymore).
Bug: 48386
Change-Id: I8d7aeffc8166487806e3489b054f508c5e9418ff
The code to record the first/last child stacks was written before
I decided on using a recursive call going only one step when such
a stack was encountered.
As we only ever test the length of the stack most of the code around
calculating the stack can be thrown away, and all we need is a simple
test to see if we are the first/last child of the immediate parent.
Change-Id: Iffb03c649e166c9f89061a4d944fa07633f16aba
This is caused by a limitation of surface fragments in that they
always expand to include insertions touching them. In this case
we build surface fragments contain adjacent listItems, so when
the first listItem is de-listed a transaction is first created to
split the list. This insertion of ('/list', 'list') is adjacent
to the second surface fragment and so becomes part of that fragment.
This then causes the wrong node to be passed to unindentListItem.
The workaround is to use the inner range of the listItem, not
the outer range.
Bug: 48390
Change-Id: I7418910412d292ef4953e294a97f66e48d6f776f
If the previous commit properInnerHTML was renamed to
properInnerHtml, but its invocations weren't (a bug).
While DOM uses .innerHTML we use Html throughout the
rest of our code so we should be consistent either way.
Change-Id: If46bb256e938a097951c159b7a278667fd8e06a6
Objective:
* Add default sort key field to meta dialog
* Replace PagePanelLayout with a generic panel containing one or more FieldsetLayout elements
Changes:
*.php
* Added/removed file links
ve.dm.MWDefaultSortMetaItem.js
* Added getContent method
ve.dm.MetaItem.js
* Added replaceWith method
ve.dm.MetaList.js
* Allow insertion at the end by omitting offset and index
ve.dm.MWMetaDialog.js
* Added default sort key field
* Put category and default sort fields inside fieldsets
* Added loading/saving default sort key
ve.ui.PagedLayout.js
* Changed class used for pages to generic panel layout
ve.ui.PagePanelLayout
* Moved title/icon stuff to field set
ve.ui.FieldsetLayout.js
* New class, adds fieldset with legend
ve.ui.StackPanelLayout.js
* Moved up to the layouts directory
ve.ui.Dialog.css
* Moved style for paged panel from layout stylesheet
ve.ui.Layout.css
* Added styles for fieldsets
ve.ui.Widget.css
* Adjusted margins of input label widgets
ve.ui.MWCategoryWidget.js, ve.ui.MWCategoryPopupWidget.js
* Added setDefaultSortKey method
Change-Id: I979f5e3f08a688790c9f54086206ed1999af13ea
Rangy files are now 1.2 and I've added 1.3 alpha versions to make
it easier to switch between while testing.
Change-Id: I2f5d86b14bd4f87719d01e3255c28f0ae8764f4f
If we're in RTL mode and the skin is Vector-based, we need to reverse
the order of the tabs in the DOM, because that's a weird thing that
Vector does to render tabs in RTL.
See https://bugzilla.wikimedia.org/show_bug.cgi?id=46947 for discussion
about the Vector behavior.
Bug: 48017
Change-Id: Ie1214b08450aefed893739a2b862cb1e9b23a2ef
In stopWrapping we assign any left over whitespace to the paragraph
in position 3, however we weren't clearing this whitespace buffer
if an inline content node followed it.
Change-Id: I8b3ee3915044abd6bafda386430bf7f992ca4aa8
When the user presses Enter in an empty list item, we remove it. But if
the list item was the only child of the list, that leaves an empty list
which then gets a block slug, leading to all sorts of weird things, and
even pawns in Firefox. So check whether the list item was the last child
and if so, remove the list.
Bug: 48287
Change-Id: If22d9b904b8861e24d56944d791545635b2e4254
There is no need to call renderContents in ContentBranchNode constructor
because it is going to be called anyways in onSplice
Change-Id: Id1ab983668299658ecd6e89a37667cc34c701689
The way it operated was evil. It did a depth-first search from the root,
finding the node using reference equality. For documents with deep
structures, this could take a long time. Inez did some profiling and
found it was called tens of millions of times on a complex document.
Kill getOffsetFromNode() and move its functionality to getOffset().
The logic has been completely rewritten: getOffset() now traverses
up from the node rather than down from the root, and pretty much does
the reverse of what getNodeFromOffset() does. This should be much more
efficient even without offset caching in the node objects (which we may
still implement later).
Change-Id: I125f9fa423c40db6472e2c4a7c94214218ba3bc7
Objectives:
* Ensure items don't get moved to the end when their sort-key is edited
* Add placeholder text and pending styling to input
* Auto-expand input to the end of the line
* Make the minimum input width smaller
Changes:
ve.ui.MWMetaDialog.js
* Added calls to fitInput on initialize
* Fixed sort key update and insert handlers to maintain item position when updating
ve.ui.GroupElement.js
* Added index argument to addItems, allowing items to be inserted at a specific location
ve.ui.PagePanelLayout.js
* Fixed CSS class name
ve.ui.StackPanelLayout.js, ve.ui.MenuWidget.js, ve.ui.SelectWidget.js
* Passed index argument through to group element
ve.ui.PanelLayout.js
* Fixed overflow direction for scrolling option
ve.ui.Inspector.css
* Moved border-box properties to text input widget class
* Set input widget within inspectors to be 100% by default
ve.ui.Layout.css
* Updated CSS class name
* Whitespace fixes
ve.ui.Widget.css
* Made text input widgets's wrapper default to 20em wide and the input inside it be 100%, using border-box to ensure proper sizing
* Adjusted category list item and input styles to make input appear more like a category item
* Whitespace fixes
ve.ui.MWCategoryInputWidget.js
* Made category input widget inherit text input widget, rather than just input widget
ve.ui.MWCategoryWidget.js
* Replaced group functionality by mixing in group element
* Added fitInput, which automatically make the input fill the rest of the line or take up the entire next line depending on how much space is left
VisualEditor.i18n.php
* Adjusted placeholder text for category input
Change-Id: I79a18a7b849804027473084a42c36133fdacad57
The dom elements in the IV store are used for rendering, so if they
are sent by reference to the converter they get re-attached, causing
all templates to disappear from the page whenever you press 'review
and save'.
Fix is to run it through ve.copyArray, which clones all the nodes.
Change-Id: I1b03351a28ac82e0fdb7e94e761cf65d6548e501
Shields were being added twice. Switched the blank png to gif
because the red IE background couldn't be replicated. Changed
some styles from Alien to Protected.
Change-Id: I9c62665e4e0dc54b8511749b9d2a629db7990a16
init.mw.Target#serialize is an odd one because it is the only
target method that has a callback parameter (instead of
emitting the event on Target and having ViewPageTarget get
the event through that).
This line from onShowChanges needed to be added to onSerialize
// Invalidate the viewer wikitext on next change
this.surface.getModel().connect( this, { 'transact': 'onSurfaceModelTransact' } );
Though onSerialize is currently bound manually from the
serialize callback, it should be refactored to be like the others.
Bug: 44446
Change-Id: I9eddebbdf9294ee3d46286bdf1b157e00252d300
Factored the parsing of html/* attributes out into a static function.
Factored attribute (re)rendering out into ce.View, attribute updates
are much simpler now.
Change-Id: I4caa6d5e1e2c21c28ddff61c3c864e47f66cc6b2
For nodes that handle their own children (as well as leaf nodes and
meta items), store the first child's attributes in html/0-0/*, the
second child's attributes in html/0-1/*, the second element's third
child's fourth child's attributes in html/1-2-3/* , etc.
This obsoletes the ad-hoc code that basically did the same thing in
MWInlineImageNode.
Change-Id: If5abd2d5d9c361b359617ff4b0f3d6ba4c9b0142
We already do this in unit test so moving getDomElementSummary
and convertDomElements from ve.qunit.js to ve.js.
Apply ve.convertDomElements to report data before serialising.
Bug: 47948
Change-Id: Id807ccc6ff31d063be815ed4988cb35684adb76a
Store the HTML as a domElements array like everywhere else, rather than
as a string. Also disable HTML attribute preservation because there's
no point doing that when we're already preserving all of the HTML.
Also fixed a misnamed attribute (<li li="foo"> --> <li id="foo">) in
the test case.
Change-Id: I36bf8bade8118e07a75eb6f3a2427a00ef4915d7
We've housed these utilities for a while and changed some of
them quite a bit. Importing them to avoid regressions and
ensure we keep them in sync with our fork of it.
Removed references back through `@source`. They are sufficiently
different that the reference no longer adds any value.
Imported from https://github.com/Krinkle/K-js/blob/v0.1.2/test/K.test.js.
Change-Id: I9e71297246b7c248c1f032ba6b6ae1123519f3c1
It now allows you to specify which attributes to preserve in various
ways rather than just setting true or false.
Removed unused factory methods that exposed the old value.
Change-Id: I914164adcf1f0e48fa3fa85277e68c72dbad393e
The constructor doesn't use any parameter named "$resizable".
And the one usage of it (ve.ce.ImageNode) doesn't pass any
arguments.
Follows-up 3fe3032.
Change-Id: I30530f4199a7c8383933be286b7b7a705c05c26c
* It returned undefined instead of false if the subject
didn't have a 'mixins' property. This is because '&&'
is a DEFAULT operator, not an AND operator, it returns the
value, not a boolean per se.
* The logic of traversing to the constructor property was
broken since all objects in javascript have a constructor
property, and functions/constructors are also objects.
Follows-up Ic3e4472b9e694.
Change-Id: I462e7ce270c8cfc7e1970e359894ee4b7d90b881
Objective:
Generalize the shield and phantom magic, so we can use it for pretty much
any node we like. Usually this will be used with generated content nodes,
but also with aliens (of course) and possible other stuff in the future.
Bonus:
Also fixes a bug in DM that would crash VE when you selected to the end
and hit backspace.
Changes:
*.php
* Added links to files
aliens.html
* Added attributes to aliens to make them aliens again
ve.ce.AlienNode.js
* Moved shield and phantom functionality to ve.ce.ProtectedNode
ve.ce.AlienNode.js, ve.ce.MWReferenceListNode.js,
ve.ce.MWReferenceNode.js, ve.ce.MWTemplateNode.js
* Mixed in ve.ce.ProtectedNode
ve.ce.Node.css
* Reorganized styles and updated class names
* Added simple light blue hover with outline (using inset box shadow) for
protected nodes, same style as before for aliens
ve.ce.Surface.css
* Moved phantom styles to ve.ce.Node.css
ve.ce.BranchNode.js
* Moved call to setLive(false) to happen before detach() so that the
surface object is still available and events can be disconnected
ve.ce.BranchNode.js, ve.ce.Document.js, ve.ce.js, ve.ce.Surface.js, ve.ce.SurfaceObserver.js
* Adjusted CSS class names
ve.ce.Node.js
* Moved shield template to ve.ce.ProtectedNode
ve.ce.ProtectedNode.js
* New class, mix into another class to protect it from editing
ve.ce.RelocatableNode.js
* Renamed temporary surface property to relocatingSurface to avoid
confusion when debugging
ve.ce.Surface.js
* Moved phantom template to ve.ce.ProtectedNode
ve.dm.Transaction.js
* Fixed bug where most of the internal list was being deleted when the
end of the document was selected and the user pressed backspace
Change-Id: I2468b16e1ba6785ad298e38190e33493135719c3
A bug in I4bad882d1d6fb83bcdcfd0de3bfc9af52960c2ff caused the vertical
position to sometimes be NaN, and thus make the context in the wrong
place (but only vertically).
Change-Id: I5216af5c432caaa0fb400d8d006647b9f2488619
This makes it possible to use a static property to configure whether an
annotation should be applied to content added after it. This makes it
possible to do this for normal style stuff, but not for links.
TODO: Inez is going to add IE support for this since it inverts the
problem where the UI gets out of sync in all non-IE browsers to now make
it so it only gets out of sync in IE.
Bug: 48171
Change-Id: I5f279b06b098960be7bd4ad3f5e6f74b67e31d1a
Now comparing annotations in surface to insertionAnnotations
by comparable object to trigger pawn trick. Adding annotations
correctly to placeholder.
dm.Surface change method now uses setInsertionAnnotations()
and passes the AnnotationSet from offset-1. The set is cloned.
Added ve.ce.Surface.areAnnotationsCorrect() to compare either
annotations to the left or right to the insertionAnnotations.
Also use compareTo() and getComparableAnnotations() rather than
comparing by name, and fix SurfaceFragment.annotateContent() to
actually be selective when clearing rather than clearing everything.
Change-Id: I6116afa2e176daa0a0f2103a551501426829e2a6
Currently we just compare by store index, but a bold annotation
with data-parsoid attributes set should merge with a new clean bold
annotation. Similar rules apply to link annotations.
Bug: 48110
Change-Id: I93586919002c78732228e08b134e67e1a94f8ad7
For extension-specific types such as mw: , we require that all
types be matched. But we want MWTemplateNode to match
anything with an mw:Object/Template type, even if it also has
other types (like mw:WikiLink/Category in our test case).
Hack this into MWTemplate by matching on /^mw:/ then using
a matchFunction to assert that mw:Object/Template is in the
typeof attribute.
Update the test case. Because it's now a template, there's a bunch
of store stuff involved. Remove the other test case for about
group forcing because it's now a duplicate of this one.
Change-Id: Iacbe952a66d610c19b46bd76b84c50488857ac29
When converting an element that starts an about group with at
least one other element in it, we now only consider models that
support about grouping. This prevents the first node from being
converted to something else and leaving the others hanging.
In practical terms, this means that elements like
<link rel="mw:WikiLink/Category" typeof="mw:Object/Template">
get alienated and pull in the rest of their about group, rather than
being converted to a category or alienMeta or whatever and
leaving the other elements to be converted normally.
Added a test case that asserts this. Really the result should be an
MWtemplate rather than an alien, but that's a separate issue.
Also removed superfluous mustMatchAll checks; we've already
filtered the array by the time we get there.
Change-Id: I522ba4c56d5bc52c7e9aab1e2535385540c1315d
This was broken for both normal elements, where the meta item is
inside the element, and wrapper paragraphs, where the meta item
gets moved outside the wrapper.
Bug: 47712
Change-Id: I42daaf142e548e5b221ff0a52df0ad24ec6a4fd0
New ID is now passed from the API to the save event, to the onSave
handler. Empty diffs won't generate a newrevid.
Bug: 47420
Change-Id: I12ce27c8dc57f7aa753bcf5840635d5fea6b4e80
VE recreates the tab from scratch and deletes the old one
so as not to copy over access key settings. This fix
copies over classes from the old tab.
Bug: 47452
Change-Id: Ic2d42bb3034be25f388b587a00c3f523cfcc163c
The EventEmitter API we inherited from Node.js and then bastardized was
getting awkward and cumbersome. The number of uses of ve.bind was getting
out of control, and removing events meant caching the bound method in a
property. Many of the "features" of EventEmitter wasn't even being used,
some causing overhead, others just causing bloat. This change cleans up
how EventEmitter is used throughout the codebase.
The new event emitter API includes:
* emit - identical to the previous API, no longer throws an error if you
emit error without a handler
* once - identical to the previous API, still introduces a wrapper* on -
compatible with the previous API but has some new features
* off - identical to removeListener in the previous API
* connect - very similar to addListenerMethods but doesn't wrap callbacks
in closures anymore
* disconnect - new, basically the opposite of addListenerMethods
Another change that is made in this commit is mixing in rather than
inheriting from EventEmitter.
Finally, there are changes throughout the codebase anywhere
connect/disconnect could be used.
Change-Id: Ic3085d39172a8a719ce7f036690f673e59848d3a
The purpose is to flip the direction of the input inside
the link widget for RTL wikis, but flip it again to LTR
if the user inserts an external URL. This is my first VE
fix, I tried to follow conventions and avoid touching the
parent objects that are unrelated to URLs.
Bug: 47717
Change-Id: Ic13b9c3b155ce2979298cac9518c7419b9d45bac
.getClientRects() somestimes returns an empty collection which causes an
exception to be thrown by rangy. This corresponds to
.getBoundingDocumentRect() returning a hash full of zeroes.
Detect this and handle such ranges separately, by inserting dummy DOM
elements at the selection's beginning and end, then using their
position to determine where the actual selection was.
This behavior is seen sometimes in Opera, and in Chrome by using the link tool on text at the beginning of the document.
Bug: 47772
Change-Id: I4bad882d1d6fb83bcdcfd0de3bfc9af52960c2ff
Specifically by looking for "data-ve-changed",
"ChangeMarker*" and internal.changed.
Various tests, test counters and unused variables also
affected.
Bug: 45061
Change-Id: Ibd1ee68e0d650979d40574eff9cebded1a28499f
This changeset addresses a problem of pressing backspace in empty list item in order to merge it with list item above it.
Change-Id: I598da6ef24de97b0a7a7bbab6c9ee775aaab460b
Aliens now listen for surface model change events in order to
adjust the position of the phantoms.
Change-Id: I1e8bfba331a10678e9ca7e64b7818197237eb0a2
Modifications:
VisualEditor.php
* Added links to new widgets
VisualEditor.i18n.php
* Added placeholder text for category input
ve.ui.Widget.css
* Added styles for new widgets
New:
ve.ui.MWMetaDialog.js
* Create category widget with categories from dm.
* Listen to metaList for insert and remove events
** insert / remove bound methods to be improved upon additional meta groups
* Add listeners to mwCategoryWidget for new categories and updates
ve.ui.MWCategoryWidget.js
* Top-level category editing widget
ve.ui.MWCategoryItemWidget.js
* Items within a category widget
ve.ui.MWCategoryInputWidget.js
* Input for new categories, handles menu and API requests
ve.ui.MWCategoryPopupWidget.js
* Mini-inspector for a category item
Bug: 39597
Change-Id: I5eafaa484a1924a566d3a1ee1d869293089d0ecf
By making the API for adding/removing/clearing always plural, it greatly
simplifies the interfaces and reduces function call overhead in most
situations.
Change-Id: Ia8f23a373a01a8f6d5081587a591563e4f25ea42
ve.dm.Surface.js
* Allow manual truncation of the undo stack to prevent redoing something
that's been undone
Change-Id: I17534d6724fc2b325152cb2f665c6816f44232c1
Refactoring of externally sourced suggestions for text inputs.
*.php
* Added links to new file
ve.ui.InputLabelWidget.js
* Changed to focus input element, not wrapper div
ve.ui.InputWidget.js
* Fixed incorrect documentation
ve.ui.LookupInputWidget.js
* New mixing that abstracts placing a menu of options below a text input
and filling it with data from an external source
ve.ui.MenuWidget.js
* Fixed to get reference to input element, no wrapper div
ve.ui.MWLinkTargetInputWidget.js
* Moved pending and lookup functionality to mixing
* Implemented menu population using only matching pages, rather than a
combination of that and page existence checks (fewer API calls)
ve.ui.TextInputMenuWidget.js
* Added configurable container to render underneath, rather than assuming
this.input.$
* Added auto-position-on-window-resize functionality
* Fixed frame position correction to ensure that it only is used when the
overlay is in a different frame from the container to position
underneath
ve.ui.TextInputWidget.js
* Added placeholder text feature
Change-Id: If5ed1b64fd15982807691ce8bb0362970633108a
Remove all manual changes to SF ranges as these are not
undoable. Instead change translate range to default to
outer expand and build functionality around that behaviour
never changing.
As translate range is always outer I don't think we need to
check for start and end crossing over?
Added more undo tests to assert these selections are maintained
properly, and added the test case to 'update' for when and undo
point is overwritten.
Insert content now results in a selection over the inserted
content. Most usages were expecting this anyway and were
followed up with an adjustRange(-length,0) which is no longer
necessary.
Noticed that the link inspector case was never being triggered
as word boundary was always expanding to at least one char (mainly
for Hanzi selection). This doesn't make much sense as single
spaces get auto selected so removed this functionality.
Split collapseRange out into collapseRangeToStart and
collapseRangeToEnd as this may be required to get the old
behaviour (range moves to end after insert).
Change-Id: I3dc0b4d00d37bad1ca3076a69b41c5f0b3fa0570
Takes a path as input, reads it in and replaces the
"Generated by" sections and writes it back to disk.
:
Change-Id: Idd68032ba5b621958a353582ea994acd0c4cfbd3
instanceof Node doesn't work with nodes generated by the iframe hack
for some reason. Instead, use duck typing by checking for a .cloneNode
method.
>>> ve.createDocumentFromHTML('<body><tt>Foo</tt></body>').body.childNodes[0]
<tt>Foo</tt>
>>> ve.createDocumentFromHTML('<body><tt>Foo</tt></body>').body.childNodes[0] instanceof Node
false
Change-Id: I1ea1253bd204d1070cd01b666b8a90f1cb7e5e14
CSSJanus flips left for right for RTL languages. To ensure proper positioning of phantoms, the phantom container must actually be set to left:0, not right:0. Added the @noflip option before the phantoms selector to prevent CSSJanus from modifying it.
Change-Id: Id7662362d117d6c5719b9b98d7a0dbf62e9ba3ff
The toolbar has a high z-index when being floated, it doesn't need one
otherwise. This was causing an issue where the Vector actions drop-down
menu was being obscured.
Change-Id: I3c0ff7c4cf3b4a6c3d94f00ef56d7f299aeb6020
As jQuery hash problems in some cases converting HTML, it is
easier just to store the original DOM elements.
The bulk of this commit is fixing the tests as although we have an
assertion for comparing DOM elements, we don't have one for comparing
objects or arrays which may contain DOM elements.
ve.js
* copyObject & copyArray fixed to run cloneNode(true) on any item
of type Node.
* Added callback function so an object/array can be copied with
modifications.
ve.qunit.js
* Added deepEqualWithDomElements: Using the new copyObect/Array
callback, we can copy the incoming object and convert any nodes
to node summaries, then just run the normal deep equal comparison.
ve.dm.AlienNodes.js
* Instead of storing HMTL we store cloned DOM elements which we can
send straight back to the converter without any processing.
ve.dm.example.js
* Updated tests to expect DOM elements instead of HTML.
ve.dm.Converter.test.js
* Updated tests to use deepEqualWithDomElements
Bug: 47737
Change-Id: I3df8f49b170c31da9610129d53cf8cb65dd5d5f8
In this case, selectNodes() returns the paragraph, which is not a content
node, and so newFromContentBranchConversion() decides to do nothing at all.
This change makes newFromContentBranchConversion() more intelligent about
finding the content branch to operate on, fixing cases such as these
where selectNodes() returns the content branch itself rather than one of
its children.
Bug: 41203
Change-Id: I710fbf184ef5ef84d9c2f5bca2b115e0660f5b8f
fixUpInsertion now returns an object with both data and offset
which allows offset changes.
Within fixUpInsertion we lazy-generate first/lastChildStack which
is a list of parent nodes for which the current node is the first/last
child. Whenever we try to close off a node we check these stacks and
if they are populated we instead use a recursive call to start
fixUpInsertion again but with the offset shifted by 1.
Bug: 46799
Change-Id: Ic51dd03725c11f1f7e279929534ee3afea14d662
Previously, if we didn't know about a property type we would just drop it.
This led to various fixes to add support for booleans, nulls, etc. We're
now having problems again, this time with functions not being copied.
So instead of only copying types we know how to copy, deep clone the ones
we know how to and shallow copy the ones we don't know about. This seems
like a saner approach to me. Besides, it doesn't seem like cloning a
function is even possible in JS.
Change-Id: Idd1546ce3a43087a8b96a37101431e466e02f04f
The tests passed just fine in Gerrit, because it runs the tests via
MediaWiki using ResourceLoader, which was able to load jquery.client
just fine from MW core.
Change-Id: I004514ab761107b687be2fe1ff49ecfd25bead5b
Changed:
VisualEditor.i18n.php
* Updated Link inspector i18n messages
ve.ui.MetaDialog.js -> ve.ui.PagedDialog
* Moved paging functionality into Paged dialog
ve.ui.EditorPanelLayout -> ve.ui.PagePanelLayout.js
* Renamed from EditorPanelLayout to work nicely with the concept of
stacks and pages
ve.ui.GroupElement.js
* Added addItem method and change addItems to use it
ve.ui.Dialog.css
* Updated classname as per refactor of meta dialog
ve.ui.StackPanelLayout.js
* Set currentItem property on showItem
* In addItems method, show currentItem with class method
** rather display block on element
ve.ui.Layout.css
* Make editorPanel layout 100% in width.
ve.ui.Widget.css
* Added CategoryWidget and CategoryPopup styles
* Other adjustments
ve.ui.PopupWidget.js
* Added auto-close on loss of focus
* Made friendly with being initialized inside a frame
ve.ui.MWLinkTargetInputWidget.js
* Mixin ve.ui.PendingInputWidget and remove pending methods
* Prevent querying on spaces
* Reintroduce i18n messages for menu sections
ve.ui.MenuWidget.js
* Update cases of $input config property to input
New:
ve.ui.PagedDialog.js
* Refactored base-class for mwMeta dialog (and probably other dialogs
too)
* Abstracts adding and accessing pages
ve.ui.PendingInputWidget.js
* Moved pushPending and popPending methods into pending class
Change-Id: I29bcd92b7b5641941a4e98e65b2a56424a5263ff
Because we have a node for <table>, we also need one for <caption>,
otherwise we'll try to alienate it and fail.
Added the test case as a separate example document so Ed can use it
for his tests.
Removed test case asserting <caption> is alienated.
Change-Id: I3a917db58e6c0eb97899b214b07d01fc8d86b56d
Firefox fires key press events for arrow keys - but we handle them
already in keydown - so the solution is to just ignore those
key presses in the handler.
Change-Id: I1aff295a0958b75697c4d362e0d6095283f37fe8
Previously, they were only being deduplicated based on the transaction,
which meant that an undo was seen as a duplicate (but then if you undid
again, that wasn't a duplicate).
Change-Id: If432ea28e6c206a2ad5562e529e2d3ed808c20e4
Parsoid switched from <!doctype> to <!DOCTYPE>, which exposed the fact
that our dirty regex to detect whether we're dealing with a full
document or a fragment was case-sensitive. Made it case-insensitive.
Change-Id: Ia8a38488e06ca7d7a6fb9a9699b5d9b5c5eb03f2
Clearing by type in SurfaceFragment didn't actually work. Instead,
it followed a code path intended for setting and created an annotation
of that type with no data, then tried to clear that. What we really
want to do there is clear anything with that type.
This fixes the bug where unbolding of text that was already bold in
the article didn't work.
Bug: 47680
Change-Id: I77f00e63c8732420063b0453fede7f453083c913
In most places we call .contains we already know the index, so we
can avoid store lookups by using .containsIndex.
Change-Id: I45a9a421473f9bec479ab8ccceceb162b7004c3a
It is going to be used at least for figure tags for which Parsoid gives as a lot of CSS class names that are useless for rendering purpose
Change-Id: I4b1e8084a6b7ab5294e0c3cf153fc6cffb3e8dac
This is minimise the amount of data we need to serialise when
sending this over the wire.
The minimal IVStore data is added to the MW bug report, and
editedData fixed to only return the data array, not the full
LinearData object.
Documentation in AnnotationSet has finally been updated to
refelect the fact that it only stores Annotations
(was previous the generic OrderedHashSet).
getAnnotationFromOffset has been split out into a function
that just returns this indexes so that in cases where we
don't need the values we don't do an unneccesary store lookup.
Bug: 47318
Change-Id: I4819cf06d1bd0ae4f8b896052e278ca75c9551bf
Instead of calling $.append for every single char - buffer and call $.append only when really needed.
Change-Id: I53acfa795ea5dc6a8ca39ce11017daa85c9151d2
The fixUpStack is actually redundant code and closingStack
and openingStack handle all our cases. It was causing the
insertion to try to correct balance itself in the middle
of inserting two paragraphs, causing the creation on an
empty paragraph between them.
Added a test case for the fix and other cases to make
sure removing fixUpStack hasn't caused problems.
Bug: 46800
Change-Id: I35e54165709ac56e8116359a7c3b487eecf08ff7
Reuse the existing internal link annotation builder instead of using a
constructor directly, and incorrectly (it's meant to be passed an
element, not an attributes object)
Change-Id: I4cda6a9c3442cb10ebbc0844630fedba403adc91
* Only place them in a high z-index while resizing so they don't render
above dialogs and menus
* Add resize transition
ve.ce.ImageNode.js
* Switch from element attributes to CSS for setting dimensions
ve.ce.Node.css
* Add resizing class for resizable nodes for z-index
* Add transitioning class for resizable nodes for transitions
* Switch from border to inset box-shadow to not affect handle position
calculation
ve.ce.ResizableNode.js
* Add/remove resizing class while resizing
* Switch from using $image to $resiable to make the class useful for
non-image node
* Enable transition and set new dimensions before transaction processing
which will cause re-rendering)
* Delay transaction processing for resize until after transition is
complete
* Add hiding of context menu on resize start
ve.ce.Surface.js
* Add getSurface method so we can get to the context menu
Change-Id: I4667e394d0af4a80b651c2a0f6d11d30e196bf60
Redone using document.implementation.createHTMLDocument instead of the
iframe trick. It's supported by all browsers we target, including IE9.
This also makes VE work on Opera using a nasty hack.
* Previously, for reasons I'm not even trying to understand, Opera
would sometimes return an empty generic object from
ve.createDocumentFromHTML() - but only if you weren't debugging it
(Dragonfly was disabled). I have no idea what is it about the iframe
hack that makes it not like it, but fact is, it doesn't work.
* Calling .open(), .write() or .close() on the document returned by
document.implementation.createHTMLDocument acts as if it was
window.document - that is, the entire contents of the web page are
replaced with new ones. That's probably a one-word bug somewhere
deep in Opera's innards; I reported it (it got the identifier
DSK-384486). Until it gets fixed, we work around it by using
document.documentElement.innerHTML, which works reliably.
Change-Id: I90ea547c735edaba9f7ecb8f685351ac6499c53e
This involves setting some i18n messages for the target languages based on the
translations already provided - I hope this doesn't break anything for TWN but
the need for this only just became apparent; apologies!
Longer-term we will need to come up with a better way of doing this, if we are
keeping the in-VisualEditor feedback link around.
Change-Id: Id6ed80cdcd4314e84e75fb718421767162d73ef3
Parsoid is sending us some unescaped HTML in the data-parsoid
attribute. When we try to rebuild ref nodes (inline aliens)
this confuses Firefox which tries to sanitise the HTML by converting
<ref/> to <ref></span>.
As a temporary fix we can manually escape <>'s inside the
data-parsoid attribute.
Also in this commit the new MWReference nodes have been moved
to experimental as they are incomplete.
Bug: 47417
Change-Id: Ib6a0cfb880e769f28b42c9fa63ddc1abc75c399d
ve.ce.Node.css
* Added prefixes for use of box-sizing
ve.ui.MWLinkInspector.js
* Whitespace
ve.ui.Inspector.css
* Corrected input width, always 100% wide now by using box-sizing
ve.ui.DialogButtonTool.js, ve.ui.Context.js
* Updated use of getViewsForNode
ve.ui.ViewRegistry.js
* Added inheritance-based prioritization for matching views with annotations and nodes
Bug: 47413
Change-Id: I286a28002c1691e58bbd7de04ed08cceb8b3bb07
Using left and right arrow key to move to and over an image will
select the entire node.
Bug: 37870
Bug: 38129
Change-Id: I70deadd2c2707149ea33e3b8ee42fb0d8508aacc
This is showing a separate need for refactoring. We call
"this.serialize( ..., callback )" but if it failed callback
is never called and an event is emitter for the error.
That makes it rather disconnected from each other.
In this case we're lucky that all calls to serialize are similar
in nature and need the same kind of error callback but other
wise this would be pretty messed up. It obviously needs to be
untangled and get rid of this akward eventemitter dance.
This doesn't fix bug 47581, but it does fix the "Infinite loader
with no error" problem as a result of it by handling the error
in a more intuitive way.
Bug: 47581
Change-Id: Icdf64a792c13a326f494e051be47f2946928d142
iframe.contentDocument doesn't seem to have a key called 'document' at
all; I assume a different nesting was intended.
Change-Id: Ia37e3719d5247408bac2dfad1717d9193fb84c06
To help the selective serialiser we can return the original
HTML for generated content if it is unmodified.
As the output of toDomElements now depends on changes
to the dataElement we now have a 'modify' function in
the some test cases.
We also now have 'storeItems' to assert that the index-value
store is correctly populated and for loading values back
into the store for toDomElements tests.
Also make 'mw' an attribute and remove 'about' property.
Bug: 47394
Change-Id: I2bbb5d2d6a90c4eb87fa129671112c92a9b931e7
Turns out, the context property of a jQuery selection isn't always
there.
For example:
$( 'body' ).context === document
$( '<div>' ).context === undefined
Even if you later attach that div, so long as you have the old
selection around, the cached `context` property won't magically be
updated. This makes sense (although it's poorly documented in the
jQuery API) but causes issues for us, and pretty much makes the
context property useless.
Instead, we can just use the standard `ownerDocument` property,
available on all DOM elements.
This change also add support for passing in a DOM element directly, in
addition to the existing support of passing jQuery or Document objects
in.
Change-Id: Ib8a31b74f2a4f455b1318be9f5c7805a2a193c79
The 'add' tabLayout path is pretty basic and up to date. The
older (now active again) tabLayout 'replace' was fairly outdated
and unmaintained.
Fixes:
* Attributes copied from the original (except for the 'id'
attribute) were not actually beinged copied over because they
don't exist on the ca-edit list item, but on the anchor link
inside that list item.
* Clean up messages from the module registry that were unused.
Keys 'accesskey-ca-edit' and 'tooltip-ca-edit' were also inexistant.
* Add message keys for tooltip and accesskey of editsource tab.
Depends on I0bde1a228983c58b in mediawiki/core.
Bug: 47396
Change-Id: If598552fac639da645a8b1273c5fc6028695fcc1
Also add detection for whether the browser is actually broken (most are,
but some, like Opera, aren't), treat <textarea> and <listing> in addition
to <pre>, and fix a bug where the function would crash if the <pre> was
empty (because .firstChild was undefined/null).
Change-Id: I541b57e9fd5c9c42d19d0a59f6e29fb43d35c9b6
addSet:
* Instead of indexing items in the store, just union the indexStore arrays
removeSet/removeNotInSet:
* difference or intersect the indexStore arrays
filter:
* push indices into the result set instead of values
simpleArrayUnion/Intersect/Difference have been created as utilities
in ve. They are prefixed 'simple' because they use object keys to
do fast in-array comparisons. This means they are limited to string
values or values which will compare as strings (e.g. numbers).
Change-Id: I079cbdfece4f6d80ec0afd61959913f13217fcb3
By removing the transaction listeners from surface fragments we
no longer have to make sure they are always manually destroyed.
In order to retain the functionality of having fragments update
with transactions elsewhere we keep a pointer to a place in the
new complete history stack in the surface. The complete history
stack records all transactions, even undone ones.
Whenever getRange is called we replay all transactions in the
complete history (in the correct order) since the fragment was
last updated.
Also in this commit:
* Updated Format/IndentationAction to test undo(). This increases
coverage of surface fragment behaviour.
* .range is always accessed by .getRange now, although as an
optimisation we can use the noCopy mode when we a sure the
returned range will not be modified.
* Added undo test to .update (previously .onTransact)
Bug: 47343
Change-Id: I9e9818da1baa8319a3002f6d74fd1aad6732a8f5
Actually really resizing the image
Show bounding box on mouseover with 4 handles. Bounding box is resizable. Image resizes to match bounding box on mouse up.
Change-Id: I1f3dac64eb86dd1f258937e4915af101b3ac19d8
*.php
* Added links to new file
ve.ce.ImageNode.js
* Added relocatable node mixin
* Added $image reference to the actual img element, so if it's wrapped
in a sub class the functionality in the parent class doesn't break.
* Moved drag start event handling to relocatable node
* Removed drag end binding, not needed.
ve.ce.MWImageNode.js
* Moved addClass to initialization section of constructor.
* Copied 'view' data prop from image element to keep stuff working after
the wrapping.
ve.ce.Node.css
* Switched to default (arrow) cursor for images.
ve.ce.RelocatableNode.js
* New mixing for nodes that should be relocatable
* Added implementation for drag start, which tells the surface to allow
dragging this node.
ve.ce.Surface.js
* Added relocation support, which is used by relocatable nodes
* Split onDocumentDragDrop into onDocumentDragOver and onDocumentDrop
which now have implementations that support relocation of nodes
ve.ui.Context.js
* Added relocation tracking to prevent context being shown while
relocating
Change-Id: I8703adfb707af2c3224431afc3418356ac2c686c
Currently some issues, probably with loading nodes
after factories.
Toggled by global $wgVisualEditorEnableExperimentalCode.
Change-Id: Idab3dd68572c037289c6742d03fd327285110f67
Current set up leaves us with restoring when we're not and vice
versa. Not good. :-) (Partial fix of change 59968.)
Change-Id: Ia33a2f3318cf2e46b7469b2c773e91c5ee8fdefa
Don't call initialize inside the try-catch, it ends up sending exceptions thrown inside that method to /dev/null.
Change-Id: I8e0945f35c639ec156ee9a163b86fddfaed0ea7b
This was broken, especially in wrappers.
Changed the wrapping algorithm so that meta items are placed outside
wrappers if possible. On the left-hand side, this is already the case:
we don't open wrappers for meta items. On the right-hand side, this is
accomplished by buffering the meta items and only inserting them when
we encounter either real text (not whitespace) or the end of the wrapper.
If we're interrupted by real text, we insert the meta items with the
unmodified whitespace. If we're interrupted by the end of the wrapper,
we insert the meta items outside of the wrapper with whitespace stripped.
Internally, this is done by stripping the whitespace into the whitespace[0]
of the meta item to its right. Then when we output the meta items, we
either decide to 'restore' the whitespace, or to 'fixup' by also setting
whitespace[3] on the element before the whitespace.
Change-Id: Ibeea2a9906c4aae9fe6d284613edd6ec853ca5e7
Objective:
Make it possible for inspectors to inspect nodes or annotations, rather
than only annotations. Meanwhile, also make it possible for dialogs to
edit an annotation.
Strategy:
Switch from using type patterns to associate inspectors with annotations
to using arrays of classes, similar to how dialogs already work.
Introduce a view registry which provides lookups for relationships
between models and views. This is more centralized and less repetitive
than implement matching functions for both annotations and nodes in both
the dialog and inspector factories.
Changes:
*.php
* Added links to new file
ve.AnnotationAction.js
* Removed unused parameter to filter annotations using a string or regexp
ve.dm.AnnotationSet.js
* Switched from property/value arguments to callbacks
ve.ui.*(Dialog|Inspector).js
* Replaced type patterns with class lists
* Added class to view registry
ve.ui.*Tool.js, ve.ui.Context.js
* Updated model/view relationship lookup
ve.ui.*Factory.js
* Removed overly-specific lookup functions
ve.ui.Inspector.js
* Removed typePattern property
* Updated model/view relationship lookup
ve.ui.ViewRegistry.js
* New class!
* Migrated node and annotation lookup functions from factories
Change-Id: Ic2bbcf072fdd87e5ce8a03fe1ae3e6d8d50e2593
* changes:
ve.init.mw.ViewPageTarget: Put the Edit source link in the visible tab area
ve.init.mw.ViewPageTarget: Switch tabLayout from 'add' to 'replace'
So. It turns out that the design of SurfaceFragment is a little -
shall we say - wonky.
One of the best things about ve.dm.SurfaceFragment is its magical
ability to retain the intention of its range, even as transactions
are being processed. This ability is granted by each fragment
listening to the surface's change event, and responding by using
translateRange for each transaction that gets processed. Surface
fragments also have these clever methods that allow you to get a
fragment based on another, which makes adjusting the range easy to do
inline without having to manually store multiple fragments or
modifying the original.
This sounded good, and we seemed to all be convinced it was well
designed. But if you add a console.log( 'hello' ); to the first line
of ve.dm.SurfaceFragment.prototype.onTransact, and then start using
the bold tool on various selections of text, you will find that there
may indeed be a flaw. What you will probably realize is that the
number of times that particular line of code is being called is
disturbingly large, and increases each time you do just about anything
in the editor. What's going on? How did we get here? Read on…
It turns out that fragments are immortal. We create them, they listen
to the surface's transact event, we are done with them, but the
surface keeps on emitting events to the now long forgotten about
fragments. They continue to build up over time, never go out of scope,
and bloat the hell out of our program.
The same ended up being true of toolbars - and each time the context
menu fired up a new one the old one was left in limbo, still
responding to events, still taking up memory, but not being visible to
the user.
All of this immortality was causing strange and difficult to track
down problems. This patch fixes this by introducing a destroy method.
This method unbinds events, allowing the object to finally fall out of
scope and die - and more importantly stop receiving notifications of
changes.
This is a hack, but Ed will no doubt get this situation sorted out
properly by making fragments lazy-evaluate their selections by only
storing an identifier of the most recent transaction they were based
on, see bug 47343.
Change-Id: I18bb986001a44732a7871b9d79dc3015eedfb168
*.php
* Added links to new file
ve.ce.ImageNode.js
* Added focusable node mixin
ve.ce.FocusableNode.js
* New class!
* Adds isFocused and setFocused methods
* When a node is focused or blurred, 'focus' and 'blur' events are emitted
* While a node is focused, it will have the 've-ce-node-focused' class added to it's this.$
ve.ce.Surface.js
* Add detection of node focusing and setting focus and blur on nodes on change
Change-Id: I3f1ad6309571f2bfe568550e2e8f1bd5a0302085
Before, it took an array of objects and translated those to indexes
using the store. Literally every caller outside of the test suite got
an array of indexes from the linear model, translated those to objects,
then passed them into the AnnotationSet constructor which translated
them right back to indexes.
The previous behavior was kind of ridiculous on its face, but the
reason we found it is because Inez was investigating the performance
degradation when bolding a line and found that half of it was due
to the hundreds of ve.getHash() calls caused by this behavior.
Change-Id: I38df8ae9f6392849dacf477ea2f804283c964417
Subbu said that cloning of attributes like data-parsoid or typeof would
cause problems for Parsoid.
Also remove the attributes object if it becomes empty, and do the same
for the internal object.
Bug: 47297
Change-Id: I428becf95c70d0ed8af5b0c408e3966dc47fd8c3
Gabriel noticed whitespace diffs in the problem reports. These were
caused by browsers' .innerHTML being broken on <pre>s. We compensate
for this in the converter, but not when generating originalHtml.
However, a variable called originalHtml really shouldn't be generated,
it should just literally be the original, unprocessed HTML. This
does mean it includes the doctype, <html> and <head> which aren't
included in editedHtml (that one's just the contents of the <body>), but
that's much easier to deal with on Parsoid's end than random newline
diffs all over the place.
Change-Id: I8e66cb79887f49f84114ab6b4d0e0d24aea744b6
Context-sensitive nodes are HTML elements like <caption> that can only
appear in certain contexts (<table> in this case). This means that
serializing them by throwing them in a <div> and calling .innerHTML
fails, because the browser knows a <caption> can't be in a <div> and
unwraps it. jQuery's .html() function is clever though and knows to wrap
<caption> in a <table> (and has similar rules for other elements).
So use jQuery's .html() rather than manual .innerHTML stuff.
Change-Id: Id7d3eff968b3a2ba345680772f7cc32e3dcdb529
In HTML like <td>Foo <b>Bar</b></td>, the space would be stripped and
registered as trailing whitespace in the <td>, so it wouldn't be visible
in the editor and would be inserted after the </b> on the way out.
Thanks to Subbu for reporting this. This case was kind of ridiculous and
we're lucky the JRuby article contained it. To trigger the bug, you had
to have:
* a table cell
* containing unwrapped content
* consisting of
** some text
** whitespace
** open annotation (bold in my example, link in Subbu's case)
** text
** close annotation
** and nothing else
Change-Id: I2b83f02764b311a32a50956d4c8930a9394e91a4
This was broken ever since the introduction of IndexValueStore, because
the call to getDataFromDom() wasn't updated, so it crashed with a "doc
is undefined" error. Fixing part of this by passing in a new IVStore.
The data that is transmitted over the wire still has indices with no way
to find out what the corresponding annotations are. It needs to be fully
expanded but there's no way to do this in DM quite yet.
Bug: 47319
Change-Id: I761523d22e51ac560e37ae991d01a6b84224ca40
This gets us some new functionality, mainly the ability to get a position
from a point on screen.
Changes:
* Updated core and position
* Removed unused modules
Change-Id: I2145fe549c975fdbbcd7dfcf144afb26509d0050
This helps with some differences between browsers, specifically Firefox,
where e.which would be "1" even if the mouse button was not pressed.
Change-Id: Ia88449c2bc84073d903dc702bb586127618d86f2
Apparently Parsoid has always required this, and we've never sent it,
yet somehow the code in production works. This may well be the cause
of some of the selser issues we saw after the deployment attempt in
January.
Made oldid a required parameter in the API module, and default it to 0.
When we get 0, we translate that to the empty string for Parsoid's
benefit. We also need to explicitly get wgCurRevisionId in
ViewPageTarget, and that's also 0 on new pages.
Change-Id: I3a55025246014cd74e15d6d5b6c4ede7b823e5df
The first run of getDomFromData() would preserve whitespace just fine,
but it blanked out the .veInternal.whitespace[1] element in certain
cases, contaminating the linear model and making the whitespace data
inconsistent. Subsequent runs of getDomFromData() would then refuse to
serialize that whitespace because the information about it was
inconsistent.
In getDomFromData(), we sometimes unset .veInternal.whitespace[1] (i.e.
set it to undefined) to prevent double processing. Because we're
potentially going to modify .veInternal, don't assign it by reference,
but copy the object.
Added tests asserting that the linear model is unchanged after calling
getDomFromData(), because that function should never modify
linear model data. This test failed in 4 cases (all whitespace-related)
before I added the copyObject() call.
Bug: 43543
Change-Id: Ic4c93510518163894201a693ab50331413715967
This makes the Edit tab point to the VisualEditor, and adds a
"Edit source" link to the p-cactions menu.
Bug: 46872
Change-Id: I559232f3d8e42df0d45311b65df8c30425b1a368
ve.dm.Transaction
* Replace operations are now built directly from the
linear model and automatically determine what metadata
replace information they need to include:
** retainMetadata
** replaceMetadata
** insertMetadata
ve.dm.Document
* Metadata array created empty and padded out after data parsing
as we are no longer using Document.spliceData to build it (a new
test checks for correct metadata length)
* spliceData replaced with getMetadataReplace, which instead returns
transactional steps of spliceData (retain, replace, insert)
ve.dm.MetaLinearData
* Add function for merging metadata items together. Only used
once in the code (Document.getMetadataReplace) but useful
for generating test data.
ve.dm.MetaList
* Replace operations with metadata need to calculate new offset
and indices directly, but can't be applied immediately lest they
put a metaItem out of place and affect findItem.
ve.dm.MetaItem
* Add methods to support queued moves as required by MetaList
Test files
* Updated to match new pushReplace API
* Remove any instances of Document.spliceData
* Extra check on sparse metadata array length
* Rewrite spliceData tests as getMetadataReplace tests
* Count expected cases in Transaction(Processor) tests
Bug: 46954
Change-Id: I4edad1c2dd37c723bff2792bab7d694ef17a86dc
Rather than attach a function to the window and trigger it from a script
tag in the document body, it's much simpler to just use the references
we already have to execute the code immediately and directly.
This also fixes issues in Firefox where reaching in and adding functions
to the window wasn't allowed.
Change-Id: If7a84edf6ae4549b19ce36a3477311c46dbadea7
Inez reported that unitalicizing from the toolbar was broken, because
the toolbar was somehow generating annotations that had .attributes={}
as opposed to .attributes=undefined. Turned out the cause was in the
default value for element in the ve.dm.Model constructor.
Change-Id: I64ea9ef56cd15d1131c1aa23484d7420c95a8225
Added filter for nodes being passed to update state event - this
ensures that nodes are not being included with zero-length coverage, a
side effect of how selectNodes handles the virtual boundaries of text
nodes.
Change-Id: I6362114b57469b1108da11f94dc345a2bcdfc7cd
* Create MWTemplateBlockNode & MWTemplateInlineNode (in ce and dm)
* Move Alien's 'isInline' code to ve.dm.Node.static.isHybridInline
* Move definition of ce.AlienBlock/InlineNode inside ce.Aline.js file
to match dm.AlienBlock/InlineNode and MWTemplate
* Duplicate AlienBlock/Inline styles for templates
* Create test case for inline templates
* Count test cases in ve.dm.Converter.test.js automatically
Change-Id: Id9bc7f049ea974dd5e7f8b7a66080939e0948bbd
Use ve.BranchNode.getNodeFromOffset instead of
ve.dm.Document.getNodeFromOffset so correct nodes will be retrieved to
emit update events to.
Change-Id: Iaf559f0424584a3dde065e548e403c4a53207312
Change 57076 implemented the functionality required to skip
words in UnicodeJS. This change simply removes all the existing
code we had and replaces it with this implementation.
Bug: 46794
Change-Id: I6b2700d65476c4d34ba4a01a88382d7af8e736fb
This node stores the rendered in the index-value store, hashed on
a custom hash of the dm (type + mw) which makes it unique it its
parameters.
Bug: 46571
Change-Id: I0ab4c9f7bca207121d5b42e83c821771b6139da8
For data->DOM, this is easy: .toDataElements() can optionally return an
array instead of an object, and that will be treated as the data to
insert. If this happens, the converter won't descend. The node handler
can recursively invoke the converter if it needs to (although I suspect
the current implementation is broken when converting block content in an
inline context).
For DOM->data, this is a bit more complex. The node sets
.static.handlesOwnChildren = true; , which triggers the converter to
pass a data slice rather than a single data element, and not to
descend. The node handler can invoke the converter to recursively
convert DOM subtrees to data.
ve.dm.Converter (data->DOM):
* Renamed createDataElement() to createDataElements()
** .toDataElement() may return element or array, handle this
* Renamed childDataElement to childDataElements, is now an array
* Actually alienate if .toDataElement() returns null
** Shockingly, this claimed to be supported before but wasn't
* Rather than pushing to data, concat to it
** Add closing if needed
* Don't descend if .toDataElement() returned an array of length >1, or
if the node has .handlesOwnChildren = true
ve.dm.Converter (DOM->data):
* Split getDomSubtreeFromData() and getDomFromData()
* When converting a node that handles its own children, pass in a data
slice and skip over that data
Change-Id: I196cb4c0895cbf0b428a189adb61b56565573ab3
A node could already implement a toDataElements() function that
returns a data element of another node type, but it couldn't return
an annotation or a meta item. This is fixed now, and any dm.Model
subclass can now morph into any other dm.Model subclass.
I didn't originally plan to do this today at all, but doing this now
makes my upcoming converter changes easier. Surprise feature!
Change-Id: Ief6ac302094df084221a5a97c32a522b929c2960
This will allow toDataElement() functions to just call this function
with a DOM element, rather than having to have all the recursion context
data to pass in.
Also expose this information using getters.
Change-Id: I89574c42385267e08704f018c0892d63014376a6
ve.ce.ImageNode.js
* Moved in generic stuff from MWImageNode
* Added drag end handler (empty, will be used soon)
ve.ce.MWImageNode.js
* Changed to inherit ImageNode
* Moved generic stuff out
ve.dm.ImageNode.js
* Added attribute extraction/preservation for src, width and height
ve.dm.MWImageNode.js
* Changed to inherit ImageNode
* Re-using ImageNode's attribute handling to extract/preserve attributes on both the image and wrapper level
Change-Id: Ied4e1ece24e6804220eac35330790f7084df55de
ve.ui.MetaDialog.js
* Added scrolling to outline panel
ve.ui.css
* Added reusable animation keyframes
ve.ui.Dialog.css
* Changed dialog head style
* Changed dialog cancel button to close icon button
* Added animation of dialog opening
* Increased min-height of dialog to always show a little content
ve.ui.Icons-*.css
* Added close icon (not sure why it was missing)
ve.ui.Window.css
* Moved head padding out of window and into implementations of window
ve.ui.Dialog.js
* Moved apply button to footer
* Renamed cancel button to close button
* Overrode close method with triggers a closing animation and then calls the parent close method after an animation is complete
* Added classes to close and apply buttons to make styling less ambiguous
* Converted cancel button (now the close button) to an icon button
ve.ui.Window.js
* Added footer to dialog
VisualEditor*.php
* Added close message
Change-Id: Iededbc54b287328b3047b05efad6ca3cc152caa5
window.close( true ) thing sucked, and was being named and used
inconsistently throughout the code.
The new approach uses an action string, so it looks more like
window.close( 'accept' ) or window.close( 'back' ). This makes it easy
to steer the behavior at any point in the window close code path.
Most importantly for the link inspector, this allows us to now restore
the previous selection when the user presses escape or clicks the back
button, while still moving the cursor to the end and collapsing the
selection upon pressing enter and allowing removal by clicking the
trash can.
This commit also cleans some things up, like the various ways we have
to close an inspector which all seem useless because we wouldn't want
to just randomly close an inspector on someone. An inspector should
be closed only when the user has dealt with it.
ve.InspectorAction.js
* Removed close method
ve.ui.LinkInspector.js
* Updated documentation
* Passing action to parent method
* Updated logic to deal with change from "remove" to "action" argument
* Added selection restauration on "back" action
ve.ui.Context.js
* Added action to call to close
* Removed closeInspector method
ve.ui.Dialog.js
* Moved event handlers to the top
* Added actions to calls to close
* Added click block event handler to prevent focus changes
ve.ui.Inspector.js
* Added actions to calls to close
* Added storing of previous selection - this is different from
initialSelection because it's captured before the selection is
modified by setup
ve.ui.Window.js
* Updated documentation
* Updated argument name from "remove" to "action"
ve.ui.WindowSet.js
* Updated documentation
* Removed auto-close, replaced it with error if trying to open a window
when another is already open
* Removed close method
Change-Id: Ie8f72504177dd6ba169fdddbb776fd5397b831c4
It's been passed in for a while, but nothing ever used it. As we know
some browsers don't like it when we create elements in the wrong
document, and this ensures we always use the correct document for
createElement().
Change-Id: Ia3d2fabe0516956105ad2b5625ed2f76c015c26e
ve.dm.Converter and ve.ce.ContentBranchNode were duplicating a fair bit
of logic for annotation rendering. Moved the annotation opening and
closing logic into ve.dm.Converter.openAndCloseAnnotations, and
implemented both annotation rendering code paths in terms of that
function with callbacks for caller-specific behavior.
Change-Id: I7cba7d2fda7002287b07949a1b8120ba80bfe854
This provides the functionality for keyboard word skipping
(i.e. pressing ctrl/alt + arrow key).
Bug: 46794
Change-Id: Ib0861fa075df805410717a148b8a6e166d947849
We weren't really using it exclusively for nodes any more, and the only
functionality in there was for using .static.name
Change-Id: Ie26928cd01faee95a10912201663b45f1f20fb19
Just like ve.dm.Model is a common base class for dm.Node, dm.Annotation
and dm.MetaItem.
ce.View abstracts the this.model and this.$ behavior, including liveness,
whitelisted HTML attribute rendering and adding a back reference in
.data(). The back reference has been renamed from .data( 'node' ) to
the more generic .data( 'view' ).
At this point this means ce.Annotation is just a shell around ce.View
(except where it defaults to a span rather than a div), but that could
change in the future.
Change-Id: I0eef5b80718e0b0fcd3f8bba096b452f0bb680d0
ve.dm.Model is now the common base class for these three. ve.dm.Node
inherited from ve.Node before, so it now uses it as a mixin instead.
This required changing ve.Node's usage of ve.EventEmitter from
inhertiance to a mixin as well, because inherited methods apparently
don't get mixed in correctly.
* Change annotation terminology from linmodAnnotation to element for
consistency with Node, MetaItem and Model
* Reimplement getClonedElement() in Node for .internal treatment
Change-Id: Ifd3922af23557c0b0f8984d36b31c8a1e2ec497e
They worked fine with just one group, but once Rob added a second group
everything came falling down.
* Index the return value of findItem() into the correct array
(list.items for all, list.groups[groupname] for groups)
* Expect null if there is something at the coordinates but it's in the
wrong group
* Keep track of the next index and expect that for forInsertion when
findItem() returned null, as well as at the end of each offset
Change-Id: I76438f583cea5694ce04fa2f4e7e88f8f8f236d1
This changes the annotation API to be the same as the node API, sans
a few boolean flags that don't apply. The APIs were different, but
there was really no good reason why, so this makes things simpler for
API users. It also means we'll be able to factor a bunch of things out
because they're now duplicated between nodes, meta items and annotations.
Linear model annotations are now objects with 'type' and 'attributes'
properties (rather than 'name' and 'data'), for consistency with elements.
They now also contain html/0/* attributes for HTML attribute preservation,
which obsoletes the htmlTagName and htmlAttributes properties.
dm.Annotation subclasses take a reference to such an object and implement
conversion using .static.toDataElement and .static.toDomElements just
like nodes do. The custom .getHash() functions are no longer necessary
because of the way HTML attribute preservation was reimplemented.
CE rendering has been moved out of dm.Annotation (it never made sense to
have CE rendering functions in DM classes, this was bothering me) and into
separate ce.Annotation subclasses. These are very similar to CE nodes in
that they have a this.$ generated based on something in the DM; the main
difference is that nodes listen to events and update themselves, whereas
annotations are static and are simply destroyed and rebuilt when they
change. This change also adds whitelisted HTML attribute rendering for
annotations, as well as class="ve-ce-FooAnnotation" attributes.
Now that annotation classes produce real DOM nodes rather than weird
objects describing HTML tags, we can't generate HTML as a string in
ce.ContentBranchNode anymore. getRenderedContents() has been rewritten
to be much more similar to the way the converter renders annotations;
in fact, significant parts of it were copied from the converter, so that
should be factored out in the future. This change actually fixes an
annotation rendering discrepancy between ce.ContentBranchNode and
dm.Converter; see the diff of ve.ce.ContentBranchNode.test.js.
ve.ce.MWEntityNode.js:
* Remove stray property
ve.dm.MWExternalLinkAnnotation.js:
* Store 'rel' attribute
ve.dm.TextStyleAnnotation.js:
* Put all the conversion logic in the abstract base class
ve.dm.Converter.js:
* Also feed annotations through getDomElementsFromDataElement() and
createDataElement()
ve.dm.Node.js:
* Fix undocumented property
ve.ce.ContentBranchNode.test.js:
* Add descriptive messages for each test case
* Compare DOM trees, not HTML strings
* Compare without all the class="ve-ce-WhateverAnnotation" clutter
ve.ui.LinkInspector.js:
* Replace direct .getHash() calls (evil!) with ve.getHash()
Bug: 46464
Bug: 44808
Change-Id: I31991488579b8cce6d98ed8b29b486ba5ec38cdc
* In matchTypeRegExps(), skip string types
** Didn't break because we currently have mixes of strings and regexes
* Combine types from rel, typeof and property rather than picking one
** Added test case in ve.dm.example that resembles actual Parsoid output
* If the element has extension-specific types, not only restrict type
matching to extension-specific types, but also require that *all* types
present on the element be matched
Change-Id: Iacf3851a0ca9081d2c813b42435484a47cec6230
This is a redux of logic already in master.
Moved from keydown to keypress because IE
fires keydown multiple times for held keys.
Changed the logic to determine that the current
offset is just after an element that should not be
directly edited.
Change-Id: I5206d8919abde740d92f636b0c8618c4ebb6f6ff
Instead of returning val when a custom hash is found,
feed it back into val and let the object sorting take
place if required.
Bug: 46895
Change-Id: I6a9b42facd97fbf49042d3a082121ec93659b9f1
As described in the bug, ve.getHash performs JSON.stringify so to
customise a hash the object should just return an object to be
hashed, not the hash string itself.
Bug: 46895
Change-Id: If11071d4b04a01e25102ffb57240882f650ee10d
This is one of the blockers for splitting VE up into separate
repositories or extending VE with an extension.
ve.ui.Frame.js
It's critical that we don't emit initialize from ve.ui.Frame until
it's completely loaded, especially its styles, because we will
begin measuring it straight away.
Involved loading the stylesheets using $.ajax and setting base
URL of the iframe to the ve.ui styles directory so all the image
URLs still worked. This won't work for stylesheets from multiple
locations, so we needed a more robust solution.
The new solution uses some trickery described in the code
documentation, but essentially no longer depends on all
stylesheets being located in the same folder.
ve.ui.Dialog.js, ve.ui.Inspector.js, ve.ui.Window.js
Static methods are now being used to extend a window class to
include different stylesheets rather than simple array
concatenation.
Change-Id: I619238732f975d41305f81f8f818a577a40f49da
*/index.php
* Added links to new files
VisualEditor.php
* Added links to new files
* Removed keys of non-existent messages
ve.ui.ContentDialog.js, ve.ui.MetaDialog.js
* Removed redundant comments
ve.ui.MediaDialog.js
* New dialog, just for media
icons.ai, picture.png, picture.svg, ve.ui.Icons-*.css
* Added picture icon
ve.ui.MediaButtonTool.js
* New button, just for media (shows up in the context toolbar)
ve.ui.DialogButtonTool.js
* New base class for dialog buttons
ve.ui.Context.js
* Added basic support for showing dialog buttons, in addition to
annotation buttons, in the context toolbar - to test, select only an
image node
ve.ui.Dialog.js
* Prevent clicks on the click-block from changing focus
* Moved initialize to below the event handlers and updated its
documentation
ve.ui.DialogFactory.js
* Added a way to get the names of dialogs that can be used to edit a
node
ve.ui.Inspector.js
* Removed close handler which set focus, this is done already in window
ve.ui.InspectorFactory.js
* Fixed comment so it's not telling lies anymore
ve.ui.Window.js
* Removed auto-focus on frame, it's changing the focus in the parent
document which blows-away the focus in CE, and it really isn't needed
as it turns out
VisualEditor.18n.php
* Added media dialog title message
* Added media tool tooltip message
Bug: 37870
Change-Id: I9150c46b3e292910fed899fa60d6da433049ca45
To verify
* Save "MediaWiki:Edit" with "Edit page" (anything not "Edit")
* Set this.tabLayout = 'replace';
* Observe that the ve-edit tab is now "Edit" (msg: vector-view-edit)
instead of "Edit page" (msg: edit)
Bug: 42117
Change-Id: I2e7dd85cd14049101e2d49751d37797d77bc7c9d
Depencency tree looked like this
* ext.visualEditor.viewPageTarget
- ve.init.platform
- ve.init.target
** ext.visualEditor.core
- (most ve.* classes)
*** ext.visualEditor.base
- ve.js
Some of the ve classes are calling ve.msg from the global scope
at load time (e.g. in the definition of static properties or in
constructors of classes that were immediately instantiated in
the same file).
Platform needs to be initialised in the base module.
ve.init.Platform.js was already there, but that's just an
abstract base class. The the ve.init.platform property is set
from the implementation classes' files.
Updated makeStaticLoader.php and re-ran for test and demo html.
The fake "Standalone Init" module is now gone, which shows that
this was needed as test/ and demo/ already put their platform
code in/after the 'ext.visualEditor.base' module in the html.
Bug: 45175
Change-Id: I47d7d92495974572194700c98a219d22ecbfaf4b
Created an IndexValueStore class which can store any object and return
an integer index to its hash map.
Linear data is now stored in ve.dm.LinearData instances. Two subclasses
for element and meta data contain methods specific to those data types
(ElementLinearData and MetaLinearData).
The static methods in ve.dm.Document that inspected data at a given
offset are now instance methods of ve.dm.ElementLinearData.
AnnotationSets (which are no longer OrderedHashSets) have been moved
to /dm and also have to be instantiated with a pointer the store.
Bug: 46320
Change-Id: I249a5d48726093d1cb3e36351893f4bff85f52e2
Using element.height was returning 0 if the attribute was empty
when in fact what we mean to store is null (i.e. auto height).
This takes care of the writing of attributes in CE as jQuery
ignores an attribute-set command if the value is null.
Also in this commit I've implemented a basic toDomElements
that outputs the original HTML (code copied from AlienNode).
This stops the code from throwing an exception but will
eventually need to be rewritten to rebuild the HTML from
the attributes stored in the DM.
Bug: 56336
Change-Id: I297a1d0a07e9ebf9d0110fb1cdf266f8415f25b7
When the cursor is between ce="false" elements and an editable next
sibling, IE often sets the anchorNode to be the ce="false" element
(or text node within). This change returns aliens to ce="false"
(abandoning the former true within true IE trick), and ensures that
the cursor is in the right place on keydown by programmatically
setting the selection.
Change-Id: I952488510f32b096b27e8e55d4afc7df930e0072
Also removed a few redundant headings in class documentation
comments. There is already an @class and it looks a bit odd in
the generated pages:
<h2>TextString</h2>
<p>TextString</p>
<p>This class provides a ...</p>
Change-Id: Ie311c6993ed02e79272dbde71f6a1bc252ef3037
*.php
* Updated links to files
ve.ui.MetaDialog
* Added stack panel that now contains category and language editor panels
* Attached outline widget to stack panel
ve.ui.FlaggableWidget -> ve.ui.FlaggableElement
* Moved to elements
ve.ui.GroupWidget -> ve.ui.GroupElement
* Moved to elements
* Removed invalid event documentation
ve.ui.LabledWidget -> ve.ui.LabledElement
* Moved to elements
ve.ui.StackPanelLayout.js
* New class, mutually exclusive panel container
ve.ui.TitledPanelLayout
* Remvoed, using labeled element instead
ve.ui.Element.css
* Added for elements
* Moved label style here, from widget styles
*.css, ve.ui.ButtonWidget.js, ve.ui.InputLabelWidget, ve.ui.OptionWidget, ve.ui.SelectWidget
* Adjusted class names to reflect widget -> element migration
Change-Id: I32f504c844dba7aae1b286eef06ca046627bdc8d
This will make the popup with callout functionality easy to reuse elsewhere - in the first case most likely the popup menus for the category widget.
*.php
* Added links to the new widget
ve.ui.Context.css, ve.ui.Widget.css
* Moved styles to the widget stylesheet
ve.ui.Context.js, ve.ui.PopupWidget
* Moved "popup" specific stuff to the new popup widget
Change-Id: I823c6e2c5e1ec11088898e9621d93e983c3b76f3
Better comments for:
* ve.ce.Document.getRelativeOffset,
* ve.ce.Document.getSiblingWordBoundary.
Convert ve.ce.Surface.getSelectionRect to a static method.
Moved getNodeAndOffset from ve.ce.Surface to ve.ce.Document.
Change-Id: Ic00221fa463205d04c9b52150c0dd15904493b1e
Initially just with a Wordbreak module to implement Unicode standard
on 'Default Word Boundaries'. Due to it's standaloneability this has
been written as a separate library. Non-BMP characters are currently
not supported.
Bug: 44085
Change-Id: Ieafa070076f4c36855684f6bc179667e28af2c25
ve.ui.Widget.css
* Made sections use a default cursor - they aren't clickable so they shouldn't appear to be
Change-Id: Id74288040080c18b8595f2903239bc82e8bc1ab2
The phantoms prevent direct clicking into aliens,
and the recent selection changes prevent keyboard
navigation into aliens, but one issue remained.
Clicking to place the cursor just after an alien
would actually focus within the alien. Typing
modified the alien content. By nesting ce="true"
within ce="true", IE ceases this behavior.
Dragging state is now set to false when blurring
the document. The mouseup event sets dragging to
false, but the event is cancelled because blur
happens between mousedown and mouseup. Phantom
display logic uses on this property.
Change-Id: I162dea89838756fd28d63ff66cc4a5e5bda2873a
ve.ui.Dialog.css
* Fix issue where the use of margin auto on the outer dialog wrapper
would expose parts of the underlying content - this is resolved by
making the outer wrapper cover the whole screen and making the
window frame use margin auto
ve.ui.Icons*.css
* Added missing settings icon rule
ve.ui.Layout.css
* Added styles for editor panel
ve.ui.Window.css
* Removed default height, setting it specifically in inspector now
ve.ui.EditorPanelLayout.js
* New layout, adds a title and icon above the content
ve.ui.TitledEditorLayout.js
* Similar to labeled widget, but for panels
ve.ui.MetaDialog.js
* Using settings icon now
* Switched to using a specific layout - still hard-coded for
categories
ve.ui.Frame.js
* Modified style loader to guarantee order of style rules, no matter
what order they load in
*.php
* Moved layouts to be included after widgets so they can use widgets
* Added links to new layouts
Change-Id: I7ff5f5f095460fd4f6cf841f4182bfb92bf034da
These events occur when an item is inserted or removed by onTransact(),
so both for insertions/removals done through the MetaList mutators and
insertions/removals done by any other means.
We have to gather these events and batch them up because we have to allow
offset translation and index recomputation to occur first (otherwise
calling .getOffset() and .getIndex() on inserted items doesn't work).
Change-Id: I74a9a21398eca4e9afd7148171af20d439cf7ebd
Mostly by extracting parts of onDocumentKeyDown method into separated methods: handleLeftOrRightArrowKey and handleUpOrDownArrowKey
Change-Id: If19abf2218bc667c729f7bf388074061cec3031c
Add .insertMeta() and .removeMeta() methods to insert and remove
metadata through the meta list. For convenience, there is also a
.remove() method in MetaItem that wraps around removeMeta().
Also rename insertItem() and removeItem() to addInsertedItem() and
deleteRemovedItem() to avoid confusion, and make the MetaList
constructor take a dm.Surface rather than a document so we can call
change().
Change-Id: I4b62a3109404cfd56f5de68938e1db908b03e678
@emits, @returns, @chainable & @throws should always appear
in that order, according to CODING.md.
Change-Id: I9b192e018a028a8b32730c288cc4e3108800fb58
Previously these were static functions in TransactionProcessor
which instantiated a TP called .process() on it. These are now
methods of ve.dm.Document.
Also moved the emission of the 'transact' event on the document from
TransactionProcessor to Document itself, and moved the tests asserting
double application is protected against from TP to Document (because
the corresponding code moved as well).
Change-Id: I7c9f22a14accaf0ba1f70d5aa4f0573bb7e677d0
This caused the page to stay in a dimmed state because it would
throw an exception before tearDownSurface() and showPageContent()
would be called.
Bug: 46456
Change-Id: I91ad2b110c2c523a4bb367407e3f33a953328ab4
Objective: Refactor menu widgets so that the majority of their code can be reused, and then add an outline widget which shares the same base classes.
ve.ui.Dialog.css
* Make dialog a fixed width and have a minimum and maximum height while always being centered in the window.
* Add style for the outline panel
* Add border below the title
* Move font-size adjustment to child elements to preserve layout scale
ve.ui.Inspector.css
* Make inspectors fade in when being opened (will happen after the size transition is complete)
* Add initial size for inspector to prevent the default size of the unfinished contents from making it too large while loading
ve.ui.Tool.css
* Update classes according to changes in labeled widgets
ve.ui.Widget.css
* Add display: block to widget labels to support use of autoEllipsis on them
* Update classes according to changes in labeled widgets
* Add styles for new select, option and outline item widgets
* Remove unused group and items classes for menu widgets (which are now subclasses of the select widget and no longer have grouping built-in)
ve.ui.Window.css.js
* Moved selection disabling rules up to the head to prevent selection drawing around the title
ve.ui.GroupWidget.js
* New widget that manages "items", allowing getting, adding, removing and clearing
ve.ui.MenuSectionItemWidget.js
* New widget that can be used inside a menu to create an unselectable, unhighlightable item that describes a section of the menu
ve.ui.OptionWidget.js
* New widget to be used with select widgets, provides select and highlight functionality
ve.ui.OutlineItemWidget.js
* New widget to be used with outline widgets, extends option and adds support for an icon to be rendered to the left of the label
ve.ui.OutlineWidget.js
* New widget that provides a vertically stacked list of mutually exclusive options, extends select
ve.ui.SelectWidget.js
* New widget that implements most of what menu once did, only now it also handles all the events for it's child elements internally
ve.ui.MetaDialog.js
* Hacked in support for an outline widget in the outline pane
* Added classes for styling purposes
ve.ui.FormatDropDownTool.js
* Modified call to menu item constructor as per changes therein
* Reorganized options config to make construction simpler
* Changed to setLabel after selecting the item to prevent the label from being changed to the wrong value as a side-effect of setting the item
ve.ui.DropDownTool.js
* Added $$ in config for menu widget - just in case later on we use a drop-down inside of a frame
* Using jQuery .text() method to propagate the selected item's text to the label rather than keeping around a plain text copy of the label in a property
ve.ui.Context.js
* Improve context/inspector behavior in regards to initial sizing
ve.ui.js
* Added context property to $$ returned by get$$ so it's easy to get the document object (for event binding) wherever you have a $$
ve.ui.Window.js
* Fixed incorrect case for boolean type in comment
* Added getFrame method
ve.ui.ButtonWidget.js
* Removed extra class being set on label
ve.ui.LabeledWidget.js
* Added class on label
* Added fitLabel method which uses autoEllipsis internally
ve.ui.MenuItemWidget.js
* Moved nearly all of the implementation to option so it could be reused
ve.ui.Menu.js
* Moved most of the implementation to select and group
ve.ui.MWLinkTargetInputWidget
* Prevent aborting and re-querying if the value hasn't actually changed
* Updated populateMenu method as per changes in menu class
*.php
* Added links to new files
Change-Id: I2271b5cc0554973b13cfbff94caf16901c02caa5
This removes the "grow from nothing" effect (which may have been a
little overkill) but fixes the situation where the inspector is open
and you click to a new location and it moves to the new location and
then transitions down to the menu (which looks bad).
Change-Id: I19d27da6fea7c36965c83aa73836b1bc870c9bcc
* Document them consistently between secetions Inheritance and
Static Properties under their own (new) section Events.
* Removed any quotes or brackets around the event name in existing
@emit annotations
Search: @emit.*['"{}(){}]
* For every call to this.emit() anywhere, added @emits.
* Fixed all warnings for references to undefined events
(introduced as a result of the previous point).
Event handler parameter documented based on the emit() call
and actual handlers using the event. Usually the latter is
more elaborate.
* Extend coverage of jQuery as needed
(copied from mwcore/maintenance/jsduck/external.js
written by me, hereby implicitly and explicitly released under MIT).
Specifics
* ve.ce.Surface#onContentChange: Fixed type of range from Object to ve.Range.
* ve.ce.SurfaceObserver#poll: Fix syntax for code from {} to `backticks`.
* ve.ui.Toolbar#onContextChange: Doesn't actually emit "clearState" event.
Removed #onClearState in Tool, ButtonTool and DropdownTool.
Bug: 45872
Change-Id: Id879aa769b2c72d86a0322e75dddeb868211ce28
This is just a prototype - if it will be as useful as I expect
then it will get refactored (and probably get a better name +
location).
Change-Id: Ice1a2bd7d498d9d8438c35239216f01bd3db1826
Layouts
* Makes widget inherit from element
* Adds layout which also inherits from element
* Adds grid and panel layouts
* Uses grid layout in meta dialog
Other changes
* Corrects issues with several of the stand-alone files by fixing and using makeStaticLoader.php
Change-Id: I6b92c0204e176c914c26eff8c03ea417578e080c
A MetaList is a collection of MetaItems representing all of the
metadata in a ve.dm.Document, and it updates itself live as the
underlying document changes.
Currently this interface is read-only, I'll add mutators next.
Change-Id: If7bfc9563af37e22dcdca9a682d6decc2f6f1872
demo.css
* Removed toolbar floating styles, which were out of sync and essentially a duplication of those in ve.Surface.css
ve.Surface.css
* Reorganized rules
* Fixed some CSS syntax issues
Change-Id: I94eb83fa74312266817f8932f54fc9b89332c524
If the user has undone all their actions they should not be able to
save the document. By updating the 'edited' property we also solve
the issue of the onbeforeunload alert displaying if all edits
have been undone.
Bug: 42939
Change-Id: Ib3bc5b0e2f21781166a17a3fdf4f5286e6713859
Rather than meta-things being special kinds of nodes, they are now a
separate class of things (MetaItems) along with Nodes and Annotations.
* Created a generic ve.dm.MetaItem that meta items inherit from.
There will be actual instances of this class as well in the upcoming
meta group code.
* Renamed MetaNode to AlienMetaItem, MWMetaNode to MWMetaItem,
'metaBlock'/'metaInline' to 'alienMeta'
* Created a MetaItemFactory, handle meta items in the ModelRegistry
* Kill ve.dm.Node.static.isMeta, now obsolete
ve.dm.Converter:
* Pass in the MetaItemFactory
* Look up data element types in the ModelRegistry rather than the
NodeFactory, because they can be either nodes or meta items
* Document createDataElement() and make explicit that modelClass can be
either a node or a meta item
* Handle meta items in getDataFromDom()
* In getDomFromData(), check the MetaItemFactory as well as the NodeFactory
Change-Id: I893709c6f3aa00f85c1b905b70f9f4e597bdeada
We'll need this to let a MetaList observe a Document and adjust to changes.
We should probably also have SurfaceFragment listen to this event instead.
Change-Id: I9e811e242969eb44afe0b4fa8153d0fb1b0071cd
Before, replacement operations that both inserted and removed data at
the same time would be treated as removals followed by insertions,
so we'd reap the metadata from the affected range and move it to the
start of the range. For a pure replacement, this doesn't make any sense.
Instead, preserve the first min(insertLength, removeLength) elements in
the metadata array, then perform a pure insertion splice or a pure
removal splice for the length adjustment. Any metadata reaped in a
removal splice is restored at the offset where we started removing,
after the preserved portion.
These changes make the behavior of metadata reaping saner in general
(the previous behavior had the potential to move metadata around if it
was near a paragraph opening or closing and you converted the paragraph
to a heading), and makes the behavior match up with translateOffset(),
which is desirable for MetaList synchronization.
Change-Id: If9a1c6a7cf43ead7e3e1e8f6e081b139ca65fa53
ve.ui.Widget.css
* Adjust menu up a few pixels to match other uses of ve.ui.MenuWidget (the format drop down)
ve.ui.LinkInspector.js
* Moved the form value initialization to a timeout that fires well after the animation of the inspector - this is only important because the first element has a menu that pops up and the menu was rendering in the wrong location
ve.ui.Frame.js
* Added reference to frame within this.$$ by passing it to get$$
ve.ui.Inspector.js
* Removed auto-focus on open from inspector base class - this will be done in a more specific and controlled way instead
ve.ui.js
* Added optional frame argument to get$$ so that it's easy to get the frame from any $$ that's bound to an iframe document
ve.ui.Window.js
* Removed duplicate static member assignments
* Added auto-focus on the window's frame before calling onOpen
* Added auto-blur of anything focused within the iframe after calling onClose
ve.ui.MWLinkTargetInputWidget.js
* Auto-highlight the selected item when populating a menu so that pressing enter always keeps the currently selected item selected
ve.ui.TextInputMenuWidget.js
* Take the frame's position into account when positioning a menu below an input
Change-Id: I334f7db29af6b821bcfc8dc3c0ccba2636d4d9b1
Replacing [a-zA-Z] with a long unicode expression which encompasses
all the characters in the unicode 'letters' category. Similarly replacing
[0-9] with an expression for 'numbers'.
Bug: 44085
Change-Id: Idd403339caa24769ce08133dda06ab6d4b9d694e
This is a major refactor of user interface context, frame, dialog
and inspector classes, including adding several new classes which
generalize managing inspectors/dialogs (which are now subclasses
of window).
New classes:
* ve.ui.Window.js - base class for inspector and dialog classes
* ve.ui.WindowSet.js - manages mutually exclusive windows, used
by surface and context for dialogs and inspectors respectively
* ve.ui.DialogFactory - generates dialogs
* ve.ui.IconButtonWidget - used in inspector for buttons in the head
Refactored classes:
* ve.ui.Context - moved inspector management to window set
* ve.ui.Frame - made iframes initialize asynchronously
* ve.ui.Dialog and ve.ui.Inspector - moved initialization to async
initialize method
Other interesting bits:
ve.ui.*Icons*.css, *.svg, *.png, *.ai
* Merged icon stylesheets so all icons are available inside windows
* Renamed inspector icon to window
ve.ui.*.css
* Reorganized styles so that different windows can include only
what they need
* Moved things to where they belonged (some things were in strange places)
ve.init.Target.js, ve.init.mw.ViewPageTarget.js, ve.init.sa.Target.js
* Removed dialog management - dialogs are managed by the surface now
ve.ui.*Dialog.js
* Renamed title message static property
* Added registration
ve.ui.*Inspector.js
* Switch to accept surface object rather than context, which conforms
to the more general window class without losing any functionality
(in fact, most of the time the surface was what we actually wanted)
ve.ui.MenuWidget.js, ve.ui.MWLinkTargetInputWidget.js
* Using surface overly rather than passing an overlay around
through constructors
Change-Id: Ifd16a1003ff44c48ee7b2c66928cf9cc858b2564
The IndentationAction was created against a version of master which
didn't have the new Surface constructor signature. This commit resolves
that conflict.
Change-Id: Ifc17f95acfa6057963d503448405355831b1ff97
Also in this commit is a minor fix to the regular expression so it
behaves as documented (the hyphen needed escaping).
Bug: 44085
Change-Id: Idc315e2dce79be8f028b5681c60f74e175b9d869
MWLinkTargetInputWidget annotation property was being killed
on populateMenu.
Other changes:
* Removed calls to sanitize on subclasses setValue methods
as those methods call the parent class method which already
sanitizes input.
Bug: 46025
Change-Id: I169dd58a06122122f187f9d751076ef56b255558
The new jshint (0.9.1 > 1.1.0) is smarter about detecting trailing
whitespace (which enabled in our jshintrc file).
Looks like we did indeed let it slip through a few times in ve.Document.
Also cleaning up comment from * to - for consistency and avoiding
block-comment characters.
Change-Id: Ie1621816d608b5c42028ee945346d872a747c6a4
isolateAndUnwrap now unwraps to a level determined by a target type
i.e. the type you are going to convert to.
Also in this commit wrap/unwrap/rewrap have been refactored to use
getLengthDifference. unwrap now takes an inner/outer unwrap depth.
Change-Id: I3c6249de43232a9ef64f498a0aaf66b1c44973f2
Wrapper paragraphs should only be unwrapped if they are the first
element in their parent - or if there is a block level element separating
them from the previous unwrapped paragraph.
Empty paragraphs should only be unwrapped if they are empty and the
last element in their parent.
Also in this commit is a simple test for IndentationAction.decrease().
Bug: 45590
Change-Id: I1f47d12db6d57d984fd4607f667a3b62c53f3dd6
Heading and Preformatted nodes have rules that should only
exist under a document node in MediaWiki.
Two new node types have been created as has a new DropdownTool which
uses these. The MW init options have been changed to use the new
DropdownTool.
Bug: 45295
Change-Id: I3f47e1ae1f5c1415bde58a75385e4bf5f4b8fffc
Change-Id: Ibc3f49c55ded5490fcb071f0ccf9f25a71a06c97
Warning: categories.json Class 've.NodeFactory' not found in categories file
Warning: ve.ui.ContentDialog.js:8: Unknown type ve.ui.Surface
Warning: ve.ui.MetaDialog.js:8: Unknown type ve.ui.Surface
Warning: ve.ui.Dialog.js:8: Unknown type ve.ui.Surface
The ve.Surface constructor was recently changed, but the instantiation
in the FormatAction tests was not updated accordingly.
The constructor now requires a ve.init.Target object.
Bug: 39597
Change-Id: Ia4193fbab5c63007ed057009bf9a39f1f9d18fb7
Add a static.name property to ce nodes and make sure both ce
and dm nodes always use the static.name property in constructors
and registration calls.
The result of this is that any given node type should now only
appear once in the code as a string.
Bug: 45701
Change-Id: Ibf31de16ab28ad58209c1443cd74f93dda278998
Changes include:
VisualEditor.i18n.php, VisualEditor.php
* i18n labels for dialogs
ve.init.mw.ViewPageTarget.js
* Initial go at onOpenDialog and onCloseDialog methods
ve.init.Target.js
* Change calls to dialog hide & show to close & open
ve.ui.MetaDialog.js, ve.ui.ContentDialog.js
* Pass surface when constructing
* Add static title message property
ve.ui.Surface.css
* Set high z-index for toolbar for shadow to overlap dialog.
ve.ui.Dialog.js
* Extends EventEmitter class.
* Changed hide/show method names to open/close.
* Create base ui elements.
ve.Surface.js
* Create instance of meta dialog.
Change-Id: I867ca0546606eeb5e2ab7f612bb5af700ab877ec
Apparently in IE even after you call clearTimeout, the function passed
to setTimeout might still get invoked (not 100% of the time).
It depends on the time difference between calling clearTimeout and
when that function was supposed to be called.
Change-Id: I050c1ecc51c1d891a028fb777243573487357171
Major changes:
demos/ve/index.php
* Renamed ve-demo-content to ve-demo-editor
ve.init.mw.ViewPageTarget, ve.init.sa.Target
* Added handlers for dialog events
ve.ui.*Dialog.js
* Added skeleton classes for dialogs
ve.init.Target.js
* Create abstract class methods for Target.
ve.init.sa.Target.js
* Create Standalone target view methods.
ve.init.mw.Target.js
* Added MW specific target view methods.
* Integration action buttons are now added to the edit
view in the toolbar.
ve.Surface.js
* Simplified constructor, now requiring a target which contains the container
* Other changes include some documentation and code cleanup.
Bug: 39597
Change-Id: Iff39266bdd3052f34bda254ca407030dbbc81f26
Unfortunately the Http::get wapper provides no data if anything but
an OK status is returned, so ApiVisualEditor now uses MWHttpRequest
directly.
If a non-OK status in encountered the error code and message are
passed through to the JSON output, and rendered in the error
alert by VE.
The error code passed through is parsoidserver-http-NNN although
other suggestions are welcome.
Bug: 44354
Change-Id: I166ecf81c40f0f1c62663f2096753269d28f2916
I encountered a very difficult to track down error while working on
ve.ui.Dialog where a copy-pasted inheritClass call overwrote the
prototype of ve.ui.Widget.
By adding this check, we can ensure that 2 identical calls to
inheritClass won't silently make the system explode. This check is
lightweight and will save someone down the line a bit of time and head
scratching.
Change-Id: I014d53722fc8d941ec415462d258a79985e0e3d7
Modified handleEnter to check for the condition that shift-enter
is being pressed inside of a preformatted block. If so, a break
node is inserted.
Bug: 45355
Change-Id: Iae7b3c88b7cd976e519c09821a064078228acc79
Objective:
Refactor UI widgets, improve usability and accessibility of menus, general cleanup and style improvements.
Extras:
Fixed documentation in a few other files to make descriptions of jQuery event arguments more consistent, classes inherit correctly, and made use of the @cfg functionality in jsduck.
Changes:
.docs/config.json
* Added window, HTMLDocument, HTMLElement, DocumentFragment and XMLHttpRequest to externals, so jsduck doesn't throw warnings when they are used
demos/ve/index.php, modules/ve/test/index.php, VisualEditor.php
* Moved widgets above tools (since tools use widgets)
demos/ve/index.php
* Refactored widget initialization to use options
* Renamed variables to match widget names
ve.init.mw.ViewPageTarget.css
* Adjusted text sizes to make widgets work normally
* Added margins for buttons in toolbar (since button widgets
don't have any)
* Removed styles for init buttons (button widgets now)
ve.init.mw.ViewPageTarget.js
* Switched to using button widgets (involved moving things around
a bit)
ve.ui.LinkInspector.js, ve.ui.MWLinkInspector.js
* Renamed static property "inputWidget" to
"linkTargetInputWidget" to better reflect the required base class
for the properties value
icons.ai, check.png, check.svg
* Added "check" icon, used in menu right now to show which item
is selected
ve.ui.Icons-raster.css, ve.ui.Icons-vector.css
* Added check icon
* Removed :before pseudo selectors from most of the icon classes (not need by button tool anymore, makes them more reusable now)
ve.ui.Tool.css
* Adjusted drop down tool styles so menu appears below, instead
of on top, of the label
* Adjusted paragraph font size to better match actual content
* Updated class names to still work with menu widget changes
(items are their own widgets now)
* Updated selectors as per changes in the structure of button tools
ve.ui.Widget.css
* Added styles for buttons and menu items
* Adjusted menu styles
ve.ui.*ButtonTool.js
* Added config options argument passthrough
ve.ui.ButtonTool.js
* Moved var statement to the top inside constructor
* Switched to using "a" tag to get cross-browser :active support
* Added icon to inside of button to make icon styles more reusable
* Removed disabled support (now provided by widget parent class)
ve.ui.FormatDropDownTool.js
* Updated options initialization to construct menu item objects
* Modified handling of items to account for changes in menu and
item classes
* Optimized onUpdateState method a bit, adding early exit to
inner loop
ve.ui.ButtonTool.js, ve.ui.DropdownTool.js, ve.ui.Context.js,
ve.ui.Frame, ve.ui.Tool.js, ve.ui.Widget.js
* Added chain ability to non-getter methods
ve.ui.DropdownTool.js
* Removed items argument to constructor
* Updated code as per changes in menu class
* Fixed inconsistent naming of event handler methods
* Removed item event handling (now handled by items directly)
* Made use of this.$$ to ensure tool works in other frames
ve.ui.Tool.js
* Made tools inherit from widget
* Moved trigger registry event handler to a method
ve.ui.Context.js
* Switched from using menu to contain toolbar to a simple wrapper
ve.ui.js
* Added get$$ method, a convenience function for binding jQuery
to a specific document context
ve.ui.*Widget.js
* Switched to using a config options object instead of individual arguments
* Added options
* Factored out flags and labels into their own classes
* Refactored value setting methods for inputs
ve.ui.MenuWidget.js, ve.ui.MenuItemWidget.js
* Broke items out into their own classes
* Redesigned API
* Updated code that uses these classes
* Added support for keyboard interaction
* Made items flash when selected (delaying the hiding of the menu for 200ms)
ve.ui.LinkTargetInputWidget.js, ve.ui.MWLinkTargetInputWidget
* Refactored annotation setting methods
Change-Id: I7769bd5a5b79f1ab36f258ef9f2be583ca503ce6
Follows-up I44bcb79a59 and various other changes.
Please remember to generate documentation and resolve
all warnings before pushing into gerrit.
Change-Id: I8a372443e841308463376d8673ce027a97bbcd30
Using localStorage for copy and paste between ve instances previously worked, but broke with the introduction of AnnotationSet. After a discussion with James, rich copy and paste from many sources is the real goal, so copy and paste enhancement should work toward that end.
Change-Id: I58c0f4525e486fada997872b40c2317f57034b7a
rewrapAllNodes is effectively the same as unwrap then wrap
except it operates as one transaction as so avoids a potentially
invalid intermediate state.
Added some more comments for unwrapAllNodes and renamed a varaible
for consistency.
Fixed a typo in Transaction.newFromWrap comment.
Bug: 45242
Change-Id: Ie752a788d087055d97c7c6f75f59c6a2680d26c7
demos/ve/demo.css, demos/ve/index.php
* Style changes for utilities and dump output
* Initially disable the log range button, activate when there's a range to log
* Make range inputs read-only
* Rename some widget variables
* Add extra structure and classes to dump output
ve.ui.Widget.css
* Remove left/right margin for buttons
* Simplify opaque white color
* Modify selector for disabled buttons - see changes in ve.ui.Widget.js
* Added styles for text input widget's readonly and disabled states
ve.ui.Widget.js
* Added disabled state
ve.ui.ButtonWidget.js
* Moved click event handler to method
ve.ui.InputLabelWidget.js
* Moved click event handler to method
ve.ui.InputWidget.js
* Moved input change event handler to method
* Added readOnly state
ve.ui.LinkTargetInputWidget.js
* Corrected documentation
ve.ui.MenuWidget.js
* Blocked interaction while widget is disabled
ve.ui.MWLinkTargetInputWidget.js
* Corrected documentation
* Blocked interaction while widget is disabled
ve.ui.TextInputMenuWidget.js
* Blocked interaction while widget is disabled
Change-Id: I7ea89873b50a98d058d1dd1e309e3e8b7c8e7b2e
Previously, we would translate to the right of an insertion, but for
wrapping transactions that means we end up with something like
<ul><li>|<p>...</p></li></ul>|, which doesn't make any sense. This
change changes this to <ul><li>|<p>...</p>|</li></ul>.
* Add parameter to translateOffset() that toggles the behavior for
the offset before an insertion
* In translateRange(), translate start and end differently
** In some cases this can map them across each other, fix that
Change-Id: Ia2197b08d9f6763be3f2db5a59546ddc3f74a281
We already combine consecutive operations of other types, but didn't do
that for remove. We have to do this, though, because translateOffset()
gets confused otherwise.
Change-Id: I4285a3efd9f2297398f57e2f24adb26adafdf465
* Deleted blocks of code that are never executed.
* Deleted method (showCursor) that is never used.
Change-Id: I031585b40f384d3e0e5d4cb03f626c9229d97fcf
I was seeing intermittent test failures caused by exceptions in
ce.SurfaceObserver (!!), seems to be caused by the FormatAction test
creating a surface but not destroying it.
Change-Id: I7ab070d3c8db934eb9781ac8a6466475144c214e
This changes the node API to work with multiple elements, so we can
support about groups. Instead of passing in and returning single DOM
elements, we use arrays of DOM elements.
ve.dm.Converter:
* Pass modelRegistry into the constructor
* Remove onNodeRegister handler and its data
* Remove getDataElementFromDomElement() and
getDataAnnotationFromDomElement(). Most logic moved into
getDataFromDom(), some into createDataElement()
* Remove createAlien(), replaced with
createDataElement( ve.dm.AlienNode, ... )
* Replace doAboutGrouping() (which wrapped about groups) with
getAboutGroup() (which returns an array of the nodes in the group)
* Put in a hack so <meta>/<link> elements with an mw: property aren't
alienated
* Remove about group wrapping behavior in favor of just outputting
multiple nodes
ve.dm.AlienNode.js:
* For multi-element aliens, only choose inline if all elements are
inline, not just the first one
ve.dm.example.js:
* Add html/0 stuff for meta nodes
* Fix test case to reflect new alien behavior
Change-Id: I40dcc27430f778bc00a44b91b7d824bfb2718be6
Defaults to false, nodes can opt into about grouping. Not being used
yet, will be used in the converter rewrite.
Change-Id: Ic2a529241e69fb07ac926c826ead0108193b3050
wrapAllNodes was calulating the new selection incorrectly. This has
been fixed and a test added.
unwrapAllNodes takes a depth as its argument and unwraps that many
elements from inside the selection.
Tests for wrap/unwrap apply also now check that applying a wrap
and then its inverse as an unwrap result in the document reverting
to its original state.
Change-Id: I7dcacdfb5894be59ffad69b369d7b32933a25b61
In our test case, offset 12 was mapped to 16, but that should be 11.
The problem here was that the offset right before the removal was
mapped to right after the removal, but that's only valid if we're
dealing with a removal, not when we're dealing with a replacement
where we're both removing and inserting data.
Change-Id: Ibf3c1463c0de009578cd50736f19bae82669ced8
This method will take a selection of siblings and ensure they
are the only chlidren in their first parent which can be placed anywhere
(for example the first parent of a tableCell which can be placed anywhere
is a table, and for a listItem is a list).
The method ensures no redundant empty tags are created, so if
the selection encompasses all siblings then no action is taken.
Also in this commit are two test cases run against ve.dm.example.isolationData.
Change-Id: I783bd5ecd9d43d61f9b2685985409b4d746cbe94
This fixes a problem that phantoms would remain visible if moving the mouse quickly. Now binding to mousemove and also mouseout.
Change-Id: I4f5e3319038828f83b108e9f5a45f54ebfeb7027
Use ve.bind in order to change context within which
callback is called - reduces a need of introducing
new local variable.
Change-Id: I75ece695548c87073dd22e5e7ec80057d7132d22
The Parsoid output will also be expected to be a full HTML document. For
backwards compatibility, we allow for the Parsoid output to be a
document fragment as well. We don't send a full document back yet, also
for b/c -- we'll change this later once Parsoid has been updated in
production.
ve.dm.Converter.js:
* Make getDataFromDom() accept a document rather than a node
** Split off the recursion (which does use nodes) into its own function
** For now we just convert the <body>. In the future, we'll want to do
things with the <head> as well
* Pass the document around so we can use it when creating elements
* Make getDomFromData() return a document rather than a <div>
ve.init.mw.Target.js:
* Store a document (this.doc) rather than a DOM node (this.dom)
* Pass around documents rather than DOM nodes
* Detect whether the Parsoid output is an HTML document or a fragment
using a hacky regex
* When submitting to Parsoid, submit the innerHTML of the <body>
ve.init.mw.ViewPageTarget.js:
* s/dom/doc/
* Store body.innerHTML in this.originalHtml
ve.Surface.js:
* s/dom/doc/
demos/ve/index.php:
* Don't wrap HTML in <div>
* Pass HTML document rather than DOM node to ve.Surface
ve.dm.Converter.test.js:
* Construct a document from the test HTML, rather than a <div>
ve.dm.example.js:
* Wrap the HTML in the converter test cases in <body> tags to prevent
misinterpretation (HTML fragments starting with comments, <meta>,
<link> and whitespace are problematic)
Change-Id: I82fdad0a099febc5e658486cbf8becfcdbc85a2d
Converts an HTML string to a brand new document using an iframe hack
(proper ways to do this exist, but don't work cross-browser).
Parsoid will serve us full HTML documents rather than document fragments
soon, so we'll need this functionality (along with some other changes
that I'm working on now) to deal with that change.
This doesn't currently work quite right in IE8 (although we have lots of
other issues in IE8) as well. It's not that hard to fix up though: we
just have to leave the iframe attached to the main document (should
probably provide a destroy function in that case) and the tests have to
deal with the fact that IE normalizes <head></head> to
<head><title></title></head> .
(For backwards compatibility, we'll have to deal with document fragments
as well; this will be implemented as an MW-specific hack in the
integration in the next commit.)
Change-Id: I15f877583c39124ba1c5e8e22585297ff3bac8d6
Resolves (Bug 44838)
Changes:
* onLoad: Setup only if activating. Prevents ve from loading after aborted
while activating.
* onViewTabClick: add clause for activating mode. Calls deactivate with an
override, and exits activating mode.
Change-Id: Ia61cd1d576b63098419474ad58bc01362c08541e
This means that <p data-foo="bar"> will now be converted to a paragraph
with attributes {"html/0/data-foo":"bar"} rather than {"html/foo":"bar"}
This paves the way for multi-element node (about group) handling in the
node API: nodes representing multiple DOM elements will have html/i/attr
to represent an attribute of the i'th DOM element.
Change-Id: Iea52bdccd721942ca708c8f9f47e934524809845
When encountering an inline node (i.e. content node that's not a text
node) within a branch node that's not a content branch node, the
converter should start a wrapper. But it doesn't do this, it only opens
wrappers for text nodes and annotations.
Fixed this in the converter, added a test for it, and fixed an existing
test that asserted the broken behavior.
Change-Id: I6e143e21e68b68f0d85b8772e24a2d3a5d465410
ve.Node.js
* Removed unused emitUpdate property
* Made traverseUpstream a dynamic method rather than static
ve.ce.Node.js, ve.ce.Surface.js
* Updated calls to traverseUpstream
Change-Id: I28a2dac61aa32668d35854fbdb7712401c42336a
Graphics (*.ai, *.png, *.svg)
* Took a pass on all images making them sharper and clearer
* Renamed bold and italic to bold-b and bold-a
* Added bold-f, italic-k, bold-a and italic-a
* Reorganized illustrator file
ve.ui.Icons-raster.css, ve.ui.Icons-vector.css
* Added classes for new icons
* Appended bullet, number, indent and outdent class names with "list"
ve.ui.*ButtonTool.js
* Added definitions for static icon property
* For bold and italic, added i18n style definitions
ve.ui.ButtonTool.js
* Switched from re-using the name property (which is intended to be the symbolic name of the tool used when registering with the tool factory) to using an static icon property for defining the icon
Change-Id: I43e7c35835a1e6dfb06f2a70226fac0d395008e8
* Introduce context object as specified for
ve.dm.Node.static.toDataElement()
* Remove wrapping variable in favor of context.wrapping
* Remove wrappingIsOurs in favor of context.canCloseWrapper
* Introduce originallyExpectingContent and use it to repopulate
context.expectingContent after closing a wrapper
* Replace most uses of branchHasContent with context.expectingContent
** Except for two cases where we need originallyExpectingContent
These changes fix a case where a metaBlock was generated in an inline
position. Updated the tests to reflect this.
Change-Id: I6baf6053f8a3a0b7d91487f812b9235a7b2b3db1
This allows the converter to provide the node handlers with context
information, which hybrid nodes (such as alien and meta) need to decide
which shape to take.
Change-Id: I36860bee560a38ee39a149109be3706e39258edc
Continues where Ibb682332a6084e357104183641a104e3ae1e253f left off, adding tests and removing inconsistencies between the behavior of the document constructor, which was adding empty text nodes to empty paragraphs, and correcting other tests which expected empty text nodes to be there as well.
Change-Id: I414d061cdd494b8023f14e944eda2910a4dab0d4
When there's 2 entities or inline content nodes (like aliens) with text between them, removing that text should remove the node too. If you don't remove the node then CE won't think to make a slug between the two inline nodes.
Change-Id: Ibb682332a6084e357104183641a104e3ae1e253f
Objective: Simplify the registration and use of triggers
Changes:
* Renamed ve.Command to ve.Trigger
* Renamed command demo to trigger demo
* Removed language prefixing of triggers
* Generating trigger tooltips rather than hard-coding them in i18n
* Added documentation to clarify that only 'mac' and 'pc' are supported platforms, and how the default is chosen
* Simplified trigger registry's register command
* Updated trigger registrations
Change-Id: Ibab6ad5b5c86f24707f064967dc2119a81125392
This resolves a TODO
* Added logic to support passing an argument into annotation constructor which is used as the data property (reusing the element argument)
* Updated documentation
* Simplified instantiation of annotations
Change-Id: I142b8fa3883bf70c896a2a568088d833814ef2dc
Extension-specific types are RDFa types (or type regexes) that are
registered with the ModelRegistry separately. If an element has a type
that is extension-specific, then that element can only be matched by a
rule that asserts one of its extension-specific types.
For MediaWiki, we would call
ve.dm.modelRegistry.registerExtensionSpecificType(/^mw:/ ) .
So then an element like <span typeof="mw:foobar"> would either match a
rule specifically for mw:foobar, if one exists, or no rule at all; even
the rule for <span> would not match. The consequence of this is that
elements with unrecognized mw:-prefixed RDFa types are alienated.
Change-Id: Ia8ab1fe5dffb9f813689324372a168e8e4a3e0bc
This won't usefully register the node with the converter right now, but
we need to allow this because the ModelFactory tests will need to have
stub nodes with tag-only matches.
Change-Id: I023cc8ff647363ab55c73dff39b17ca47e9e6681
ModelRegistry registers both annotations and nodes, and performs
matching on both at the same time. It also registers annotations with
the AnnotationFactory, and nodes with the NodeFactory.
Change-Id: I5e68e506a0e573cc0afe6304ccea058ffc20d1c8
Add static properties for matching, data<->DOM conversion, and name. Use
matchTagNames, toDataElement and toDOMElement. name isn't used yet.
Change-Id: I5e7df3303bbd65e6968e931b568c23d76003a9a4
Lots of fixes for "it's" being used incorrectly.
ve.ce.Document.js
* Filled in documentation for missing params
ve.FormatAction.js
* Fixed incorrect tag for returns documentation
Change-Id: Ic256cc6952c31f5e6ae8be92919a0799cfe6188b
* Removed mousedown handler (dragging is handled in ve.ce.surface)
* Added attribute change handler to ve.ce.Node to keep attribute changes on the model in sync with the DOM
Change-Id: I1d6a7f3dc3136439ce511a4f3eb5a54797c8f996
Objective:
* Put command shortcuts in button title attributes. (Bug 42919)
* Provide a registry for platform specific command triggers and their
corresponding i18n messages. (Bug 44012)
* Enable loading of triggers after ve.Surface is created. (lazy load)
Changes:
VisualEditor.i18n.php
* Add default trigger i18n messags for mac and pc system platforms
VisusalEditor.php, demos/ve/index.php
* Add links to files
ve.init.mw.Platform.js
* Define getUserLanguage and getSystemPlatform methods.
ve.init.sa.Platform.js
* Define getUserLanguage and getSystemPlatform methods.
ve.init.Platform.js
* Define abstract methods: getUserLangauge, getSystemPlatform
ve.ui.BoldBUttonTool.js, ve.ui.IndentButtonTool.js, ve.ui.ItalicButtonTool.js,
ve.ui.LinkButtonTool.js, ve.ui.OutdentButtonTool.js, ve.ui.RedoButtonTool.js,
ve.ui.UndoButtonTool.js
* Add registration for command triggers.
ve.Surface.js
* Methodize loading of triggers.
* Bind register event to ve.triggerRegistry to allow lazy loading of triggers.
ve.ui.Tool.js
* Init pre-registered tooltip messages.
* Update tool titles when new triggers are loaded.
ve.CommandRegistry.js
* Remove command registration ( moved to buttons themselves )
ve.TriggerRegistry.js
* New class for registering triggers.
ve.init.mw.ViewPageTarget.js
* Changed instance of unindent command to outdent.
Change-Id: Id8580a3f81aac751db0b7482422a73912648dfed
Logical grouping for Init, Browser Events, Custom Events, Utilities, Helpers, Getters, and Setters. This may be a precursor to a future, larger refactoring.
Change-Id: I059f88a604f0b5bc383eb3ae274bab0fe2dc476b
Resolves a TODO related to the paste target div.
VisualEditor.php
* Added link to ve.Surface.css
ve.Surface.js
* Cleaned up initialization of .ve-surface element
* Removed float clearing div (see ve.Surface.css)
* Removed paste div (moved to ve.ce.Surface)
ve.Surface.css
* Added rule which adds an ":after" element to handle clearing floats
ve.ce.Surface.js
* Cleaned up initialization of DOM elements
* Added paste target div
* Replaced paste element selectors with direct references to this.$pasteTarget
ve.ce.Surface.css
* Changed paste div styles to use a namespaced class instead of a generic ID
demos/ve/index.php
* Added link to ve.Surface.css
Change-Id: Ib93d45ac82ae643fc8e659f5a063c02a8ddacdde
The normalize method doesn't need to be explicitly called anymore because there's not any code that changes the properties of a range directly anymore.
A good way to prove it's not needed anymore is to move the normalization logic to the constructor and then add "console.log(this.from <= this.to );" to the normalize method - you will find that it's never actually doing anything at all because the range was normalized by the constructor.
ve.Range
* Moved normalization logic to constructor
* Removed calls to normalize method
* Removed normalize method
* Simplified documentation for flip method
* Whitespace fixes
ve.Document, ve.dm.Transaction, ve.dm.Surface, ve.dm.Document, ve.ce.Surface
* Removed calls to range.normalize
* Switched to using range.isCollapsed instead of comparing properties directly
Change-Id: I80bfd06f88579c34dce2083c2b70d63ab92f1275
* Made method descriptions imperative: "Do this" rather than "Does this"
* Changed use of "this object" to "the object" in method documentation
* Added missing documentation
* Fixed incorrect documentation
* Fixed incorrect debug method names (as in those VeDmClassName tags we add to functions so they make sense when dumped into in the console)
* Normalized use of package names throughout
* Normalized class descriptions
* Removed incorrect @abstract tags
* Added missing @method tags
* Lots of other minor cleanup
Change-Id: I4ea66a2dd107613e2ea3a5f56ff54d675d72957e
Objectives:
* Make the link inspector easier to use
* Try to resolve a few bugs (bug 43841, bug 43063, bug 42986)
* Stop using jquery.multiSuggest (which didn't really understand annotations)
* Better divide MediaWiki specifics from generic implementations
Changes:
VisualEditor.php, modules/ve/test/index.php, demos/ve/index.php
* Updated links to files
ve.Registry
* Fixed mistake where registry was initialized as an array - this didn't cause any errors because you can add arbitrary properties to an array and use it like any other object
ve.Factory
* Removed duplicate initialization of registry property
* Added entries property, which is an array that's appended to for tracking the order of registrations
ve.CommandRegistry
* Added mwLink command which opens the mwLink inspector
ve.ui.TextInputWidget
* Added basic widget class for text inputs
ve.ui.TextInputMenuWidget
* Added widget that provides a menu of options for a text input widget
ve.ui.MWLinkTargetInputWidget
* Added MediaWiki specific link target widget
ve.ui.MenuWidget
* Converted ve.ui.Menu into a widget
* Moved the body of onSelect to onMouseUp
ve.ui.LinkTargetInputWidget
* Added link target widget which adds link annotation functionality to a normal text input
ve.ui.InputWidget
* Added generic input widget which emits reliable and instant change events and synchronizes a value property with the DOM value
ve.ui.Widget
* Added base widget class
* Widgets can be used in any frame
ve.ui.Tool
* Fixed line length issues
ve.ui.InspectorFactory
* Made use of new entries property for factories to select the most recently added inspector if more than one match a given annotation
ve.ui.Inspector
* Added auto-focus on the first visible input element on open
* Moved afterClose event to after re-focus on document on close
* Added documentation
ve.ui.Frame
* Adjusted documentation
* Added binding of $$ to the frame context so it can be passed around
* Added documentation
ve.ui.Context
* Added ve.ui.Widget.css to iframes
* Updated code as per moving of ve.ui.Menu to ve.ui.MenuWidget
* Removed unused positionBelowOverlay method
* Added CSS settings to set overlay left and width properties according to context size
* Added documentation
ve.ui.DropdownTool
* Updated code as per moving of ve.ui.Menu to ve.ui.MenuWidget
ve.ui.FormatDropdownTool
* Added documentation
ve.ui.MWLinkButtonTool
* Added MediaWiki specific version of ve.ui.LinkButtonTool, which opens the mwLink inspector
ve.ui.Widget.css
* Added styles for all widgets
ve.ui.Tool.css, ve.init.sa.css, ve.init.mw.ViewPageTarget.css, ve.init.mw.ViewPageTarget-apex.css
* Updated code as per moving of ve.ui.Menu to ve.ui.MenuWidget
ve.ui.Menu.css
* Deleted (merged into ve.ui.Widget.css)
ve.ui.Menu.css
* Deleted suggest styles (no longer used)
pending.gif, pending.psd
* Added diagonal stripe animation to indicate a pending request to the API
ve.ui.MWLinkInspector
* Added MediaWiki specific inspector which uses MediaWiki specific annotations and widgets
ve.ui.LinkInspector
* Removed mw global hint (not needed anymore)
* Switched from comparing targets to annotations (since the target text is ambiguous in some situations)
* Switched to using input widget, which is configured using a static property
* Removed use of jquery.multiSuggest
* Moved MediaWiki specifics to their own class (ve.ui.MWLinkInspector)
ve.init.mw.ViewPageTarget
* Added MediaWiki specific toolbar and command options
Change-Id: I859b5871a9d2f17d970c002067c8ff24f3513e9f
Warning: modules/ve/test/ve.qunit.js:5: Class QUnit not found
Warning: .docs/categories.json No class found matching a pattern 've.Position' in categories file
Warning: modules/ve/ce/ve.ce.Surface.js:1297: Unknown type MouseEvent
Warning: modules/ve/ce/ve.ce.Surface.js:1297: Unknown type int
Follows-up:
* Ic21c9d3f
* Ib521eaa6
Change-Id: I8e371a2d4d91a1f03bd4ef59d18b7df715f23238
Some of these stubs didn't inherit Node at all. Made them all inherit
LeafNode because their rules specify they can't have children.
Change-Id: If4afc8de350f67ee78a41307c426ec2aceeb884f
The title attribute should only be rendered. It should not be put in the
HTML that is sent back to Parsoid.
Change-Id: I63c0373c71c3bf01a4238af3ccd02c835a118e2f
Follow up for I6a7c9e8ee8f995731bc205d666167874eb2ebe23
The first pass that Timo took missed the following cases
* "{Array|String}": string is just one of the values
* "{String[]}": string is followed by [] to indicate an array of strings
Change-Id: I65e595e8d37fb624802d84af9536a2d3c5d73c7d
CE doesn't actually render meta nodes anymore now that we split them out
into the meta-linmod.
I took a stab at consolidating metaBlock and metaInline (into simply
'meta'), but we can't do that with the current node API unless we put a
lot of meta-specific hacks in the converter. So I'm leaving this for the
node API rewrite.
Change-Id: Ie83413df718eabcaeb504316a2db0d24a1be2226
IE does not properly support MouseEvent.detail for reporting the number of clicks in a user action. The new clickCounter() function takes a mousedown event and returns the detail property if non-IE or calculates the detail by comparing to a recent history (up to 3) of mousedowns.
Change-Id: Ib521eaa695d7e436d67ebb49106159daadc2ee38
Added check for the existence of the surface before the save dialog is hidden. This oversight caused errors when there was a load error and the user clicked cancel.
Change-Id: I3b6d8d4d9f4c81ffcbd7996d6b17ac04f33bf6d7
See CODING.md for how to run it.
Mistakes fixed:
* Warning: Unknown type function
-> Function
* Warning: Unknown type DOMElement
-> HTMLElement
* Warning: Unknown type DOM Node
-> HTMLElement
* Warning: Unknown type Integer
-> Mixed
* Warning: Unknown type Command
-> ve.Command
* Warning: Unknown type any
-> number
* Warning: Unknown type ve.Transaction
-> ve.dm.Transaction
* Warning: Unknown type ve.dm.AnnotationSet
-> ve.AnnotationSet
* Warning: Unknown type false
-> boolean
* Warning: Unknown type ve.dm.AlienNode
ve.dm doesn't have a generic AlienNode like ve.ce
-> Unknown type ve.dm.AlienInlineNode|ve.dm.AlienBlockNode
* Warning: Unknown type ve.ve.Surface
-> ve.ce.Surface
* ve.example.lookupNode:
-> Last @param should be @return
* ve.dm.Transaction.prototype.pushReplace:
-> @param {Array] should be @param {Array}
* Warning: ve.BranchNode.js:27: {@link ve.Node#hasChildren} links to non-existing member
-> (removed)
* Warning: ve.LeafNode.js:21: {@link ve.Node#hasChildren} links to non-existing member
-> (removed)
Differences fixed:
* Variadic arguments are like @param {Type...} [name]
instead of @param {Type} [name...]
* Convert all file headers from /** to /*! because JSDuck tries
to parse all /** blocks and fails to parse with all sorts of
errors for "Global property", "Unnamed property", and
"Duplicate property".
Find: \/\*\*([^@]+)(@copyright)
Replace: /*!$1$2
* Indented blocks are considered code examples.
A few methods had documentation with numbered lists that were
indented, which have now been updated to not be intended.
* The free-form text descriptions are parsed with Markdown,
which requires lists to be separated from paragraphs by an
empty line.
And we should use `backticks` instead of {braces} for inline
code in text paragraphs.
* Doc blocks for classes and their constructor have to be
in the correct order (@constructor, @param, @return must be
before @class, @abstract, @extends etc.)
* `@extends Class` must not have Class {wrapped}
* @throws must start with a {Type}
* @example means something else. It is used for an inline demo
iframe, not code block. For that simply indent with spaces.
* @member means something else.
Non-function properties are marked with @property, not @member.
* To create a link to a class or member, in most cases the name
is enough to create a link. E.g. Foo, Foo.bar, Foo.bar#quux,
where a hash stands for "instance member", so Foo.bar#quux,
links to Foo.bar.prototype.quux (the is not supported, as
"prototype" is considered an implementation detail, it only
indexes class name and method name).
If the magic linker doesn't work for some case, the
verbose syntax is {@link #target label}.
* @property can't have sub-properties (nested @param and @return
values are supported, only @static @property can't be nested).
We only have one case of this, which can be worked around by
moving those in a new virtual class. The code is unaltered
(only moved down so that it isn't with the scope of the main
@class block). ve.dm.TransactionProcessor.processors.
New:
* @mixins: Classes mixed into the current class.
* @event: Events that can be emitted by a class. These are also
inherited by subclasses. (+ @param, @return and @preventable).
So ve.Node#event-attach is inherited to ve.dm.BreakNode,
just like @method is.
* @singleton: Plain objects such as ve, ve.dm, ve.ce were missing
documentation causing a tree error. Documented those as a
JSDuck singleton, which they but just weren't documented yet.
NB: Members of @singleton don't need @static (if present,
triggers a compiler warning).
* @chainable: Shorthand for "@return this". We were using
"@return {classname}" which is ambiguous (returns the same
instance or another instance?), @chainable is specifically
for "@return this". Creates proper labels in the generated
HTML pages.
Removed:
* @mixin: (not to be confused with @mixins). Not supported by
JSDuck. Every class is standalone anyway. Where needed marked
them @class + @abstract instead.
Change-Id: I6a7c9e8ee8f995731bc205d666167874eb2ebe23
This happens when the <span> is the start of unwrapped content. The
converter logic to look at the tag name in wrapping mode doesn't kick in
because we're not yet in wrapping mode at that point.
The core issue was that previously, we relied on the document
structure/state to choose between alienBlock and alienInline, and only
used the tag name where the document structure was ambiguous (wrapping).
Changed this to be the other way around: we now rely primarily on the
tag name, and if that doesn't match what we expect based on the document
structure, we work around that if possible. Specifically:
* inline tag in our wrapper --> inline alien
* block tag in our wrapper --> close wrapper, block alien
* inline tag in wrapper that's not ours --> inline alien
* block tag in wrapper that's not ours --> *inline* alien
* inline tag in structural location --> open wrapper, inline alien
* block tag in structural location --> block alien
* inline tag in content location --> inline alien
* block tag in content location --> *inline* alien
only in the fourth and the last case do we need to use the "wrong" alien type to
preserve document validity, and it will always be inline where block was
expected, which should reduce UI issues.
The condensed version of the above, which is used in the code, is:
* If in a non-wrapper content location, use inline
* If in a wrapper that's not ours, use inline
* Otherwise, decide based on tag name
* Open or close wrapper if needed
ve.dm.Converter:
* Replace isInline logic in createAlien() with the above
* Factor out code to start wrapping (was duplicated) into startWrapping()
* Call startWrapping() if createAlien() returns an alienInline and we're
in a structural location
Tests:
* Add test cases with aliens at the start and end of unwrapped content
** The first one failed prior to these changes and now passes, the
second one was already passing
* Fix about group test case, was exhibiting the bug that this commit fixes
Change-Id: I657aa0ff5bc2b57cd48ef8a99c8ca930936c03b8
The {{coords}} template is correctly rendered as an inlineAlien, which previously did not have shields. However, the template has a deeply nested span that is positioned and floated. The fix is to shift shielding logic up to AlienNode (from AlienBlockNode) and to show phantoms on all shields (both block and inline). I've also updated the aliens demo to exhibit this corner case.
Change-Id: Ifce60c7762c0ead5c6fe29d6eabf601c1565cbfa
Although $.toJSON optimises heavily for modern browsers (it
becomes a direct reference to JSON.stringify), we still load the
extra plugin.
JSON is specified as part of ECMAScript 5, but most browsers
supported this one before they supported the rest of ES5.
http://caniuse.com/#search=JSON
Cut off for native JSON is IE7, Firefox 3.0 (3.6 supports it) and
Safari 3. Not any of our concern as VE will most likely never
support those (certainly not at this point in time, and less
likely as time goes on).
Change-Id: I4e8f26ac94763fa38d29e41264de0247f53a21e5
en.wikipedia.org has a template gala for edit notices with a whole
bunch of html framework outputted by default from
MediaWiki:Editnotice-0 (even if their underlying system has no
matches for the current page).
In the core editor from EditPage.php this isn't a problem as the
element is just idling hidden above the editor.
In the case of VisualEditor (where we have a custom delivery for
the edit notices) we don't want to say "1 notice available" on
every page, so we need to be smart and quickly walk the dom of the
notice, filter out invisible nodes, and if the resulting nodes
have no contents, ignore the notice all together.
Change-Id: I65447da8b88a9bae9c24ff155544ff66b3fe9100
The rules have changed, these constraints are no longer needed
and actually causing the table.diff to ignore the restrictions
and bump out of the container beyond the width of the window.
This restores the condition under which table.diff is displayed
by core EditPage.php.
Follows-up I5f59482f4db.
Change-Id: I456644bf14efab7dac351818d5c3bb69b9b3c993
Basically saveDialog-body now has three slides:
* review
* report
* save
There is a viewPage.swapSaveDialog method that is called like this
viewPage.swapSaveDialog( 'review' );
initially called from showSaveDialog.
Misc:
* Replaced more reused core message with a ve ones:
savearticle => visualeditor-savedialog-label-save
showdiff => (removed)
* Removed min-height from saveDialog. When slide-review is
load, it is very short and there shouldn't be 10em's of
whitespace below the loader + buttons.
To avoid problems with diff cache being cleared while looking
at the save dialog, we lock and unlock the surface.
We could later remove this as and optimise it as feature, but for
now this fixes a bug.
Change-Id: I5f59482f4db16264014720b199d7652843c36108
-Prevents previously inspected link suggestions from showing prior
to rebuild.
-Ability for onInput to be executed immediately.
-Removed duplicated logic from open method.
-No longer calling onInput on enter key.
Change-Id: I11792b03ec01cc1929009fb76089adcc86c97629
Drop "-down" class in favour of :active CSS pseudo-class.
* http://kimblim.dk/css-tests/selectors/
* http://www.quirksmode.org/css/contents.html
* http://caniuse.com/#search=css%202.1
Rename methods consistently to enableFoo and disableFoo.
Use mw.notify instead of mw.util.jsMessage (the latter takes a
string of html and parses it, instead of taking text).
Also, jsMessage is obsolete (legacy wrapper around mw.notify).
Rename slide-main to slide-save in preparation of other slides
and introduction of multi-step save dialog.
Re-introduce "disabled" state (not css, but actual state) so that
pressing "Show changes" multiple times will not spawn multiple
async operations. The save function guards against this by keeping
a static property in the internal helper method, but there are
still some operations happening between the button and that method
this should be guarded in the UI instead. Follows-up I67819168.
Change-Id: Idf0331377e6be814ccae853228d6159b4ad5a159
In the change: I6781916822b4173ba906b9bc4c341219fbf10d82
71b97ec45b was reversed when I submitted 1789545284
Change-Id: I6cc59a27817bfbe55c7cbf45bba746a4bd6c375f
I noticed this bug on [[List of Presidents of the United States]]. When
there's HTML that looks like "<td>Foo\n<meta/></td>", the converter will
collect the newline in wrappedWhitespace, then attempt to splice it out
and store it in internal data. But instead, it ends up splicing out the
/metaBlock element, which causes strange unbalanced input, which causes
an empty table in the node tree.
Change-Id: I79ed2fa9a834cc42759c7d21250d8842f563d38f
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