Quill: Replacing indentation classes with inline styles -- RTL support

Created on 23 Jan 2018  路  7Comments  路  Source: quilljs/quill

I'm trying to rewrite the indentation attributor to to use styles instead of classes, i.e. style="margin-left: 2em" instead of class="ql-indent-1".

This is what I've come up with:

import Parchment from 'parchment';

const levels = [1, 2, 3, 4, 5];
const multiplier = 2;

class IndentAttributor extends Parchment.Attributor.Style {
    add(node, value) {
        return super.add(node, `${value * multiplier}em`);
    }

    value(node) {
        return parseFloat(super.value(node)) / multiplier || undefined; // Don't return NaN
    }
}

const IndentStyle = new IndentAttributor('indent', 'margin-left', {
    scope: Parchment.Scope.BLOCK,
    whitelist: levels.map(value => `${value * multiplier}em`)
});

export default IndentStyle;

This is working nicely, but I need to support right text alignment, and so I need to switch margin-left with margin-right when the current line is right aligned or when the line direction attribute is 'rtl`.

How can I do it?

Most helpful comment

For angular 2+:

Create file quill.d.ts: (you can try using @types/quill module, but it doesn't work for me because getting some error)
declare module 'quill';

Add import in your component:
import * as Quill from 'quill';

Add class:

class IndentAttributor extends Quill.import('parchment').Attributor.Style {
  multiplier = 2;

  constructor(name: string, style: string, params: any) {
    super(name, style, params);
  }

  add(node, value) {
    return super.add(node, `${value * this.multiplier}rem`);
  }

  value(node) {
    return parseFloat(super.value(node)) / this.multiplier || undefined;
  }
}

Add function in your component:

  createCustomIndent(): void {
    const levels = [1, 2, 3, 4, 5];
    const multiplier = 2;
    const indentStyle = new IndentAttributor('indent', 'margin-left', {
      scope: Quill.import('parchment').Scope.BLOCK,
      whitelist: levels.map(value => `${value * multiplier}rem`),
    });

    Quill.register(indentStyle);
  }

And run it in constructor for example:

  constructor() {
    this.createCustomIndent();
  }

All 7 comments

where I use these code in angular2

I'm trying to rewrite the indentation attributor to to use styles instead of classes, i.e. style="margin-left: 2em" instead of class="ql-indent-1".

This is what I've come up with:

import Parchment from 'parchment';

const levels = [1, 2, 3, 4, 5];
const multiplier = 2;

class IndentAttributor extends Parchment.Attributor.Style {
  add(node, value) {
      return super.add(node, `${value * multiplier}em`);
  }

  value(node) {
      return parseFloat(super.value(node)) / multiplier || undefined; // Don't return NaN
  }
}

const IndentStyle = new IndentAttributor('indent', 'margin-left', {
  scope: Parchment.Scope.BLOCK,
  whitelist: levels.map(value => `${value * multiplier}em`)
});

export default IndentStyle;

This is working nicely, but I need to support right text alignment, and so I need to switch margin-left with margin-right when the current line is right aligned or when the line direction attribute is 'rtl`.

How can I do it?

why i copy your code and then occur this error: Uncaught TypeError: BlotClass.create is not a function?
this is my import way

import IndentStyle from '@/indentStyle';
Quill.register(IndentStyle, true)

I made this same IndentAttributor and was receiving the same BlotClass.create is not a function, but found a solution here: https://github.com/quilljs/quill/issues/2351#issuecomment-433495029

Also, here is a codepen that uses the same code as @tegola with it working fine. I hope in posting this codepen, we can find a solution to resolve the text-align issue that this issue originally targets:
https://codepen.io/anon/pen/LgqBxm

For angular 2+:

Create file quill.d.ts: (you can try using @types/quill module, but it doesn't work for me because getting some error)
declare module 'quill';

Add import in your component:
import * as Quill from 'quill';

Add class:

class IndentAttributor extends Quill.import('parchment').Attributor.Style {
  multiplier = 2;

  constructor(name: string, style: string, params: any) {
    super(name, style, params);
  }

  add(node, value) {
    return super.add(node, `${value * this.multiplier}rem`);
  }

  value(node) {
    return parseFloat(super.value(node)) / this.multiplier || undefined;
  }
}

Add function in your component:

  createCustomIndent(): void {
    const levels = [1, 2, 3, 4, 5];
    const multiplier = 2;
    const indentStyle = new IndentAttributor('indent', 'margin-left', {
      scope: Quill.import('parchment').Scope.BLOCK,
      whitelist: levels.map(value => `${value * multiplier}rem`),
    });

    Quill.register(indentStyle);
  }

And run it in constructor for example:

  constructor() {
    this.createCustomIndent();
  }

For angular 2+:

Create file quill.d.ts: (you can try using @types/quill module, but it doesn't work for me because getting some error)
declare module 'quill';

Add import in your component:
import * as Quill from 'quill';

Add class:

class IndentAttributor extends Quill.import('parchment').Attributor.Style {
  multiplier = 2;

  constructor(name: string, style: string, params: any) {
    super(name, style, params);
  }

  add(node, value) {
    return super.add(node, `${value * this.multiplier}rem`);
  }

  value(node) {
    return parseFloat(super.value(node)) / this.multiplier || undefined;
  }
}

Add function in your component:

  createCustomIndent(): void {
    const levels = [1, 2, 3, 4, 5];
    const multiplier = 2;
    const indentStyle = new IndentAttributor('indent', 'margin-left', {
      scope: Quill.import('parchment').Scope.BLOCK,
      whitelist: levels.map(value => `${value * multiplier}rem`),
    });

    Quill.register(indentStyle);
  }

And run it in constructor for example:

  constructor() {
    this.createCustomIndent();
  }

Wow I spend like two days looking for this solution in angular, Thanks!!!

Hello guys,
I did some workaround on it, and it's worked for rtl and ltr, I added event listener on .ql-direction when the editor created

editorCreated(quill) { const toolbar = quill.getModule('toolbar'); toolbar.addHandler('image', this.imageHandler.bind(this)); this.quillEditor = quill; this.changeQuillDirection(); document.querySelector('.ql-direction').addEventListener('click', (e) => { this.createCustomIndent(); }) }

and I modified this function:

createCustomIndent(): void {
const levels = [1, 2, 3, 4, 5];
const multiplier = 2;
let indentStyle;
if(document.querySelector('.ql-direction.ql-active')){
indentStyle = new IndentAttributor('indent', 'margin-right', {
scope: Quill.import('parchment').Scope.BLOCK,
whitelist: levels.map(value => ${value * multiplier}rem),
});
}else{
indentStyle = new IndentAttributor('indent', 'margin-left', {
scope: Quill.import('parchment').Scope.BLOCK,
whitelist: levels.map(value => ${value * multiplier}rem),
});
}
Quill.register(indentStyle);
}

so .ql-direction button has class ql-active only if the direction was rtl and in this case I will register margin-right not left.

Github code block doesn't work with me to see the code clearly copy and past it in the editor.

Thank you

Unfortunately, your solutions does not apply to a class based instantiation like the original one (mine).

Thanks though, might help others.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

splacentino picture splacentino  路  3Comments

rsdrsd picture rsdrsd  路  3Comments

aletorrado picture aletorrado  路  3Comments

emanuelbsilva picture emanuelbsilva  路  3Comments

benbro picture benbro  路  3Comments