Commit graph

80 commits

Author SHA1 Message Date
Trevor Parscal 3f3c87ce24 Link inspector fixes
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
2013-04-24 18:29:55 -07:00
Ed Sanders 8b09dd7650 The resurrection
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
2013-04-22 12:50:23 +01:00
Trevor Parscal bf254f44da UI "Views" refactor
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
2013-04-18 15:53:50 -07:00
Trevor Parscal 2419f7638c Death and/or destruction
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
2013-04-18 13:56:20 -07:00
Trevor Parscal 7ac32bc0f6 No more confusing boolean argument for closing windows
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
2013-04-10 12:31:49 -07:00
Catrope 2eb0d2a6b2 Great Annotation Refactor of 2013
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
2013-04-08 18:10:16 -07:00
Ed Sanders 277c4f6c28 Change custom .getHash functions to .getHashObject
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
2013-04-08 23:29:56 +01:00
Trevor Parscal ec912dc2d1 Link inspector menu not appearing in the right place
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
2013-03-14 16:56:04 -07:00
Trevor Parscal 1572ec1569 Context, frame, window, dialog and inspector refactor
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
2013-03-14 00:03:31 +00:00
Trevor Parscal a5aeca3ff5 Major UI refactoring and improvements
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
2013-02-26 12:29:08 -08:00
Timo Tijhof 0031725751 Cleanup: Omit second argument to setTimeout for "nextTick"
Not 0 or 1.

Change-Id: Ia6eb985e649c5bd196f87aac98c3919e60be9a86
2013-02-26 00:34:58 +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
Rob Moen 4d3ccb7b99 Annotate newly inserted target text as a link.
Fixes (Bug 44086)

Changes:
ve.ui.LinkInspector.js
- Annotate fragment for affected range.
- Fragment returned by insertContent was a zero length range, therefore
no content was being annotated.  It is questionable whether insertContent
should return the affected range or not.
- Also changes behavior of editing existing link annotations so that the cursor is after the annotation rather than covering it when the inspector is closed

Change-Id: Ic53b9844f84781cad05ac1f63964c9aaf7de68c3
2013-02-07 16:06:08 -08:00
Trevor Parscal 280c85d8e7 Added support for passing data into annotation constructors
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
2013-01-28 11:01:52 -08:00
Trevor Parscal bf5ba1ea2b Fixed documentation errors
Many of these problems were introduced in I859b5871a9d2f17d970c002067c8ff24f3513e9f

Change-Id: Ifc2dc4934f782c4ce5107e3a356e357aef754083
2013-01-22 23:38:01 +00: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
Trevor Parscal f31dc45da8 (bug 43841) Major ve.ui rewrite, especially ve.ui.LinkInspector
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
2013-01-15 15:05:11 -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 abdcacd68a Move the cursor to the end of newly inserted links
Inserted links happen when the cursor is not near a word, so we insert the target as text

Change-Id: I06c2c425d28db7ca61f13c438e25cc9c75f391f4
2012-12-11 11:09:26 -08:00
Trevor Parscal 353297e5b5 (bug 42925) Inspector doesn't open properly
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
2012-12-10 16:48:13 -08:00
Rob Moen 9ba19af1c0 Immediately provide default suggestions based on 0 results.
Allows suggest tool to open immediately and provide new page and
external link suggestions for link inspector.

Resolves (Bug 42341)

Change-Id: I79bc3e31033b5c38c3ed6ab23e601476cb17ba8f
2012-11-29 15:26:47 -08:00
Trevor Parscal 8fc98868c9 Fixed inspector behavior
ve.ui.Inspector
* Removed disabled state and interfaces - this isn't needed
* Renamed prepareSelection to onInitialize
* Using event emitter to run onInitialize, onOpen and onClose methods
* Left removal up to the child class to handle in the onClose method
* Replaced calls on context to close inspector to calling close directly
* Renamed prepareSelection stub to onInitialize
* Emitting initialize event from within the open method
* Added recursion guarding to close method
* Changed the close method's argument to be remove instead of accept - the more common case is to save changes, and the only time you wouldn't save changes is if you were to remove the annotation
* Moved focus restore to close method

ve.ui.Context
* Moved the majority of the code in openInspector and closeInspector to event handlers for onInspectorOpen and onInspectorClose
* Updated calls to closeInspector re: accept->remove argument change

ve.ui.LinkInspector
* Renamed prepareSelection to onInitialize and rewrote logic and documentation
* Removed unused onLocationInputChange method
* Moved restore focus (now it's in the inspector base class)

ve.dm.SurfaceFragment
* Added word mode for expandRange

ve.dm.Surface
* Added locking/unlocking while processing transactions - this was not an issue before because this was effectively being done manually throughout ce (which needs to be cleaned up) but once we started using the content action to insert content dm and ce started playing off each other and inserting in a loop - we already do this for undo/redo so it makes sense to do it here as well

ve.InspectorAction
* Updated arguments re: close method's accept->remove argument change

Change-Id: I38995d4101fda71bfb2e6fe516603507ce820937
2012-11-21 12:01:14 -08:00
Trevor Parscal 05e39c1733 Always apply inspected annotations to the right range
When you leave the inspector by changing the selection, we need to apply changes to the old selection.

ve.ui.Inspector
* Added initialSelection
* Change getMatchingAnnotations to use a given fragment rather than generating it's own
* Set initialSelection on open

ve.ui.Context
* Make hiding the context accept changes

ve.ui.LinkInspector
* Passing a fragment into getMatchingAnnotations now
* Using fragment API instead of actions API to control the range of the fragment

Change-Id: If6c8845285d87d0f144b15d50c38e192c797be59
2012-11-19 17:54:55 -08:00
Catrope f856a10fa0 Merge "Added undo-before-apply for new link annotations" 2012-11-20 01:10:29 +00:00
Trevor Parscal 9c22ee346a Added undo-before-apply for new link annotations
When the link inspector is used to create a new annotation, the text is annotated with the default link target derived from the selected text. Then if the inspector is used to change that value, yet another transaction is processed when the inspector is closed.

To avoid having to press undo 2x, this change makes the inspector undo it's first change before applying the changed annotation.

This change also introduces insert, remove and select content actions.

Change-Id: I3e29189158fb01336d6b053bc2a8bda2a91a0a46
2012-11-19 17:10:05 -08:00
Trevor Parscal 96fcbbd695 Cleanup var statements
Put non-assignment vars first

Change-Id: Id868976bc4d7c21032aef5020fe5fd0eb5df7a14
2012-11-19 17:05:34 -08:00
Trevor Parscal d2476a26d2 The great inspector and context rewrite of 2012
ve.AnnotationAction
* Added filter to the clearAll method to allow clearing all matching annotations only

ve.dm.Document
* Some variable renaming for consistency

ve.dm.SurfaceFragment
* Added truncateRange method
* Added annotation scope to expandRange method
* Added support for passing an annotation object into annotateContent method
* Switched to using name instead of type in annotateContent method to match the ve.dm.Annotation class
* Fixed logic in annotation mode of expandSelection so that expansion only takes place if the annotation is found

ve.ui.LinkInspector
* Moved most of the functionality elsewhere
* General reorganization
* Changed setOverlayPosition to accept 2 arguments instead of an object with 2 properties and renamed it to positionOverlayBelow
* Check for annotation object before extracting target information from it
* Initialize default target as empty string to avoid undefined being cast to a string and the default target becoming 'undefined'

icons.ai, inspector.png, inspector.svg
* Added generic inspector icon which will be used when a custom icon is not specified in future inspector subclasses

ve.ui.Inspector.Icons
* Added inspector icon
* Renamed clear icon to remove to match it's actual image

ve.ui.Context
* Greatly simplified the interface, reducing the number of methods by inlining a few things and combining others
* Now always listening to resize events on the window rather than only while document is focused
* Not listening to scroll events anymore, they used to affect the top/bottom positioning of the menu which we don't do anymore
* Lots of cleanup and reorganization
* No need to fallback to empty array since getInspectorsForAnnotations does so already
* Only consider fully-covered annotations for inspectors

ve.ui.Frame
* Simplified the constructor by introducing the createFrame method
* General cleanup
* Typo fixes

ve.ui.Inspector
* Generalized lots of functionality previously located in the link inspector class which will be useful to all inspectors (such as title, clear button, saving changes, etc.)
* Added setDisabled and isDisabled methods to manage CSS changes and avoid needing to check the CSS to determine the state of the inspector (storing state in the view is evil)
* Added getMatchingAnnotations method for convenience
* Added prepareSelection stub
* Lots of cleanup and documentation
* Type pattern is now defined in base class
* Added stubs for onOpen and onClose with documentation so that subclass authors know what these methods do
* Removed checks for onOpen or onClose methods since they are now noop stubs and are always there
* Added stub and removed checks for onRemove
* Made esc key close and accept - the illusion is supposed to be that the link changes are applied instantly, even though they are only updated when you close, so all closing except for when removing should apply changes - i.e. esc is now equal to back rather than being a special function that doesn't have an associated affordance
* Only consider fully-covered annotations when getting matching annotations

ve.ui.InspectorFactory
* Depending on type pattern now since it's always there
* Added getInspectorsForAnnotations method
* Return empty array if annotation set is empty

VisualEditor, VisualEditor.i18n
* Added default inspector message

Change-Id: I1cc008445bcbc8cba6754ca4b6ac0397575980d5
2012-11-19 15:21:27 -08:00
Trevor Parscal d631bac3db Merge "Base for inspectors & context menu to operate on 0 length selection." 2012-11-02 21:38:14 +00:00
Rob Moen 5d86bc4379 Base for inspectors & context menu to operate on 0 length selection.
* Allow inspector to open with 0 length selection.
* Allow context menu to open with 0 length selection.
* Fixed bug in doc.getAnnotationsFromRange on zero length selection:
  Method now returns annotations from start vs empty annotation set.

Change-Id: I3937c5c2824c7396d0c3ee11c13ffecdbed6052a
2012-11-02 13:08:32 -07:00
Trevor Parscal a4e0e83f24 Cleanup tool API
* Moved to tool specific configuration to static properties (left tool instance specific stuff in the constructors)
* Added documentation for tool configurations
* Centralized typePattern matching for inspectors

Change-Id: Ieacf61b320c10fd37ea69a05e543313fa990b403
2012-10-31 11:10:17 -07:00
Rob Moen 9563f0880d UI context reorganization, inspector rewrite, iframe refactor, icon generalization
* Only show the inspector if the selected text has an inspectable annotation
* Replace the inline menu with a toolbar containing inspectable annotations
* Change the appearance of the inspector to match new mockups
* Add the trash can icon for removing annotations
* Move iframe handling code into a class that manages all that nonsense

Change-Id: I840f72426f9a9e50054a28de950393f0e9913153
2012-10-26 14:46:11 -07:00
Trevor Parscal 5cd4222d9c Whitespace and comment cleanup for dm annotation classes
* Added comments to classes and methods
* Quieted a jshint warning
* Broke some long lines
* Replaced instances of "var\t" with "var "

Change-Id: I1d617ed9e5180f1a3dff42078fb5debb5d718407
2012-10-17 12:35:28 -07:00
Catrope a328a43373 Fix UI for annotation API changes
Change-Id: Ib8341436ba966628c93854a742d8b3a5b45a1d83
2012-10-12 17:53:42 -07:00
Rob Moen 4613707909 re: AnnotationSet, fix JS error in getFirstLinkAnnotation.
Change-Id: I6a3cb4eb2164bf1c4c8f715e42117ac06cccac04
2012-09-24 17:16:10 -07:00
Rob Moen d5d44df053 Regression fix, clearing only link annotations when creating link.
Clearing only existing selected links when:
1) Creating a link
2) Pressing clear button

Change-Id: I4b1bcd9a3ac177b2f9b4af2d562d4c4fec09d5c5
2012-09-24 15:03:53 -07:00
Trevor Parscal 944228aec7 Whitespace and comments
* Added documentation for ve.AnnotationSet
* Replaced uses of "// Inheritance" with "// parent Constructor"
* Added "// Mixin constructor" where needed
* Added missing section comments like "/* Static Methods */"
* Cleaned up excessive newlines (matching /\n\n\n/g)
* Put unnecessarily multi-line statements on a single line

Change-Id: I2c9b47ba296f7dd3c9cc2985581fbcefd6d76325
2012-09-17 16:53:03 -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
Rob Moen 442a8358ea (Bug 33094) Disallow invalid page titles in LinkInspector.
Detecting page status in a similar way as WikiEditor inspector.
Disabled accept button now behaves appropriately.
Accept button status is now evaluated on enter or submit.

Change-Id: Ibfef6ffd87cb9a71e37242d6214d0f8e3af2e2c0
2012-09-14 14:51:26 +02:00
Trevor Parscal 4cdce88b9a Merge "Fixed multiple bugs with Context Icon appearing when not relevant." 2012-09-07 23:12:31 +00:00
Rob Moen bcaab3332e Fixed multiple bugs with Context Icon appearing when not relevant.
Icon appears when scrolling and resizing window.
	Instead of always setting the context on scroll and resize, bind to the
	updateContextIcon method.
Icon appears when selecting a non content data offset.
	Changed logic to show icon changed to content length vs range difference.

Move Link inspector getSelectionText to ve.dm.document getText.
Rationale, more bits of the code depend on evaluating content.
Added new ve.Range truncate method.
Remove getSelectionText, using truncate range & document.getText instead.

Change-Id: Ibd3e99c923f18d2c96a86d92e74e2e9ebd49c85f
2012-09-07 16:12:14 -07:00
Catrope 74ed8e8766 Rename ve_foo_bar back to VeFooBar per discussion
Change-Id: Ibf6d4f08c4761727b2e3952a76e474c8221b38f9
2012-09-06 16:15:55 -07:00
Timo Tijhof b1d9c83b5d Object management: Object create/inherit/clone utilities
* For the most common case:
  - replace ve.extendClass with ve.inheritClass (chose slightly
    different names to detect usage of the old/new one, and I
    like 'inherit' better).
  - move it up to below the constructor, see doc block for why.

* Cases where more than 2 arguments were passed to
  ve.extendClass are handled differently depending on the case.

  In case of a longer inheritance tree, the other arguments
  could be omitted (like in "ve.ce.FooBar, ve.FooBar,
  ve.Bar". ve.ce.FooBar only needs to inherit from ve.FooBar,
  because ve.ce.FooBar inherits from ve.Bar).

  In the case of where it previously had two mixins with
  ve.extendClass(), either one becomes inheritClass and one
  a mixin, both to mixinClass().

  No visible changes should come from this commit as the
  instances still all have the same visible properties in the
  end. No more or less than before.

* Misc.:
 - Be consistent in calling parent constructors in the
   same order as the inheritance.
 - Add missing @extends and @param documentation.
 - Replace invalid {Integer} type hint with {Number}.
 - Consistent doc comments order:
   @class, @abstract, @constructor, @extends, @params.
 - Fix indentation errors
   A fairly common mistake was a superfluous space before the
   identifier on the assignment line directly below the
   documentation comment.
   $ ack "^ [^*]" --js modules/ve
 - Typo "Inhertiance" -> "Inheritance".
 - Replacing the other confusing comment "Inheritance" (inside
   the constructor) with "Parent constructor".
 - Add missing @abstract for ve.ui.Tool.
 - Corrected ve.FormatDropdownTool to ve.ui.FormatDropdownTool.js
 - Add function names to all @constructor functions. Now that we
   have inheritance it is important and useful to have these
   functions not be anonymous.

   Example of debug shot: http://cl.ly/image/1j3c160w3D45

   Makes the difference between

   < documentNode;
   > ve_dm_DocumentNode
     ...
     : ve_dm_BranchNode
       ...
       : ve_dm_Node
         ...
         : ve_dm_Node
           ...
           : Object
             ...

   without names (current situation):

   < documentNode;
   > Object
     ...
     : Object
       ...
       : Object
         ...
         : Object
           ...
           : Object
             ...

   though before this commit, it really looks like this
   (flattened since ve.extendClass really did a mixin):

   < documentNode;
   > Object
     ...
     ...
     ...

   Pattern in Sublime (case-sensitive) to find nameless
   constructor functions:
   "^ve\..*\.([A-Z])([^\.]+) = function \("

Change-Id: Iab763954fb8cf375900d7a9a92dec1c755d5407e
2012-09-06 15:29:31 -07: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
Rob Moen 67749504d2 Center Ellpisis for long page titles. Misc positioning fixes.
MultiSuggest:
Added CSS Ellipsis config option which provides CSS to suggestion items.

LinkInspector:
-Configured multiSuggest for page suggestions with CSS ellipsis off and removed CSS definitions.
Instead, using jquery.autoEllpisis plugin for centered position ellipsis. (Bug 39591)
-Temporary tweak to link input padding to prevent text from overlapping down arrow.
Down arrow soon to be implemented differently.

RTL Fixes:
-MultiSuggest overlay positions correctly by setting a width.
-MultiSuggest background image position fix.

Change-Id: I806ead5a2c2621589f76cfb2b03805cbd0b0a18a
2012-09-05 13:21:29 -07:00
Trevor Parscal d208ca9002 Cleaned up uses of jQuery to create and appendTo/prependTo
* Separated DOM changes from creation of elements
* Always using parsing for element creation with known attributes
* Always using attr or addClass for variable attributes

Change-Id: Id101f56594014786892d382d06c658f416224a9c
2012-08-29 18:43:48 +02:00
Trevor Parscal a52d7ff65a Finally getting rid of all the es-* stuff and other cruft
* Switched a lot of classes from es-* to ve-ui-*
* Removed all the DOM structure left over from the old sandbox demo
* Got rid of transparent backgrounds
* Added menu font-size rule to stand-alone target
* Moved some rules around that were in the wrong places
* Got rid of some unused/unneeded methods in the mw target (attach and detach surface methods)
* Added active class to context icon with shallower shadow effect so it doesn't break your spacial perception when you click on it
* Renamed the iframe and iframe wrapper elements so it's easier to see where they came from
* Removed unused CSS rules
* Fixed some uses of prop( 'class', … ) to addClass

Change-Id: I54a660ca0baf0baa4463faca7a1edcf648130b6b
2012-08-28 13:59:35 -07:00
Trevor Parscal a8166fe5a4 A bit of cleanup in the inspector and suggestion code
* function() -> function ()
* ){ -> ) {
* Quoted JSON keys (Look the other way Timo!)
* Using more descriptive group names, which also avoid using "new" as a key
* Line breaks at 100 columns using 4 spaces/tab
* Not setting classes on suggestion items that have no effect (such as 'external' on a div - even on an <a> tag this isn't enough to get the style because it's not inside #content)

Change-Id: I37032fa8ba93adb7b719d9797f9b1b806359cc13
2012-08-27 16:39:08 -07:00
Rob Moen 986d25eea1 Move caching mechanism out of multiSuggest plugin to linkInspector
Fixed issue where overlay would be incorrectly positioned if built
from previous caching method.

Change-Id: Id7c3ba211d5344292da47917a9bd06654823ee87
2012-08-24 14:04:33 -07:00
Trevor Parscal 7576c0fa5f Some basic link inspector style changes
Some of the HTML structure in the suggestions might need to be changed to pull off pixel-perfect reproduction of the original design, but this gets us very close.

Change-Id: Ie574577af4815e4f0fc9f8a03e57759dd9dfff84
2012-08-20 12:32:42 -07:00