Code Monkey home page Code Monkey logo

Comments (7)

gztchan avatar gztchan commented on August 22, 2024 16
import Embed from '../../quill/blots/embed';

class Caption extends Embed {
  static create(value) {
    let node = super.create(value);
    node.innerText = value;
    return node;
  }

  value() {
    return this.domNode.innerText;
  }
}

Caption.blotName = 'caption';
Caption.tagName = 'SPAN';

export default Caption;
import Block from '../../quill/blots/block';
import Embed from '../../quill/blots/embed';
import { sanitize } from '../../quill/formats/link';

class SingleImageBlot extends Block {
  static create(value) {
    let node = super.create(value);
    // node.setAttribute('contenteditable', false);
    return node;
  }

  constructor(domNode, value) {
    super(domNode, value);
    const image = Parchment.create('image', value);
    const caption = Parchment.create('caption', 'placeholder');
    this.appendChild(image);
    this.appendChild(caption);
  }

  static match(url) {
    return /\.(jpe?g|gif|png)$/.test(url) || /^data:image\/.+;base64/.test(url);
  }

  static sanitize(url) {
    return sanitize(url, ['http', 'https', 'data']) ? url : '//:0';
  }

  deleteAt(index, length) {
    this.removeChild(this.children.head);
    removeElements(this);
    super.deleteAt(index, length);
  }
}

function removeElements(blot) {
  const list = blot.children;
  while (list.head) {
    blot.removeChild(list.head);
  }
}

SingleImageBlot.blotName = 'single-image';
SingleImageBlot.className = 'ql-editor-single-image';
SingleImageBlot.tagName = 'DIV';

export default SingleImageBlot;

issue:

image
(blank place between icons is trigger)

I am not sure the way I built SingleImageBlot is correct or not (create sub-blot), and I found that when cursor is between the caption, and then press enter, content get disordered. In addition, deletion of caption doesn't work any more. So, I really wonder that how can I handle keyboard events in nested blot, and is there any examples or best practices recommended?

from parchment.

kilgarenone avatar kilgarenone commented on August 22, 2024 8

@jhchen
I couldn't find any documentation on how to create complex nested blot, and then be able to get the deltas using the getContents.

For example, how do I even go about coming up with this simple nesting for iframe using blot:

<div style="left: 0; width: 100%; height: 0; position: relative; padding-bottom: 56.2493%;">
     <iframe src="https://www.youtube.com/embed/6LuREkiF_Hs?rel=0&amp;showinfo=0" style="border: 0; top: 0; left: 0; width: 100%; height: 100%; position: absolute;" allowfullscreen scrolling="no">
     </iframe>
</div>

from parchment.

gztchan avatar gztchan commented on August 22, 2024 7

Actually, I want a high customized editor, including blots, modules, themes, based on Quill's system, when I make a new blot, I find that the document about Parchment is not that helpful.

Thank you for helping me comprehend the whole library, and I will keep watching about that. 👍

from parchment.

barry800414 avatar barry800414 commented on August 22, 2024 4

I have the same requirement as @kilgarenone

I want to insert something like this, a div wrapper to wrap iframe element to control the size of iframe. However, I have tried my best, I still cannot make it.

    <div class="video-container">
        <iframe src="xxx">
        </iframe>
    </div>

Thie followings are my code (using react-quill) :

const BlockEmbed = Quill.import('blots/block/embed');
class VideoContainer extends BlockEmbed {
  static create(value) {
    const node = super.create();
    node.setAttribute('class', 'video-container');

    const child = document.createElement('iframe');
    child.setAttribute('src', value);
    child.setAttribute('frameborder', 0);
    child.setAttribute('allowfullscreen', true);
    node.appendChild(child);
    return node;
  }

  // get value of the node (for implement undo function)
  static value(node) {
    return node.firstChild.getAttribute('src');
  }
}

VideoContainer.blotName = 'video-container';
VideoContainer.tagName = 'div';
Quill.register(VideoContainer);

function insertVimeo() {
  const vimRegExp = /\/\/(player.)?vimeo.com\/([a-z]*\/)*([0-9]{6,11})[?]?.*/;
  const url = prompt('Enter Vimeo URL:');
  if (url && vimRegExp.test(url)) {
    // generate embed link
    const vimMatch = url.match(vimRegExp);
    const src = ['//player.vimeo.com/video/', vimMatch[3]].join('');

    const cursorPosition = this.quill.getSelection().index;
    this.quill.insertEmbed(cursorPosition, 'video-container', src);
    this.quill.setSelection(cursorPosition + 1);
  }
}

class QuillScreen extends Component {
  constructor(props) {
    super(props);
    this.state = { text: '' };
    this.handleChange = this.handleChange.bind(this);

    this.toolbarOptions = {
      // suppose to be all supported toolbar buttons
      container: [
        // sample for adding new button in toolbar
        ['vimeo'],
        ['bold', 'italic', 'underline', 'strike'], // toggled buttons
        ['blockquote', 'code-block', 'code', 'formula', 'link'],
        ['video', 'image'],

        [{ header: 1 }, { header: 2 }], // custom button values
        [{ list: 'ordered' }, { list: 'bullet' }],
        [{ script: 'sub' }, { script: 'super' }], // superscript/subscript
        [{ indent: '-1' }, { indent: '+1' }], // outdent/indent
        [{ direction: 'rtl' }], // text direction

        [{ size: ['small', false, 'large', 'huge'] }], // custom dropdown
        [{ header: [1, 2, 3, 4, 5, 6, false] }],

        [{ color: [] }, { background: [] }], // dropdown with defaults from theme
        [{ font: [] }],
        [{ align: [] }],

        ['clean'], // remove formatting button
      ],
      handlers: {
        vimeo: insertVimeo,
      },
    };

    // suppose to be all supported format
    this.formats = [
      ['background', 'bold', 'color', 'font', 'code', 'italic', 'link', 'size', 'strike', 'script', 'underline'],
      ['blockquote', 'header', 'indent', 'list', 'align', 'direction', 'code-block'],
      ['formula', 'image', 'video'],
      ['video-container'],
    ];
  }

  handleChange(value) {
    this.setState({ text: value });
  }

  render() {
    return (
      <ReactQuill
        value={this.state.text}
        onChange={this.handleChange}
        modules={{
          toolbar: this.toolbarOptions,
        }}
      />
    );
  }
}

from parchment.

johnking avatar johnking commented on August 22, 2024 1

@gztchan @jhchen

I have a similar requirement as @gztchan. In my case, I want to create a document from a JSON file, which has the document structure:

   Page -> Paragraph(s) -> sentence(s) -> words. 

For Page, I can use scroll blot of quill editor to represent it.
For Word of each sentence, I can use text blot to represent it.

but I need blots to represent sentences and paragraphs, because there are other useful information belong to these granular level such as the start-time of the sentence, end-time etc...

  1. I want to create a sentence blot based on inline blot, which host all the words of it.
  2. I want to create a paragraph blot based on block blot, which host all the sentences of it.

but I don't know how to insert/add sentenceBlot and paragraphBlot into the quill editor. There are only insertText and insertEmbed APIs available.

May you please give me any suggestions on my use case?

thanks a lot.
-John

from parchment.

jhchen avatar jhchen commented on August 22, 2024

There are lots of ways to do this depending what you want specifically. What's the use case?

from parchment.

jhchen avatar jhchen commented on August 22, 2024

You have not answered the question about your use case so since I don't know what you are trying to achieve, I don't know if it is correct or not either.

With regards to your specific question about keyboard events, that is outside of the scope of Parchment. Parchment is just the data model. You might want to look at Quill for a fuller editor.

from parchment.

Related Issues (20)

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.