Quill: Getting the current line the cursor is on

Created on 11 Oct 2016  路  9Comments  路  Source: quilljs/quill

I need to be able to format an entire line at once, but using formatLine() doesn't work for format operations such as 'bold' and 'underline'. I can only assume that this is the intended behavior. Either way I need a way to perform those operations on an entire line regardless of the selection length, so I was wondering if maybe there was a way I could get the selection range for the current line based on an index?

discussion

Most helpful comment

I need a similar thing and am using Parchment.find and traversing the data structure to count the lines.

const Parchment = Quill.import('parchment')
quill.on('editor-change', (range) => {
  const selection = document.getSelection()
  const node = selection.getRangeAt(0).startContainer
  const blot = Parchment.find(node)
  let block = blot
  // find ancestor block blot
  while (block.statics.blotName !== 'block' && block.parent)
    block = block.parent
  const root = block.parent // assume parent of block is root
  let cur
  const next = root.children.iterator()
  let index = 0
  while (cur = next()) {
    index++
    if (cur === block) break
  }
  console.log(index)
})

All 9 comments

I need a similar thing and am using Parchment.find and traversing the data structure to count the lines.

const Parchment = Quill.import('parchment')
quill.on('editor-change', (range) => {
  const selection = document.getSelection()
  const node = selection.getRangeAt(0).startContainer
  const blot = Parchment.find(node)
  let block = blot
  // find ancestor block blot
  while (block.statics.blotName !== 'block' && block.parent)
    block = block.parent
  const root = block.parent // assume parent of block is root
  let cur
  const next = root.children.iterator()
  let index = 0
  while (cur = next()) {
    index++
    if (cur === block) break
  }
  console.log(index)
})

@rashfael 's snippet worked great for me except I had to append a .parentNode onto the end of the selection.getRangeAt()

Yeah, it worked to me as well, however what I needed was both the character index and length which would select the current line. Although I think what I should do is add my own block formats. Because that's what I really need, line level bold, underline, ect.

I believe you should be able to cleanly combine the line number from the snippet above with the quill editor's getSelection() to get all the pieces of info you need.

I've been using custom inline formats for my use case and the snippet above combined with root.descendants(Parchment.query(MyInlineBlot.blotName)) let's me loop through all my elements easily.

There is not an API for getting lines at the moment. Does anyone want to propose one?

The original question was about making the entire paragraph bold or underlined. To do that, with the current Quill API, that is possible by just applying a class that works on the block level, rather than the online level. A sample that does that is here: https://github.com/bibledit/playground/tree/master/quill. It is in the files classes.html and classes.js and classes.css. One does not need to have an API for getting lines, to do the above.

I came across this thread after solving this myself, so I haven't tried rashfael's solution, but I figured I may as well share what I've done. This code was part of a module, so you may need to replace this.quill with your editor object. Code edited for ease of use. On a side note - is there a "proper" way of create a range object?

getLines(range, quill) {
  // returns an array of ranges representing the lines that 'range' is part of.
  // getLines({index: 2, length: 0}) : [{index: number, length: number}]

  let firstLine = quill.getText(0, range.index).split("\n").length - 1;
  let lastLine = quill.getText(0, range.index+range.length).split("\n").length - 1;

  let text = quill.getText().split("\n");
  text.forEach(function(line, index, ary){ ary[index] += '\n'; });

  let lines = [];
  lines.push({
    'index': text.slice(0,firstLine).reduce( (a,b) => { return a + b.length; }, 0),
    'length': text[firstLine].length
  });
  for (let i = firstLine+1; i <= lastLine; ++i) {
    let lastline = lines[lines.length-1];
    lines.push({
      'index':  lastline.index + lastline.length,
      'length': text[i].length
    });
  }

  return lines;
}

I was able to solve my issue by styling header tags and using something like:
quill.formatLine(sel.index, sel.length, 'header', 1);
It was a quick workaround but I realize you could add your own line level formats if you wanted to. Hope this helps anyone who needs to quickly format and entire line with custom styles.

I came across this thread after solving this myself, so I haven't tried rashfael's solution, but I figured I may as well share what I've done. ~This code was part of a module, so you may need to replace this.quill with your editor object.~ Code edited for ease of use. On a side note - is there a "proper" way of create a range object?

getLines(range, quill) {
  // returns an array of ranges representing the lines that 'range' is part of.
  // getLines({index: 2, length: 0}) : [{index: number, length: number}]

  let firstLine = quill.getText(0, range.index).split("\n").length - 1;
  let lastLine = quill.getText(0, range.index+range.length).split("\n").length - 1;

  let text = quill.getText().split("\n");
  text.forEach(function(line, index, ary){ ary[index] += '\n'; });

  let lines = [];
  lines.push({
    'index': text.slice(0,firstLine).reduce( (a,b) => { return a + b.length; }, 0),
    'length': text[firstLine].length
  });
  for (let i = firstLine+1; i <= lastLine; ++i) {
    let lastline = lines[lines.length-1];
    lines.push({
      'index':  lastline.index + lastline.length,
      'length': text[i].length
    });
  }

  return lines;
}

Your solution works like a charm for me.
I use it to invert lines by shortcut. Line(s) up or down like in source code editors.
Thank you !

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Softvision-MariusComan picture Softvision-MariusComan  路  3Comments

aletorrado picture aletorrado  路  3Comments

Kivylius picture Kivylius  路  3Comments

lastmjs picture lastmjs  路  3Comments

splacentino picture splacentino  路  3Comments