├── .gitignore ├── example-react ├── .gitignore ├── src │ ├── index.html │ └── js │ │ ├── client.js │ │ └── constants.js ├── webpack.config.js └── package.json ├── example ├── assets │ ├── codex2x.png │ ├── json-preview.js │ └── demo.css ├── example.html ├── example-vue.html ├── dist │ └── anchor.js └── example-dev.html ├── src ├── index.css ├── util.js └── index.js ├── readme-dev.md ├── .gitmodules ├── webpack.config.js ├── package.json ├── readme.md ├── dist ├── bundle.js └── main.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | npm-debug.log 3 | /.idea/ 4 | .DS_Store -------------------------------------------------------------------------------- /example-react/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | npm-debug.log 3 | /.idea/ 4 | .DS_Store -------------------------------------------------------------------------------- /example/assets/codex2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kaaaaaaaaaaai/editorjs-alignment-blocktune/master/example/assets/codex2x.png -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | .ce-tune-alignment--right { 2 | text-align: right; 3 | } 4 | .ce-tune-alignment--center { 5 | text-align: center; 6 | } 7 | .ce-tune-alignment--left { 8 | text-align: left; 9 | } -------------------------------------------------------------------------------- /example-react/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /readme-dev.md: -------------------------------------------------------------------------------- 1 | yarn init 2 | 3 | yarn add -D @babel/core babel-loader webpack @babel/preset-env style-loader css-loader raw-loader webpack-cli 4 | 5 | それぞれのmoduleを追加(手動じゃだめっぽい) 6 | 7 | git submodule add https://github.com/editor-js/paragraph example/tools/paragraph 8 | 9 | webで読みこめば良い 10 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "example/tools/paragraph"] 2 | path = example/tools/paragraph 3 | url = https://github.com/editor-js/paragraph 4 | [submodule "example/tools/header"] 5 | path = example/tools/header 6 | url = https://github.com/editor-js/header 7 | [submodule "example/tools/delimiter"] 8 | path = example/tools/delimiter 9 | url = https://github.com/editor-js/delimiter 10 | -------------------------------------------------------------------------------- /src/util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * node 作成用 3 | * @param tagName 4 | * @param classNames 5 | * @param attributes 6 | * @returns {*} 7 | */ 8 | export function make(tagName, classNames = null, attributes = {}) { 9 | const el = document.createElement(tagName); 10 | 11 | if (Array.isArray(classNames)) { 12 | el.classList.add(...classNames); 13 | } else if (classNames) { 14 | el.classList.add(classNames); 15 | } 16 | 17 | for (const attrName in attributes) { 18 | el[attrName] = attributes[attrName]; 19 | } 20 | return el; 21 | } -------------------------------------------------------------------------------- /example-react/webpack.config.js: -------------------------------------------------------------------------------- 1 | var debug = process.env.NODE_ENV !== "production"; 2 | var webpack = require('webpack'); 3 | var path = require('path'); 4 | 5 | module.exports = { 6 | context: path.join(__dirname, "src"), 7 | entry: "./js/client.js", 8 | module: { 9 | rules: [{ 10 | test: /\.jsx?$/, 11 | exclude: /(node_modules|bower_components)/, 12 | use: [{ 13 | loader: 'babel-loader', 14 | options: { 15 | presets: ['@babel/preset-react', '@babel/preset-env'] 16 | } 17 | }] 18 | }] 19 | }, 20 | output: { 21 | path: __dirname + "/src/", 22 | filename: "client.min.js" 23 | }, 24 | plugins: debug ? [] : [ 25 | new webpack.optimize.OccurrenceOrderPlugin(), 26 | new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }), 27 | ] 28 | }; -------------------------------------------------------------------------------- /example-react/src/js/client.js: -------------------------------------------------------------------------------- 1 | import ReactDOM from "react-dom"; 2 | import React, { Component } from "react"; 3 | 4 | import EditorJs from "react-editor-js"; 5 | 6 | import { EDITOR_JS_TOOLS } from "./constants"; 7 | 8 | class ReactEditor extends Component { 9 | render() { 10 | return ( 11 | 27 | ); 28 | } 29 | } 30 | 31 | ReactDOM.render(, document.getElementById("root")); 32 | -------------------------------------------------------------------------------- /example-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-react", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "scripts": { 7 | "build": "webpack --mode production", 8 | "build:dev": "webpack --mode development --watch", 9 | "pull_tools": "git submodule update --init --recursive" 10 | }, 11 | "dependencies": { 12 | "@babel/core": "^7.13.16", 13 | "@babel/preset-env": "^7.13.15", 14 | "@babel/preset-react": "^7.13.13", 15 | "@editorjs/editorjs": "^2.20.2", 16 | "@editorjs/header": "^2.6.1", 17 | "@editorjs/paragraph": "^2.8.0", 18 | "@editorjs/quote": "^2.4.0", 19 | "add": "^2.0.6", 20 | "babel-loader": "^8.2.2", 21 | "editorjs-header-with-anchor": "^2.6.0", 22 | "react": "^17.0.2", 23 | "react-dom": "^17.0.2", 24 | "react-editor-js": "^1.9.0", 25 | "webpack": "^5.35.1", 26 | "webpack-cli": "^4.6.0", 27 | "webpack-dev-server": "^3.11.2", 28 | "yarn": "^1.22.10" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: './src/index.js', 3 | mode: "production", 4 | // ES5(IE11等)向けの指定 5 | target: ["web", "es5"], 6 | module: { 7 | rules: [ 8 | { 9 | test: /\.js$/, 10 | exclude: /node_modules/, 11 | use: [ 12 | { 13 | loader: 'babel-loader', 14 | options: { 15 | presets: [ '@babel/preset-env' ], 16 | }, 17 | }, 18 | ] 19 | }, 20 | { 21 | test: /\.css$/, 22 | use: [ 23 | 'style-loader', 24 | 'css-loader' 25 | ] 26 | }, 27 | { 28 | test: /\.(svg)$/, 29 | use: [ 30 | { 31 | loader: 'raw-loader', 32 | } 33 | ] 34 | } 35 | ] 36 | }, 37 | output: { 38 | path: __dirname + '/dist', 39 | publicPath: '/', 40 | filename: 'bundle.js', 41 | library: 'AlignmentBlockTune', 42 | libraryTarget: 'umd' 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /example-react/src/js/constants.js: -------------------------------------------------------------------------------- 1 | // import Embed from "@editorjs/embed"; 2 | // import Table from "@editorjs/table"; 3 | // import List from "@editorjs/list"; 4 | // import Warning from "@editorjs/warning"; 5 | // import Code from "@editorjs/code"; 6 | // import LinkTool from "@editorjs/link"; 7 | // import Image from "@editorjs/image"; 8 | // import Raw from "@editorjs/raw"; 9 | import Header from "@editorjs/header"; 10 | import Quote from "@editorjs/quote"; 11 | // import Marker from "@editorjs/marker"; 12 | // import CheckList from "@editorjs/checklist"; 13 | // import Delimiter from "@editorjs/delimiter"; 14 | // import InlineCode from "@editorjs/inline-code"; 15 | // import SimpleImage from "@editorjs/simple-image"; 16 | import AlignmentTuneTool from "../../../dist/bundle"; 17 | import AnchorBlockTune from "../../../example/dist/anchor"; 18 | 19 | export const EDITOR_JS_TOOLS = { 20 | anyTuneName: { 21 | class: AlignmentTuneTool, 22 | config: { 23 | default: "right", 24 | blocks: { 25 | header: "center", 26 | list: "right" 27 | } 28 | } 29 | }, 30 | anchorTune: AnchorBlockTune, 31 | header: { 32 | class: Header, 33 | tunes: ["anyTuneName", "anchorTune"] 34 | }, 35 | quote: { 36 | class:Quote, 37 | tunes: ["anchorTune"] 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "editorjs-text-alignment-blocktune", 3 | "version": "1.0.2", 4 | "main": "./dist/bundle.js", 5 | "license": "MIT", 6 | "keywords": [ 7 | "codex editor", 8 | "paragraph", 9 | "alignment", 10 | "tool", 11 | "editor.js", 12 | "editorjs" 13 | ], 14 | "repository": { 15 | "type": "git", 16 | "url": "https://github.com/kaaaaaaaaaaai/editorjs-alignment-blocktune.git" 17 | }, 18 | "scripts": { 19 | "build": "webpack --mode production", 20 | "build:dev": "webpack --mode development --watch", 21 | "pull_tools": "git submodule update --init --recursive" 22 | }, 23 | "devDependencies": { 24 | "@babel/core": "^7.13.14", 25 | "@babel/preset-env": "^7.13.12", 26 | "babel-loader": "^8.2.2", 27 | "css-loader": "^5.2.0", 28 | "raw-loader": "^4.0.2", 29 | "style-loader": "^2.0.0", 30 | "webpack": "^5.30.0", 31 | "webpack-cli": "^4.6.0" 32 | }, 33 | "bugs": { 34 | "url": "https://github.com/kaaaaaaaaaaai/paragraph-with-alignment/issues" 35 | }, 36 | "homepage": "https://github.com/kaaaaaaaaaaai/paragraph-with-alignment#readme", 37 | "directories": { 38 | "example": "example" 39 | }, 40 | "dependencies": {}, 41 | "author": "kaaaaaaaaaaai ", 42 | "description": "text alignment block tune tool for Editor.js" 43 | } 44 | -------------------------------------------------------------------------------- /example/assets/json-preview.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Module to compose output JSON preview 3 | */ 4 | const cPreview = (function (module) { 5 | /** 6 | * Shows JSON in pretty preview 7 | * @param {object} output - what to show 8 | * @param {Element} holder - where to show 9 | */ 10 | module.show = function(output, holder) { 11 | /** Make JSON pretty */ 12 | output = JSON.stringify( output, null, 4 ); 13 | /** Encode HTML entities */ 14 | output = encodeHTMLEntities( output ); 15 | /** Stylize! */ 16 | output = stylize( output ); 17 | holder.innerHTML = output; 18 | }; 19 | 20 | /** 21 | * Converts '>', '<', '&' symbols to entities 22 | */ 23 | function encodeHTMLEntities(string) { 24 | return string.replace(/&/g, '&').replace(//g, '>'); 25 | } 26 | 27 | /** 28 | * Some styling magic 29 | */ 30 | function stylize(string) { 31 | /** Stylize JSON keys */ 32 | string = string.replace( /"(\w+)"\s?:/g, '"$1" :'); 33 | /** Stylize tool names */ 34 | string = string.replace( /"(paragraph|quote|list|header|link|code|image|delimiter|raw|checklist|table|embed|warning)"/g, '"$1"'); 35 | /** Stylize HTML tags */ 36 | string = string.replace( /(<[\/a-z]+(>)?)/gi, '$1' ); 37 | /** Stylize strings */ 38 | string = string.replace( /"([^"]+)"/gi, '"$1"' ); 39 | /** Boolean/Null */ 40 | string = string.replace( /\b(true|false|null)\b/gi, '$1' ); 41 | return string; 42 | } 43 | 44 | return module; 45 | })({}); 46 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ![](https://badgen.net/badge/Editor.js/v2.22.3/blue) 2 | 3 | # Text Alignment tune tool for Editor.js 4 | You can add text alignment to any block. 5 | 6 | ![image](https://user-images.githubusercontent.com/2194021/113727385-0c913780-9730-11eb-836e-c536b6c19f23.gif) 7 | 8 | If you can help, please push the Star button :) 9 | 10 | ### required 11 | - editor.js v2.22.3 ↑ 12 | 13 | ## Installation 14 | 15 | ### Install via NPM 16 | 17 | Get the package 18 | 19 | ```shell 20 | npm i --save editorjs-text-alignment-blocktune 21 | ``` 22 | 23 | Include module at your application 24 | 25 | ```javascript 26 | const AlignmentTuneTool = require('editorjs-text-alignment-blocktune'); 27 | ``` 28 | 29 | ### Download to your project's source dir 30 | 31 | 1. Upload folder `dist` from repository 32 | 2. Add `dist/bundle.js` file to your page. 33 | 34 | ### Load from CDN 35 | 36 | `https://cdn.jsdelivr.net/npm/editorjs-text-alignment-blocktune@latest` 37 | 38 | ## usage 39 | and look [editor.js document](https://editorjs.io/configuration#block-tunes-connection) 40 | ``` 41 | tool:{ 42 | list: { 43 | class: List, 44 | inlineToolbar: true, 45 | }, 46 | header: { 47 | class: Header, 48 | tunes: ['anyTuneName'], 49 | }, 50 | paragraph: { 51 | class: Paragraph, 52 | inlineToolbar: false, 53 | tunes: ['anyTuneName'], 54 | }, 55 | anyTuneName: { 56 | class:AlignmentTuneTool, 57 | config:{ 58 | default: "right", 59 | blocks: { 60 | header: 'center', 61 | list: 'right' 62 | } 63 | }, 64 | } 65 | } 66 | ``` 67 | 68 | ## Config Params 69 | 70 | 71 | | Field | Type | Description | 72 | | ----- | -------- | ------------------ | 73 | | default | `string` | "left"/"center"/"right", If not set, it will be "left".| 74 | | blocks | `object` | Default alignment can be set for each block | 75 | -------------------------------------------------------------------------------- /example/example.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | Editor.js 🤩🧦🤨 example 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 |
23 | Plugins 24 | Usage 25 | Configuration 26 | API 27 |
28 |
29 |
30 |
31 |
32 | No submodules found. Run yarn pull_tools 33 |
34 |
35 | editor.save() 36 |
37 |
38 |
39 |

40 | 
41 |       
44 |     
45 |
46 | 47 | 48 | 56 | 57 | 58 | 59 | 60 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /example/assets/demo.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Styles for the example page 3 | */ 4 | body { 5 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; 6 | font-size: 14px; 7 | line-height: 1.5em; 8 | margin: 0; 9 | } 10 | 11 | .ce-example { 12 | font-size: 16.2px; 13 | } 14 | 15 | .ce-example__header { 16 | border-bottom: 1px solid #E8E8EB; 17 | height: 50px; 18 | line-height: 50px; 19 | display: flex; 20 | padding: 0 30px; 21 | margin-bottom: 30px; 22 | flex-wrap: wrap; 23 | } 24 | 25 | .ce-example__header a { 26 | color: inherit; 27 | text-decoration: none; 28 | } 29 | 30 | .ce-example__header-logo { 31 | font-weight: bold; 32 | } 33 | 34 | .ce-example__header-menu { 35 | margin-left: auto; 36 | } 37 | 38 | @media all and (max-width: 730px){ 39 | .ce-example__header-menu { 40 | margin-left: 0; 41 | margin-top: 10px; 42 | flex-basis: 100%; 43 | font-size: 14px; 44 | } 45 | } 46 | 47 | .ce-example__header-menu a { 48 | margin-left: 20px; 49 | } 50 | 51 | @media all and (max-width: 730px){ 52 | .ce-example__header-menu a { 53 | margin-left: 0; 54 | margin-right: 15px; 55 | } 56 | } 57 | 58 | .ce-example__content { 59 | max-width: 1100px; 60 | margin: 0 auto; 61 | -webkit-font-smoothing: antialiased; 62 | -moz-osx-font-smoothing: grayscale; 63 | } 64 | 65 | .ce-example__content--small { 66 | max-width: 500px; 67 | border-left: 1px solid #eee; 68 | border-right: 1px solid #eee; 69 | padding: 0 15px; 70 | } 71 | 72 | .ce-example__output { 73 | background: #1B202B; 74 | overflow-x: auto; 75 | padding: 0 30px; 76 | } 77 | 78 | .ce-example__output-content { 79 | max-width: 650px; 80 | margin: 30px auto; 81 | color: #ABADC3; 82 | font-family: 'PT Mono', Menlo, Monaco, Consolas, Courier New, monospace; 83 | font-size: 13.3px; 84 | } 85 | 86 | .ce-example__output-content:empty { 87 | display: none; 88 | } 89 | 90 | .ce-example__button { 91 | display: block; 92 | margin: 50px auto; 93 | max-width: 180px; 94 | background: #4A9DF8; 95 | padding: 17px 30px; 96 | box-shadow: 0 22px 18px -4px rgba(137, 207, 255, 0.77); 97 | transition: all 150ms ease; 98 | cursor: pointer; 99 | border-radius: 31px; 100 | color: #fff; 101 | font-family: 'PT Mono', Menlo, Monaco, Consolas, Courier New, monospace; 102 | text-align: center; 103 | } 104 | 105 | .ce-example__button:hover { 106 | background: #3D8DE5; 107 | transform: translateY(2px); 108 | box-shadow: 0 20px 15px -4px rgba(137, 207, 255, 0.77); 109 | } 110 | 111 | .ce-example__output-footer { 112 | padding: 30px 0; 113 | font-size: 14.2px; 114 | letter-spacing: 0.3px; 115 | text-align: center; 116 | } 117 | 118 | .ce-example__output-footer a { 119 | color: #fff; 120 | text-decoration: none; 121 | } 122 | 123 | @media all and (max-width: 730px){ 124 | .ce-example__header, 125 | .ce-example__content{ 126 | padding: 0 20px; 127 | } 128 | } 129 | 130 | /** 131 | * JSON highlighter 132 | */ 133 | .sc_attr { 134 | color: rgb(148, 162, 192); 135 | } 136 | .sc_key { 137 | color: rgb(190, 213, 255); 138 | } 139 | .sc_toolname { 140 | color: rgb(15, 205, 251); 141 | } 142 | .sc_tag { 143 | color: rgb(4, 131, 216); 144 | } 145 | .sc_bool { 146 | color: rgb(247, 60, 173); 147 | } 148 | 149 | .ce-example .ce-block:first-of-type h2.ce-header{ 150 | font-size: 50px; 151 | } 152 | 153 | .ce-example h2.ce-header{ 154 | font-size: 30px; 155 | } 156 | 157 | .ce-example h3.ce-header { 158 | font-size: 24px; 159 | } 160 | 161 | .ce-example h4.ce-header { 162 | font-size: 18px; 163 | } 164 | -------------------------------------------------------------------------------- /example/example-vue.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | Editor.js 🤩🧦🤨 example 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | {{ message }} 21 |
22 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Build styles 3 | */ 4 | require('./index.css').toString(); 5 | const {make} = require('./util'); 6 | 7 | class AlignmentBlockTune { 8 | 9 | /** 10 | * Default alignment 11 | * 12 | * @public 13 | * @returns {string} 14 | */ 15 | static get DEFAULT_ALIGNMENT() { 16 | return 'left'; 17 | } 18 | 19 | static get isTune() { 20 | return true; 21 | } 22 | 23 | getAlignment(){ 24 | if(!!this.settings?.blocks && this.settings.blocks.hasOwnProperty(this.block.name)){ 25 | return this.settings.blocks[this.block.name] 26 | } 27 | if(!!this.settings?.default){ 28 | return this.settings.default 29 | } 30 | return AlignmentBlockTune.DEFAULT_ALIGNMENT 31 | } 32 | /** 33 | * 34 | * @param api 35 | * @param data 既に設定されているデータ 36 | * @param settings tuneに設定項目 37 | * @param block tuneに設定されてるblock 38 | */ 39 | constructor({ api, data, config, block}) { 40 | this.api = api; 41 | this.block = block; 42 | /** 43 | config:{ 44 | default: "right", 45 | blocks: { 46 | header: 'center', 47 | list: 'right' 48 | } 49 | }, 50 | */ 51 | this.settings = config; 52 | this.data = data || { alignment: this.getAlignment() } 53 | this.alignmentSettings = [ 54 | { 55 | name: 'left', 56 | icon: `` 57 | }, 58 | { 59 | name: 'center', 60 | icon: `` 61 | }, 62 | { 63 | name: 'right', 64 | icon: `` 65 | } 66 | ]; 67 | this._CSS = { 68 | alignment: { 69 | left: 'ce-tune-alignment--left', 70 | center: 'ce-tune-alignment--center', 71 | right: 'ce-tune-alignment--right', 72 | } 73 | } 74 | } 75 | 76 | /** 77 | * block自体をwrapしてくれる 78 | * constructorで与えられたalignmentを代入しようとすると、holderが確定してなく 79 | * renderでやろうとすると、tuneを表示時に処理が走る 80 | * @param blockContent 81 | */ 82 | wrap(blockContent) { 83 | this.wrapper = make("div"); 84 | this.wrapper.classList.toggle(this._CSS.alignment[this.data.alignment]) 85 | this.wrapper.append(blockContent) 86 | return this.wrapper 87 | } 88 | 89 | /** 90 | * rendering block tune 91 | * @returns {*} 92 | */ 93 | render() { 94 | const wrapper = make("div"); 95 | this.alignmentSettings.map(align => { 96 | const button = document.createElement('button'); 97 | button.classList.add(this.api.styles.settingsButton); 98 | button.innerHTML = align.icon; 99 | button.type = 'button'; 100 | 101 | button.classList.toggle(this.api.styles.settingsButtonActive, align.name === this.data.alignment); 102 | wrapper.appendChild(button); 103 | return button 104 | }).forEach((element, index, elements) => { 105 | element.addEventListener('click', () => { 106 | this.data = { 107 | alignment: this.alignmentSettings[index].name 108 | } 109 | elements.forEach((el, i) => { 110 | const {name} = this.alignmentSettings[i]; 111 | el.classList.toggle(this.api.styles.settingsButtonActive, name === this.data.alignment); 112 | //toggle alignment style class for block 113 | this.wrapper.classList.toggle(this._CSS.alignment[name], name === this.data.alignment) 114 | }); 115 | }); 116 | }); 117 | return wrapper; 118 | } 119 | /** 120 | * save 121 | * @returns {*} 122 | */ 123 | save() { 124 | return this.data; 125 | } 126 | } 127 | 128 | module.exports = AlignmentBlockTune; 129 | -------------------------------------------------------------------------------- /example/dist/anchor.js: -------------------------------------------------------------------------------- 1 | !function(e,n){"object"==typeof exports&&"object"==typeof module?module.exports=n():"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?exports.AnchorBlockTune=n():e.AnchorBlockTune=n()}(self,(function(){return(()=>{var e={966:(e,n,t)=>{function r(e,n){for(var t=0;t';var r=document.createElement("input");return r.placeholder=this.api.i18n.t("Anchor"),r.classList.add(this._CSS.classInput),r.value=this.getAnchor(),r.addEventListener("input",(function(n){var t=n.target.value.replace(/[^a-z0-9_-]/gi,"");t.length>0?e.data.anchor=t:e.data.anchor=void 0})),n.appendChild(t),n.appendChild(r),n}},{key:"save",value:function(){return this.data}}])&&r(n.prototype,t),a&&r(n,a),e}();e.exports=a},424:(e,n,t)=>{"use strict";t.d(n,{Z:()=>o});var r=t(645),a=t.n(r)()((function(e){return e[1]}));a.push([e.id,".cdx-anchor-tune-wrapper {\n display: flex;\n}\n\n.cdx-anchor-tune-icon {\n width: 12px;\n height: 22px;\n margin-left: 7px;\n}\n\n.cdx-anchor-tune-icon svg {\n vertical-align: inherit;\n}\n\n.cdx-anchor-tune-input {\n width: 80px;\n border: 0;\n box-sizing: border-box;\n margin-left: 7px;\n outline: none;\n}\n",""]);const o=a},645:e=>{"use strict";e.exports=function(e){var n=[];return n.toString=function(){return this.map((function(n){var t=e(n);return n[2]?"@media ".concat(n[2]," {").concat(t,"}"):t})).join("")},n.i=function(e,t,r){"string"==typeof e&&(e=[[null,e,""]]);var a={};if(r)for(var o=0;o{"use strict";var r=t(379),a=t.n(r),o=t(424);a()(o.Z,{insert:"head",singleton:!1}),o.Z.locals},379:(e,n,t)=>{"use strict";var r,a=function(){var e={};return function(n){if(void 0===e[n]){var t=document.querySelector(n);if(window.HTMLIFrameElement&&t instanceof window.HTMLIFrameElement)try{t=t.contentDocument.head}catch(e){t=null}e[n]=t}return e[n]}}(),o=[];function i(e){for(var n=-1,t=0;t{var n=e&&e.__esModule?()=>e.default:()=>e;return t.d(n,{a:n}),n},t.d=(e,n)=>{for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},t.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),t(966)})()})); -------------------------------------------------------------------------------- /dist/bundle.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.AlignmentBlockTune=e():t.AlignmentBlockTune=e()}(self,(function(){return function(){var t={966:function(t,e,n){function r(t,e){for(var n=0;n'},{name:"center",icon:''},{name:"right",icon:''}],this._CSS={alignment:{left:"ce-tune-alignment--left",center:"ce-tune-alignment--center",right:"ce-tune-alignment--right"}}}var e,n,a;return e=t,a=[{key:"DEFAULT_ALIGNMENT",get:function(){return"left"}},{key:"isTune",get:function(){return!0}}],(n=[{key:"getAlignment",value:function(){var e,n;return null!==(e=this.settings)&&void 0!==e&&e.blocks&&this.settings.blocks.hasOwnProperty(this.block.name)?this.settings.blocks[this.block.name]:null!==(n=this.settings)&&void 0!==n&&n.default?this.settings.default:t.DEFAULT_ALIGNMENT}},{key:"wrap",value:function(t){return this.wrapper=i("div"),this.wrapper.classList.toggle(this._CSS.alignment[this.data.alignment]),this.wrapper.append(t),this.wrapper}},{key:"render",value:function(){var t=this,e=i("div");return this.alignmentSettings.map((function(n){var r=document.createElement("button");return r.classList.add(t.api.styles.settingsButton),r.innerHTML=n.icon,r.type="button",r.classList.toggle(t.api.styles.settingsButtonActive,n.name===t.data.alignment),e.appendChild(r),r})).forEach((function(e,n,r){e.addEventListener("click",(function(){t.data={alignment:t.alignmentSettings[n].name},r.forEach((function(e,n){var r=t.alignmentSettings[n].name;e.classList.toggle(t.api.styles.settingsButtonActive,r===t.data.alignment),t.wrapper.classList.toggle(t._CSS.alignment[r],r===t.data.alignment)}))}))})),e}},{key:"save",value:function(){return this.data}}])&&r(e.prototype,n),a&&r(e,a),t}();t.exports=a},630:function(t,e,n){"use strict";function r(t){return function(t){if(Array.isArray(t))return i(t)}(t)||function(t){if("undefined"!=typeof Symbol&&Symbol.iterator in Object(t))return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return i(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?i(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n1&&void 0!==arguments[1]?arguments[1]:null,i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},a=document.createElement(t);for(var o in Array.isArray(n)?(e=a.classList).add.apply(e,r(n)):n&&a.classList.add(n),i)a[o]=i[o];return a}n.r(e),n.d(e,{make:function(){return a}})},424:function(t,e,n){"use strict";var r=n(645),i=n.n(r)()((function(t){return t[1]}));i.push([t.id,".ce-tune-alignment--right {\n text-align: right;\n}\n.ce-tune-alignment--center {\n text-align: center;\n}\n.ce-tune-alignment--left {\n text-align: left;\n}",""]),e.Z=i},645:function(t){"use strict";t.exports=function(t){var e=[];return e.toString=function(){return this.map((function(e){var n=t(e);return e[2]?"@media ".concat(e[2]," {").concat(n,"}"):n})).join("")},e.i=function(t,n,r){"string"==typeof t&&(t=[[null,t,""]]);var i={};if(r)for(var a=0;a 7 | 8 | 9 | 10 | 11 | Editor.js 🤩🧦🤨 example 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 21 | 22 |
23 | Plugins 24 | Usage 25 | Configuration 26 | API 27 |
28 |
29 |
30 |
31 |
32 | No submodules found. Run yarn pull_tools 33 |
34 |
35 | editor.save() 36 |
37 |
38 |
39 |

 40 | 
 41 |       
 44 |     
45 |
46 | 47 | 48 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 190 | 191 | 192 | -------------------------------------------------------------------------------- /dist/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development"). 3 | * This devtool is neither made for production nor for readable output files. 4 | * It uses "eval()" calls to create a separate source file in the browser devtools. 5 | * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) 6 | * or disable the default devtool with "devtool: false". 7 | * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). 8 | */ 9 | /******/ (function() { // webpackBootstrap 10 | /******/ var __webpack_modules__ = ({ 11 | 12 | /***/ "./src/index.js": 13 | /*!**********************!*\ 14 | !*** ./src/index.js ***! 15 | \**********************/ 16 | /***/ (function(module, __unused_webpack_exports, __webpack_require__) { 17 | 18 | eval("function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nfunction _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/**\n * Build styles\n */\n__webpack_require__(/*! ./index.css */ \"./src/index.css\").toString();\n\nvar _require = __webpack_require__(/*! ./util */ \"./src/util.js\"),\n make = _require.make;\n\nvar AlignmentBlockTune = /*#__PURE__*/function () {\n function AlignmentBlockTune(_ref) {\n var api = _ref.api,\n data = _ref.data,\n setting = _ref.setting,\n block = _ref.block;\n\n _classCallCheck(this, AlignmentBlockTune);\n\n console.log(\"constructor start\");\n console.log({\n api: api,\n data: data,\n setting: setting,\n block: block\n });\n console.log(\"constructor end\");\n this.api = api;\n }\n\n _createClass(AlignmentBlockTune, [{\n key: \"render\",\n value: function render() {\n // const button = document.createElement('button');\n // button.classList.add(this.api.styles.button);\n var button = make('button', this.api.styles.button);\n button.textContent = 'H';\n return button;\n }\n }, {\n key: \"save\",\n value: function save() {\n return {\n prop: 'value'\n };\n }\n }], [{\n key: \"isTune\",\n get: function get() {\n return true;\n }\n }]);\n\n return AlignmentBlockTune;\n}();\n\nmodule.exports = AlignmentBlockTune;\n\n//# sourceURL=webpack://alignment-blocktune/./src/index.js?"); 19 | 20 | /***/ }), 21 | 22 | /***/ "./src/util.js": 23 | /*!*********************!*\ 24 | !*** ./src/util.js ***! 25 | \*********************/ 26 | /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { 27 | 28 | "use strict"; 29 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"make\": function() { return /* binding */ make; }\n/* harmony export */ });\nfunction _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\"); }\n\nfunction _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === \"string\") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === \"Object\" && o.constructor) n = o.constructor.name; if (n === \"Map\" || n === \"Set\") return Array.from(o); if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }\n\nfunction _iterableToArray(iter) { if (typeof Symbol !== \"undefined\" && Symbol.iterator in Object(iter)) return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }\n\nfunction _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }\n\n/**\n * node 作成用\n * @param tagName\n * @param classNames\n * @param attributes\n * @returns {*}\n */\nfunction make(tagName) {\n var classNames = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;\n var attributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var el = document.createElement(tagName);\n\n if (Array.isArray(classNames)) {\n var _el$classList;\n\n (_el$classList = el.classList).add.apply(_el$classList, _toConsumableArray(classNames));\n } else if (classNames) {\n el.classList.add(classNames);\n }\n\n for (var attrName in attributes) {\n el[attrName] = attributes[attrName];\n }\n\n return el;\n}\n\n//# sourceURL=webpack://alignment-blocktune/./src/util.js?"); 30 | 31 | /***/ }), 32 | 33 | /***/ "./node_modules/css-loader/dist/cjs.js!./src/index.css": 34 | /*!*************************************************************!*\ 35 | !*** ./node_modules/css-loader/dist/cjs.js!./src/index.css ***! 36 | \*************************************************************/ 37 | /***/ (function(module, __webpack_exports__, __webpack_require__) { 38 | 39 | "use strict"; 40 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../node_modules/css-loader/dist/runtime/api.js */ \"./node_modules/css-loader/dist/runtime/api.js\");\n/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0__);\n// Imports\n\nvar ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_0___default()(function(i){return i[1]});\n// Module\n___CSS_LOADER_EXPORT___.push([module.id, \".ce-paragraph {\\n line-height: 1.6em;\\n outline: none;\\n}\\n.ce-paragraph--right {\\n text-align: right;\\n}\\n.ce-paragraph--center {\\n text-align: center;\\n}\\n.ce-paragraph--left {\\n text-align: left;\\n}\\n\\n.ce-paragraph[data-placeholder]:empty::before{\\n content: attr(data-placeholder);\\n color: #707684;\\n font-weight: normal;\\n opacity: 0;\\n}\\n\\n/** Show placeholder at the first paragraph if Editor is empty */\\n.codex-editor--empty .ce-block:first-child .ce-paragraph[data-placeholder]:empty::before {\\n opacity: 1;\\n}\\n\\n.codex-editor--toolbox-opened .ce-block:first-child .ce-paragraph[data-placeholder]:empty::before,\\n.codex-editor--empty .ce-block:first-child .ce-paragraph[data-placeholder]:empty:focus::before {\\n opacity: 0;\\n}\\n\\n.ce-paragraph p:first-of-type{\\n margin-top: 0;\\n}\\n\\n.ce-paragraph p:last-of-type{\\n margin-bottom: 0;\\n}\\n\\n\\n.svg-icon {\\n width: 1em;\\n height: 1em;\\n}\\n\\n.svg-icon path,\\n.svg-icon polygon,\\n.svg-icon rect {\\n fill: #4691f6;\\n}\\n\\n.svg-icon circle {\\n stroke: #4691f6;\\n stroke-width: 1;\\n}\", \"\"]);\n// Exports\n/* harmony default export */ __webpack_exports__[\"default\"] = (___CSS_LOADER_EXPORT___);\n\n\n//# sourceURL=webpack://alignment-blocktune/./src/index.css?./node_modules/css-loader/dist/cjs.js"); 41 | 42 | /***/ }), 43 | 44 | /***/ "./node_modules/css-loader/dist/runtime/api.js": 45 | /*!*****************************************************!*\ 46 | !*** ./node_modules/css-loader/dist/runtime/api.js ***! 47 | \*****************************************************/ 48 | /***/ (function(module) { 49 | 50 | "use strict"; 51 | eval("\n\n/*\n MIT License http://www.opensource.org/licenses/mit-license.php\n Author Tobias Koppers @sokra\n*/\n// css base code, injected by the css-loader\n// eslint-disable-next-line func-names\nmodule.exports = function (cssWithMappingToString) {\n var list = []; // return the list of modules as css string\n\n list.toString = function toString() {\n return this.map(function (item) {\n var content = cssWithMappingToString(item);\n\n if (item[2]) {\n return \"@media \".concat(item[2], \" {\").concat(content, \"}\");\n }\n\n return content;\n }).join(\"\");\n }; // import a list of modules into the list\n // eslint-disable-next-line func-names\n\n\n list.i = function (modules, mediaQuery, dedupe) {\n if (typeof modules === \"string\") {\n // eslint-disable-next-line no-param-reassign\n modules = [[null, modules, \"\"]];\n }\n\n var alreadyImportedModules = {};\n\n if (dedupe) {\n for (var i = 0; i < this.length; i++) {\n // eslint-disable-next-line prefer-destructuring\n var id = this[i][0];\n\n if (id != null) {\n alreadyImportedModules[id] = true;\n }\n }\n }\n\n for (var _i = 0; _i < modules.length; _i++) {\n var item = [].concat(modules[_i]);\n\n if (dedupe && alreadyImportedModules[item[0]]) {\n // eslint-disable-next-line no-continue\n continue;\n }\n\n if (mediaQuery) {\n if (!item[2]) {\n item[2] = mediaQuery;\n } else {\n item[2] = \"\".concat(mediaQuery, \" and \").concat(item[2]);\n }\n }\n\n list.push(item);\n }\n };\n\n return list;\n};\n\n//# sourceURL=webpack://alignment-blocktune/./node_modules/css-loader/dist/runtime/api.js?"); 52 | 53 | /***/ }), 54 | 55 | /***/ "./src/index.css": 56 | /*!***********************!*\ 57 | !*** ./src/index.css ***! 58 | \***********************/ 59 | /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { 60 | 61 | "use strict"; 62 | eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! !../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ \"./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js\");\n/* harmony import */ var _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0__);\n/* harmony import */ var _node_modules_css_loader_dist_cjs_js_index_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! !!../node_modules/css-loader/dist/cjs.js!./index.css */ \"./node_modules/css-loader/dist/cjs.js!./src/index.css\");\n\n \n\nvar options = {};\n\noptions.insert = \"head\";\noptions.singleton = false;\n\nvar update = _node_modules_style_loader_dist_runtime_injectStylesIntoStyleTag_js__WEBPACK_IMPORTED_MODULE_0___default()(_node_modules_css_loader_dist_cjs_js_index_css__WEBPACK_IMPORTED_MODULE_1__.default, options);\n\n\n\n/* harmony default export */ __webpack_exports__[\"default\"] = (_node_modules_css_loader_dist_cjs_js_index_css__WEBPACK_IMPORTED_MODULE_1__.default.locals || {});\n\n//# sourceURL=webpack://alignment-blocktune/./src/index.css?"); 63 | 64 | /***/ }), 65 | 66 | /***/ "./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js": 67 | /*!****************************************************************************!*\ 68 | !*** ./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js ***! 69 | \****************************************************************************/ 70 | /***/ (function(module, __unused_webpack_exports, __webpack_require__) { 71 | 72 | "use strict"; 73 | eval("\n\nvar isOldIE = function isOldIE() {\n var memo;\n return function memorize() {\n if (typeof memo === 'undefined') {\n // Test for IE <= 9 as proposed by Browserhacks\n // @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805\n // Tests for existence of standard globals is to allow style-loader\n // to operate correctly into non-standard environments\n // @see https://github.com/webpack-contrib/style-loader/issues/177\n memo = Boolean(window && document && document.all && !window.atob);\n }\n\n return memo;\n };\n}();\n\nvar getTarget = function getTarget() {\n var memo = {};\n return function memorize(target) {\n if (typeof memo[target] === 'undefined') {\n var styleTarget = document.querySelector(target); // Special case to return head of iframe instead of iframe itself\n\n if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {\n try {\n // This will throw an exception if access to iframe is blocked\n // due to cross-origin restrictions\n styleTarget = styleTarget.contentDocument.head;\n } catch (e) {\n // istanbul ignore next\n styleTarget = null;\n }\n }\n\n memo[target] = styleTarget;\n }\n\n return memo[target];\n };\n}();\n\nvar stylesInDom = [];\n\nfunction getIndexByIdentifier(identifier) {\n var result = -1;\n\n for (var i = 0; i < stylesInDom.length; i++) {\n if (stylesInDom[i].identifier === identifier) {\n result = i;\n break;\n }\n }\n\n return result;\n}\n\nfunction modulesToDom(list, options) {\n var idCountMap = {};\n var identifiers = [];\n\n for (var i = 0; i < list.length; i++) {\n var item = list[i];\n var id = options.base ? item[0] + options.base : item[0];\n var count = idCountMap[id] || 0;\n var identifier = \"\".concat(id, \" \").concat(count);\n idCountMap[id] = count + 1;\n var index = getIndexByIdentifier(identifier);\n var obj = {\n css: item[1],\n media: item[2],\n sourceMap: item[3]\n };\n\n if (index !== -1) {\n stylesInDom[index].references++;\n stylesInDom[index].updater(obj);\n } else {\n stylesInDom.push({\n identifier: identifier,\n updater: addStyle(obj, options),\n references: 1\n });\n }\n\n identifiers.push(identifier);\n }\n\n return identifiers;\n}\n\nfunction insertStyleElement(options) {\n var style = document.createElement('style');\n var attributes = options.attributes || {};\n\n if (typeof attributes.nonce === 'undefined') {\n var nonce = true ? __webpack_require__.nc : 0;\n\n if (nonce) {\n attributes.nonce = nonce;\n }\n }\n\n Object.keys(attributes).forEach(function (key) {\n style.setAttribute(key, attributes[key]);\n });\n\n if (typeof options.insert === 'function') {\n options.insert(style);\n } else {\n var target = getTarget(options.insert || 'head');\n\n if (!target) {\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");\n }\n\n target.appendChild(style);\n }\n\n return style;\n}\n\nfunction removeStyleElement(style) {\n // istanbul ignore if\n if (style.parentNode === null) {\n return false;\n }\n\n style.parentNode.removeChild(style);\n}\n/* istanbul ignore next */\n\n\nvar replaceText = function replaceText() {\n var textStore = [];\n return function replace(index, replacement) {\n textStore[index] = replacement;\n return textStore.filter(Boolean).join('\\n');\n };\n}();\n\nfunction applyToSingletonTag(style, index, remove, obj) {\n var css = remove ? '' : obj.media ? \"@media \".concat(obj.media, \" {\").concat(obj.css, \"}\") : obj.css; // For old IE\n\n /* istanbul ignore if */\n\n if (style.styleSheet) {\n style.styleSheet.cssText = replaceText(index, css);\n } else {\n var cssNode = document.createTextNode(css);\n var childNodes = style.childNodes;\n\n if (childNodes[index]) {\n style.removeChild(childNodes[index]);\n }\n\n if (childNodes.length) {\n style.insertBefore(cssNode, childNodes[index]);\n } else {\n style.appendChild(cssNode);\n }\n }\n}\n\nfunction applyToTag(style, options, obj) {\n var css = obj.css;\n var media = obj.media;\n var sourceMap = obj.sourceMap;\n\n if (media) {\n style.setAttribute('media', media);\n } else {\n style.removeAttribute('media');\n }\n\n if (sourceMap && typeof btoa !== 'undefined') {\n css += \"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))), \" */\");\n } // For old IE\n\n /* istanbul ignore if */\n\n\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n while (style.firstChild) {\n style.removeChild(style.firstChild);\n }\n\n style.appendChild(document.createTextNode(css));\n }\n}\n\nvar singleton = null;\nvar singletonCounter = 0;\n\nfunction addStyle(obj, options) {\n var style;\n var update;\n var remove;\n\n if (options.singleton) {\n var styleIndex = singletonCounter++;\n style = singleton || (singleton = insertStyleElement(options));\n update = applyToSingletonTag.bind(null, style, styleIndex, false);\n remove = applyToSingletonTag.bind(null, style, styleIndex, true);\n } else {\n style = insertStyleElement(options);\n update = applyToTag.bind(null, style, options);\n\n remove = function remove() {\n removeStyleElement(style);\n };\n }\n\n update(obj);\n return function updateStyle(newObj) {\n if (newObj) {\n if (newObj.css === obj.css && newObj.media === obj.media && newObj.sourceMap === obj.sourceMap) {\n return;\n }\n\n update(obj = newObj);\n } else {\n remove();\n }\n };\n}\n\nmodule.exports = function (list, options) {\n options = options || {}; // Force single-tag solution on IE6-9, which has a hard limit on the # of