Introduction to the lightweight Rich Text Editor wangEditor source code structure, wangeditor source code

Source: Internet
Author: User

Introduction to the lightweight Rich Text Editor wangEditor source code structure, wangeditor source code
1. Introduction

  WangEditor-a lightweight html Rich Text Editor (Open Source Software)

  • Website: http://www.wangeditor.com/
  • Demo: http://www.wangeditor.com/wangEditor/demo.html
  • Github: https://github.com/wangfupeng1988/wangEditor
  • QQ: 164999061

It has been around seven or eight months since I released wangEditor. With the recently added video insertion, emoticons, and map functions, the basic functions have been improved. Several bugs were modified during this period, which were all reflected by netizens. As to whether the program is stable, I dare not say it. After all, there are not many applications. Currently, there are only dozens of people who are interested in wangEditor. They will occasionally raise some bugs, but as long as they are told, I will solve them as soon as possible. At least we agree on the speed and attitude of modifying the bug and adding features.

  

According to github, there are currently 105 commits, that is, I have submitted 105 Code updates, and this number will continue to increase. If you have any bugs, you can submit them to me through the QQ group.

2. Introduce the source code structure

The source code of wangEditor. js is currently more than 2200 lines. It is not a simple task to introduce its structure by writing a blog. So here I will make a long short speech. I would like to give a brief introduction of the key points and not to be too arrogant. Otherwise, everyone will be impatient at the end.

If I have to evaluate the source code design and architecture, I will score 70 points. It is not perfect, but it has already met my basic needs. For example, I recently added several features (inserting videos, maps, and emojis) by modifying the configuration items, without modifying the core part of the source code. The principle of openness and closures-open to expansion and closed to modification. I think I have basically done this.

Finally, I will share with you the purpose of the wangEditor source code design, in order to give you some comments. Raise some questions, some suggestions, or issues that I have not yet realized. In short, I hope the software will become better and better.

3. A jQuery plug-in

WangEditor is a jQuery plug-in and developed based on jquery. (If you do not understand the jquery plug-in, make up your own courses. This article will not cover this article ). Defining a jquery plug-in is actually very simple. The last dozens of lines of wangEditor. js source code are defined.

// -------------------------------------- Generate the jquery plug-in ---------------------------------- $. fn. extend ({/** options: {* $ initContent: $ elem, // configure the content to be initialized * menuConfig: [...], // configure the menu to be displayed (menuConfig will overwrite hideMenuConfig) * onchange: function (){...}, // configure the onchange event, * uploadUrl: 'string' // Image Upload address *} */'angeditor': function (options) {if (this [0]. nodeName! = 'Textarea ') {// only TEXTAREA alert is supported ('wangeditor prompt: Use textarea to expand the rich text box. Demo.html '); return;} var options = options |{}, menuConfig = options. menuConfig, $ initContent = options. $ initContent | $ ('<p> <br/> </p>'), onchange = options. onchange, uploadUrl = options. uploadUrl; // obtain the editor object var editor = $ E (this, $ initContent, menuConfig, onchange, uploadUrl); // render the editor and hide textarea this. before (editor. $ editorContainer); this. hide (); // initialize selection editor when the page is loaded. initSelection (); return editor ;}});

The above code is actually very simple, it is to accept some configuration items and then call a $ E function, return an editor object, and finally render it to the page. The most important thing is the $ E function.

// Obtain the editor object var editor = $ E (this, $ initContent, menuConfig, onchange, uploadUrl );

Do you think this method means var $ div =$ ('div? -- By the way, I imitated jquery in this design.

4. object-oriented design like jQuery

The $ E function mentioned above is defined in this way.

// Global constructor $ E = function ($ textarea, $ initContent, menuConfig, onchange, uploadUrl) {return new $ E. fn. init ($ textarea, $ initContent, menuConfig, onchange, uploadUrl );};

In the above Code, the constructor is $ E. fn. init. $ E is just an entry and returns an object from the new constructor.

So what is $ E. fn? -- It is short for $ E. prototype -- many js systems like this, so I will become taller!

// Prototype is abbreviated as fn $ E. fn = $ E. prototype;

Since $ E. fn. init is the constructor, so the prototype of the new object (that is, the editor in the preceding section) points to: $ E. fn. init. prototype. Isn't it too long? It is better to point the prototype to $ E. fn.

$E.fn.init.prototype = $E.fn;

  At this point, no one has ever looked at the jquery design or source code, and he must feel dizzy-that is normal.. When I first came into contact with jquery, I couldn't get around. But later I saw more, and later I used it myself. It was really easy to use. When you are working on your own js Code, do not give it a try!

5. Tool Functions & object functions

In fact, this design is also based on jquery. In jquery, functions are all $ attributes, for example, $. trim (), and object functions are all $. fn attributes. For example, the html method of detail ('div'example .html () is defined by detail .fn.html.

The same is true in wangEditor. js. Many tool functions (such as log output, quotation mark translation, and url security check) are $ E attributes. Many object functions (such as text, append, and change) are $ E. fn attributes.

Why can an object function be defined on $ E. fn? -- Because the constructor is $ E. fn. init, and $ E. fn. init. prototype = $ E. fn; do you understand?

6. menu configuration items

WangEditor currently has 28 functional menus, and it is impossible to write and execute code for each menu. Because we are object-oriented programming, we follow the "open and closed principle" design.

Not to mention, in the first version, I actually wrote and executed code for a menu, and later I found that it could not be extended at all. Now, my purpose is to write a menu Processing Engine (including menu initialization, page pop-up close, command execution). Menu extension is implemented through configuration items. This menu processing engine is not explained in this article today. It is very troublesome. I will share it with you through video.

First, we need to classify all menus. Otherwise, how can we determine the configuration items? I divide all the menus into four categories:

  • Command type: click the button to execute the command, such as "bold" and "underline"
  • DropMenu type: click the button to bring up the drop-down menu, and then select the command. Such as "font" and "font size"
  • DropPanel type: click the button to bring up the panel, and then select the command. For example, "background color" and "facial expression"
  • Modal type: click the button to bring up the dialog box. You need to enter the content before executing the command. For example, "insert image" and "insert map location"

The following describes how to configure a menu button:

'Menuid-1': {'title': (string, required) title, 'type' :( string, required) type, which can be btn/dropMenu/dropPanel/modal, 'txt ': (string, required) fontAwesome font style, for example, 'fa-head', 'style': (string, optional) set the 'hotkey' (string, optional) shortcut keys, such as 'ctrl + B ', 'ctrl, shift + I', 'alt, meta + y', etc. ctrl, shift, alt, meta: Four function keys (only type = btn is valid) 'command': (the command name of the serial file document.exe cCommand, such as 'fontname'; can also be a custom command name, for example, if the "undo", "Insert table" button (type = modal, the command is invalid), and 'dropmenu': ($ ul, optional) type = dropMenu, to return a $ ul, as the drop-down menu, 'droppanel ':( $ div, Optional) type ==droppanel is, to return a $ div, as the pop-up box 'modal' :( $ div, optional) type = modal yes, to return a $ div, as the pop-up box, 'callback' :( function, optional) callback Function ,},

When configuring another menu, you must follow this rule. Otherwise, the parsing engine cannot correctly parse the configuration item. Here, paste a few simple configuration items for each type of menu button:

'Fontfamily ': {'title': 'type', 'type': 'dropmenu', 'txt': 'icon-wangEditor-font ', 'command ': 'fontname', 'dropmenu': function () {var arr = [], // note that commandValue is required here, otherwise, the program will not track temp = '<li> <a href = "#" commandValue = "$ {value}" style = "font-family :$ {family }; ">$ {txt} </a> </li> ', $ ul; $. each ($ E. styleConfig. fontFamilyOptions, function (key, value) {arr. push (temp. replace ('$ {value}', value ). replace ('$ {family} ', Value ). replace ('$ {txt}', value) ;}); $ ul =$ (paie.html Templates. dropMenu. replace ('{content}', arr. join (''); return $ ul;}, 'callback': function (editor) {// console. log (editor) ;}, 'bold ': {'title': 'bold', 'type': 'btn ', 'hotkey': 'ctrl + B ', 'txt ': 'icon-wangEditor-bold', 'command': 'bold ', 'callback': function (editor) {// console. log (editor) ;}, 'forecolor': {'title': 'preview', 'type': 'Dro PPanel ', 'txt': 'icon-wangEditor-pemer', // if you want to use the color 'txt ': 'fa fa-pencel | color: #4a7db1 'style ': 'color: blue; ', 'command': 'forecolor', 'droppanel': function () {var arr = [], // Note: commandValue is required here, otherwise, the program will not track temp = '<a href = "#" commandValue = "$ {value}" style = "background-color :$ {color }; "title =" $ {txt} "class =" forColorItem "> & nbsp; </a> ', $ panel; $. each ($ E. styleConfig. colorOptions, function (key, value ){ Var floatItem = temp. replace ('$ {value}', key ). replace ('$ {color}', key ). replace ('$ {txt}', value); arr. push (Templates. dropPanel_floatItem.replace ('{content}', floatItem) ;}); $ panel =$ (paie.html Templates. dropPanel. replace ('{content}', arr. join (''); return $ panel; }}, 'createlink ': {'title': 'insert link', 'type': 'modal ', 'txt ': 'icon-wangEditor-link', 'modal': function (editor) {var urlTx TId = $ E. getUniqeId (), titleTxtId = $ E. getUniqeId (), blankCheckId = $ E. getUniqeId (), btnId = $ E. getUniqeId (); content = 'link: <input id = "' + urlTxtId + '" type = "text" style = "width: 300px; "/> <br/> '+' title: <input id =" '+ titleTxtId +' "type =" text "style =" width: 300px; "/> <br/> '+' New window: <input id = "'+ blankCheckId +'" type = "checkbox" checked = "checked"/> <br/> '+' <button id = "'+ btnId +' "type =" button" Class = "wangEditor-modal-btn"> insert link </button> ', $ link_modal = $ (paie.html Templates. modalSmall. replace ('{content}', content); $ link_modal.find ('#' + btnId ). click (function (e) {// note that $ link_modal in this method should not be the same as the variable name in other modal !! Otherwise, the program will be confused // the specific reason has not been verified ??? Var url = $. trim ($ ('#' + urlTxtId ). val (), title = $. trim ($ ('#' + titleTxtId ). val (), isBlank = $ ('#' + blkcheckid ). is (': checked'), link_callback = function () {// create link callback $ (' # '+ urlTxtId ). val (''); $ ('#' + titleTxtId ). val ('') ;}; if (url! = '') {// Xss filters if ($ E. filterXSSForUrl (url) === false) {alert ('your input content contains insecure characters. Please enter it again! ') Return;} if (title = ''&&! IsBlank) {editor. command (e, 'createlink ', url, link_callback);} else {editor. command (e, 'mcmcreatelink ', {'url': url, 'title': title, 'isblank': isBlank}, link_callback );}}}); return $ link_modal ;}}
7. Summary

The above are only some important parts, and there are many others. For example, the core technology of Rich Text Editor: execCommand, how to support fontIcon of IE6, how to parse menu buttons, and how expressions and maps are implemented. If the time is limited, we will not explain it one by one. If you are interested, you can refer to the source code.

Finally, I would like to thank you for your correction!

  • Website: http://www.wangeditor.com/
  • Demo: http://www.wangeditor.com/wangEditor/demo.html
  • Github: https://github.com/wangfupeng1988/wangEditor
  • QQ: 164999061

Bytes -------------------------------------------------------------------------------------------------------------

Welcome to my tutorial:From design to ModelDeep understanding of javascript prototype and closure Series"Css", "Explanation of Microsoft petshop4.0 source code", and "interpretation of json2.js source code"

Welcome to my open-source project --WangEditor, lightweight web Rich Text Editor

Bytes -------------------------------------------------------------------------------------------------------------

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.