ProMMirror के साथ एक सरल WYSIWYG संपादक लिखना

जब Sports.ru को अपने WYSIWYG संपादक की आवश्यकता थी , तो हमने इसे प्रोसेमिरर लाइब्रेरी के आधार पर बनाने का फैसला किया। इस उपकरण की प्रमुख विशेषताओं में से एक इसकी विशिष्टता और अनुकूलन की व्यापक संभावनाएं हैं, इसलिए इसकी मदद से आप संपादक को किसी भी परियोजना के लिए बारीक से बारीक कर सकते हैं। विशेष रूप से, प्रोसेमिरर का उपयोग पहले से ही द न्यूयॉर्क टाइम्स और द गार्जियन में किया जा रहा है इस लेख में, हम प्रोसेमिरर का उपयोग करके अपने WYSIWYG संपादक को लिखने के तरीके के बारे में बात करेंगे।

ProMMirror के साथ एक सरल WYSIWYG संपादक लिखना

प्रोसेमिरर का अवलोकन


प्रोसेमिरोर के लेखक मरिजन हावेर्बके हैं, जो मुख्य रूप से लोकप्रिय पुस्तक एलोक्वेंट जावास्क्रिप्ट के लेखक के रूप में सामने वाले डेवलपर समुदाय में जाने जाते हैं । हमारे काम की शुरुआत में (शरद ऋतु 2018), इस पुस्तकालय के साथ काम करने पर कोई सामग्री नहीं थी, लेखक से आधिकारिक दस्तावेज और ट्यूटोरियल को छोड़कर। लेखक के दस्तावेज़ीकरण पैकेज में कई खंड शामिल हैं, उनमें से सबसे उपयोगी हैं प्रोसेमिरर गाइड (मूल अवधारणाओं का वर्णन) और संदर्भ मैनुअल (पुस्तकालय कल्पना)। नीचे प्रोसेमिरर गाइड के प्रमुख विचारों का सारांश है।

ProseMirror हमेशा एक दस्तावेज़ की स्थिति को अपने डेटा संरचना में संग्रहीत करता है। और पहले से ही इस संरचना से रनटाइम में संबंधित डोम तत्व उस पेज पर उत्पन्न होते हैं जिसके साथ अंतिम उपयोगकर्ता इंटरैक्ट करता है। इसके अलावा, प्रोसेमिरर न केवल वर्तमान स्थिति (राज्य) को स्टोर करता है, बल्कि पिछले परिवर्तनों का इतिहास भी है, जिसे आवश्यक होने पर वापस रोल किया जा सकता है। राज्य में कोई भी परिवर्तन लेन-देन के माध्यम से होना चाहिए, डोम पेड़ के साथ सामान्य जोड़तोड़ सीधे यहां काम नहीं करेगा। लेन-देन एक अमूर्तता है जो चरण-दर-चरण राज्य परिवर्तन के तर्क का वर्णन करता है। उनके काम का सार राज्य प्रबंधन के लिए पुस्तकालयों में कार्यों को भेजने और निष्पादित करने की याद दिलाता है, उदाहरण के लिए, Redux और Vuex।

पुस्तकालय ही स्वतंत्र मॉड्यूल पर बनाया गया है जिसे अक्षम किया जा सकता है या जरूरतों के आधार पर जोड़ा जा सकता है। मुख्य मॉड्यूल की एक सूची जिसे हमने सोचा था कि लगभग सभी को इसकी आवश्यकता होगी:

  • अभियोजक-मॉडल - एक दस्तावेज मॉडल जो किसी दस्तावेज़ के सभी घटकों, उनकी संपत्तियों और कार्यों का वर्णन करता है जो उन पर किया जा सकता है;
  • अभियोजक-राज्य - एक डेटा संरचना जो एक निश्चित समय पर निर्मित दस्तावेज़ की स्थिति का वर्णन करती है, जिसमें चयनित टुकड़े और एक राज्य से दूसरे राज्य में जाने के लिए लेनदेन शामिल है;
  • अभियोजक-दृश्य - ब्राउज़र और टूल में दस्तावेज़ की प्रस्तुति ताकि उपयोगकर्ता दस्तावेज़ के साथ बातचीत कर सके;
  • अभियोजन-परिवर्तन - लेन-देन के इतिहास को संग्रहीत करने के लिए एक कार्यात्मक, जिसकी मदद से लेनदेन को लागू किया जाता है और जो आपको पिछले राज्यों में वापस रोल करने या एक दस्तावेज़ के संयुक्त विकास का संचालन करने की अनुमति देता है।

इस न्यूनतम सेट के अलावा, निम्नलिखित मॉड्यूल भी उपयोगी हो सकते हैं:

  • प्रोसेमिरर-कमांड - संपादन के लिए तैयार कमांड का एक सेट। एक नियम के रूप में, आपको कुछ और अधिक जटिल या व्यक्तिगत लिखने की आवश्यकता है, लेकिन मैरिजन हावेर्बके ने पहले ही हमारे लिए कुछ चीजें की हैं, उदाहरण के लिए, पाठ के चयनित टुकड़े को हटाना;
  • अभियोजक-कीमैप - कीबोर्ड शॉर्टकट निर्दिष्ट करने के लिए दो तरीकों का एक मॉड्यूल;
  • prosemirror-history – , .. , , , ;
  • prosemirror-schema-list – , ( DOM-, , ).

ProseMirror


एक संपादक रूपरेखा तैयार करके शुरू करते हैं। ProseMirror में स्कीमा उन तत्वों की एक सूची को परिभाषित करता है जो हमारे दस्तावेज़ और उनके गुणों में हो सकते हैं। प्रत्येक तत्व में एक TODOM विधि होती है, जो यह निर्धारित करती है कि वेब पेज पर DOM ट्री में इस तत्व का प्रतिनिधित्व कैसे किया जाएगा।

WYSIWYG के सिद्धांत को इस तथ्य के बारे में सटीक रूप से महसूस किया जाता है कि योजना बनाते समय हम इस बात पर पूर्ण नियंत्रण रखते हैं कि पृष्ठ पर संपादन योग्य सामग्री कैसे प्रदर्शित होती है, और, तदनुसार, हम प्रत्येक तत्व को ऐसे HTML संरचना दे सकते हैं और शैलियों को देख सकते हैं जैसे सामग्री को देखा जा सकता है। नोड्स को आपकी आवश्यकताओं के अनुसार बनाया और अनुकूलित किया जा सकता है, विशेष रूप से, सबसे अधिक संभावना है कि आपको पैराग्राफ, शीर्षकों, सूचियों, चित्रों, पैराग्राफ, मीडिया की आवश्यकता हो सकती है।

मान लीजिए कि पाठ के प्रत्येक पैराग्राफ को "पी" वर्ग "पैराग्राफ" के साथ टैग में लपेटा जाना चाहिए, जो लेआउट के लिए आवश्यक पैराग्राफ शैलियों के नियमों को निर्धारित करता है। तो इस मामले में ProseMirror स्कीमा इस तरह लग सकता है:

import { Schema } from "prosemirror-model";

const mySchema = new Schema({
    nodes: {
        doc: {
           content: 'block'
        },
        text: {},
        paragraph: {
            content: 'inline',
            group: 'block',
            toDOM: function toDOM(node) {
                return ['p', {class: 'paragraph'}, 0];
            },
        },
    },
});

सबसे पहले, हम अपने स्कीमा को बनाने के लिए कंस्ट्रक्टर को आयात करते हैं और उस पर एक ऑब्जेक्ट पास करते हैं जो भविष्य के संपादक में नोड्स (बाद में नोड्स के रूप में संदर्भित) का वर्णन करता है। नोड्स अमूर्तताएं हैं जो बनाई जा रही सामग्री के प्रकारों का वर्णन करती हैं। उदाहरण के लिए, ऐसी योजना के साथ, संपादक में केवल प्रकार के पाठ और पैराग्राफ के नोड्स हो सकते हैं। डॉक शीर्ष-स्तरीय नोड का नाम है, जिसमें केवल ब्लॉक तत्व शामिल होंगे, अर्थात। इस मामले में केवल पैराग्राफ से (क्योंकि हमने दूसरों का वर्णन नहीं किया है)।

टेक्स्ट टेक्स्ट नोड्स हैं, कुछ हद तक टेक्स्ट डोम नोड्स के समान हैं। समूह की संपत्ति का उपयोग करते हुए, हम अपने नोड्स को अलग-अलग तरीकों से समूहित कर सकते हैं ताकि उन्हें कोड में अधिक आसानी से एक्सेस किया जा सके। समूह हमारे लिए सुविधाजनक किसी भी तरह से सेट किए जा सकते हैं। हमारे मामले में, हमने नोड्स को केवल ब्लॉक और इनलाइन में विभाजित किया है। पाठ डिफ़ॉल्ट रूप से इनलाइन है, इसलिए इसे स्पष्ट रूप से छोड़ा जा सकता है।

एक पूरी तरह से अलग चीज पैराग्राफ (पैराग्राफ) है। हमने घोषणा की कि पैराग्राफ इनलाइन पाठ तत्वों से मिलकर बने होते हैं, और DOM में उनका अपना प्रतिनिधित्व भी होता है। एक पैरा एक ब्लॉक तत्व होगा, मोटे तौर पर इस अर्थ में कि डोम ब्लॉक तत्व हैं। इस योजना के अनुसार, पृष्ठ पर पैराग्राफ ऑनलाइन संपादक में निम्नानुसार प्रस्तुत किए जाएंगे:

<p class="paragraph">Content of the paragraph</p>

अब आप स्वयं संपादक बना सकते हैं:

import { EditorState } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
import { Schema } from "prosemirror-model";

const mySchema = new Schema({
    nodes: {
        doc: {
            content: 'block+'
        },
        text: {
            group: 'inline',
            inline: true
        },
        paragraph: {
            content: 'inline*',
            group: 'block',
            toDOM: function toDOM(node) {
                return ['p', {class: 'paragraph'}, 0];
            },
        },
    },
});

/**
 * @classdesc  
 * @param {Object} el DOM-,    
 */
export default class Wysiwyg {
    constructor(el) {
        this.el = el;
    }

    /**
      * @description     
      * @param {Object} content ,    
      */
    setArticle(content) {
        const state = EditorState.fromJSON(
            {schema: mySchema},
            content,
        );
        const view = new EditorView(this.el, {state: state});
    }
}

शुरुआत में, हमेशा की तरह, हम सभी आवश्यक कंस्ट्रक्टरों को संबंधित मॉड्यूल से आयात करते हैं और ऊपर वर्णित योजना लेते हैं। हम संपादक को आवश्यक तरीकों के एक सेट के साथ एक वर्ग के रूप में बनाते हैं। वेब पेज के लिए सामग्री को संपादित करने और बनाने में सक्षम होने के लिए, आपको लेख के लेआउट और सामग्री का उपयोग करके एक राज्य, राज्य बनाने और दिए गए मूल तत्व में वर्तमान स्थिति से सामग्री को प्रस्तुत करने की आवश्यकता है। हमने इन क्रियाओं को सेटआर्टिकल पद्धति में रखा, सिवाय इसके कि अब तक कुछ भी आवश्यक नहीं है।

इसी समय, सामग्री वैकल्पिक है। यदि यह नहीं है, तो आपको एक खाली संपादक मिलता है, और सामग्री पहले से ही सीधे मौके पर बनाई जा सकती है। मान लें कि हमारे पास इस मार्कअप वाली HTML फ़ाइल है:

<div id="editor"></div>

किसी पृष्ठ पर एक खाली WYSIWYG संपादक बनाने के लिए, आपको एक स्क्रिप्ट में केवल कुछ पंक्तियों की आवश्यकता होती है, जो इस मार्कअप के साथ पृष्ठ पर चलती है:

//     
import Wysiwyg from 'wysiwyg';

const root = document.getElementById('editor');
const myWysiwyg = new Wysiwyg(root);
myWysiwyg.setArticle();

इस कोड का उपयोग करके, आप स्क्रैच से कोई भी टेक्स्ट लिख सकते हैं। इस बिंदु पर, आप पहले से ही देख सकते हैं कि प्रोसेमिरर कैसे काम करता है।

जब कोई उपयोगकर्ता इस संपादक में पाठ टाइप करता है, तो राज्य लेनदेन होता है। उदाहरण के लिए, यदि आप उपरोक्त योजना के साथ संपादक में "यह मेरा नया कूल WYSIWYG संपादक है" वाक्यांश टाइप करते हैं, तो प्रोसेमिरर लेन-देन के उपयुक्त सेट को आमंत्रित करके कीबोर्ड इनपुट पर प्रतिक्रिया देगा, और इनपुट पूरा होने के बाद, दस्तावेज़ स्थिति की सामग्री इस तरह दिखाई देगी:

content: [
    {
        type: 'paragraph',
        value: '    WYSIWYG-',
    },
]

यदि हम कुछ पाठ चाहते हैं, उदाहरण के लिए, पहले से निर्मित एक लेख की सामग्री, संपादन के लिए संपादक में खोली जाए, तो यह सामग्री पहले बनाई गई योजना के अनुरूप होनी चाहिए। तब संपादक इनिशियलाइज़ेशन कोड थोड़ा अलग दिखेगा:

//     
import Wysiwyg from 'wysiwyg';

const root = document.getElementById('editor');
const myWysiwyg = new Wysiwyg(root);
const content = {
    type: 'doc',
    content: [
        {
            type: 'paragraph',
            value: 'Hello, world!',
        },
        {
            type: 'paragraph',
            value: 'This is my first wysiwyg-editor',
        }
    ],
};
myWysiwyg.setArticle(content);

हुर्रे! हमने अपना पहला संपादक बनाया, जो नई सामग्री बनाने और संपादन के लिए मौजूदा को खोलने के लिए एक स्वच्छ पृष्ठ बना सकता है।

आगे संपादक के साथ क्या करना है


लेकिन यहां तक ​​कि नोड्स के एक पूर्ण सेट के साथ, हमारे संपादक में अभी भी महत्वपूर्ण कार्यों का अभाव है - पाठ, पैराग्राफ का प्रारूपण। इसके लिए, नोड्स के अलावा, स्वरूपण, निशान के लिए सेटिंग्स के साथ एक ऑब्जेक्ट भी सर्किट में स्थानांतरित किया जाना चाहिए। सादगी के लिए, हम उन्हें ब्रांड कहते हैं। और इन सभी तत्वों को जोड़ने, हटाने और स्वरूपण को नियंत्रित करने के लिए, उपयोगकर्ताओं को एक मेनू की आवश्यकता होगी। मेन्यू को कस्टम प्लगइन्स का उपयोग करके जोड़ा जा सकता है जो मेनू ऑब्जेक्ट्स को स्टाइल करता है और कुछ कार्यों को चुनते समय दस्तावेज़ की स्थिति में परिवर्तन का वर्णन करता है।

प्लगइन्स का उपयोग करके, आप किसी भी डिज़ाइन को बना सकते हैं जो संपादक की अंतर्निहित सुविधाओं का विस्तार करता है। प्लगइन्स का मुख्य विचार यह है कि वे कुछ उपयोगकर्ता कार्यों को संसाधित करते हैं ताकि उनके अनुरूप लेनदेन उत्पन्न हो सके। उदाहरण के लिए, यदि आप नई खाली सूची बनाने और पहले तत्व की शुरुआत में कर्सर को स्थानांतरित करने के लिए मेनू में सूची आइकन पर क्लिक करना चाहते हैं, तो हमें निश्चित रूप से संबंधित प्लगइन में इस लेनदेन का वर्णन करने की आवश्यकता है।

आप आधिकारिक प्रलेखन में सेटिंग्स और प्लगइन्स को प्रारूपित करने के बारे में अधिक पढ़ सकते हैं , साथ ही साथ प्रोसेमिरर सुविधाओं का उपयोग करने के बहुत छोटे उपयोगी उदाहरण बहुत उपयोगी हो सकते हैं

युपीडीयदि आप रुचि रखते हैं कि कैसे हम एक मौजूदा परियोजना में प्रोसेमिरोर पर आधारित एक नए संपादक को एकीकृत करते हैं, तो हमने एक अन्य लेख में इस बारे में बात की

All Articles