npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@iqs/react-summernote

v2.3.13

Published

Summernote (Super simple WYSIWYG editor) adaptation for react http://summernote.org

Downloads

45

Readme

React SummerNote

React SummerNote 是一個 React 版本的 WYSIWYG 的 rich text editor,基於 SummerNote 建構

  • Stable Version: v2.3.13

  • 版本修改紀錄:Changelog

Online Demo

上面連結是一個 React SummerNote 的基本展示

Demo

Package Dependencies

React SummerNote 依賴以下套件

必要套件

  • react: ^16.8.6
  • react-dom: ^16.8.6
  • prop-types: ^15.7.2

第三方套件

  • bootstrap: ^4.6.2
  • popper.js: ^1.16.1
  • summernote: ^0.8.18
  • jquery: ^3.6.1
  • store: ^2.0.12

Install

必要依賴安裝

npm i bootstrap popper.js summernote jquery store --save

安裝 React SummerNote

npm i @iqs/react-summernote --save 

設定 Webpack

使 jQuery, store 可以在 Component 中被存取,而不需額外 import

{
    ...,
    plugins: [
        new webpack.ProvidePlugin({
            $: "jquery",
            jQuery: "jquery",
            store: "store",
        })
    ] 
}

Super simple to use

import React from 'react'
import { render } from 'react-dom'
import SummerNote from 'react-summernote'
import 'react-summernote/dist/main.css'

// 自動載入必要套件
SummerNote.ImportCode()

render(
    <SummerNote value="Default value"
        options={{
            lang: 'en',
            height: 350,
            dialogsInBody: true,
            toolbar: [
                ['style', ['style']],
                ['font', ['bold', 'underline', 'clear']],
                ['fontname', ['fontname']],
                ['para', ['ul', 'ol', 'paragraph']],
                // plugin
                ["table", ["jTable", "jMerge", "jBackcolor", "jBorderColor", "jAlign", "jTableInfo", "jWidthHeightReset"]],
                ['insert', ['link', 'picture', 'video']],
                ['view', ['fullscreen', 'codeview']],
                //["anchor",["anchor", "toc", "markAnchor", "editAnchor"]]
            ]
        }}
        onChange={e => console.log(e)}
    />
    , document.getElementById('root')
)

options.toolbar

  • Insert
    • picture: open image dialog
    • link: open link dialog
    • video: open video dialog
    • table: insert a table
    • hr: insert a horizontal rule
  • Font Style
    • fontname: set font family
    • fontsize: set font size
    • color: set foreground and background color
    • forecolor: set foreground color
    • backcolor: set background color
    • bold: toggle font weight
    • italic: toggle italic
    • underline: toggle underline
    • strikethrough: toggle strikethrough
    • superscript: toggle superscript
    • subscript: toggle subscript
    • clear: clear font style
  • Paragraph style
    • style: format selected block
    • ol: toggle ordered list
    • ul: toggle unordered list
    • paragraph: dropdown for paragraph align
    • height: set line height
  • Misc
    • fullscreen: toggle fullscreen editing mode
    • codeview: toggle wysiwyg and html editing mode
    • undo: undo
    • redo: redo
    • help: open help dialog
  • Table (Plugin)
    • jTable: 表格欄位長寬縮放
    • jMerge: 框選後合併 cell
    • jBackcolor: cell 的背景色
    • jBorderColor: 整個表格 border 顏色
    • jAlign: cell 的對齊方式
    • jTableInfo: 調整整個 table 的 margin
    • jWidthHeightReset: 重設 cell 寬高

options

設置 options props,即可設置客製化功能與 UI 顯示

summernote deep-dive

更詳細的設定方式,可以參閱上面的官方說明

Control Editor

下面簡單示範如何使用新版 API 控制編輯器 (version > v2.0.0)

import React, { Component } from 'react'
import SummerNote from './SummerNote'

class App extends Component {

    constructor(props) {
        super(props)
        this.editor = React.createRef()
    }

    componentDidMount(){
        const editor = this.editor.current
        editor.focus()                      // 焦點設置在 editor 上
        editor.isEmpty()                    // 編輯器內容是否為空
        editor.reset()                      // 清除編輯器所有內容
        editor.disable()                    // 使編輯器禁止輸入
        editor.enable()                     // 使編輯器可以輸入
        editor.insertImage()                // 插入圖片 (詳情可參考下一個段落)
        editor.insertNode(/* html node */)  // 插入 HTML 節點    
        editor.insertText('')               // 插入純文字 
    }
    render() {
        return (<SummerNote ref={this.editor}/>)
    }
}

Upload Image

自訂上傳圖片的方法,複製圖片(剪貼簿中)貼上編輯器時,就會觸發該方法

import React, { Component } from 'react'
import SummerNote from './SummerNote'

class App extends Component {

    constructor(props) {
        super(props)
        this.editor = React.createRef();
    }
    
    onImageUpload = file => {
        let image = file[0]
        this.editor.current.insertImage('https://i.imgur.com/JOOEENx.png', ($image) => {
            $image.css("width", Math.floor($image.width() / 2));
            $image.attr("title", image.name);
        })
    }

    render() {
        return (<SummerNote onImageUpload={this.onImageUpload} ref={this.editor}/>)
    }
}

1

Paste from Office Word

貼上 Word 內容時,SummerNote 會解析剪貼簿中的 rtf 內容,解析後會自動將 <img> 部分轉換成 base64 格式的圖片資源,這些 <img> 都會被加上 class .zap-img-uploading,可以在使用 jQuery 進行後續處理

import React, { Component } from 'react'
import SummerNote from './SummerNote'

function onImagePasteFromWord($imgs) {
    // $imgs collect imgs from this pasting action
    $imgs.removeClass('zap-img-uploading')
}

class App extends Component {
    render() {
        return (<SummerNote onImagePasteFromWord={onChange} />)
    }
}

Wordpaste

Paste from Office Excel

貼上 Excel 內容時,SummerNote 會解析剪貼簿中的 HTML 內容,解析後會自動將樣式附加進去,但目前不支援包含 Excel 中的圖片,需額外逐一手動複製貼上

Excel

自行 import 必要依賴

如果專案也有使用 Bootstrap 等套件,不希望重複引用,可以自行引入必要依賴

// 自動載入必要套件
//SummerNote.ImportCode()

// 以下為必要依賴,可以自行在您的專案中引入 (須注意順序)
require('bootstrap/dist/css/bootstrap.min.css')
require('bootstrap/js/dist/modal')
require('bootstrap/js/dist/dropdown')
require('bootstrap/js/dist/tooltip')
require('bootstrap/js/dist/tab')
require('summernote/dist/summernote-bs4.css')
require('summernote/dist/summernote-bs4.min.js')
require('react-summernote/plugin/custom/summernote-patch-dom')
require('react-summernote/plugin/custom/summernote-patch-handle')

summernote-patch-dom: 用於修復字體、字型等樣式無法正常套用到框選範圍內的所有節點。因官方尚未發布涵蓋 Summernote PR#4472 的版本,故在此使用 plugin 覆寫 dom.walkPoint, dom.nextPointWithEmptyNode

目前 Summernote 版本 0.8.18,待官方發佈新版本後可移除此 plugin

參考:Summernote issue#4471

summernote-patch-handle: 用於修復圖片顯示框位置偏移。因官方尚未發布涵蓋 Summernote PR#4283 的版本,故在此使用 plugin 覆寫 modules.handle.update

目前 Summernote 版本 0.8.18,待官方發佈新版本後可移除此 plugin

Plugin

2.0.4 的版本開始,引入了 table plugin,可針對 table 元素進行更多操作

require('react-summernote/plugin/summernote-ext-table')
require('react-summernote/plugin/summernote-ext-table.css')

其他 Plugin

若要自行引入 plugin 可參考 Plugin 介紹

如果 Plugin 無法載入

請嘗試引用 src/plugin 裡面的 plugin

以 table plugin 為例

require('@iqs/react-summernote/src/plugin/misc/summernote-ext-table')
require('@iqs/react-summernote/src/plugin/misc/summernote-ext-table.css')

XSS 白名單

summernote 包含一個原始碼的 xss 過濾機制,規則如下:

/<\/*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|ilayer|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|t(?:itle|extarea)|xml)[^>]*?>/gi

options 中修改內建白名單,即可客製化保留部分 tag 不被過濾

<SummerNote value="Default value"
    options={{
        height: 350,
        toolbar: [
            ['view', ['fullscreen', 'codeview']],
        ],
        // 白名單
        codeviewFilterRegex: /<\/*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|ilayer|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|t(?:itle|extarea)|xml)[^>]*?>/gi, 
        // 白名單
        codeviewFilter: true, // 是否開啟白名單過濾
        codeviewIframeFilter: false // 是否開啟 iframe src 網址過濾
    }}
/>
, document.getElementById('root')

更多詳細設定可以參閱官方文件

嵌入影片

以下是依據 Summernote 0.8.18 videoDialog 整理出已知的有效網址

YouTube

  • YouTube 網域 + 路徑 + id
    • https://youtube.com/embed/Dm_BrGu1sHM
  • YouTube 網域 + 路徑 + id + 時戳
    • https://www.youtube.com/watch?v=Dm_BrGu1sHM&t=300
    • https://m.youtube.com/v/Dm_BrGu1sHM?t=300
  • 網址附帶的其他參數需放在時戳之後
    • https://m.youtube.com/v/Dm_BrGu1sHM?t=300&si=YsiSA_iLcKJMtDVq

| 網域 | 路徑 | id | 時戳 | | ---------------------------------------------------------- | ------------------------------------------------------------ | ---------- | ------------------------------------------------------ | | youtube.com/ www.youtube.com/ m.youtube.com/ | embed/ v/ watch?v= watch?(任意字元)&v= | (11個字元) | ?t=(任意字元) &t=(任意字元) t=(任意字元) |

Instagram

  • Instagram 網域 + 路徑 + id
    • https://www.instagram.com/p/Cy8sEXrv9xu
  • 網址附帶的其他參數需放在 id 之後
    • https://www.instagram.com/p/Cy8sEXrv9xu?igshid=MzRlODBiNWFlZA==

| 網域 | 路徑 | id | | ---------------------------------------- | ---- | ---------- | | www.instagram.com/instagram.com/ | p/ | (任意字元) |

優酷

  • 優酷網域 + 路徑 + id_ + id + .html
    • https://v.youku.com/v_show/id_XNTA3MzUyMTUyMA==.html
  • 網址附帶的其他參數需放在 .html 之後
    • https://v.youku.com/v_show/id_XNTA3MzUyMTUyMA==.html?spm=a2hja.14919748_WEBHOME_NEW.drawer15.d_zj1_4&s=efbfbd4a46efbfbd5975&scm=20140719.manual.19594.show_efbfbd4a46efbfbd5975

| 網域 | 路徑 | 前綴 | id | 後綴 | | -------------- | --------- | ----- | ------------------------------- | ------- | | v.youku.com/ | v_show/ | id_ | (至少一個任意字元)(零或數個=) | .html |

DailyMotion

  • DailyMotion網域 + 路徑 + id
    • https://www.dailymotion.com/video/x8pi9hp

| 網域 | 路徑 | id | 參數 | | ---------------------- | -------------------- | -------------------------------------- | ------------------------------------------------------ | | www.dailymotion.com/ | video/ hub/ | (至少一個非_的字元)(多個非#的字元) | (零組或一組 (#video=)(至少一個非 _& 的字元)) |

For contributor

Setup Node

  • node: v16.20.2
  • npm: v8.19.4

以 nvm 安裝

nvm install v16.20.2
nvm use v16.20.2

Install Dependencies

安裝依賴套件

  • npm ci 依據 package-lock.json 安裝套件
npm ci

NPM Scripts

npm 有準備以下指令,分別說明如下,如果您也想貢獻程式碼,可以參考使用:

  • npm run build:用於打包整個套件,輸出到 dist 目錄下的一個 main.js 檔案,用於發布新的套件版本
  • npm run web:以 src/start.js 為起始,打包出一個 demo 網站,輸出到 docs,並且使用 production 產品模式執行,用於發布成 Repo 的 Page 網站
  • npm run dev:以 src/start.js 為起始,打包出一個 demo 網站,輸出到 docs,並且使用 dev 開發模式執行,用於發布成 Repo 的 Page 網站
  • npm run test:啟動一個 webpack-dev-server,以 src/test.js 為起始,用於測試直接引用打包 (build) 後的 summernote ,觀察引用打包後的程式執行起來是否有問題
  • npm start:開發人員主要模式,啟動一個 webpack-dev-server,以 src/start.js 為起始,用於測試原始程式執行起來是否有問題,並開發新功能

Commit Message

可使用 vscode extension Commit Message Editor 編輯 Commit Message

Code Structure

Summernote.jsx

src/components/SummerNote.jsx

Summernote 連結器,與原生 Summernote 對接

App.jsx

src/components/App.jsx

引入使用 Summernote Component,DEMO 呈現依賴此檔案設定

ImportCode.js

src/components/ImportCode.js

ImportCode 會引入所有 Plugin,若有新增 Plugin 需要在此引入

module.exports = function () {
    // ...
    require('../plugin/custom/summernote-custom-style')
}

SummernotePlugin

@iqs/react-summernote: v2.2.20 開始

import SummerNote, { SummernotePlugin } from '@iqs/react-summernote'

Methods

  • SummernotePlugin.createSummernoteButton
  • SummernotePlugin.createSummernotePlugin

Types

  • global $.summernote
  • SummernotePlugin.createSummernotePlugin
  • SummernotePlugin.SummernotePluginClass
  • SummernotePlugin.SummernotePluginFunction
  • SummernotePlugin.createSummernoteButton
  • SummernotePlugin.SummernoteContext
  • ...

Plugin

src/plugin/

Plugin 目錄架構由 Awesome Summernote 訂定,IQS 自己寫的都放在 src/plugin/custom/

檔案名稱以 summernote- 開頭,Plugin 名稱、按鈕名稱以 小駝峰 命名

有新增 Plugin 記得更新文件 src/plugin/README.md

For maintainer

上版 DEMO 網站流程

iq-service-inc.github.io/react-summernote

  1. pushmaster 分支

  2. 觸發 Github Workflow Deploy Master Branch to Github Pages

  3. 待 Workflow 完成即上版完成

發佈 npm 套件流程

NPM - @iqs/react-summernote

  1. 修改 README.md 版本號

  2. 修改 package.json 版本號

  3. 更新 CHANGELOG.md

  4. pushmaster 分支

  5. 發布 Github Release

    • 選擇新 Tag
    • 標題為 Tag
    • 內容貼 CHANGELOG
    • 內容最後附上差異比對連結
      • e.g.
      **Full Changelog**: https://github.com/iq-service-inc/react-summernote/compare/v2.2.19...v2.2.20
  6. 觸發 Github Workflow Publish Package to npmjs

  7. 待 Workflow 完成即發佈完成

For repo admins

.github/workflows/ 存放所有 Github Workflows

  1. Deploy Master Branch to Github Pages: 自動部署 Pages

  2. Publish Package to npmjs: 發佈 npm 套件

    若發布流程失敗,出現 404 Not Found - PUT https://registry.npmjs.org/@iqs%2freact-summernote - Not found 等訊息,可能是 Token 無效或過期

License

The MIT License (MIT)
Copyright (c) 2023 Zap