# Release 0.8.0

**URL:** <https://discuss.prosemirror.net/t/release-0-8-0/336>\
**Category:** Announce\
**Created:** [June 15, 2016, 1:50pm UTC](https://discuss.prosemirror.net/t/release-0-8-0/336 "2016-06-15T13:50:31Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)\
**Post date:** [June 15, 2016, 1:50pm UTC](https://discuss.prosemirror.net/t/release-0-8-0/336/1 "2016-06-15T13:50:31Z")

</div>

I’ve just released version 0.8.0. The goal of this release was to simplify the structure of the library, as described in [issue #305](https://github.com/ProseMirror/prosemirror/issues/305). I think this succeeded gloriously, leading to much more cleanly decoupled modules, but it did have some costs. Firstly, there’s a long list of breaking changes (see below). And secondly, creating a basic editor is now somewhat more work, since there’s no longer a default schema or a magic system that automatically activates menu items and key bindings based on your schema.

You can see the new patches (all 130 of them) [on github](https://github.com/prosemirror/prosemirror/compare/0.7.0...0.8.0). Get the new version from NPM.

## Release notes

### Breaking changes

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`](http://prosemirror.net/version/0.8.0.html#schema-basic) module exports the schema, node types, and mark types that used to make up the default schema.

The [`schema`](http://prosemirror.net/version/0.8.0.html#option_schema) option is no longer optional (though it is implied if you pass a [`doc`](http://prosemirror.net/version/0.8.0.html#option_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`](http://prosemirror.net/version/0.8.0.html#option_keymap) option. The [default value](http://prosemirror.net/version/0.8.0.html#baseKeymap) 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](http://prosemirror.net/version/0.8.0.html#Plugin).

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`](http://prosemirror.net/version/0.8.0.html#Fragment.toDOM) and [`parseDOM`](http://prosemirror.net/version/0.8.0.html#Schema.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`](http://prosemirror.net/version/0.8.0.html#NodeType.toDOM), [`matchDOMTag`](http://prosemirror.net/version/0.8.0.html#NodeType.matchDOMTag) and [`matchDOMStyle`](http://prosemirror.net/version/0.8.0.html#MarkType.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](https://github.com/marijnh/subscription#readme) module is used for this. The event emitters for an editor instance are grouped in its [`on`](http://prosemirror.net/version/0.8.0.html#ProseMirror.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`](http://prosemirror.net/version/0.8.0.html#ProseMirror.on.click), [`clickOn`](http://prosemirror.net/version/0.8.0.html#ProseMirror.on.clickOn), [`doubleClick`](http://prosemirror.net/version/0.8.0.html#ProseMirror.on.doubleClick), [`doubleClickOn`](http://prosemirror.net/version/0.8.0.html#ProseMirror.on.doubleClickOn), and [`contextMenu`](http://prosemirror.net/version/0.8.0.html#ProseMirror.on.contextMenu) event emitters.

The `removed` event on [marked ranges](http://prosemirror.net/version/0.8.0.html#MarkedRange) was replaced by an `onRemove` option.

The [`apply`](http://prosemirror.net/version/0.8.0.html#ProseMirror.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`](http://prosemirror.net/version/0.8.0.html#ProseMirror.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`](http://prosemirror.net/version/0.8.0.html#commands.toggleMark) command.

The functionality from the `ui/update` module was moved into the `edit` module and is now available through the [`scheduleDOMUpdate`](http://prosemirror.net/version/0.8.0.html#ProseMirror.scheduleDOMUpdate), [`unscheduleDOMUpdate`](http://prosemirror.net/version/0.8.0.html#ProseMirror.unscheduleDOMUpdate), and [`updateScheduler`](http://prosemirror.net/version/0.8.0.html#ProseMirror.updateScheduler) methods.

[Selection](http://prosemirror.net/version/0.8.0.html#Selection) objects now contain [resolved](http://prosemirror.net/version/0.8.0.html#ResolvedPos) 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](http://prosemirror.net/version/0.8.0.html#Fragment.findDiffStart) on `Fragment`.

Some [transformation](http://prosemirror.net/version/0.8.0.html#Transform) methods are now less vague in their parameters. [`wrap`](http://prosemirror.net/version/0.8.0.html#Transform.wrap) requires the range to wrap and the entire set of wrappers as argument, [`lift`](http://prosemirror.net/version/0.8.0.html#Transform.lift) expects a range and target depth.

The [`findWrapping`](http://prosemirror.net/version/0.8.0.html#findWrapping) and [`liftTarget`](http://prosemirror.net/version/0.8.0.html#liftTarget) functions are used to compute these before trying to apply the transformation. They replace `canWrap` and `canLift`.

The structure of the [markdown](http://prosemirror.net/version/0.8.0.html#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`](http://prosemirror.net/version/0.8.0.html#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`](http://prosemirror.net/version/0.8.0.html#menu) module is now a single module, which exports the menu primitives along with the [`menuBar`](http://prosemirror.net/version/0.8.0.html#menuBar) and [`tooltipMenu`](http://prosemirror.net/version/0.8.0.html#tooltipMenu) plugins.

Menu construction is no longer entangled with command definitions. The `MenuCommand` class was replaced with a [`MenuItem`](http://prosemirror.net/version/0.8.0.html#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`](http://prosemirror.net/version/0.8.0.html#Tooltip) class and the [prompt](http://prosemirror.net/version/0.8.0.html#FieldPrompt)-related functionality. Now that command parameters no longer exist, the interface for creating a prompt was also changed.

The events emitted by the [`collab`](http://prosemirror.net/version/0.8.0.html#collab) module (which now exports a plugin) are now [subscriptions](https://github.com/marijnh/subscription#readme) on the plugin state object, named [`mustSend`](http://prosemirror.net/version/0.8.0.html#Collab.mustSend) and [`receivedTransform`](http://prosemirror.net/version/0.8.0.html#Collab.receivedTransform).

`Step.register` was renamed to [`Step.jsonID`](http://prosemirror.net/version/0.8.0.html#Step.jsonID).

All non-essential CSS rules were removed from the core.

### Bug fixes

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.

### New features

[Plugins](http://prosemirror.net/version/0.8.0.html#Plugin) 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`](http://prosemirror.net/version/0.8.0.html#option_plugins) option is the easiest way to enable plugins.

The [`contextAtCoords`](http://prosemirror.net/version/0.8.0.html#ProseMirror.contextAtCoords) method provides more precise information about a given position (including the exact nodes around the position) than the existing `posAtCoords` method.

The [`EditorTransform`](http://prosemirror.net/version/0.8.0.html#EditorTransform) abstraction is now more closely integrated with the editor selection, and you can call [`setSelection`](http://prosemirror.net/version/0.8.0.html#EditorTransform.setSelection) on it to update the selection during a transform.

The new [`applyAndScroll`](http://prosemirror.net/version/0.8.0.html#EditorTransform.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`](http://prosemirror.net/version/0.8.0.html#ProseMirror.addActiveMark) and [`removeActiveMark`](http://prosemirror.net/version/0.8.0.html#ProseMirror.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`](http://prosemirror.net/version/0.8.0.html#Node.forEach) method on nodes and fragments now also passes the node’s index to its callback.

Nodes now have a [`textBetween`](http://prosemirror.net/version/0.8.0.html#Node.textBetween) method that retrieves the text between two positions.

A new [`NodeRange`](http://prosemirror.net/version/0.8.0.html#NodeRange) abstraction (created with the [`blockRange`](http://prosemirror.net/version/0.8.0.html#ResolvedPos.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`](http://prosemirror.net/version/0.8.0.html#NodeType.create) method: [`createChecked`](http://prosemirror.net/version/0.8.0.html#NodeType.createChecked), which raises an error if the given content isn’t valid (full) content for the node, and [`createAndFill`](http://prosemirror.net/version/0.8.0.html#NodeType.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`](http://prosemirror.net/version/0.8.0.html#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`](http://prosemirror.net/version/0.8.0.html#insertPoint) function for finding the position at which a node can be inserted.

The [`OrderedMap`](http://prosemirror.net/version/0.8.0.html#OrderedMap) class received a new method, [`addBefore`](http://prosemirror.net/version/0.8.0.html#OrderedMap.addBefore).

A new module, [`example-setup`](http://prosemirror.net/version/0.8.0.html#example-setup) provides a plugin that makes it easy to set up a simple editor with the [basic schema](http://prosemirror.net/version/0.8.0.html#schema-basic) and the key bindings, menu items, and input rules that used to be the default.

The [list](http://prosemirror.net/version/0.8.0.html#ListItem) 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.

---

<div class="post-metadata">

**Author:** ![forresto](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/forresto/32/108_2.png) [@forresto](https://discuss.prosemirror.net/u/forresto)\
**Post date:** [June 15, 2016, 7:47pm UTC](https://discuss.prosemirror.net/t/release-0-8-0/336/2 "2016-06-15T19:47:59Z")

</div>

> [@marijn](#):
>
> The SchemaItem class, along with the register and updateAttrs static methods on that class, have been removed.

What replaces `Custom.register('parseDOM', 'div' ...` and `Custom.prototype.serializeDOM` ?

Edit: `matchDOMTag` and `toDOM` look like what I’m looking for: [Port the dino demo to current API · ProseMirror/website@7a76931 · GitHub](https://github.com/ProseMirror/website/commit/7a7693162739f2ae749bbf609782f4ec374c71ed#diff-34ba11d811fd160712c96e663dd31d8aL11)

---

<div class="post-metadata">

**Author:** ![wes-r](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/wes-r/32/77_2.png) [@wes-r](https://discuss.prosemirror.net/u/wes-r)\
**Post date:** [June 20, 2016, 3:45pm UTC](https://discuss.prosemirror.net/t/release-0-8-0/336/3 "2016-06-20T15:45:06Z")

</div>

Just wanted to chime in and say that the restructure of commands and usage of keymap has allowed me to drastically cleanup my integration of ProseMirror. I have a handful of behavior differences, particularly around lists, and it is a huge help to be able to chain commands. This allowed me to inject my special handlers before the defaults and then fallback to the defaults for non special cases.

---

<div class="post-metadata">

**Author:** ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)\
**Post date:** [June 21, 2016, 7:25am UTC](https://discuss.prosemirror.net/t/release-0-8-0/336/4 "2016-06-21T07:25:20Z")

</div>

> [@wes-r](#):
>
> Just wanted to chime in and say that the restructure of commands and usage of keymap has allowed me to drastically cleanup my integration of ProseMirror.

Thanks for letting me know! That’s the effect I was hoping for.

---

<div class="post-metadata">

**Author:** ![johanneswilm](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/johanneswilm/32/19_2.png) [@johanneswilm](https://discuss.prosemirror.net/u/johanneswilm)\
**Post date:** [June 22, 2016, 9:52am UTC](https://discuss.prosemirror.net/t/release-0-8-0/336/5 "2016-06-22T09:52:46Z")

</div>

@marijn: Is there any reason to suspect that transformations that were serialized to JSON in PM 0.7.0 would possibly not be applicable on an instance running PM 0.8.1?

---

<div class="post-metadata">

**Author:** ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)\
**Post date:** [June 22, 2016, 10:05am UTC](https://discuss.prosemirror.net/t/release-0-8-0/336/6 "2016-06-22T10:05:16Z")

</div>

Transformations don’t have a `toJSON` method, but if you mean their steps, their JSON format should be compatible between 0.7 and 0.8 (but not between 0.6 and 0.7).

---

<div class="post-metadata">

**Author:** ![johanneswilm](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/johanneswilm/32/19_2.png) [@johanneswilm](https://discuss.prosemirror.net/u/johanneswilm)\
**Post date:** [June 22, 2016, 10:10am UTC](https://discuss.prosemirror.net/t/release-0-8-0/336/7 "2016-06-22T10:10:03Z")

</div>

Yes, sorry. The steps. Thanks, that’s very helpful!

---

<div class="post-metadata">

**Author:** ![johanneswilm](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/johanneswilm/32/19_2.png) [@johanneswilm](https://discuss.prosemirror.net/u/johanneswilm)\
**Post date:** [June 23, 2016, 5:40pm UTC](https://discuss.prosemirror.net/t/release-0-8-0/336/8 "2016-06-23T17:40:41Z")

</div>

before PM 0.8.0, I used to be able to do other operations with dom nodes that were created. For example put them into a formula rendering system or a citation creation system. Now that `serializeDOM` has been exchanged with ```toDOM``, I no longer have access to the dom node that is being created, do I?

I used to do:

```
let dom = serializer.renderAs(node, "span", {
    class: 'equation',
})
katexRender(node.attrs.equation, dom, {throwOnError: false})
dom.setAttribute('contenteditable', 'false')
return dom
```

---

<div class="post-metadata">

**Author:** ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)\
**Post date:** [June 23, 2016, 7:31pm UTC](https://discuss.prosemirror.net/t/release-0-8-0/336/9 "2016-06-23T19:31:25Z")

</div>

For leaf nodes, you can still return any DOM node from `toDOM`, and your example looks like it’s a leaf node.

---

<div class="post-metadata">

**Author:** ![johanneswilm](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/johanneswilm/32/19_2.png) [@johanneswilm](https://discuss.prosemirror.net/u/johanneswilm)\
**Post date:** [June 25, 2016, 9:07am UTC](https://discuss.prosemirror.net/t/release-0-8-0/336/11 "2016-06-25T09:07:25Z")

</div>

I see, thanks.

How about turning the collaborative mode off and then on again in order to set the document?

I see I can do collabEditing.detach() to get rid of it. But I can find no way of reattaching it or of setting the version when reattaching it.

---

<div class="post-metadata">

**Author:** ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)\
**Post date:** [June 25, 2016, 7:21pm UTC](https://discuss.prosemirror.net/t/release-0-8-0/336/12 "2016-06-25T19:21:05Z")

</div>

You can do `collabEditing.config({version: X}).attach(pm)`.

---

<div class="post-metadata">

**Author:** ![johanneswilm](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/johanneswilm/32/19_2.png) [@johanneswilm](https://discuss.prosemirror.net/u/johanneswilm)\
**Post date:** [June 26, 2016, 11:32pm UTC](https://discuss.prosemirror.net/t/release-0-8-0/336/13 "2016-06-26T23:32:02Z")

</div>

thanks!

And then I was wondering why you access the collab the way you do. It seems like what was previously available under `pm.mod.collab` can now be found under `pm.plugin.Collab`, yet you seem to be using `let collab = collabEditing.get(pm)` to get it. Is this just a preference or is there a reason why one shouldn’t access it under `pm.plugin.Collab`?

And one thing that seems slightly unpractical: Earlier one could listen to the signal from the collab module when it received new transforms. Now one has to register a listener. The main difference here is that this listener has to be reregistered every time the collab module is readded, which wasn’t the case when signals were used.

I wonder: would it not be possible to allow for setDoc and changing the version of the collab plugin without having to remove it? Maybe there could be a setting for the collab module to ignore the setDoc?

---

<div class="post-metadata">

**Author:** ![marijn](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/marijn/32/15_2.png) [@marijn](https://discuss.prosemirror.net/u/marijn)\
**Post date:** [June 27, 2016, 6:23am UTC](https://discuss.prosemirror.net/t/release-0-8-0/336/14 "2016-06-27T06:23:24Z")

</div>

> [@johanneswilm](#):
>
> Is this just a preference or is there a reason why one shouldn’t access it under pm.plugin.Collab?

It’s not documented, which means you shouldn’t use it. The `Collab` property name is generated at run-time (in a way that prevents collisions), and it isn’t predictable. Always go through the plugin object to get its state.

> [@johanneswilm](#):
>
> Earlier one could listen to the signal from the collab module when it received new transforms. Now one has to register a listener. The main difference here is that this listener has to be reregistered every time the collab module is readded, which wasn’t the case when signals were used

I’m not sure what you mean. What did you mean to type where it says ‘readded’? The lifetime of subscriptions is the same as the lifetime of the old event handlers – they live as long as the collab object.

---

<div class="post-metadata">

**Author:** ![johanneswilm](https://discuss.prosemirror.net/user_avatar/discuss.prosemirror.net/johanneswilm/32/19_2.png) [@johanneswilm](https://discuss.prosemirror.net/u/johanneswilm)\
**Post date:** [June 28, 2016, 1:00am UTC](https://discuss.prosemirror.net/t/release-0-8-0/336/15 "2016-06-28T01:00:06Z")

</div>

> [@marijn](#):
>
> It’s not documented, which means you shouldn’t use it. The Collab property name is generated at run-time (in a way that prevents collisions), and it isn’t predictable. Always go through the plugin object to get its state.

Ah ok. That makes sense.

> [@marijn](#):
>
> I’m not sure what you mean. What did you mean to type where it says ‘readded’? The lifetime of subscriptions is the same as the lifetime of the old event handlers – they live as long as the collab object.

Ok, somehow that didn’t trigger any bugs in our previous version. At any rate, I found a way around it.

I think our code is working again after the transition to PM 0.8.2 . I just hope the amounts of changes needed will start getting less in future releases.
