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
The new form was implemented in Parsoid and deployed in October, so enough time
has passed that there is no longer any need for VisualEditor to support the old
type.
Bug: 56009
Change-Id: Ief2e584345ccdb0e7eb44ab16c4bc14f7c14f5ec
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 it takes 4 arguments which are all properties
of the document model, so just pass the model instead and
access the properties later. Rename to getDomFromModel.
Change-Id: I0c378a04dc08b9b90bdc3984f8fa8c4acfe0b667
In order to do this we have to separate out the removal
operation from NDFR, so it becomes newFromDocumentInsertion
(again, although actually, for the first time). As NFDI is
an insertion we can just run fixUpInsertion on the data
part of it.
In order for the removal operation to be a proper removal
we have to allow metadata removal (the default is to merge it).
Change-Id: I16d575b61b9796e7e889f2c27cfe02b4a40b7639
This fixes some of the problems with pasting references.
It's a bit overzealous in that references get renumbered even when
replacing, which is unnecessary but doesn't actually have any
noticeable effect.
Unfortunately, the internal list state depends so much on the converter
having run that we now need to add yet another hack, to set the counter
to the appropriate value.
Change-Id: I3c6514ce600af4f4c037f419554d34b5a5c86a63
* Our metadata insertions now need to be the same length as the data
insertion, not one more, so:
** Remove the +1 in the listMetadata splice
** Shorten the metadata variable by dropping the merging of the
metadata right before and right after the internal list; it was
also including the metadata right after the internal list twice
*** We still need to deal with this in some way though, left a TODO
** Fix the metadata insertion test for these changes
* Fix null reference keys in the test data; we made all references
keyed a while ago, but this test data was never updated for that
** The remapping of reference data doesn't remap auto/N keys yet,
left a FIXME for that
Change-Id: I8ef4e6ee7c1808574d81d0b83294848afd400cd7
Because that's what it is now since 'head' was added. Also removed
the wrapping <body> tag (now added by the test runner) and renamed
normalizedHtml to normalizedBody.
Change-Id: I5624ae076c5e661d2789e499cd28e8282c885409
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
Since I0f0a826c in Parsoid, numbered external links are now empty
<a rel="mw:ExtLink"></a> tags. This means we have to put in a node type
for them to prevent them from being considered empty annotations and
getting converted to alienMeta.
MWNumberedExternalLinkNode is protected and focusable to avoid making
the link text (which isn't editable) clickable. It isn't inspectable
yet, we need to work on that.
Bug: 53505
Change-Id: I83f69695f3974089e51a84e799f31ab6ed879e05
Parsoid changed these types from mw:WikiLink/{Category,Language}
to mw:PageProp/{Category,Language} in I0f0a826c. We had previously
added support for them in 4d91e4ed but code overwrote the new types
with the old ones on the way out, triggering the DOM corruption warning.
Change-Id: I768ec2ffd623e5a01f18959277786697603a97f0
Using the MW APIs get a resized version of the image and use
GeneratedContentNode to cache the url.
Bug: 55697
Change-Id: I418f7e1464663f447d46de7ffc29aa5f52d23b12
Instead select the node and require the user to press delete
again if they really meant to delete the node.
Also test cases!
Bug: 55336
Change-Id: I66520e18740e78ce6313f9b31bb575d06b91bea8
We already getSlice which returns a ve.dm.DocumentSlice, so using
the word slice in this method is very confusing. What we are actually
doing is creating a ve.dm.Document from a range. Also remove argument
overloading as it's not particularly helpful and would make the new
name a lie.
Change-Id: I93da3419510410b170396e6765fbe2a87f9795be
Replaces newFromNodeReplacement(). newFromNodeReplacement was very
simplistic and didn't support metadata or internal list items, so
if you had comments or references inside of the data you were editing
(reference contents or an image caption), they'd get mangled.
With this, you can do:
newDoc = doc.getDocumentSlice( node );
// Edit newDoc
tx = ve.dm.Transaction.newFromDocumentReplace( doc, node, newDoc );
surface.change( newDoc );
and that takes care of metadata, internal list items, and things like
references that reference internal list items.
ve.dm.Document.js:
* In getDocumentSlice(), store a reference to the original document
and the number of items in its InternalList at the time of slicing
in the created slice. This is used for reconciliation when the
modified slice is injected back into the parent document with
newFromDocumentReplace().
ve.dm.InternalList.js:
* Add a method for merging in another InternalList. This provides a
mapping from old to new InternalList indexes so the linear model data
being injected by newFromDocumentReplace() can have its InternalList
indexes remapped.
ve.dm.Transaction.js:
* Replace newFromNodeReplacement() with newFromDocumentReplace()
ve.ui.MWMediaEditDialog.js, ve.ui.MWReferenceDialog.js:
* Use getDocumentSlice/newFromDocumentReplace for editing captions/refs
* Change insertion code path to insert an empty internalItem/caption, then
newFromDocumentReplace into that
* Add empty internalList to new mini-documents
ve/test/dm/ve.dm.Transaction.test.js:
* Replace newFromNodeReplacement tests with newFromDocumentReplace tests
ve-mw/test/dm/ve.dm.Transaction.test.js (new):
* Add tests for newFromDocumentReplace with mwReference nodes
ve.dm.mwExample.js:
* Add data for newFromDocumentReplace with mwReference tests
VisualEditor.hooks.php:
* Add new test file
Bug: 52102
Change-Id: I4aa980780114b391924f04df588e81c990c32983
Simply generating ':3' as the "unique" name for the 4th reference
doesn't work. Even if getUniqueListKey() had been used, that only
checks for conflicts with names that have already been encountered
(i.e. occur in <ref> tags that precede the current one), not for
conflicts with names that first occur further down in the document.
The solution is to generate names at serialization time, when we
have full knowledge of which names are in use. Internally, we use
'literal/<name>' for names that literally appeared in the source,
and 'auto/<number>' for unnamed references. Then at serialization
time, we translate 'auto/<number>' to 'literal/:<number>' if needed
(i.e. if the reference was reused).
ve.dm.MWReferenceNode.js:
* toDataElement()
** Prefix listKey with literal/ or auto/ as appropriate
* toDomElements()
** Map auto/ listKeys to unique names
** Don't try to unset the name if not present (was unsetting a property
that didn't exist anyway)
ve.dm.InternalList.js:
* Remove now-unused isUniqueListKey()
* Rewrite getUniqueListKey()
** Make prefix configurable
** Take previously generated unique keys into account
** Map the same old key (auto/N) to the same generated key (literal/:M)
* Add getNextUniqueNumber() as a source for auto/N numbers: previously
used the length of the itemHtmlQueue, but that only works during
conversion, not from the UI dialog
ve.ui.MWReferenceDialog.js:
* For new references or conflicting names, generate an auto/N key and
let toDomElements() deal with actually mapping that to name
ve.dm.InternalList.test.js:
* Rename listKeys to new style
* Split the test case into two groups so we can test multi-group cases
* Add tests for getUniqueListKey()
ve.dm.mwExample.js:
* Rename things to new style
* Modify the test case so it attempts to trigger bug 54341
Bug: 54341
Change-Id: I726fb83e6fb66ffec643d996768a854ec9474b3d
This avoids problems when unnamed references were copy-pasted.
Knowing that key is always non-null simplifies a lot of logic
elsewhere.
Bug: 53365
Change-Id: I3a23123ae732d9583814d38dd880a0cdf691fd5d
GeneratedContentNode didn't track concurrent updates at all, so a
race condition was possible: if the node was updated a second time
before the first update had been rendered, the second update might
render first and then be overwritten by the other one.
To prevent this, we track the promise associated with the current
render. If a new update is launched while a previous one is still
pending we attempt to abort the old one by calling .abort() on it,
and ignore any future resolution or rejection from it.
Also allow rerenders based on non-model data by calling
.update( { config object } );
Change-Id: I8feefd9e8fb6c41d06b8b20131e3be5e37954e83
This is bit of a hack, as leading whitespace could be
significant if styled with white-space:pre.
Long term VE shouldn't be editing the user's HTML, and
should just highlight potential formatting issues.
We avoid the stripping in preformatted elements as we
expect they will have that styling.
Bug: 51462
Change-Id: I654d98e17dd604cb2a192831ff3f3597f95b9962
It's totally unnecessary, and actually caused a bug where new references
got about="undefined", which caused Parsoid to about-group adjacent
new references together.
Bug: 52228
Change-Id: Id40d53c72a35412d612ae9441ae3d561622c1bec
When we encounter a ref tag inside the mw-data of a references
tag, we pass it off to the converter and store it as nested data.
In toDomElements we convert any nested children and write them
back to mw-data if changed.
As refs in references are invisible we exclude them when generating
the references list in ve.ce.MWReferenceListNode.
Bug: 51741
Change-Id: I31d06616849a00449df0fc77f3b33e46207cdc7f
These have been pointing to the same method for a while now,
we can safely remove these obsolete aliases and just use it
as generic copy.
* Each file touched by my editor had its new line at EOF fixed
where absent
* Don't copy an otherwise unused empty object
(ve.dm.Converter)
* Use common ve#copy syntax instead to create a link
(ve.dm.Document, ve.dm.example)
* Remove redundant conditionals for isArray/copyArray/copyObject
(ve.dm.example)
Change-Id: If560e658dc1fb59bf01f702c97e3e82a50a8a255
To achieve this we need to evaluate the DOM contents of
transclusion nodes to see if it consists solely of meta items
and whitespace.
To check for meta items we do a model registry match, but with an
additional parameter to exclude mwTransclusion types as a possible
result (as the first item may be a meta tag, but with a mw:Transclusion
typeof attribute).
Bug: 51322
Change-Id: I89a220350fb7e10e15f3682d21438539196a5846
These represent <nowiki> tags. If the user doesn't edit the text inside
the nowiki, we round-trip the <span typeof="mw:Nowiki"> wrapper cleanly,
but if they do edit it, we unwrap it. This then triggers re-escaping
in Parsoid, and prevents cases where the user edits the text to no
longer need escaping but Parsoid still wraps it in <nowiki> because
of the <span typeof="mw:Nowiki"> wrapper.
In order to detect whether the contents have changed, the nowiki
annotation stores a copy of its contents. To avoid infinite recursion,
we have to exclude this attribute for hash generation.
Bug: 47678
Change-Id: I2edc46b6d87d2f91e952efcb09c0edae5166958f
An empty document is one which contains no 'real' data, so
we should check for meta-only documents when deciding whether
to add in a wrapper paragraph.
Bug: 50289
Change-Id: Ib3ebf0717aa0c6c51fd1d0b14e95de50b2842647
Adjacent annotations should not be merged if they both
originate from Parsoid. This is a hack because this logic
should be in Parsoid, not VE.
Bug: 49873
Change-Id: If1e23e3039178300d72b1c0c585931417bb603b5
Also in this commit is a fix to the regex for brackets in general
as previously it was grouping multiple pairs together which was
making the stack count incorrect.
Bug: 50801
Change-Id: I2cd825eaa7242e37a6317286cb8f9a4a78e693e2
Some of the ones that were moved to ve-mw disappeared from index.php
(the MW-only test runner) and/or VisualEditor.hooks.php (the runner for
Special:JavaScriptTest that's also used by Jenkins).
Add the missing tests, and rename the SurfaceFragment test. We can't
add the ViewPageTarget test to the index.php file in ve-mw because
it only works when running inside an actual MediaWiki instance.
Change-Id: Iec34f2029f5f9c34855b4d79ef70db5751461a96
This is harmful because we don't know whether <span> is acceptable
in context. They're not allowed in <tbody> for instance, and so if
we replace a <tr> with a <span> that breaks things.
Instead, use the nodeName of the first original DOM element.
Change-Id: I95ea9f13985767123f692706c6cc71fefd74d517
Move all MW-specific files into the ve-mw directory, in preparation
for moving them out into a separate repo.
All MW-specific files were moved into a parallel directory structure
in modules/ve-mw . Files with both generic and MW-specific things were
split up. Files in ve/init/mw/ were moved to ve-mw/init/ rather than
ve-mw/init/mw ; they're still named ve.init.mw.* but we should change
that. Some of the test files for core classes had MW-specific test cases,
so those were split up and the test runner was duplicated; we should
refactor our tests to use data providers so we can add cases more easily.
Split files:
* ve.ce.Node.css
* ve.ce.ContentBranchNode.test.js (MWEntityNode)
* ve.ce.Document.test.js (some core test cases genericized)
* ve.dm.InternalList.test.js (uses mwReference test document)
* ve.dm.SurfaceFragment.test.js, ve.ui.FormatAction.test.js
** Made core tests use heading instead of mwHeading
** Updated core tests because normal headings don't break out of lists
** Moved test runners into ve.test.utils.js
* ve.ui.Icons-*.css
* ve.ui.Dialog.css (MW parts into ve.ui.MWDialog.css)
* ve.ui.Tool.css
* ve.ui.Widget.css (move ve-ui-rtl and ve-ui-ltr to ve.ui.css)
ve.dm.Converter.test.js: Moved runner functions into ve.test.utils.js
ve.dm.example.js:
* Refactored createExampleDocument so mwExample can use it
* Removed wgExtensionAssetsPath detection, moved into mw-preload.js
* Genericized withMeta example document (original version copied to mwExample)
* Moved references example document to mwExample
ve.dm.mwExample.js:
* Move withMeta and references example documents from ve.dm.example.js
* Add createExampleDocument function
ve-mw/test/index.php: Runner for MW-specific tests only
ve-mw/test/mw-preload.js: Sets VE_TESTDIR for Special:JavaScriptTest only
ve.ui.Window.js:
* Remove magic path interpolation in addLocalStyleSheets()
* Pass full(er) paths to addLocalStyleSheets(), here and in subclasses
ve.ui.MWDialog.js: Subclass of Dialog that adds MW versions of stylesheets
ve.ui.MW*Dialog.js:
* Subclass MWDialog rather than Dialog
* Load both core and MW versions of stylesheets that have both
ve.ui.PagedDialog.js: Converted to a mixin rather than an abstract base class
* Don't inherit ve.ui.Dialog
* Rather than overriding initialize(), provide initializePages() which the
host class is supposed to call from its initialize()
* Rename onOutlineSelect to onPageOutlineSelect
ve.ui.MWMetaDialog.js, ve.ui.MWTransclusionDialog.js:
* Use PagedDialog as a mixin rather than a base class, inherit MWDialog
bullet-icon.png: Unused, deleted
Stuff we should do later:
* Refactor tests to use data providers
* Write utility function for SVG compat check
* Separate omnibus CSS files such as ve.ui.Widget.css
* Separate omnibus RL modules
* Use icon classes in ViewPageTarget
Change-Id: I1b28f8ba7f2d2513e5c634927a854686fb9dd5a5