Fixed several issues in the handling of clicks on and near leaf nodes.
Fix bug where
liftTarget
would
produce false positives.
Improve support for using ProseMirror in a shadow DOM.
The
ProseMirror.on.domPaste
event can now be used to entirely override the handling of paste
events.
The new
ProseMirror.root
property returns the document or shadow DOM root that the editor is
part of.
New method
PosMap.forEach
to
easily iterate over the changed ranges in a position map.
Marked ranges
now support an elementBefore
option to insert a DOM node before the
range.
Fix DOM node leak in the creation of menu SVG icons.
Fix regression where clickOn
and doubleClickOn
handlers weren't
called on clicked leaf nodes.
Fix crash in DOM parser when parsing a DOM change.
Pasting a single leaf node (a node that doesn't allow content) works again.
Parsing Markdown text with code blocks (indented or fenced) works again.
Fixes a bug where clicking a selectable leaf node would create a selection before that node.
Fix the way requestAnimationFrame
is called to please Internet
Explorer.
Mouse-related event handlers (click
, clickOn
, doubleClick
,
doubleClickOn
, contextMenu
) are now passed the original DOM event.
Adds a new module schema-tables
, that exports node types and
commands for tables, along with a way to easily add them to your
schema.
When pasting text, assign some basic structure to it by inserting
<p>
and <br>
tags.
Fix a bug in EditorTranform.selection
.
Disable the setBlockType
command for non-textblock blocks.
Make splitBlock
handle content restrictions better.
Fix OrderedMap.append
and OrderedMap.prepend
to allow raw-object
arguments.
Fix bug where Node.textContent
didn't actually return a value.
Make the wrapInList
command more robust in the face of schema
constraints.
Fixes addActiveMark
and removeActiveMark
ignoring marks from the
document, and thus accidentally resetting the set of marks when used.
Properly export the parser, serializer, and state classes from the
markdown
module.
The src/
directory no longer uses ES6 modules, and is now
CommonJS-based instead. With ES6 support—except for modules—being
pretty much complete in browsers and node, that was the only thing
holding us back from running the code directly, without compilation.
There is no longer a default schema in the model
module. The new
schema-basic
module exports the schema, node
types, and mark types that used to make up the default schema.
The schema
option is no longer optional (though
it is implied if you pass a doc
option).
The Command
abstraction was entirely removed. When the docs talk
about commands now, they refer to plain functions that take an
editor instance as argument and return a boolean indicating whether
they could perform their action.
Keymaps now map keys to such command functions. The basic keymap for
an editor is no longer inferred from commands, but is now determined
by the keymap
option. The
default value contains a minimal set of bindings not
related to any schema elements.
Defining new options is no longer a thing. Modules that used to use
defineOption
now export plugins.
Changing options at run-time through setOption
is no longer
supported, since the remaining built-in options don't require this.
The docFormat
option, getContent
/setContent
editor methods, and
the format
module have been dropped. You need to explicitly convert
between formats yourself now.
The DOM parsing and serializing from the format
module was moved
into the model
module, as the toDOM
and
parseDOM
methods.
The conversions to and from text and HTML were dropped. HTML can be done by going through the DOM representation, the text format conversions were never very well defined to begin with.
Declaring the way a node or mark type is parsed or serialized was
simplified. See the new toDOM
,
matchDOMTag
and
matchDOMStyle
properties.
The SchemaItem
class, along with the register
and updateAttrs
static methods on that class, have been removed. NodeType
and
MarkType
no longer share a superclass, and registering values on
such types is no longer a thing.
Textblock
is no longer a class that you derive node type classes
from. Just use Block
, and the isTextblock
getter will return the
right value based on the node type's content.
Event handlers are no longer registered with node-style on
methods,
but attached to specific values representing an event source. The
subscription module
is used for this. The event emitters for an editor instance are
grouped in its on
property. So now you'd say
pm.on.change.add(...)
to register a change handler.
The event-like node type methods handleClick
, handleDoubleClick
,
and handleContextMenu
are no longer supported. Instead, you're
expected to use the click
,
clickOn
,
doubleClick
,
doubleClickOn
, and
contextMenu
event emitters.
The removed
event on marked ranges was replaced by
an onRemove
option.
The apply
method on an editor now always
returns the transform, whereas it used to return false
if no change
was made. Its scroll
property (containing a commonly used options
object) was removed.
The checkPos
method on editor objects was removed.
The rank
argument to addKeymap
was
renamed priority
and its meaning was inverted.
The setMark
method on editor instances was removed. Its role is
mostly taken over by the toggleMark
command.
The functionality from the ui/update
module was moved into the
edit
module and is now available through the
scheduleDOMUpdate
,
unscheduleDOMUpdate
, and
updateScheduler
methods.
Selection objects now contain resolved
positions, because that's what you need 99% of the time when you
access them. Their old properties are still there, in addition to
$from
, $to
, $anchor
, and $head
properties. The constructors of
the selection classes expect resolved positions now.
The findDiffStart
and findDiffEnd
functions were moved to
methods on Fragment
.
Some transformation methods are now less vague in their
parameters. wrap
requires the range to wrap and
the entire set of wrappers as argument, lift
expects a range and target depth.
The findWrapping
and liftTarget
functions are used to compute these before trying to apply the
transformation. They replace canWrap
and canLift
.
The structure of the markdown parser and serializer was
changed to no longer rely on SchemaItem.register
. Adjusting the
parser and serializer now works differently (you explicitly create an
object rather than relying on information attached to node types).
The autoinput
module was removed. The inputrules
module now exports a plugin that can be used to add input rules, along
with a number of basic input rules and helper functions to create
schema-specific input rules.
The menu
module is now a single module, which exports the
menu primitives along with the menuBar
and
tooltipMenu
plugins.
Menu construction is no longer entangled with command definitions. The
MenuCommand
class was replaced with a MenuItem
class, which directly declares the things it would previously get from
a command. The concept of a MenuGroup
was dropped (we just use
arrays, since they are always static). Some helper functions for
creating menu items, along with some basic icons, are exported from
the menu
module.
The ui
module is now a single module, which exports the
Tooltip
class and the prompt-related
functionality. Now that command parameters no longer exist, the
interface for creating a prompt was also changed.
The events emitted by the collab
module (which now
exports a plugin) are now
subscriptions on the
plugin state object, named mustSend
and
receivedTransform
.
Step.register
was renamed to Step.jsonID
.
All non-essential CSS rules were removed from the core.
Several issues where the code didn't properly enforce the content constraints introduced in 0.7.0 were fixed.
When pasting content into an empty textblock, the parent node it was originally copied from is now restored, when possible.
Several improvements in the handling of composition and input events (mostly used on mobile platforms). Fixes problem where you'd get a strange selection after a complex composition event.
Make by-word deletion work properly on astral plane characters.
Fix leaked spacer node when the menu bar was disabled while it was floating.
Plugins are objects used to attach (and detach) a specific
piece of functionality to an editor. Modules that extend the editor
now export values of this type. The plugins
option is the easiest way to enable plugins.
The contextAtCoords
method provides
more precise information about a given position (including the exact
nodes around the position) than the existing posAtCoords
method.
The EditorTransform
abstraction is now more
closely integrated with the editor selection, and you can call
setSelection
on it to update the
selection during a transform.
The new applyAndScroll
method on
editor transforms provides a convenient shortcut for the common case
of applying a transformation and scrolling the selection into view.
The new methods addActiveMark
and
removeActiveMark
provide explicit
control over the active stored marks.
The edit
module now exports an object commands
containing a number
of command functions and functions that produce command functions.
Most of the old command objects have an equivalent here.
The forEach
method on nodes and fragments now also
passes the node's index to its callback.
Nodes now have a textBetween
method that
retrieves the text between two positions.
A new NodeRange
abstraction (created with the
blockRange
method on positions) is used
to specify the range that some of the transformation methods act on.
Node types got two new variants of their create
method: createChecked
, which raises an
error if the given content isn't valid (full) content for the node,
and createAndFill
, which will
automatically insert required nodes to make the content valid.
The fixContent
method on node types was removed.
You can now pass a second argument to the Schema
constructor, and access its value under the schema object's data
property, to store arbitrary user data in a schema.
The transform module now exports an insertPoint
function for finding the position at which a node can be inserted.
The OrderedMap
class received a new method,
addBefore
.
A new module, example-setup
provides a plugin
that makes it easy to set up a simple editor with the
basic schema and the key bindings, menu items, and
input rules that used to be the default.
The list node types in the basic schema now require the first child of a list item to be a regular paragraph. The list-related commands are now aware of this restriction.
The following properties on node types have lost their meaning:
kind
, contains
, canBeEmpty
and containsMarks
. The NodeKind
type is also gone.
The information they used to encode is now put in a content expression, which is part of the schema spec, not the node. Such expressions can refer directly to other nodes in the schema (by name).
SchemaSpec
is now an interface, not a class. Its
nodes
field refers to NodeSpec
objects, rather than directly to NodeType
constructors. These hold
not only a constructor but also a content expression and optionally a
group identifier.
The NodeType
methods canContain
,
canContainFragment
, canContainMark
, canContainContent
, and
canContainType
are gone, since they can't accurately express the
constraints of the new content expressions.
Instead, nodes now expose canReplace
,
canReplaceWith
, and
canAppend
. The
contentMatchAt
method gets you a
ContentMatch
object which provides further ways to
reason about content.
NodeType.findConnection
is now at
ContentMatch.findWrapping
, and takes
and returns attributes as well as node types.
Mark types lost their rank
property, as their ordering
is now determined by the order in which they appear in the schema
spec.
Transform steps are now regular classes,
AddMarkStep
, RemoveMarkStep
,
ReplaceStep
, and
ReplaceAroundStep
.
Transform.step
now only takes a step object, not
separate values. The "join"
, "split"
, and "ancestor"
step types
have been superseded by ReplaceStep
and ReplaceAroundStep
.
The collaborative editing protocol was changed, to resolve a synchronization problem. See the guide for an overview of the new protocol.
Node nesting is now expressed through a more powerful mechanism, content expressions.
The ContentMatch
class provides a way to apply and
reason about such content expressions.
The new OrderedMap
class makes it possible to extend
and modify the sets of nodes and
marks in a schema while keeping control over
their order.
Since splitting isn't always possible any more, a new function
canSplit
is exported by the
transform
module.
The new options scrollTreshold
and
scrollMargin
provide more control over scrolling
behavior.
nodesBetween
now passes the node's index to
its callback as fourth argument.
Node types gained a getter isLeaf
to conveniently test whether they allow content.
Resolved positions got a new method
indexAfter
, and their methods that
expect a depth allow the argument to be omitted to specify the
position's own depth, or a negative integer to be passed to specify a
depth relative to the position's depth.
Composition (IME) input is now more robust. This mostly effects Android browsers, where typing is now less buggy.
The iOS virtual keyboard's default case should now update as you type (rather than being stuck in whatever state it was in when you started typing).
Text input read through composition or input events now fires input rules.
A problem where transform filters could corrupt the undo history has been fixed.
0.6.0 (2016-04-13)
Positions in the document are now represented by
integers, rather
than Pos
objects. This means that every function parameter, return
value, or property that used to be a Pos
is now a number instead.
Be extra wary about functions that return an optional position—0 is
a valid position now, so if your code is just checking if (pos) ...
,
it'll break when getting a 0.
The countCoordsAsChild
,
handleClick
,
handleDoubleClick
, and
handleContextMenu
methods on
node types, which used to take a path as an array of
numbers, now get a single number pointing at the node's position in
the document instead.
The "selectNodeLeft/Right/Up/Down"
commands, which were a hack to make node
selection work, are now no longer exposed as commands.
The key bindings for block types changed again, due to the old ones still clashing with default OS X bindings. They are now prefixed with Shift-Ctrl (rather than Shift-Cmd on OS X).
Nodes lost the size
and width
properties, and now expose
a nodeSize
property instead, which is the total
size of the node. The size
attribute on
fragments changed meaning to point at the total size of
the fragment's children (rather than their count).
Node iterators are gone, and replaced by index-based access using the
childCount
property and the
child
and maybeChild
accessors.
The chunkBefore
and chunkAfter
methods on nodes are replaced by a
childBefore
and
childAfter
method with the same role but
slightly different semantics.
Node.slice
now returns a Slice
.
Node.sliceBetween
is gone. The method that
just returns a reduced Node
is now called cut
(and also present on fragments).
The node and fragment methods splice
,
append
, close
, replaceDeep
, and the old replace
are gone.
Document manipulation is now best done in one shot using the new
replace
method, which replaces a range of the
document with a Slice
.
Since we are no longer using arrays of numbers to find nodes,
Node.path
is gone. To find out what an integer position points at,
use Node.resolve
, and then inspect the resulting
ResolvedPos
object.
Node.nodeAfter
is now called Node.nodeAt
. It does mostly the same
thing, except that it now takes a number position.
Node.nodesBetween
passes a start position for the current node,
rather than mutable path, to its callback. Node.inlineNodesBetween
is gone, since it is now very easy to do something like that with
nodesBetween
. Node.descendants
is a new shorthand that iterates
over all descendant nodes.
Fragments lost their toArray
, map
, and some
methods, and otherwise mostly mirror the changes in the Node
type.
The constant empty fragment now lives under Fragment.empty
rather
than emptyFragment
.
Steps lost their pos
property. They now only store a
from
and to
(as numbers rather than Pos
objects).
The result of applying a step no longer contains a
position map. Those can be derived from a step without
applying it now (using the posMap
method). A
failing step no longer returns null
. Rather, a step result contains
either an error message or an updated document.
You no longer need to provide a position map when inverting a step.
The Mappable
interface's map
method now returns a plain position, instead of a
MapResult
. Use the
mapResult
method if you need the additional
information.
Position maps have gotten much simpler, and are created differently now.
Transforms no longer silently ignore failing steps
unless you explicitly tell them to by using the
maybeStep
method. The
step
method, along with most of the other
transformation methods, will raise an error when they can't be
applied.
Transform.replace
now takes a
Slice
object, rather than a full replacement document
with start and end positions.
An unsoundness in the collaborative editing algorithm's handling of replace steps has been fixed.
The SVG icons now also work when you have a <base>
tag on your page.
Fix select-all on Firefox.
Fix crash in history compression.
Properly handle HTML sublists not wrapped in an <li>
tag.
Prevent Ctrl-Enter and Ctrl-Backspace on OS X from messing up our document.
Handle the case where a clipboardData
object is present but doesn't
actually work (iOS).
ProseMirror.flush
now return a boolean
indicating whether it redrew the display.
New data type, Slice
, which represents a piece of document along
with information about the nodes on both sides that are ‘open’ (can be
joined to adjacent nodes when inserting it into a document).
The new "transformPasted"
event can be used to transform pasted or dragged content, as a parsed
Slice
.
The Node.eq
predicate can now be used to determine whether two nodes
are equal.
Mark types can
now control whether they are applied to text typed after such a mark
with their
inclusiveRight
property.
The join
and lift
transform methods now have a silent
parameter to suppress exceptions
when they can not be applied.
The type
parameter to setNodeType
now
defaults to the node's current type.
toDOM
, toHTML
, and toText
now
accept Fragment
objects as well as nodes.
List items now have lift
and
sink
commands.
Fix malformed call that caused any nodes rendered with
contenteditable=false
to be replaced by a bogus <div>
.
0.5.0 (2016-03-22)
ProseMirror now ignores most evens when not focused, so you can have focusable fields inside the editor.
The Markdown serializer is now a lot more clever about serializing mixed inline styles.
Event handlers unregistering themselves is now safe (used to skip next event handler).
The default command parameter prompt UI now shows the command label and a submit button.
When joining an empty textblock with a non-empty one, the resulting block now gets the type of the non-empty one.
Node types can now handle double clicks with a handleDoubleClick
method.
Undo and redo now restore the selection that was current when the history event was created.
The collab module now fires a "collabTransform"
event when receiving
changes.
The "filterTransform"
event can now be used to cancel transforms.
Node kinds can now specify both their super- and sub-kinds.
0.4.0 (2016-02-24)
The way valid parent-child relations for node types are
specified was changed. Instead of relying on strings, node
kinds are now objects that specify arbitrary sub-kind
relations. The static kinds
property on node types replaced by a
non-static kind
property holding such a kind object, and the
contains
property is now expected to hold a kind object instead of a
string.
The keybindings for make-paragraph and make-heading were changed. To make the current textblock a paragraph, you now press Ctrl/Cmd-0, and to make it a heading, you press Ctrl/Cmd-N, where N is the level of the heading.
Copy-pasting between ProseMirror instances is now more robust (the question of whether the selection cuts through nodes at the start and end of the fragment is preserved).
Selection management on mobile platforms should now be improved (no longer unusable, probably still quite buggy).
Fix a problem where reading a change from the DOM was confused by trailing whitespace in a text block.
Fix a bug in scrolling things into view that would break scrolling of anything except the whole document.
Don't render menu dropdown elements unless they actuall have content.
Fix bug that would reset the selection when a
selectionChange
event handler
tried to access it.
The selection classes are now properly exported from
the edit
module.
Drop events can now be intercepted.
The beforeTransform
event is
now fired before a transform is applied.
Menu command icon specs can now provide a
dom
property to provide a piece of DOM structure as their icon.
DOM parser specs can now include a selector
property to only run the parser on nodes that match the selector.
0.3.0 (2016-02-04)
The way menu items for menu modules are configured now works
differently, expecting types from the menu
module.
The way commands declare themselves to be part of a menu group is also
different—the information previously stored in the menuGroup
and
display
properties now goes, in a somewhat different format, in the
menu
property.
The command parameter prompting functionality was changed. The
paramHandler
option has been replaced by a
commandParamPrompt
option. The prompting
functionality now lives in the prompt
module, and
should be easier to extend.
The styling and animation of menus and tooltips was changed to be simpler and easier to maintain. Fancy UI looks are now considered out of scope for this module, and something that should be implemented in third-party modules.
Selection on mobile should work much better now (though probably still far from perfect).
Pressing enter on a mobile device will no longer corrupt the display.
New menu building blocks in the menu
module allow
more control and flexibility when defining menus.
ProseMirror.history
is now documented and received a
new isAtVersion
method to check whether an
editor is 'clean' relative to a given version.
0.2.0 (2016-01-28)
-
The
register
method's signature changed, requiring an item name as well as a namespace. Most uses of the schema registry now use that name to replace a field that was previously part of the registered value. For example, command specs no longer have aname
field, but use the registry name. (This was needed to make it possible to selectively override or disable registered values in classes that derive from schema items.) -
InputRule
s no longer have aname
field, and the corresponding constructor parameter was removed.removeInputRule
now takes a rule object rather than a name string. -
Items in the 'insert' and node type menus are now added with
register
(under"insertMenu"
and"textblockMenu"
) rather then with a direct property. -
The JSON representation of marks changed. This release will still parse the old representation (spitting out a warning). The next release won't, so if you're storing JSON data make sure you parse and re-save at least once with 0.2.0 before upgrading further.
-
The function passed to the
UpdateScheduler
constructor now starts in the DOM write phase (used to be read). -
The
"flushed"
event was removed. -
The
selectedDoc
andselectedText
methods were removed.
-
The Markdown parser now throws an error when encountering a token it doesn't know how to handle.
-
The menubar will no longer hide the top of the content when the controls inside of it line-wrap.
-
Dropped content is now properly selected.
-
Less fragile rules for curly quote autocompletion.
-
The DOM parser now ignore non-displaying tags (like
<script>
and<style>
). -
Our
package.json
now has a"main"
field. -
Fix bug where trailing newlines in code blocks would not be visible.
-
Fix several issues with locating positions in the DOM that occurred for node types that wrapped their content in more than a single element (such as the default code blocks).
-
The menu/menu module now exposes an object
paramTypes
which allows you to add or redefine the types of parameters that can be rendered. -
The ui/update module now exports
scheduleDOMUpdate
andunscheduleDOMUpdate
functions to schedule synchronized DOM updates. -
Schema items now expose a
cleanNamespace
method to 'forget' values registered on superclasses. -
The computation of registered values on schema items can now be delayed to schema-instantiation-time with the
registerComputed
method. -
Schema items can now register
"configureMarkdown"
items to influence the way the parser library is initialized. -
The
"splitBlock"
command will now split off a plain paragraph when executed at the start of a different kind of textblock. -
Node types may now define a
handleContextMenu
method to intercept context menu events inside of them. -
The
Heading
node type now supports amaxLevel
property that subclasses can use to configure the maximum heading level. -
Node types can now declare themselves to be
draggable
. -
Node selections can now be dragged.
Initial release.