PhantomJS doesn't play nicely with document.execCommand and complex
HTML. For testing the attribute stripping, use the clipboardData
path. Add in a special clipboard key value that allows us to manually
trigger this from the tests ('useClipboardData-0').
Change-Id: I0de842095a6a9a766f0f9a2249064ca7707283c8
When pasting into a selected paragraph, or emptying a paragraph Chrome
adds a linebreak. Our paste into empty uses a selected paragraph for
context so the converter picks up this extra linebreak.
It is possible that this breaks are intentional but not likely
so better just to trim than to leave the user with a break which
doesn't even render clearly.
Bug: 58347
Change-Id: Ia6b22cdaeedf1a75bb529c9a5312add9c3ce182c
getDirectionFromRange returns the direction property of the ce nodes under
that range. That method is mostly useful to recognize the overall block
direction of a selection or fragment.
The method is currently used in the following locations:
* ve.ui.Toolbar onContextChange - as a means to recognize the current context's
block direction for the icon directionality.
* ve.ui.MWExtensionInspector - if the selection is text and not an existing node
the input directionality adjusts to the context direction.
Bug: 57421
Change-Id: Ifc01b8e5dc0a2fe39d221e59e452c5cfad709a2d
This means we no longer have to inject the store/internalList etc.
state into the converter manually before generating DOM.
Change-Id: I9d1f5f2592a7c5bf4ad404416b79ad65afd83b9c
ve.dm.MWTransclusionNode
* Implement getClonedElement to remove originalDomElements
and originalMw. We don't want to put these in the clipboard
as there is no guarantee they are the rendering of the current
set of parameters (a refresh may be in progress) and they may
confuse the converter on the way back in.
Remove about attribute to prevent about grouping of duplicated
nodes.
* Set an extra attribute to flag that the outputted DOM doesn't
have any generated content attached to it that can be stored
on load.
* Check for said attribute in toDataElement and skip the
storeGeneratedContents step. This will trigger an async update
of the generated contents on paste.
ve.ce.Surface
* Call cloneElements before writing to pasteTarget so data in external
clipboard is stripped of generated contents.
ve.dm.Node
* Only strip data-parsoid as other attributes may be meaningful.
ve.dm.mwExample, ve.dm.Node.test
* Update tests
Bug: 58241
Change-Id: I3e15cc97e94747647078204a0b398e6ac3ec6382
It appears that if the pasteTarget is given focus too close to the
range being set it may not take effect in time. Moving up to before
any of the selection setting logic seems to fix the issue.
Bug: 58283
Change-Id: I9bfb0ab6952863496fb3548e6804cb347d52cc57
In Chrome you can paste the empty string which triggers
the paste events but doesn't change the paste target. This
results in the insertion of the context character on empty
lines. To avoid this we can detect if the selection we put
around the context character is still there and abort the
paste.
Bug: 58138
Change-Id: Ib73465a2376cd316dbac6ce2567ecb64bc500307
And other focus behavior fixes.
ve.ce.Surface.prototype.focus:
* Restore focus to the pasteTarget if a focusedNode was selected.
This function is invoked when a dialog is closed, and we were
always focusing the documentNode, which means the selection was
restored incorrectly when the selection was really in the pasteTarget.
ve.ce.Surface.prototype.documentOnFocus:
* Don't rerender the model selection if the documentNode was focused but
a focusedNode is selected. Otherwise the user can never deselect a
focusedNode.
ve.ce.Surface.prototype.onModelSelect:
* Rerender the selection even if prev === next. This function was
already called as a means to rerender a lost selection, and it didn't
work if it so happened that the selection was still the same and was
on a focusedNode.
* Clear the surfaceObserver state when moving focus from the
documentNode to the pasteTarget. If we don't do this, then placing
the selection back in the documentNode at the exact same place where
it was before will not be noticed by the observer.
ve.ui.Context.prototype.onSurfaceFocus:
* Hide the context only when an inspector is open, not just when the
context popup is visible. This ensures that the context is still
hidden when the user clicks out of an inspector, but fixes a bug
where the context was hidden when the selection was restored on
an inspectable focusedNode.
Bug: 58090
Change-Id: I0658f025a9c6005d769fd0291380fcb9c1ba4f32
Stripping all HTML atributes (to avoid CE-added styles such as
'font-size: 1em;') also strips data-parsoid which can cause
round trip errors. As an improvement only strip the style
attribute.
Bug: 58136
Change-Id: I34386bd847d1cf0583317a8b07916e43ff7af029
Let's experiment with this via our local Gruntfile. If it works
fine we can install it in Jenkins (similar to node-csslint).
Verify through $ npm install && npm test;
Fixed all outstanding violations.
Also:
* Added syntaxhighight to ignore.
* Added imetests (which contain unformatted JSON) to ignore.
* In ve.dm.ModelRegistry#matchTypeRegExps, removed redundant
!! cast from the [+!!withFunc] statement which was hitting
a bug in node-jscs. All callers to this local private function
pass a literal boolean true/false so no need to cast it.
* Removed "/* key .. , value */" from ve.setProp, though this
wasn't caught by node-jscs, found it when searching for " , ".
* Made npm.devDependencies fixed instead of using tilde-ranges.
This too often leads to strange bugs or sudden changes. Fixed
them at the version they were currently ranging to.
Bug: 54218
Change-Id: Ib2630806f3946874c8b01e58cf171df83a28da29
It's not much of an optimisation to combine these loops but
separating them gives us greater flexibility.
Move the building of the node tree to happen lazily when
getDocumentNode is called.
In the rich paste path we can now create the DM without building
the node tree and remove the metadata.
Change-Id: I10b4bc486ff8ff8037158aa6dfd45aac87557d42
Following on from getDomFromModel, this returns a document model
instead of element linear data. The only instance that hasn't been
replaced is in rich paste, where we need to sanitize the converted
data before constructing the document model.
This should be cleaned up in a later commit.
Change-Id: I37a2b641632af2cb515e3409deed5cd1fa358af5
Currently we assume getNearestContentOffset will give us something
sane however it can return -1 when there is no nearby content and so
an exception is thrown. In this case we have to create an empty
paragraph to place the cursor in.
Change-Id: Ic6c19da881e47ff6be45cdaa4b71bfcc1c654796
Didn't bother to deduplicate blur-focus event pairs that occur when the
focus moves from the documentNode to the pasteTarget or vice versa
(this happens when switching between normal selection and FocusableNode
selection).
Change-Id: If1ccd2fbf11de956b6c2364ae81b9dc20a1bf409
* changes:
Plain text paste with paste special
Use rare unicode characters for paste placeholders
Rich paste
Add fixUpInsertion to newFromDocumentReplace
This is a prerequisite to browser-based grapheme cluster handling, which
is needed so left/right cursoring and backspace behave as users expect.
modules/ve/ve.js
modules/ve/ce/ve.ce.Document.js
modules/ve/ce/ve.ce.js
* Revert cluster-aware splitting to trivial javascript code unit splitting
* Rewrite ve.splitClusters as a trivial compatibility method (remove soon)
* getClusterOffset/getByteOffset use unicodeJS.graphemebreak.splitClusters
modules/unicodejs/tools/unicodejs-properties.py
modules/unicodejs/unicodejs.graphemebreakproperties.js
modules/unicodejs/unicodejs.js
* Allow grapheme break tests to work with surrogate pairs
demos/ve/pages/minimal.html
demos/ve/pages/multibyte.html
demos/ve/pages/unicode.html
* replace file with more precise tests
modules/ve/test/ve.test.js
* Remove reference to grapheme-based splitting (which is no longer used)
* Correct typo
Bug: 53757
Bug: 51472
Bug: 51596
Bug: 51846
Change-Id: Ife34c87ebe40bc1689298b592eec5c0cdc2f7589
Register ctrl/cmd+shift+v as a trigger which sets a flag for the
next paste event.
When the paste special flag is set, modify the sanitizeData method
to strip all annotations, and any elements other than paragraphs.
Bug: 53781
Change-Id: If814e1786ffa805b52ab32f4a06f52da743fd9af
Allow pasting of rich (HTML) content.
ve.ce.Surface
* Use a sliced document clone for converting to DM HTML (copy)
* Add full context to pasteTarget before copying
* Add ve-pasteProtect class to spans to prevent them being dropped
* Implement external paste by converting HTML to data and inserting
with newFromDocumentInsertion
* Remove clipboard key placeholder after read so they aren't picked
up by rich paste. Hash no longer includes the placeholder.
* Detect the corruption of important spans and fallback to clipboard
data HTML if available.
ve.dm.LinearData
* Add clone method for copy
ve.dm.ElementLinearData
* Add compareUnannotated for use by context diffing.
* Add sanitize method for cleaning data according to a set of rules.
ve.dm.Transaction
* Add range parameter for inserting a range of a document only,
e.g. stripping the paste context.
ve.dm.Document
* Implement sliced document clone creation so that DM HTML
is generated correctly in onCopy
ve.dm.DocumentSlice
* Replaces LinearDataSlice. Now has two ranges for balanced data
and data with a full context.
ve.init.Target.js
* Define default, loose, paste rules (just remove aliens).
ve.init.mw.ViewPageTarget
* Define strict MW paste rules:
+ no links, spans, underlines
+ no images, divs, aliens
+ strip extra HTML attribues
ve.init.sa.Target, ve.init.mw.ViewPageTarget, ve.ui.Surface
* Pass through and store paste rules.
Bug: 41193
Bug: 48170
Bug: 50128
Bug: 53828
Change-Id: I38d63e31ee3e3ee11707e3fffed5174e1d633b42
There was a bug when you moved over an image with the arrow keys:
if your selection was on an image and you pressed an arrow key, the
selection would move but focus would remain with the paste target
rather than going back to the document node, which caused strange
symptoms (immobilizing the arrow keys and scrolling horizontally)
in Firefox.
Bug: 57600
Change-Id: Iaf6a49787dd2fd2f3f88abd0d1f5ae512fd3fd68
ve/ce/SurfaceObserver.js
* Do not setTimeout if frequency === null
demos/ve/eventLogger.html
* Standalone event logging script
ve/test/ce/imetests/*.js
* JSON event logs for various tests/browsers/IMEs
ve/test/ce/ve.ce.test.js
* Add an IME test
VisualEditor.hooks.php
* Add test files
Change-Id: I50e89d5a289f3fcb4fe2a6835a2ec96fb497242c
Us grouping the inheritable static properties that way is an
implementation detail that is polluting the index and makes
it harder to refer to individual identifiers.
It also causes problems under JSDuck 5 because that version is
more strict about defining properties (Foo.static.bar) of which
the parent is not defined in the index (Foo.static), we'd have
to add a sea of `@static @property {Object} this.static` all
over the place. Might as well hide this implementation detail
and just consider them static properties (just like we already
do for "private" properties).
Change-Id: Ibf2ebf7752aabc2b75b6ac6fa00e2284a181a600
Otherwise you get rendering issues when you resizing adjacent
resizable nodes and you drag over the other node.
Change-Id: Ie70833fa6ae38879b70a19e8d7ecec13a1d54e92
The generation promise can get resolved (e.g. AJAX request can complete)
after the node has been detached. In that case accessing this.model.doc
will fail, so check for this in doneGenerating().
Also attempt to abort the pending promise on teardown.
Bug: 56649
Change-Id: Ia55f1c2c8dc3a3619c0b50795e50fcae4bc6471f
When the editor is focused, the selection goes back to the start of
the document. This was remedied in the .focus() method, but not in
response to native focus events, so when external code blurred then
refocused the editor, the selection would move to the top.
This broke section editing on wikis where ULS is installed: the
selection would be initialized at the start of the section, but then
ULS would load and blur the documentNode (by focusing the pasteTarget)
and then focus it again, so the selection would move to the top.
Instead of restoring the selection only in .focus(), restore it in
response to focus events on the documentNode. When this is done,
saving and restoring the scrollTop is no longer needed.
Bug: 56651
Change-Id: I14700174ee092f9b208215d31a7d1871078a89bf
The resizing handles under ResizableNode are created in the location of the image
but if the page is edited and the image moves relative to the document, the handles
remained where the image was previously and not where its updated location is at.
This code fixes that bug by changing the CE event listening to the model's 'transact'
instead of 'history', and clears the cached offset when a 'transact' event happens.
Change-Id: Id0e4296dd89b24839ba68a534ca77d73c23b7434
Objectives:
* Rename this.$ to this.$element
* Rename this.$$ to this.$
* Get rid of the need to use this.frame.$$
* Rename OO.ui.Element.get$$ to OO.ui.Element.getJQuery
Changes: (using Sublime Text regex patterns)
* Replace "get$$" with "getJQuery"
* Replace "\.(\$)([^\$a-zA-Z])" with ".$element$2"
* Replace "\.(\$\$)" with ".$"
* Replace "'$$'" with "'$'"
* Set this.$ to null in constructor of OO.ui.Window
* Set this.$ to this.frame.$ in initialize method of OO.ui.Window
* Replace "\.(frame.\$)([^\$a-zA-Z])" with ".\$$2"
Bonus:
* Use this.$() in a bunch of places where $() was erroneously used
Change-Id: If3d870124ab8d10f8223532cda95c2b2b075db94
* Move and rename generic parts of ve.ui to OO.ui
* We now have a UI test suite because ve.Element (outside ve.ui)
is now part of oojs-ui, so it needs a test suite.
* Added to the MW test run (just like we do for unicodejs).
* Updated csslint config (also added ve-mw and syntaxhighlight
which were missing).
oojs-ui still depends on the TriggerRegistry in VE, this is addressed
in a follow-up commit.
Change-Id: Iec147155c1ddf20b73a4d15d87b8742207032312
* changes:
Get rid of dmRendering hack in ve.ce.MWInternalLinkAnnotation
Render resolved URLs for href and src attributes in CE
Give ce.Annotations a reference to their ce.ContentBranchNode
Track the original HTMLDocument in ve.dm.Document
Create CE nodes and annotations with the correct $$
Add ve.resolveUrl for URL resolution
Don't render href as src in MWBlockImageNode
Rename 'html' to 'body' in converter tests
Centralize href computation in getHref(). Because getHref() is provided
by the generic LinkAnnotation class, the subclass implementation is
now simpler.
Bug: 51487
Change-Id: Ia6ca85bc84b4f4453b572285836adb631e8d0683
URLs are resolved according to the <base> URL from the Parsoid DOM.
For instance, a link can have its href set to '../Foo' in the DM, and
the target will show up as '../Foo' in the link inspector, but the CE
rendering will be <a href="http://localhost/Foo"> (assuming Parsoid sent
<base href="http://localhost/wiki/Bar">).
Bug: 48915
Change-Id: I919135eb758c82361525078f276ca193dc4c4820
This gives them a way to reach the dm.Document, which is needed
for ce.Annotations to do URL resolution.
Change-Id: Ia18bd8fc3510ad1b627644cd2c6ebcf148254e05
Most of CE wasn't passing through $$ at all. Also fix CE tests that
weren't passing the required surface parameter to the ce.Document
constructor.
Change-Id: Ia234f174050f4b2666ec20e8acc24c6aa4305202
This is done by using the computed property value rather than the
literal attribute value when rendering href and src attributes.
Helpfully, this provides perfect URL resolution natively in the browser,
which means the document's <base> is respected and all that good stuff.
For GeneratedContentNodes, we also need to find all DOM elements inside
the rendered DOM that have href or src attributes and resolve those.
This is done in the new getRenderedDomElements() function, which the
existing cleanup steps (remove <link>/<meta>/<style>, clone for
correct document) were moved into.
In order to make sure that the computed values are always computed
correctly, we need to make sure that in cases where HTML strings
in data-mw are parsed, they're parsed in the context of the correct
document so the correct <base> is applied.
We still need to solve this problem for models that actually store and
edit an href or src as an attribute. I'll post more about that on
bug 48915.
Bug: 48915
Change-Id: Iaccb9e3fc05cd151a0f5e632c8d3bd3568735309
ContentBranchNode renderContents changes the browser selection, so we
need to change it back.
ve.ce.ContentBranchNode.js
* When rerendering, set a flag on ve.ce.Surface
ve.ce.Surface.js
* On model documentUpdate, reapply selection if flag set
Change-Id: Ib8a168e6ec674b9d8021423f21f7acca75c2fd7c
The SurfaceObserver lock guarded against setTimeout calls, but the lock
was only ever used synchronously.
Remove 'lock' and 'unlock' events. Instead, re-sync the SurfaceObserver
by listening to the 'documentUpdate' and 'select' events.
Signed-off-by: Roan Kattouw <roan.kattouw@gmail.com>
Change-Id: Ib15c39f3d25677da70625581b3b2765ae66994b4
ve.dm.Surface.js:
* Stop emitting 'change' and remove its event documentation
ve.ce.Surface.js:
* Listen to 'select' instead of 'change'
* Perform a CE surface update after model-based keydown handling
ve.dm.Surface.test.js:
* Stop asserting that 'change' is emitted
Change-Id: I8f16289493e835d890709c6dfe093d04c18522b6