Giter VIP home page Giter VIP logo

parchment's Introduction

Parchment Build Status

Parchment is Quill's document model. It is a parallel tree structure to the DOM tree, and provides functionality useful for content editors, like Quill. A Parchment tree is made up of Blots, which mirror a DOM node counterpart. Blots can provide structure, formatting, and/or content. Attributors can also provide lightweight formatting information.

Note: You should never instantiate a Blot yourself with new. This may prevent necessary lifecycle functionality of a Blot. Use the Registry's create() method instead.

npm install parchment

See Cloning Medium with Parchment for a guide on how Quill uses Parchment its document model.

Blots

Blots are the basic building blocks of a Parchment document. Several basic implementations such as Block, Inline, and Embed are provided. In general you will want to extend one of these, instead of building from scratch. After implementation, blots need to be registered before usage.

At the very minimum a Blot must be named with a static blotName and associated with either a tagName or className. If a Blot is defined with both a tag and class, the class takes precedence, but the tag may be used as a fallback. Blots must also have a scope, which determine if it is inline or block.

class Blot {
  static blotName: string;
  static className: string;
  static tagName: string | string[];
  static scope: Scope;

  domNode: Node;
  prev: Blot | null;
  next: Blot | null;
  parent: Blot;

  // Creates corresponding DOM node
  static create(value?: any): Node;

  constructor(domNode: Node, value?: any);

  // For leaves, length of blot's value()
  // For parents, sum of children's values
  length(): Number;

  // Manipulate at given index and length, if applicable.
  // Will often pass call onto appropriate child.
  deleteAt(index: number, length: number);
  formatAt(index: number, length: number, format: string, value: any);
  insertAt(index: number, text: string);
  insertAt(index: number, embed: string, value: any);

  // Returns offset between this blot and an ancestor's
  offset(ancestor: Blot = this.parent): number;

  // Called after update cycle completes. Cannot change the value or length
  // of the document, and any DOM operation must reduce complexity of the DOM
  // tree. A shared context object is passed through all blots.
  optimize(context: { [key: string]: any }): void;

  // Called when blot changes, with the mutation records of its change.
  // Internal records of the blot values can be updated, and modifications of
  // the blot itself is permitted. Can be trigger from user change or API call.
  // A shared context object is passed through all blots.
  update(mutations: MutationRecord[], context: { [key: string]: any });

  /** Leaf Blots only **/

  // Returns the value represented by domNode if it is this Blot's type
  // No checking that domNode can represent this Blot type is required so
  // applications needing it should check externally before calling.
  static value(domNode): any;

  // Given location represented by node and offset from DOM Selection Range,
  // return index to that location.
  index(node: Node, offset: number): number;

  // Given index to location within blot, return node and offset representing
  // that location, consumable by DOM Selection Range
  position(index: number, inclusive: boolean): [Node, number];

  // Return value represented by this blot
  // Should not change without interaction from API or
  // user change detectable by update()
  value(): any;

  /** Parent blots only **/

  // Whitelist array of Blots that can be direct children.
  static allowedChildren: Registry.BlotConstructor[];

  // Default child blot to be inserted if this blot becomes empty.
  static defaultChild: Registry.BlotConstructor;

  children: LinkedList<Blot>;

  // Called during construction, should fill its own children LinkedList.
  build();

  // Useful search functions for descendant(s), should not modify
  descendant(type: BlotClass, index: number, inclusive): Blot;
  descendants(type: BlotClass, index: number, length: number): Blot[];

  /** Formattable blots only **/

  // Returns format values represented by domNode if it is this Blot's type
  // No checking that domNode is this Blot's type is required.
  static formats(domNode: Node);

  // Apply format to blot. Should not pass onto child or other blot.
  format(format: name, value: any);

  // Return formats represented by blot, including from Attributors.
  formats(): Object;
}

Example

Implementation for a Blot representing a link, which is a parent, inline scoped, and formattable.

import { InlineBlot, register } from 'parchment';

class LinkBlot extends InlineBlot {
  static blotName = 'link';
  static tagName = 'A';

  static create(url) {
    let node = super.create();
    node.setAttribute('href', url);
    node.setAttribute('target', '_blank');
    node.setAttribute('title', node.textContent);
    return node;
  }

  static formats(domNode) {
    return domNode.getAttribute('href') || true;
  }

  format(name, value) {
    if (name === 'link' && value) {
      this.domNode.setAttribute('href', value);
    } else {
      super.format(name, value);
    }
  }

  formats() {
    let formats = super.formats();
    formats['link'] = LinkBlot.formats(this.domNode);
    return formats;
  }
}

register(LinkBlot);

Quill also provides many great example implementations in its source code.

Block Blot

Basic implementation of a block scoped formattable parent Blot. Formatting a block blot by default will replace the appropriate subsection of the blot.

Inline Blot

Basic implementation of an inline scoped formattable parent Blot. Formatting an inline blot by default either wraps itself with another blot or passes the call to the appropriate child.

Embed Blot

Basic implementation of a non-text leaf blot, that is formattable. Its corresponding DOM node will often be a Void Element, but can be a Normal Element. In these cases Parchment will not manipulate or generally be aware of the element's children, and it will be important to correctly implement the blot's index() and position() functions to correctly work with cursors/selections.

Scroll

The root parent blot of a Parchment document. It is not formattable.

Attributors

Attributors are the alternative, more lightweight, way to represent formats. Their DOM counterpart is an Attribute. Like a DOM attribute's relationship to a node, Attributors are meant to belong to Blots. Calling formats() on an Inline or Block blot will return both the format of the corresponding DOM node represents (if any) and the formats the DOM node's attributes represent (if any).

Attributors have the following interface:

class Attributor {
  attrName: string;
  keyName: string;
  scope: Scope;
  whitelist: string[];

  constructor(attrName: string, keyName: string, options: Object = {});
  add(node: HTMLElement, value: string): boolean;
  canAdd(node: HTMLElement, value: string): boolean;
  remove(node: HTMLElement);
  value(node: HTMLElement);
}

Note custom attributors are instances, rather than class definitions like Blots. Similar to Blots, instead of creating from scratch, you will probably want to use existing Attributor implementations, such as the base Attributor, Class Attributor or Style Attributor.

The implementation for Attributors is surprisingly simple, and its source code may be another source of understanding.

Attributor

Uses a plain attribute to represent formats.

import { Attributor, register } from 'parchment';

let Width = new Attributor('width', 'width');
register(Width);

let imageNode = document.createElement('img');

Width.add(imageNode, '10px');
console.log(imageNode.outerHTML); // Will print <img width="10px">
Width.value(imageNode); // Will return 10px
Width.remove(imageNode);
console.log(imageNode.outerHTML); // Will print <img>

Class Attributor

Uses a class name pattern to represent formats.

import { ClassAttributor, register } from 'parchment';

let Align = new ClassAttributor('align', 'blot-align');
register(Align);

let node = document.createElement('div');
Align.add(node, 'right');
console.log(node.outerHTML); // Will print <div class="blot-align-right"></div>

Style Attributor

Uses inline styles to represent formats.

import { StyleAttributor, register } from 'parchment';

let Align = new StyleAttributor('align', 'text-align', {
  whitelist: ['right', 'center', 'justify'], // Having no value implies left align
});
register(Align);

let node = document.createElement('div');
Align.add(node, 'right');
console.log(node.outerHTML); // Will print <div style="text-align: right;"></div>

Registry

All methods are accessible from Parchment ex. Parchment.create('bold').

// Creates a blot given a name or DOM node.
// When given just a scope, creates blot the same name as scope
create(domNode: Node, value?: any): Blot;
create(blotName: string, value?: any): Blot;
create(scope: Scope): Blot;

// Given DOM node, find corresponding Blot.
// Bubbling is useful when searching for a Embed Blot with its corresponding
// DOM node's descendant nodes.
find(domNode: Node, bubble: boolean = false): Blot;

// Search for a Blot or Attributor
// When given just a scope, finds blot with same name as scope
query(tagName: string, scope: Scope = Scope.ANY): BlotClass;
query(blotName: string, scope: Scope = Scope.ANY): BlotClass;
query(domNode: Node, scope: Scope = Scope.ANY): BlotClass;
query(scope: Scope): BlotClass;
query(attributorName: string, scope: Scope = Scope.ANY): Attributor;

// Register Blot class definition or Attributor instance
register(BlotClass | Attributor);

parchment's People

Stargazers

浅浅 avatar  avatar José Delpino avatar  avatar Felipe Silveira avatar  avatar William Huang avatar MikeThuchchai avatar  avatar SongYongET avatar Siddharth avatar Unknown Moon avatar  avatar Bram Adams avatar T-CODE avatar bobolele avatar Seonu Jang avatar RieN 7z avatar Ching-Han Ho avatar Tony Stark avatar Max Baumann avatar Timothy Spann avatar lorsque avatar Kostadin Mandulov avatar  avatar Katja Lutz avatar Xun Qilong avatar younggglcy avatar Mathieu Laurent avatar Patrick Son avatar Jaen Figueroa avatar Maryam Arif avatar sanghun lee avatar acvv_khalil avatar Gustavo Giserman avatar Geoff Holden avatar  avatar Jake Duth avatar mark avatar Romain Borremans avatar Dmitriy Sh. (Brookit) avatar  avatar Nguyễn Hữu Nguyên Ý avatar Michael avatar  avatar Derek Myers avatar Liu Wenyuan avatar Ice-Hazymoon avatar Fox2081 avatar RosApr avatar SungJin Jin avatar  avatar Hung Hoang avatar Progyan Bhattacharya avatar amare zenebe avatar solenex avatar Jessica Claire Edwards avatar Dusan Kocurek avatar Acheul avatar czf avatar  avatar  avatar Misha Gezha avatar Seung Min Lee avatar Sarah avatar Ya-Che Li avatar Hyunseok Oh avatar  avatar steam(VR)punk waiting for wankunder(wear) to dry. avatar kevin.xu avatar SeongjaeMoon avatar Toothbrush avatar Gurlivleen Singh Kainth avatar Avery Pierce avatar Dorian Neto avatar Siro Díaz Palazón avatar 郭之存 avatar Alex Lomia avatar zoujia avatar Drew Hester avatar Michael Wang 汪東陽 avatar Léonard Henriquez avatar Meng Jun avatar  avatar  avatar  avatar Ted avatar vvt avatar Anatolii Preobrazhenskyi avatar Stoner avatar lefarcen avatar Jin Yao avatar  avatar İlker Atik avatar  avatar Mr.Chaofan avatar Kenn Costales avatar Steffen Langer avatar Steven Junio avatar Yordano Morel avatar

Watchers

 avatar Jason Chen avatar Dusan Kocurek avatar Byron Milligan avatar James Cloos avatar  avatar Shareef Ali avatar Michael Anthony avatar Austin Anderson avatar Nicholas Cole avatar Samuli Ulmanen avatar Viesturs Teivāns avatar win avatar Donel Adams avatar Prabagar G avatar  avatar  avatar  avatar

parchment's Issues

Limit top node of the document to be a table>tbody and only allow children to be tr>td

Hello,
I am trying to figure out how to force ScrollBlot to be a table>tbody and only allow first level children to be Blots represented by tr and td tag ( e.g. smallest block level Blot is single cell table row).

I understand I need to define my block blot with tag tr and override some methods on the blot class.
How do I approach ScrollBlot ?

Expand documentation

Now that I've implemented some Custom blots for our companies project, I'm planning to document some of the things I've learned for future maintainers of our project. I'd prefer for that documentation to be public and not in our internal documentation. Some of the topics include:

  • Parchment/Quill's document model.
    • The way Blot's connect to each other (LinkedList with prev, next, children, parent).
    • The way Blot's connect their domNode (blot.domNode and domNode.__blot).
  • A Blot's lifecycle
    • static create() -> constructor() -> attach()
    • update()
    • optimize()
    • remove() -> detach()
  • Different methods of creating a Blot and inserting it somewhere
    • insertAt()/insertBefore()/insertInto()
    • replace()/replaceWith()
  • How Blot's are created from DOM Nodes / Requirement to not have overlap between tags or use another method to distinguish DOM Nodes.
  • split() / isolate()
  • Scopes
    • What are they
    • Why do the exist
    • Hierachy?
  • Mapping of DOM Node types to Blots
    • div (wrapper) -> Container
    • TextNode -> TextBlot
    • Span (Container of multiple Text Nodes) -> Inline
    • Paragraph -> Block
  • Embed as an escape hatch / Non-contenteditable content.

@jhchen I'd mainly like to know where you would prefer this information to live? Would a docs folder at the top level of the repo do? I'd write it all as markdown, so it would be easy enough to pull pieces out and into the quill documentation if you'd like things to live there eventually.

Support for multiple class names on InlineBlot

Hi!

My use case calls to add multiple classes to a custom inline blot:

class Note extends Inline {};
Note.blotName = 'note';
Note.tagName = 'spann';
Note.className = `selection ${styles.selection} ${styles[`selection--note`]}`;
Quill.register(Note);

With the current code, I get an error when trying to use this:

Uncaught DOMException: Failed to execute 'add' on 'DOMTokenList': The token provided ('selection selection--1LM1N selection--note--2E3D2') contains HTML space characters, which are not valid in tokens.

It seems this line does not support multiple classes. It seems trivial to split the string by spaces then potentially add multiple. I'd be happy to contribute a PR but I wanted to make sure there wasn't a reason why this support does not already exist.

Thanks

Allow svg tag.

I want to allow SVG tags in the Quill editor. However, I do not know why, but it will not work. Should it be possible?

Engine rule in package.json maybe too strict?

I was checking out yarn today (new package manager to replace npm client), and it complained on a project I have that uses Quill, with:

$ yarn
yarn install v0.15.1
info No lockfile found.
[1/4] 🔍  Resolving packages...
[...]
[2/4] 🚚  Fetching packages...
error [email protected]: The engine "node" is incompatible with this module. Expected version "^5.3".
error Found incompatible module
info Visit http://yarnpkg.com/en/docs/cli/install for documentation about this command.
lola:~/src/participedia/frontend on master*

FYI:

$ node --version
v6.4.0

Which makes me think that it may make sense to make the engine line in package.json be more generous, maybe using >= instead of ^.

I'm no package.json versioning expert though.

Reference quill editor from blot

Hello,

After a lot of searching I couldn't find an example of referencing the editor from a custom blot. The examples I saw tackle this by working with a global quill instance, e.g.:
var quill = ....
Is it possible to access the current quill instance where the blot is inserted and if not - is it difficult to implement?

Much appreciated for the great library!

Unregister from registry

Hello. There is issue with global Quill.registry.

When you are creating a two instances of Quill where every instance uses custom modules. Then they are shared because Quill#register is for global registering.

Would be great to have ability to register modules per instance or a way to unregister modules from Registry or from the specific instance.

There is simple workaround and it is to check the instance id in the constructor of custom module. If this instance has allowed this module and do stuffs with it. But it is an issue with overwriten modules. E.g.: I want use for one Quill custom keyboard and for second one the default keyboard.

I can do another workaround and that is calling super methods in overwriten methods. But it makes a mess in our code.

I will prefer a method in Parchment what can unregister existing things.

Thank you.

Webpack: Module build failed, Typescript emitted no output

Hello,

I'm trying to use Quill Editor in Aurelia and Webpack, which has parchment as a dependency.

The build is successful with transpileOnly as true, but due to which i lose the Typescript capabilities. When i donot defin ethe transpileOnly for ts-loader,

{
         test: /\.ts?$/,
         use: [
                "babel-loader",
                {
                       loader: "ts-loader",
                }
        ]
},

I get the following Error,

ERROR in ./node_modules/parchment/src/attributor/attributor.ts
Module build failed: Error: Typescript emitted no output for C:\Users\project\node_modules\parchment\src\attributor\attributor.ts.
You should not need to recompile .ts files in node_modules.
Please contact the package author to advise them to use --declaration --outDir.
More https://github.com/Microsoft/TypeScript/issues/12358
    at successLoader (C:\Users\project\node_modules\ts-loader\dist\index.js:39:15)
    at Object.loader (C:\Users\project\node_modules\ts-loader\dist\index.js:21:12)
 @ ./node_modules/parchment/src/parchment.ts 10:0-49 30:15-25
 @ ./node_modules/quill/core.js
 @ ./node_modules/quill/quill.js
 @ ./src/resources/custom-elements/quill-editor/quill-editor.ts
 @ ./src/resources/index.ts
 @ ./src/main.ts
 @ ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js
 @ multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry (webpack)-dev-server/client?http://localhost:3333 @babel/polyfill aurelia-bootstrapper

ERROR in ./node_modules/parchment/src/attributor/class.ts
Module build failed: Error: Typescript emitted no output for C:\Users\project\node_modules\parchment\src\attributor\class.ts.
You should not need to recompile .ts files in node_modules.
Please contact the package author to advise them to use --declaration --outDir.
More https://github.com/Microsoft/TypeScript/issues/12358
    at successLoader (C:\Users\project\node_modules\ts-loader\dist\index.js:39:15)
    at Object.loader (C:\Users\project\node_modules\ts-loader\dist\index.js:21:12)
 @ ./node_modules/parchment/src/parchment.ts 11:0-49 31:11-26
 @ ./node_modules/quill/core.js
 @ ./node_modules/quill/quill.js
 @ ./src/resources/custom-elements/quill-editor/quill-editor.ts
 @ ./src/resources/index.ts
 @ ./src/main.ts
 @ ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js
 @ multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry (webpack)-dev-server/client?http://localhost:3333 @babel/polyfill aurelia-bootstrapper

ERROR in ./node_modules/parchment/src/attributor/store.ts
Module build failed: Error: Typescript emitted no output for C:\Users\project\node_modules\parchment\src\attributor\store.ts.
You should not need to recompile .ts files in node_modules.
Please contact the package author to advise them to use --declaration --outDir.
More https://github.com/Microsoft/TypeScript/issues/12358
    at successLoader (C:\Users\project\node_modules\ts-loader\dist\index.js:39:15)
    at Object.loader (C:\Users\project\node_modules\ts-loader\dist\index.js:21:12)
 @ ./node_modules/parchment/src/parchment.ts 13:0-49 33:11-26
 @ ./node_modules/quill/core.js
 @ ./node_modules/quill/quill.js
 @ ./src/resources/custom-elements/quill-editor/quill-editor.ts
 @ ./src/resources/index.ts
 @ ./src/main.ts
 @ ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js
 @ multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry (webpack)-dev-server/client?http://localhost:3333 @babel/polyfill aurelia-bootstrapper

ERROR in ./node_modules/parchment/src/attributor/style.ts
Module build failed: Error: Typescript emitted no output for C:\Users\project\node_modules\parchment\src\attributor\style.ts.
You should not need to recompile .ts files in node_modules.
Please contact the package author to advise them to use --declaration --outDir.
More https://github.com/Microsoft/TypeScript/issues/12358
    at successLoader (C:\Users\project\node_modules\ts-loader\dist\index.js:39:15)
    at Object.loader (C:\Users\project\node_modules\ts-loader\dist\index.js:21:12)
 @ ./node_modules/parchment/src/parchment.ts 12:0-49 32:11-26
 @ ./node_modules/quill/core.js
 @ ./node_modules/quill/quill.js
 @ ./src/resources/custom-elements/quill-editor/quill-editor.ts
 @ ./src/resources/index.ts
 @ ./src/main.ts
 @ ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js
 @ multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry (webpack)-dev-server/client?http://localhost:3333 @babel/polyfill aurelia-bootstrapper

ERROR in ./node_modules/parchment/src/blot/abstract/container.ts
Module build failed: Error: Typescript emitted no output for C:\Users\project\node_modules\parchment\src\blot\abstract\container.ts.
You should not need to recompile .ts files in node_modules.
Please contact the package author to advise them to use --declaration --outDir.
More https://github.com/Microsoft/TypeScript/issues/12358
    at successLoader (C:\Users\project\node_modules\ts-loader\dist\index.js:39:15)
    at Object.loader (C:\Users\project\node_modules\ts-loader\dist\index.js:21:12)
 @ ./node_modules/parchment/src/parchment.ts 2:0-54 21:13-26
 @ ./node_modules/quill/core.js
 @ ./node_modules/quill/quill.js
 @ ./src/resources/custom-elements/quill-editor/quill-editor.ts
 @ ./src/resources/index.ts
 @ ./src/main.ts
 @ ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js
 @ multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry (webpack)-dev-server/client?http://localhost:3333 @babel/polyfill aurelia-bootstrapper

ERROR in ./node_modules/parchment/src/blot/abstract/format.ts
Module build failed: Error: Typescript emitted no output for C:\Users\project\node_modules\parchment\src\blot\abstract\format.ts.
You should not need to recompile .ts files in node_modules.
Please contact the package author to advise them to use --declaration --outDir.
More https://github.com/Microsoft/TypeScript/issues/12358
    at successLoader (C:\Users\project\node_modules\ts-loader\dist\index.js:39:15)
    at Object.loader (C:\Users\project\node_modules\ts-loader\dist\index.js:21:12)
 @ ./node_modules/parchment/src/parchment.ts 3:0-48 22:10-20
 @ ./node_modules/quill/core.js
 @ ./node_modules/quill/quill.js
 @ ./src/resources/custom-elements/quill-editor/quill-editor.ts
 @ ./src/resources/index.ts
 @ ./src/main.ts
 @ ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js
 @ multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry (webpack)-dev-server/client?http://localhost:3333 @babel/polyfill aurelia-bootstrapper

ERROR in ./node_modules/parchment/src/blot/abstract/leaf.ts
Module build failed: Error: Typescript emitted no output for C:\Users\project\node_modules\parchment\src\blot\abstract\leaf.ts.
You should not need to recompile .ts files in node_modules.
Please contact the package author to advise them to use --declaration --outDir.
More https://github.com/Microsoft/TypeScript/issues/12358
    at successLoader (C:\Users\project\node_modules\ts-loader\dist\index.js:39:15)
    at Object.loader (C:\Users\project\node_modules\ts-loader\dist\index.js:21:12)
 @ ./node_modules/parchment/src/parchment.ts 4:0-44 23:8-16
 @ ./node_modules/quill/core.js
 @ ./node_modules/quill/quill.js
 @ ./src/resources/custom-elements/quill-editor/quill-editor.ts
 @ ./src/resources/index.ts
 @ ./src/main.ts
 @ ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js
 @ multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry (webpack)-dev-server/client?http://localhost:3333 @babel/polyfill aurelia-bootstrapper

ERROR in ./node_modules/parchment/src/blot/block.ts
Module build failed: Error: Typescript emitted no output for C:\Users\project\node_modules\parchment\src\blot\block.ts.
You should not need to recompile .ts files in node_modules.
Please contact the package author to advise them to use --declaration --outDir.
More https://github.com/Microsoft/TypeScript/issues/12358
    at successLoader (C:\Users\project\node_modules\ts-loader\dist\index.js:39:15)
    at Object.loader (C:\Users\project\node_modules\ts-loader\dist\index.js:21:12)
 @ ./node_modules/parchment/src/parchment.ts 7:0-37 26:9-18
 @ ./node_modules/quill/core.js
 @ ./node_modules/quill/quill.js
 @ ./src/resources/custom-elements/quill-editor/quill-editor.ts
 @ ./src/resources/index.ts
 @ ./src/main.ts
 @ ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js
 @ multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry (webpack)-dev-server/client?http://localhost:3333 @babel/polyfill aurelia-bootstrapper

ERROR in ./node_modules/parchment/src/blot/embed.ts
Module build failed: Error: Typescript emitted no output for C:\Users\project\node_modules\parchment\src\blot\embed.ts.
You should not need to recompile .ts files in node_modules.
Please contact the package author to advise them to use --declaration --outDir.
More https://github.com/Microsoft/TypeScript/issues/12358
    at successLoader (C:\Users\project\node_modules\ts-loader\dist\index.js:39:15)
    at Object.loader (C:\Users\project\node_modules\ts-loader\dist\index.js:21:12)
 @ ./node_modules/parchment/src/parchment.ts 8:0-37 24:9-18
 @ ./node_modules/quill/core.js
 @ ./node_modules/quill/quill.js
 @ ./src/resources/custom-elements/quill-editor/quill-editor.ts
 @ ./src/resources/index.ts
 @ ./src/main.ts
 @ ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js
 @ multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry (webpack)-dev-server/client?http://localhost:3333 @babel/polyfill aurelia-bootstrapper

ERROR in ./node_modules/parchment/src/blot/inline.ts
Module build failed: Error: Typescript emitted no output for C:\Users\project\node_modules\parchment\src\blot\inline.ts.
You should not need to recompile .ts files in node_modules.
Please contact the package author to advise them to use --declaration --outDir.
More https://github.com/Microsoft/TypeScript/issues/12358
    at successLoader (C:\Users\project\node_modules\ts-loader\dist\index.js:39:15)
    at Object.loader (C:\Users\project\node_modules\ts-loader\dist\index.js:21:12)
 @ ./node_modules/parchment/src/parchment.ts 6:0-39 27:10-20
 @ ./node_modules/quill/core.js
 @ ./node_modules/quill/quill.js
 @ ./src/resources/custom-elements/quill-editor/quill-editor.ts
 @ ./src/resources/index.ts
 @ ./src/main.ts
 @ ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js
 @ multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry (webpack)-dev-server/client?http://localhost:3333 @babel/polyfill aurelia-bootstrapper

ERROR in ./node_modules/parchment/src/blot/scroll.ts
Module build failed: Error: Typescript emitted no output for C:\Users\project\node_modules\parchment\src\blot\scroll.ts.
You should not need to recompile .ts files in node_modules.
Please contact the package author to advise them to use --declaration --outDir.
More https://github.com/Microsoft/TypeScript/issues/12358
    at successLoader (C:\Users\project\node_modules\ts-loader\dist\index.js:39:15)
    at Object.loader (C:\Users\project\node_modules\ts-loader\dist\index.js:21:12)
 @ ./node_modules/parchment/src/parchment.ts 5:0-39 25:10-20
 @ ./node_modules/quill/core.js
 @ ./node_modules/quill/quill.js
 @ ./src/resources/custom-elements/quill-editor/quill-editor.ts
 @ ./src/resources/index.ts
 @ ./src/main.ts
 @ ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js
 @ multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry (webpack)-dev-server/client?http://localhost:3333 @babel/polyfill aurelia-bootstrapper

ERROR in ./node_modules/parchment/src/blot/text.ts
Module build failed: Error: Typescript emitted no output for C:\Users\project\node_modules\parchment\src\blot\text.ts.
You should not need to recompile .ts files in node_modules.
Please contact the package author to advise them to use --declaration --outDir.
More https://github.com/Microsoft/TypeScript/issues/12358
    at successLoader (C:\Users\project\node_modules\ts-loader\dist\index.js:39:15)
    at Object.loader (C:\Users\project\node_modules\ts-loader\dist\index.js:21:12)
 @ ./node_modules/parchment/src/parchment.ts 9:0-35 28:8-16
 @ ./node_modules/quill/core.js
 @ ./node_modules/quill/quill.js
 @ ./src/resources/custom-elements/quill-editor/quill-editor.ts
 @ ./src/resources/index.ts
 @ ./src/main.ts
 @ ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js
 @ multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry (webpack)-dev-server/client?http://localhost:3333 @babel/polyfill aurelia-bootstrapper

ERROR in ./node_modules/parchment/src/registry.ts
Module build failed: Error: Typescript emitted no output for C:\Users\project\node_modules\parchment\src\registry.ts.
You should not need to recompile .ts files in node_modules.
Please contact the package author to advise them to use --declaration --outDir.
More https://github.com/Microsoft/TypeScript/issues/12358
    at successLoader (C:\Users\project\node_modules\ts-loader\dist\index.js:39:15)
    at Object.loader (C:\Users\project\node_modules\ts-loader\dist\index.js:21:12)
 @ ./node_modules/parchment/src/parchment.ts 14:0-39 16:9-23 17:10-25 18:8-21 19:9-23 20:12-29
 @ ./node_modules/quill/core.js
 @ ./node_modules/quill/quill.js
 @ ./src/resources/custom-elements/quill-editor/quill-editor.ts
 @ ./src/resources/index.ts
 @ ./src/main.ts
 @ ./node_modules/aurelia-webpack-plugin/runtime/empty-entry.js
 @ multi aurelia-webpack-plugin/runtime/empty-entry aurelia-webpack-plugin/runtime/pal-loader-entry (webpack)-dev-server/client?http://localhost:3333 @babel/polyfill aurelia-bootstrapper

Please help me out in resolving the same.

Type of v2 parchment's default export is not backwards compatible with v1.

The structure of the default exported value for 'parchment' has significantly changed. As a result it is impossible to use custom Blots and/or Attributors implemented for Quill 1 without modifying them. Was this change intentional?

Old structure:

let Parchment = {
  Scope: Registry.Scope,

  create: Registry.create,
  find: Registry.find,
  query: Registry.query,
  register: Registry.register,

  Parent: ParentBlot,
  Container: ContainerBlot,
  Leaf: LeafBlot,
  Embed: EmbedBlot,

  Scroll: ScrollBlot,
  Block: BlockBlot,
  Inline: InlineBlot,
  Text: TextBlot,

  Attributor: {
    Attribute: Attributor,
    Class: ClassAttributor,
    Style: StyleAttributor,

    Store: AttributorStore,
  }
}

New structure:

export {
  Registry as default,
  ParentBlot,
  ContainerBlot,
  LeafBlot,
  EmbedBlot,
  ScrollBlot,
  BlockBlot,
  InlineBlot,
  TextBlot,
  Attributor,
  ClassAttributor,
  StyleAttributor,
  AttributorStore,
};

Mistyped method descendents in Readme.md

// Useful search functions for descendant(s), should not modify
descendant(type: BlotClass, index: number, inclusive): Blot
descendents(type: BlotClass, index: number, length: number): Blot[];
Should be descendants - a tiny change

Thank you

Display text vs value

I am trying to implement mentions. When the value is displayed in the editor I want it to look like @john Doe but when it submits to the server I would like it to be %%john-doe%%. What is a good way to implement this? Is there a way to do a transform on the value, before it hits the onChange event or is there a better way to do this using Blots (display value vs actual value)?

Type definitions could be cleaner if the Blot and BlotConstructor interface were removed

I've been trying to improve the type definitions for Quill and have been running into this issue lately. There are quite a few places where something is typed as being Blot (from the interface) or BlotConstructor (an interface with new(): Blot). The largest issue with the Blot/BlotConstructor interface is that it requires defining static and instance properties/methods in different places. Instead you should be able to use the base Blot class ShadowBlot as a class, and where you need its constructor use typeof ShadowBlot.

Allow falsey attributes like '0' or 'false'

Current Situation
ShadowBlot of Parchement does not allow falsey attribute values like 0 or false. This leads to unexpected behavior, since it may be legitim to store values like 0 or false in an attribute value.

Problem
This piece of code is responsible for the behavior:

https://github.com/quilljs/parchment/blob/e157f433f036d9aa131557b0e9e6cca009da791b/src/blot/abstract/shadow.ts#L79-L88

The if statement in Line 81 checks value.
If it is falsey, the blot is not created.

Solution Proposal
The if condition should be changed to something like:
if (Registry.query(name, Registry.Scope.BLOT) != null && (value !== undefined || value !== null ))

Remark
I'm really new to Parchment. I don't know why value is checked at all and I don't know the implications of the proposed change.

Any comment on this is welcome, thx!

Class Attributors variations cannot contain hyphens

Hi,

Just recently noticed that Class Attributors variations cannot contain hyphens and if they do Parchment is not able to find the proper blot to process.

So I would suggest to add this info into the documentation regarding the expected pattern for the end classes:
[class-attributor-name] [-] [variation_name_without_any_hyphens]

Using quill-color as an example, if i define a color with a class called "light-brown":
[ql-color] [-] [light-brown]

Class Attributor would actually end up looking for the attributor with the keyName ql-color-light which normally wouldn't exist.

Another suggestion would be to use/expect another character to separate the keyName from the variation less common than - but that would probably break functionality for a lot of people.

Please let me know if there's any other info I'd need to provide.

Discussion: Regarding TypeScript definitions for Parchment

I am trying to maintain TypeScript definitions for Quill at the DefinitelyTyped repo.

After using it for a while I realized just having the public APIs declared in the documentations doesn't quite complete the definitions. Because as soon as I try to extend using custom Blots and Formats I run into missing type definitions.

While I can continue to build the TypeScript definitions to add all the formats and blots that Quill supports, fact that most of them inherit from Parchement got me thinking. Since Parchment is written in TS, generating definitions for it should be trivial. I tried it and I had to make a few minor changes in the tsconfig and two other classes to be able to generate TS definitions for Parchments. It will need more work to include it as a part of the webpack build process.

Coming to the questions

  1. Should I work on a PR (to Parchment) that enables d.ts file generation (and thus direct access to definitions via npm). Unless someone is working on this already, this might take me a few days to sort out. But advantage of this approach would be, the TS file would always be up to date with the code.
  2. Should I work on a completely independent d.ts file (like the current Quill definitions) and submit it to DefinitelyTyped independently. That way, the d.ts file is not tied to Parchment releases and repo, but will be playing catchup with every release.

domNode.insertBefore being passed an undefined reference (ShadowBlot)

I noticed that the insertBefore method for ShadowBlot passes an incorrect parameter to the underlying domNode.insertBefore method. The second argument is passed as undefined instead of null when refDomNode is not set.

MDN specifies that it should be passed null as behavior is inconsistent across browsers when it is passed other (invalid) values.

I have fixed this and am making a pull request shortly.

See https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore

source code reading problem

when i read source code, i want to know where it assign domNode property to blot instance, i can not find the assignment。

i am very curious about that

yarn error

error [email protected]: The engine "node" is incompatible with this module. Expected version "^5.3".
error Found incompatible module

ScrollBlot.optimize() has invalid type

ScrollBlot extends ContainerBlot and its optimize method has type:

ScrollBlot.optimize(mutations: MutationRecord[] = [], context: {[key: string]: any} = {}): void

ContainerBlot's optimize has type:

ContainerBlot.optimize(context: {[key: string]: any})

Because of the order of the parameters, the first is not a supertype of the second as it should be.

Corrupt Quill parchment results in data loss when editing (seems specific to IE)

slab/quill#1028 tracks this on the Quill side, but opening this since it seems to manifest in the parchment.

Steps to reproduce the problem:

  1. Visit http://quilljs.com/playground
  2. Copy the text non-column text blocks from http://lipsum.com/ [START with the header "The standard Lorem Ipsum passage, used since the 1500s" and END at "to avoid worse pains." before the [email protected] block]
  3. Use Ctrl + Backspace to remove 3 words ("Unable to get property 'mutations' of undefined or null reference" shows up in the console at blot.update(blot.domNode[Registry.DATA_KEY].mutations || []);). Then Ctrl + Z to undo 2 times (See "Unable to get property 'length' of undefined or null reference" now in the console on keydown var curContext = { range...)
    Expected behavior: Words are re-added back one by one until we get back to full paragraph

Actual behavior: After 2nd redo, the whole paragraph disappears and "Cannot read property 'mutations' of undefined" throws at

Platforms: IE 11.0.9600.18450 windows 10, 8 or 2012 R2

Include browser, operating system and respective versions

Version: 1.0.6

Note: This isn't limited to just Ctrl + Z/Backspace and is non-deterministic. I am able to reproduce while performing simple edit operations.

The problem seems to be that the TextBlot is getting corrupted, with its domNode not attached to a __blot. This results in a null reference when trying to access the mutations in the blot's domNode when trying to update the ScrollBlot, This puts the parchment in a weird state resulting in exceptions in followup keydown events (where the scroll lines are no longer defined, ranges are inconsistent etc.). This continues until the new ContainerBlot is created on Enter.

image

CallStack trace:
image

image

image

The TextBlot in question:

image

Class attributors remove the style property

Hello,

I'm using quill and I try to write a custom ColorClass attributor. Indeed, the one given in quill replace as expected full letters color styles by classes, but also rgb color styles by classes with hexadecimal notation. My issue is that I'm migrating from a previous editor and the old content could contain any kind of rgb values. I cannot create a class for each rgb values possibles (256^3 values). Thus, I need my attributor to convert styles to classes only for plain text colors and ignore rgb colors.

How this could be done ? I'm searching a way of accomplishing this for more than 2 hours now, and I can't afford spending more time on this since it's something that I think can or should be done very quickly.

Thanks for your time.

EDIT :

I found a workaround, but I think it's not the way to do it, because surprisingly it works for everything but em, s, u and strong tags.

  class ColorClassAttributor extends Parchment.Attributor.Class {
    add(domNode, value) {
      if (value[0] != '#')
        return super.add(domNode, value);

      domNode.style[this.attrName] = value;
      return true;
    }
  }

Nested Blot?

How can i customize a new Blot that:

  1. tagName is "DIV"
  2. There is an "img" and a "p" inside

What I want to do is build different customized Blot to extend the editor.

quill.scroll.descendant gives false hits on colour spans

I'm getting a weird error when trying to find a descendant of a certain blot-class on pasted-in content. If I have e.g.

  var contents = {"ops":[{"attributes":{"color":"#565657"},"insert":"abc "},
                         {"insert":"def "},
                         {"attributes":{"color":"#565657"},"insert":"xyz"}]};
  quill.setContents(contents);

and I have defined a class MyBlot extends Inline with tagName span,
then quill.scroll.descendant claims the third insertion is an instanceof MyBlot.

Full example at:

https://jsfiddle.net/fjg11pg6/1/

Also, if I have actual MyBlot's inside one of these colour spans, the answer from descendant(MyBlot, …) will be the text following the MyBlot.

empty line composition input problem in: mac(safari[10.1], chrome[59_dev]), win(chrome[59_dev])

please read it all and clearfully:
detail problments: slab/quill#896

For an empty line, I found that the method 'domNode.insertBefore(childNode, refNode)' [https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore], for the older webbrowsers, range object will not change, so the 'getNativeRange' method return corrent result. However, it changes for the latest webbrowsers(safari[10.1], chrome[59_dev]), and in result 'getNativeRange' return wrong result.

I think that the source code hasn't checked whether the parentNode already contains the childNode. And I tried to do so in my forked branch, than the problem fixed. But I want to make sure if it is proper to do so? If it is, i will try to merge to the original master branch.

I will be appreciate if you can answer the question. Let's make it good! @jhchen

Global Blot?

Is it possible to create a single blot that acts as an inline, block and embed blot?

TS2345: Argument of type 'NodeList' is not assignable to parameter of type 'Node[]'.

At the branch 2.0
When I do npm install
I got a error below:

ERROR in /Users/xiexing/personal/parchment/src/blot/abstract/parent.ts
[tsl] ERROR in /Users/xiexing/personal/parchment/src/blot/abstract/parent.ts(317,43)
      TS2345: Argument of type 'NodeList' is not assignable to parameter of type 'Node[]'.
  Type 'NodeList' is missing the following properties from type 'Node[]': pop, push, concat, join, and 19 more.

ERROR in /Users/xiexing/personal/parchment/src/blot/abstract/parent.ts
[tsl] ERROR in /Users/xiexing/personal/parchment/src/blot/abstract/parent.ts(318,47)
      TS2345: Argument of type 'NodeList' is not assignable to parameter of type 'Node[]'.

[Information] Calling super.deletAt in InlineBlot implementation.

I have made a InlineBlot implementation, i want to be aware when it is delete for some purpose but when i implement the deleteAt function it either :

  • Doesn't delete the last character of my blot :
 deleteAt(index, length) {
    console.log('DELETE');
  }
  • Actually delete the 'blot entirely', but having an error because the blot is already deleted Uncaught TypeError: Cannot read property 'call' of undefined :
deleteAt(index, length) {
    console.log('DELETE');
    super.deletAt(index.length);
   // Parchment.Container.proptype.deleteAt.call(this, index, length);
  }

How could i do that without having this error, or is there another way to get notified when my blot will be removed ?

Whitelist null comparison in attributor?

In the class and options interface for Attributor the whitelist type is string[] | undefined but in the class constructor and canAdd functions whitelist is compared with null. Wouldn't this cause the comparison to always return false?

UI element at end of blot

The latest parchment supports having a UI element at the start of a blot (eg for list items). Would it be acceptable to submit a pull request that adds support for these elements at the end of a blot? Our particular use case is adding a newline character to the end of a Block. At the moment we fudge this manually, but manipulating the DOM outside of Quill can be a little hairy, and it would be nicer if we could work with Quill rather than against it.

Block elements get replaced when wrapping them in a custom multiline container blot with block scope

I wrote a custom blot that extends blot/container to wrap several lines into a collapsible element (something that can e.g. be toggled via the bootstrap collapse functionality). I can create such a container and place any other blots inside, embeds, inlines and blocks alike. Copy & paste also causes no problems.

The issue I have occurs when I try to select multiple lines and turn those into a collapsible section. Inline-blots like bold and italic remain unchanged, however any block blot gets completely replaced by the blot type I have set as defaultChild in my class. I assume that the problem here is that I have to set the scope as Parchment.Scope.BLOCK_BLOT for it to work. I have traced the issue to this line in the FormatBlot class, where it replaces one block element with another (probably to prevent nesting of certain block elements that shouldn't allow it?)

So I was wondering if it might be a good idea to add another If there, checking whether the new blot is an instance of Container, and if so use this.wrap instead of this.replaceWith. Would it be easily possible to add a check like that, or might that break other parts of the editor?

What is a Container Blot?

The docs only cover these three blots: Block, Inline and Embed. However, if we look at how the List blot is built it inherits from the Container blot.

What exactly does a Container blot do and when it should be used?

Atomic Blot

Let's say I have a special LinkBlot AtomicBlot that is similar to the default LinkBlot example with the following differences. When the curser/selection is somewhere inside that AtomicBlot's text and I delete at least one character then the whole AtomicBlot is removed. Similarly, I must not be able to add characters to AtomicBlot.

My idea was to make AtomicBlot extend from the inline Embed blot. In that case the whole AtomicBlot is deleted when the cursor is right to it's last character and backspace is pressed. But when the cursor is at some other position it does only remove one character and not the whole AtomicBlot. I assume I need to override some of the Blot methods to achieve the correct behavior but I am a bit at a loss.

I was not sure whether to put this question here or on the Quill project. In any case, any advice would be appreciated.

Typo in example

In the example of the Blots section

format(name, value) {
    if (name === 'link' && value) {
      this.domNode.setAttribute('href'); // <- typo here
    } else {
      super.format(name, value);
    }
}

It should be

this.domNode.setAttribute('href', value);

TypeError: Cannot read property 'mutations' of undefined

I believe we have traces of this problem happening in a lot of places, and it should be kind of easy to fix, but maybe not really to understand:

#14
slab/quill#2312
area17/twill#458
slab/quill#889

This error is occurring in Quill when the list of nodes are, somehow, problematic.

This is a simple console.log() of blot.domNode:

image

As you can see the error occurs while processing a <br>, on line 121:

image

Because that line is compiled to

if (blot.domNode[Registry.DATA_KEY].mutations == null) ...

But it could be prevented by just:

if (blot.domNode[Registry.DATA_KEY] && blot.domNode[Registry.DATA_KEY].mutations == null) ...

Because what happens is that this particular node doesn't exists, so a mutation property is, of course, undefined.

Nested and complex bolt

Hi,

I try to develop a bulma message integration for Quill.

Message are defined like this:

<article class="message is-danger">
   <section class="message-body">
      <div class="media">
         <div class="media-left">
            <span class="icon is-large is-danger">
               <i class="fas fa-exclamation-circle fa-3x"></i>
            </span>
         </div>
         <div class="media-content">My message, the content what I want to edit.</b></div>
      </div>
   </section>
</article>

The content can ben whatever (text, list, another bulma message, etc.).

I have experiment this, but the content are not editable:

let Embed = Quill.import('blots/embed');
let Container = Quill.import('blots/container');

class Message extends Container {
  static create(value) {
    return super.create(value);
  }
}

class MessageDanger extends Embed {
  static register() {
    Quill.register(Message);
  }

  static create(value) {
    let node = super.create(value);
    console.log("create");
    return node;
  }

  constructor(domNode) {
    super(domNode);
    console.log("constructor");

    let node = domNode;
    node.setAttribute("class", "message is-danger");

    let section = document.createElement("section");
    section.setAttribute("class", "message-body");

    let divMedia = document.createElement("div");
    divMedia.setAttribute("class", "media");

    let divMediaLeft = document.createElement("div");
    divMediaLeft.setAttribute("class", "media-left");
    divMediaLeft.setAttribute("contenteditable", "false");

    let spanIcon = document.createElement("span");
    spanIcon.setAttribute("class", "icon is-large is-danger");

    let iIcon = document.createElement("i");
    iIcon.setAttribute("class", "fas fa-exclamation-circle fa-w-16 fa-3x");

    spanIcon.appendChild(iIcon);
    divMediaLeft.appendChild(spanIcon);

    let divMediaContent = document.createElement("div");
    divMediaContent.setAttribute("class", "media-content");

    divMedia.appendChild(divMediaLeft);
    divMedia.appendChild(divMediaContent);

    section.appendChild(divMedia);
    console.log("lenght: ", node.childList);
    while (node.hasChildNodes()) {
      console.log("remove child");
      node.removeChild(node.lastChild);
    }
    console.log("node: ", node);
    node.appendChild(section);

  }
}

MessageDanger.blotName = 'message-danger';
MessageDanger.className = 'message-danger';
MessageDanger.tagName = 'ARTICLE';
Quill.register(MessageDanger, true);
Quill.register(Message, true);

Message.blotName = 'message';
Message.className = 'message-container';
Message.tagName = 'SECTION';
Message.allowedChildren = [MessageDanger];
MessageDanger.requiredContainer = Message;

How can I do that ? I don't know if it is the correct way to do, according to what I want.

Add editor config file

I'd like to propose adding an editorconfig to the repo so that people using different IDE's can easily use a consistent code style (in this case 2 spaces) with the project.

Lack of code documentation?

I think that this project's code is quite beautiful and elegant (for example, Blot ). I find it striking, however, that there is no in-code documentation that describes the API.

I'm just busy learning Parchment, and good documentation in your code would have really helped me understand the intent behind many of the methods.

create a custom attributor before the initialization of Quill would cause a TypeError: TypeError: Cannot read property 'getContents' of undefined

I'm testing the custom attributor, I created a style attributor:

let CustomStyle = new Parchment.Attributor.Attribute('style', 'style');
Parchment.register(CustomStyle);

after this I initialized a new Quill

var quill = new Quill('#editor', options);

This would cause a TypeError, the stack call is:

    at History.record (quill.js:6528)
    at Emitter.<anonymous> (quill.js:6487)
    at Emitter.emit (quill.js:8605)
    at Emitter.emit (quill.js:1895)
    at Quill.modify (quill.js:1626)
    at Quill.setContents (quill.js:1457)
    at new Quill (quill.js:1129)

I couldn't figure out why this happened and when I move the customStyle after the initialize of Quill, the error doesn't appear anymore.

However the error didn't appear either when I tried to implement the style attributors before the initialize of Quill

let colors = new Parchment.Attributor.Style('background-color', 'background-color');
Parchment.register(colors);
...
var quill = new Quill('#editor', options);

I know I supposed to implement the style attributor when I'm trying to apply certain style to the domNode, I just couldn't figure out why create the custom attributor before the initialization of Quill would cause such an error.

Any enlightenment would be really appreciated!!

Parchment does not support multiple registries

Stemming from an issue mentioned in Quill's repository issue list, there has been some discussion around adding support for multiple registries in Parchment. After the new year, the discussion trailed off. The hope here is to support multiple registries so that a webpage can load a view with multiple editors, and each editor can have separate configurations for formats/blots/attributors, etc. This fork creates a solution that will allow, for example, one editor that supports bold and italic text, and one that does not. Even the content generated by copy/pasting bold and italic text will be reflected differently in each editor. The same concept is true for custom blots. The intended outcome is to create a Parchment 2.0 branch that can be used to develop toward a branch that supports a future Quill 2.0 branch supporting multiple editor registries.

Here is a fork that demonstrates proposed code changes
https://github.com/zdizzle6717/parchment/tree/feature/scope-registry-to-quill-instance

Here is the Quill issue that stemmed the conversation
slab/quill#1101

Here is a near complete Quill 2.0 branch that applies the Parchment, multiple registry solution
https://github.com/zdizzle6717/quill/tree/scope-registry-to-quill-instance

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.