Commit graph

34 commits

Author SHA1 Message Date
Catrope 6562b32aa7 Add getDocumentSlice
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
2013-05-25 11:33:14 +00:00
Ed Sanders ff7b8a2591 Transactions to store metadata merge info when present
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
2013-04-16 22:26:56 +01:00
Ed Sanders fdf30b1ac8 Store data in LinearData class with an index-value store for objects
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
2013-03-30 10:06:34 +00:00
Ed Sanders 4988efd35e UnicodeJS library to implement Unicode standards
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
2013-03-27 17:44:22 +00:00
Catrope 1176bf9677 Move .commit()/.rollback() from TransactionProcessor to Document
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
2013-03-25 21:03:44 +00:00
Inez Korczyński 8199f2a1c1 Removed ve.dm.Document.getIEStyleWordBoundary method.
Added ve.ce.Document.getSiblingWordBoundary method.

Change-Id: I44b53273429aede5be10f39c2ee2f70d96cdc6fb
2013-03-21 14:46:13 -07:00
Inez Korczyński 1c62a63bbf Introducing method ve.dm.Document.getIEStyleWordBoundary
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
2013-03-20 16:32:38 +00:00
Ed Sanders 47090bd1fd Add support for non-Latin scripts to wordBoundaryPattern
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
2013-03-14 11:17:28 -07:00
Ed Sanders 981bb3ae7c Add tests for ve.dm.Document.getNearestWordBoundary
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
2013-03-13 17:21:59 +00:00
James D. Forrester 82114467f1 Bump copyright notice year range to -2013 over -2012
199 files touched. Whee!

Change-Id: Id82ce4a32f833406db4a1cc585674f2bdb39ba0d
2013-02-19 15:37:34 -08:00
Trevor Parscal 16310f7535 Added tests and fixed inconsistencies for empty text node handling
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
2013-01-29 15:13:17 -08:00
Trevor Parscal 113c670305 Inline ve.dm.Document.offsetContainsAnnotation
Resolves TODO

ve.dm.Document.js
* Removed offsetContainsAnnotation method
* Inlined uses of removed method

ve.dm.Transaction.js
* Inlined uses of removed method

ve.dm.Document.test.js
* Removed test for removed method

Change-Id: Ie970234ad5d8c0417389b8a45defec9fd5be6a79
2013-01-17 12:07:14 -08:00
Trevor Parscal 8d33a3de0d Major Documentation Cleanup
* 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
2013-01-16 15:37:59 -08:00
Timo Tijhof b11bbed7a6 JSDuck: Generated code documentation!
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
2013-01-05 01:16:32 +01:00
Trevor Parscal 3002bbb591 (bug 42806) Copy/paste errors on unbalanced data
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
2012-12-07 13:34:28 -08:00
Trevor Parscal 5e477cbe98 (bug 42401) Cursor movement fixes
ve.ce.Surface
* Added ve.ce.Surface.adjustCursor, which replaces repetitive and buggy code that was handling left and right arrow key presses
* New method only affects the selection target, so it won't collapse the selection on you - this was what caused bug 42401
* Made hasSlugAtOffset() actually return a boolean

ve.dm.Document
* Fixed turn-around issue in ve.dm.Document.getRelativeOffset - if the offset is already valid and we can't move in the direction we want, we should just leave it be, not turn around
* Since this method was being used by ve.ce.Surface to correct the cursor position on arrow key presses, it was causing the strange cursor jumping when you pressed an arrow key while at the edge of a document

ve.dm.SurfaceFragment
* Fixed typo where getAnnotationRangeFromSelection was preserving selection direction, but checking the wrong properties

ve.dm.Document.test
* Added tests that verify turn-around issue is fixed

Change-Id: Iba55cfc3d531e7d1333b78c94912ff22179aace8
2012-11-30 09:50:47 -08:00
Catrope 49963c75fd Store the data model element in the DM tree
This is cleaner than passing around the attributes separately, and it
allows us to access the annotations in dm.LeafNode as well.

Change-Id: Ie5b90988114835831cbe5cdccf63c7cd45719e31
2012-11-27 14:36:29 -08:00
Catrope 3a047e0208 (bug 42124) Store comments in the meta-linmod
* Make converter generate meta nodes with 'style': 'comment'
* Handle style==='comment' in MetaBlockNode toDOM converter
* Add some comments to the meta test case
** Update other tests accordingly
* Change getDomElementSummary() to actually assert presence of comment
  nodes (specifically, all non-text child nodes)

Change-Id: Ieef9418f4c47df3541477d9420aa2ab8df6e3df1
2012-11-19 20:01:09 -08:00
Catrope 857535b63f Introduce meta-linmod
* ve.dm.Converter still generates metaInline/metaBlock elements as
  before, it's not affected by this change
* ve.dm.Document constructor splits its input into "real" data and
  metadata
** Metadata is stored in this.metadata (the meta-linmod) as a sparse
   array of arrays, with an element for each offset in this.data
** this.data itself does not contain the metadata
** This means the node tree also doesn't contain the metadata
** Which means CE doesn't know about it at all
* All splice operations on the linear model are sent through
  ve.dm.Document.spliceData(), which performs the splice and syncs the
  meta-linmod
** Metadata in the removed range is reaped and added to the metadata for
   the offset immediately following the removal
* ve.dm.Document.getFullData() splices the linmod and meta-linmod back
  into each other; this "full data" is then fed back to ve.dm.Converter

Change-Id: Ief6dfd5b59cc13a8457993ed85c725413029c4fb
2012-11-02 19:06:49 -07:00
Timo Tijhof 4cc2101ffd Test: Enforce # of expected assertions.
Change-Id: I041c792d1841f69677f8c7d38f67108475a0afc9
2012-10-25 22:06:07 +02:00
Catrope 43f1612324 No longer copy data in ve.dm.Document constructor
The data array is now taken by reference, and the caller must perform
any copying required.

Changed tests to make a deep copy of shared data sets (mostly
ve.dm.example) before passing them to ve.dm.Document().

Change-Id: Iedc64f9fd9cd689640de9a19379cf5f3db94a2bb
2012-10-24 17:32:35 -07:00
Catrope 405581f6b8 New annotation API: update tests
Change-Id: I301a1d89c33dd68197d629d187a9a5be8cbf3852
2012-10-12 15:07:28 -07:00
Catrope 0a6a2c7cd8 Revert "No longer create zero-length text nodes"
Inez asked for this to be merged but now says it's broken

This reverts commit 7702ec10dc
2012-10-12 18:04:15 +00:00
Catrope 7702ec10dc No longer create zero-length text nodes
We were populating empty content nodes with zero-length text nodes to
make round-trip tests in the test suite work (otherwise blanking a
paragraph leaves behind a zero-length text node whereas creating an
empty paragraph does not), but the empty nodes are causing problems in
CE apparently.

* Do not create empty text nodes when constructing a node tree
* Be more careful with text-only replacements:
** Don't resize a text node to zero, remove it instead
** There may not be a text node to resize at all, build it in that case
** Switch nodeRange to nodeOuterRange, this was probably broken before

Tests:
* Change test case for zero-length text node to assert that there is
  *no* zero-length text node :)
* Remove a test case concerning an empty text node from the
  ve.ce.TextNode suite

Change-Id: Ie677457f2f0a7823a517ba3077b844ef52a20fcc
2012-10-10 14:48:47 -07:00
Timo Tijhof ab7d6bf082 Documentation & clean up
* Commands for Sublime:

  Find*: "(\* @[a-z]+) ([^{].*) \{(.*)\}"
  Replace: "$1 {$3} $2"

  Save all && Close all

  Find: " function("
  Replace: " function ("

  Save all && Close all

  Find: "Intialization"
  Replace: "Initialization"

  Save all && Close all

* Consistent use of types (documented in CODING.rm):
  - Merged {Integer} into {Number}.
  - Merged {DOM Node} into {DOMElement}.

* Remove work-around /*jshint newcap: false */ from ve.js
  Calling Object() as a function to to use the internal
  toObject no longer throws a newcap warning in JSHint.
  It only does that normal functions now .

  (e.g. var a = Cap(); or var a = new uncap();)

* Add missing annotations (@static, @method, ..).

* Remove unused variables

* Remove null-assignments to variables that should just be
  undefined. There's a few variables explicitly set to null
  whereas they are set a few lines under and not used otherwise
  (e.g. 'tx' in ve.ce.Surface.prototype.onPaste)

Change-Id: I0721a08f8ecd93c25595aedaa1aadb0e08b83799
2012-09-17 16:02:52 +02:00
Catrope 5e7c14c868 Manage annotations in ve.AnnotationSet object
Introduced the ve.AnnotationSet class to manage sets of annotations. This
is a generalization of ve.OrderedHashSet, a class that manages a set
using an array and an object keyed by hash.

Converted everything that stores, tracks or passes around annotations to
use ve.AnnotationSet. In particular, this means the linear model now
contains AnnotationSets instead of hash-keyed objects.

This allows us to maintain the order of annotations in the linear model,
and will help fix bugs with annotation ordering and splitting.

Change-Id: I50975b0a95f4cc33017a0b59fdede9ed1eff0124
2012-09-06 14:39:38 -07:00
Timo Tijhof 71020f7175 Remainder JSHint fixes on modules/ve/*
[jshint]
ce/ve.ce.Surface.js: line 670, col 9, Too many var statements.
ce/ve.ce.Surface.js: line 695, col 6, Missing semicolon.
ce/ve.ce.Surface.js: line 726, col 22, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 726, col 41, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 733, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 734, col 24, Expected '===' and instead saw '=='.
ce/ve.ce.Surface.js: line 1013, col 13, Too many var statements.
ce/ve.ce.Surface.js: line 1019, col 17, Too many var statements.
ce/ve.ce.Surface.js: line 1023, col 18, Too many ar statements.
ce/ve.ce.Surface.js: line 1027, col 13, Too many var statements.
dm/annotations/ve.dm.LinkAnnotation.js: line 70, col 52, Insecure '.'.
dm/ve.dm.Converter.js: line 383, col 29, Empty block.
dm/ve.dm.Converter.js: line 423, col 33, Empty block.

Commands:
 * jshint .
 * ack '(if|else|function|switch|for|while)\('
 * Sublime Text 2:
   Find(*): (if|else|function|switch|for|while)\(
   Replace: $1 (
 * ack '  ' -Q # double spaces, except in certain comments

Change-Id: I8e34bf2924bc8688fdf8acef08bbc4f6707e93be
2012-09-05 13:45:09 -07:00
Trevor Parscal 264b97df7f There's no such thing as ghosts, just sneaky array references
When a document is created, it should take it upon itself to make sure it has a new reference to the data using slice, not place this on the caller. Callers that do not use slice will often find strange and mysterious things going on and not know why. The real reason is that multiple documents sharing a reference to the same data array leads to seriously messed up behavior.

Change-Id: Ic4e25fcd9bf3f41a805003520a8f38e2768f5dbf
2012-08-17 10:37:28 -07:00
Catrope d93b82347b Clean up a few commas and some indentation
The commas were resulting from converting this:
var foo = 3,
	bar = 5;

to this:

foo = 3,
bar = 5;

Change-Id: I0223b34a30d947c6a51f0601727b0c3850239e66
2012-08-10 16:49:14 -07:00
Trevor Parscal d8ee3c2c29 After much research on error objects, native = good, custom = bad
Stack traces, line numbers, etc. All the approaches I've seen are bad hacks. This is the best way to go.

Change-Id: Ib12e9d2ecfe610bcc89d046005e35cc13efa3d99
2012-08-08 10:48:53 -07:00
Trevor Parscal b4de3ead08 Throw ve.Error instead of string literals
Throwing strings is bad because it doesn't include a lot of important
information that an error object does, such as a stack trace or where
the error was actually thrown from.

ve.Error inherits directly from Error. In the future we may create
more specific subclasses and/or do custom stuff.

Some interesting reading on the subject:
* http://www.devthought.com/2011/12/22/a-string-is-not-an-error/

Change-Id: Ib7c568a1dcb98abac44c6c146e84dde5315b2826
2012-08-08 06:19:00 +02:00
Trevor Parscal 13ccb68ae1 Cleanup - all jshint conditions are now met
Also:
* Removed a lot of dead code in Surface that was used in the now dead and gone sandbox.
* Changed from throwing an exception when calling getBalancedData on a range that produces no results from selectNodes to just returning []

Change-Id: Icf27094724eae5b90eec21308f9e26afe877e3ee
2012-08-03 18:56:04 -07:00
Timo Tijhof 88f6089952 Kranitor #1: On-boarding
'''Kranitor commits''' are commits by Krinkle with his janitor hat on.
Must never contain functional changes mixed with miscellaneous changes.

.gitignore:
 * Add .DS_Store to the ignore list so that browsing the directories
   on Mac OS X, will not add these files to the list of untracked
   files.
 * Fix missing newline at end of file

.jshintrc
 * raises -> throws
 * +module (QUnit.module)
 * remove 'Node' (as of node-jshint 1.7.2 this is now part of
   'browser:true', as it should be)

Authors:
 * Adding myself

MWExtension/VisualEditor.php
 * Fix default value of wgVisualEditorParsoidURL to not
   point to the experimental instance in WMF Labs.

Issues:
 * ve.ce.TextNode:
  - Fix TODO: Don't perform a useless clone of an already-jQuerified object.
  - Use .html() to set html content instead of encapsulating between
    two strings. This is slightly faster but more importantly safer,
    and prevents situations where the resulting jQuery collection
    actually contains 2 elements instead of 1, thus messing up
    what .contents() is iterating over.
 * ve.ce.Document.test.js
  - Fix: ReferenceError: assert is not defined
 * ve.dm.Document.test.js
  - Fix: ReferenceError: assert is not defined
 * ve.dm.Transaction.test.js
  - Fix: ReferenceError: assert is not defined
 * ve.dm.TransactionProcessor.test.js
  - Fix: ReferenceError: assert is not defined
 * ext.visualEditor.viewPageTarget
  - Missing dependency on 'mediawiki.Title'

Code conventions / Misc cleanup
 * Various JSHint warnings.
 * Whitespace
 * jQuery(): Use '<tag>' for element creation,
   use '<valid><xml/></valid>' for parsing
 * Use the default operator instead of ternary when the condition and
   first value are the same.
   x = foo ? foo : bar; -> x = foo || bar;
   Because contrary to some programming language (PHP...), in JS the
   default operator does not enforce a boolean result but returns the
   original value, hence it being called the 'default' operator, as
   opposed to the 'or' operator.
 * No need to call addClass() twice, it takes a space-separated list
   (jQuery splits by space and adds if needed)
 * Use .on( event[, selector], fn ) instead of the deprecated
   routers to it such as .bind(), .delegate() and .live().
   All these three are now built-in and fully compatible with .on()
 * Add 'XXX:' comments for suspicious code that I don't want to change
   as part of a clean up commit.
 * Remove unused variables (several var x = this; where x was not
   used anywhere, possibly from boilerplate copy/paste)
 * Follows-up Trevor's commit that converts test suites to the new
   QUnit format. Also removed the globals since we no longer use those
   any more.

Change-Id: I7e37c9bff812e371c7f65a6fd85d9e2af3e0a22f
2012-07-27 14:40:00 -07:00
Trevor Parscal 76bac7d152 Move test files
Change-Id: Id0a0bd5b4a91f702cad34e9f5e7f2121763abffd
2012-07-25 14:35:49 -07:00
Renamed from tests/ve/dm/ve.dm.Document.test.js (Browse further)