sunny-html-editor 1.0.3 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +47 -104
- package/html-editor.js +168 -31
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,90 +4,64 @@
|
|
|
4
4
|
|
|
5
5
|
## 特徴
|
|
6
6
|
|
|
7
|
-
- **自己完結型** -
|
|
7
|
+
- **自己完結型** - ツールバー・コンテキストメニューを自動生成
|
|
8
|
+
- **遅延読み込み** - Excel/PDF出力用ライブラリは使用時に自動読み込み
|
|
8
9
|
- **WYSIWYG編集** - 見たまま編集、右クリックで要素追加
|
|
9
10
|
- **キーボード操作** - ↑↓で要素間移動、Shift/Ctrl+Enterで項目追加
|
|
10
11
|
- **多彩なエクスポート** - Markdown、HTML、Excel、PDF
|
|
11
12
|
- **サイドバーナビ** - 目次自動生成
|
|
12
13
|
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
### 必須
|
|
16
|
-
|
|
17
|
-
なし(基本機能のみ使用する場合)
|
|
18
|
-
|
|
19
|
-
### オプション(Excel/PDF出力に必要)
|
|
20
|
-
|
|
21
|
-
| ライブラリ | バージョン | 用途 | CDN |
|
|
22
|
-
|-----------|----------|------|-----|
|
|
23
|
-
| ExcelJS | 4.3.0+ | Excel出力 | https://cdnjs.cloudflare.com/ajax/libs/exceljs/4.3.0/exceljs.min.js |
|
|
24
|
-
| jsPDF | 2.5.1+ | PDF出力 | https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js |
|
|
25
|
-
| html2canvas | 1.4.1+ | PDF出力(HTML→Canvas変換) | https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js |
|
|
14
|
+
## インストール
|
|
26
15
|
|
|
27
|
-
|
|
16
|
+
### CDN(推奨)
|
|
28
17
|
|
|
29
18
|
```html
|
|
30
|
-
|
|
31
|
-
<script src="https://
|
|
32
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
|
|
33
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
|
|
34
|
-
|
|
35
|
-
<!-- HTML Editor -->
|
|
36
|
-
<link rel="stylesheet" href="html-editor.css">
|
|
37
|
-
<script src="html-editor.js"></script>
|
|
19
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sunny-html-editor/html-editor.css">
|
|
20
|
+
<script src="https://cdn.jsdelivr.net/npm/sunny-html-editor/html-editor.js"></script>
|
|
38
21
|
```
|
|
39
22
|
|
|
40
|
-
## インストール
|
|
41
|
-
|
|
42
23
|
### npm
|
|
43
24
|
|
|
44
25
|
```bash
|
|
45
26
|
npm install sunny-html-editor
|
|
46
27
|
```
|
|
47
28
|
|
|
48
|
-
### CDN
|
|
49
|
-
|
|
50
|
-
```html
|
|
51
|
-
<link rel="stylesheet" href="https://unpkg.com/sunny-html-editor/html-editor.css">
|
|
52
|
-
<script src="https://unpkg.com/sunny-html-editor/html-editor.js"></script>
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### ダウンロード
|
|
56
|
-
|
|
57
|
-
`html-editor.css` と `html-editor.js` をダウンロードして読み込み。
|
|
58
|
-
|
|
59
29
|
## 使い方
|
|
60
30
|
|
|
61
|
-
|
|
31
|
+
`id="editorContainer"` を持つコンテナを用意するだけ。ツールバーとコンテキストメニューは自動生成されます。
|
|
62
32
|
|
|
63
33
|
```html
|
|
64
34
|
<!DOCTYPE html>
|
|
65
|
-
<html>
|
|
35
|
+
<html lang="ja">
|
|
66
36
|
<head>
|
|
67
|
-
|
|
37
|
+
<meta charset="UTF-8">
|
|
38
|
+
<title>ドキュメントタイトル</title>
|
|
39
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sunny-html-editor/html-editor.css">
|
|
68
40
|
</head>
|
|
69
41
|
<body>
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
42
|
+
<div class="layout">
|
|
43
|
+
<main class="main">
|
|
44
|
+
<div class="container" id="editorContainer">
|
|
45
|
+
<h1>タイトル</h1>
|
|
46
|
+
<h2 id="section1">見出し</h2>
|
|
47
|
+
<p>本文...</p>
|
|
48
|
+
</div>
|
|
49
|
+
</main>
|
|
50
|
+
</div>
|
|
51
|
+
<script src="https://cdn.jsdelivr.net/npm/sunny-html-editor/html-editor.js"></script>
|
|
79
52
|
</body>
|
|
80
53
|
</html>
|
|
81
54
|
```
|
|
82
55
|
|
|
83
|
-
|
|
56
|
+
## 外部ライブラリ
|
|
84
57
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
58
|
+
Excel/PDF出力に必要なライブラリは**使用時に自動で読み込まれます**。事前の読み込みは不要です。
|
|
59
|
+
|
|
60
|
+
| ライブラリ | 用途 |
|
|
61
|
+
|-----------|------|
|
|
62
|
+
| ExcelJS | Excel出力 |
|
|
63
|
+
| jsPDF | PDF出力 |
|
|
64
|
+
| html2canvas | PDF出力(HTML→Canvas変換) |
|
|
91
65
|
|
|
92
66
|
## キーボードショートカット
|
|
93
67
|
|
|
@@ -113,64 +87,33 @@ HtmlEditor.init('#content', {
|
|
|
113
87
|
|
|
114
88
|
テーブル上では行/列の追加・削除も可能。
|
|
115
89
|
|
|
116
|
-
##
|
|
90
|
+
## ツールバーボタン
|
|
117
91
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
92
|
+
| ボタン | 機能 |
|
|
93
|
+
|--------|------|
|
|
94
|
+
| ↔️ | サイドバー表示/非表示 |
|
|
95
|
+
| 📝 | 編集モード切替 |
|
|
96
|
+
| Ⓜ️ | Markdownコピー |
|
|
97
|
+
| 🌐 | HTMLコピー |
|
|
98
|
+
| 💾 | HTML保存(ダウンロード) |
|
|
99
|
+
| 📊 | Excel出力 |
|
|
100
|
+
| 📕 | PDF出力 |
|
|
124
101
|
|
|
125
|
-
|
|
102
|
+
## バージョン履歴
|
|
126
103
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
### HTML保存
|
|
133
|
-
|
|
134
|
-
```javascript
|
|
135
|
-
// ツールバーの💾ボタン
|
|
136
|
-
// HTMLファイルとしてダウンロード
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### Excel / PDF
|
|
140
|
-
|
|
141
|
-
上記の外部ライブラリが読み込まれている必要があります。
|
|
142
|
-
読み込まれていない場合、ボタンを押すとアラートが表示されます。
|
|
143
|
-
|
|
144
|
-
## API
|
|
145
|
-
|
|
146
|
-
### HtmlEditor.init(selector, options)
|
|
147
|
-
|
|
148
|
-
エディタを初期化します。
|
|
149
|
-
|
|
150
|
-
- `selector` - コンテナ要素のセレクタまたはDOM要素
|
|
151
|
-
- `options` - オプションオブジェクト
|
|
152
|
-
|
|
153
|
-
### 返り値
|
|
154
|
-
|
|
155
|
-
HtmlEditorインスタンスを返します。
|
|
156
|
-
|
|
157
|
-
```javascript
|
|
158
|
-
var editor = HtmlEditor.init('#content');
|
|
159
|
-
|
|
160
|
-
// 編集モード切替
|
|
161
|
-
editor._action_editMode();
|
|
162
|
-
|
|
163
|
-
// サイドバー更新
|
|
164
|
-
editor._updateSidebar();
|
|
165
|
-
```
|
|
104
|
+
- **1.1.0** - ツールバー・コンテキストメニュー自動生成、外部ライブラリ遅延読み込み
|
|
105
|
+
- **1.0.3** - nullチェック強化
|
|
106
|
+
- **1.0.2** - DOMContentLoaded自動初期化
|
|
107
|
+
- **1.0.1** - メディアクエリ削除
|
|
108
|
+
- **1.0.0** - 初回リリース
|
|
166
109
|
|
|
167
110
|
## ブラウザ対応
|
|
168
111
|
|
|
169
|
-
- Chrome
|
|
112
|
+
- Chrome(推奨)
|
|
170
113
|
- Firefox
|
|
171
114
|
- Safari
|
|
172
115
|
- Edge
|
|
173
116
|
|
|
174
117
|
## ライセンス
|
|
175
118
|
|
|
176
|
-
MIT
|
|
119
|
+
MIT License - OnMax Group
|
package/html-editor.js
CHANGED
|
@@ -1,11 +1,142 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Sunny HTML Editor - 軽量WYSIWYGエディタ
|
|
3
|
-
* @version 1.0
|
|
3
|
+
* @version 1.1.0
|
|
4
4
|
*/
|
|
5
|
+
|
|
6
|
+
// ========== HTML生成関数 ==========
|
|
7
|
+
function getToolbarHtml() {
|
|
8
|
+
return '<div class="toolbar">' +
|
|
9
|
+
'<button id="toggleSidebar" title="サイドメニュー表示/非表示 (Ctrl+B)">↔️</button>' +
|
|
10
|
+
'<button id="editMode" title="編集モード (Ctrl+E)">📝</button>' +
|
|
11
|
+
'<button id="exportMd" title="Markdownコピー (Ctrl+M)">Ⓜ️</button>' +
|
|
12
|
+
'<button id="exportHtml" title="HTMLコピー">🌐</button>' +
|
|
13
|
+
'<button id="saveHtml" title="HTML保存">💾</button>' +
|
|
14
|
+
'<button id="exportExcel" title="Excel出力">📊</button>' +
|
|
15
|
+
'<button id="exportPdf" title="PDF出力">📕</button>' +
|
|
16
|
+
'</div>';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getContextMenusHtml() {
|
|
20
|
+
// テーブル用
|
|
21
|
+
var tableMenu = '<div class="context-menu" id="contextMenu">' +
|
|
22
|
+
'<div class="context-menu-item" data-action="addRowBelow">+ 行を追加</div>' +
|
|
23
|
+
'<div class="context-menu-item" data-action="addColRight">+ 列を追加</div>' +
|
|
24
|
+
'<div class="context-menu-divider"></div>' +
|
|
25
|
+
'<div class="context-menu-item delete" data-action="deleteRow">🗑 行を削除</div>' +
|
|
26
|
+
'<div class="context-menu-item delete" data-action="deleteCol">🗑 列を削除</div>' +
|
|
27
|
+
'<div class="context-menu-item delete" data-action="deleteTable">🗑 テーブルを削除</div>' +
|
|
28
|
+
'<div class="context-menu-divider thick"></div>' +
|
|
29
|
+
'<div class="context-menu-item" data-action="addH2">+ 大見出し</div>' +
|
|
30
|
+
'<div class="context-menu-item" data-action="addH3">+ 中見出し</div>' +
|
|
31
|
+
'<div class="context-menu-item" data-action="addH4">+ 小見出し</div>' +
|
|
32
|
+
'<div class="context-menu-divider"></div>' +
|
|
33
|
+
'<div class="context-menu-item" data-action="addTableBelow">+ テーブル</div>' +
|
|
34
|
+
'<div class="context-menu-divider"></div>' +
|
|
35
|
+
'<div class="context-menu-item" data-action="addParagraph">+ 本文</div>' +
|
|
36
|
+
'<div class="context-menu-divider"></div>' +
|
|
37
|
+
'<div class="context-menu-item" data-action="addUl">+ 箇条書き</div>' +
|
|
38
|
+
'<div class="context-menu-item" data-action="addOl">+ 番号リスト</div>' +
|
|
39
|
+
'<div class="context-menu-divider"></div>' +
|
|
40
|
+
'<div class="context-menu-item" data-action="addPre">+ コードブロック</div>' +
|
|
41
|
+
'<div class="context-menu-item" data-action="addBlockquote">+ 引用</div>' +
|
|
42
|
+
'</div>';
|
|
43
|
+
|
|
44
|
+
// 共通メニュー項目
|
|
45
|
+
var commonItems =
|
|
46
|
+
'<div class="context-menu-item" data-action="addH2">+ 大見出し</div>' +
|
|
47
|
+
'<div class="context-menu-item" data-action="addH3">+ 中見出し</div>' +
|
|
48
|
+
'<div class="context-menu-item" data-action="addH4">+ 小見出し</div>' +
|
|
49
|
+
'<div class="context-menu-divider"></div>' +
|
|
50
|
+
'<div class="context-menu-item" data-action="addTable">+ テーブル</div>' +
|
|
51
|
+
'<div class="context-menu-divider"></div>' +
|
|
52
|
+
'<div class="context-menu-item" data-action="addParagraph">+ 本文</div>' +
|
|
53
|
+
'<div class="context-menu-divider"></div>' +
|
|
54
|
+
'<div class="context-menu-item" data-action="addUl">+ 箇条書き</div>' +
|
|
55
|
+
'<div class="context-menu-item" data-action="addOl">+ 番号リスト</div>' +
|
|
56
|
+
'<div class="context-menu-divider"></div>' +
|
|
57
|
+
'<div class="context-menu-item" data-action="addPre">+ コードブロック</div>' +
|
|
58
|
+
'<div class="context-menu-item" data-action="addBlockquote">+ 引用</div>';
|
|
59
|
+
|
|
60
|
+
// h1用
|
|
61
|
+
var h1Menu = '<div class="context-menu" id="h1ContextMenu">' + commonItems + '</div>';
|
|
62
|
+
|
|
63
|
+
// 見出し用
|
|
64
|
+
var headingMenu = '<div class="context-menu" id="headingContextMenu">' + commonItems +
|
|
65
|
+
'<div class="context-menu-divider"></div>' +
|
|
66
|
+
'<div class="context-menu-item delete" data-action="deleteSection">🗑 セクションを削除</div>' +
|
|
67
|
+
'</div>';
|
|
68
|
+
|
|
69
|
+
// 段落用
|
|
70
|
+
var paragraphMenu = '<div class="context-menu" id="paragraphContextMenu">' + commonItems +
|
|
71
|
+
'<div class="context-menu-divider"></div>' +
|
|
72
|
+
'<div class="context-menu-item delete" data-action="deleteParagraph">🗑 本文を削除</div>' +
|
|
73
|
+
'</div>';
|
|
74
|
+
|
|
75
|
+
// リスト用
|
|
76
|
+
var listMenu = '<div class="context-menu" id="listContextMenu">' + commonItems +
|
|
77
|
+
'<div class="context-menu-divider"></div>' +
|
|
78
|
+
'<div class="context-menu-item delete" data-action="deleteList">🗑 リストを削除</div>' +
|
|
79
|
+
'</div>';
|
|
80
|
+
|
|
81
|
+
// コードブロック用
|
|
82
|
+
var preMenu = '<div class="context-menu" id="preContextMenu">' + commonItems +
|
|
83
|
+
'<div class="context-menu-divider"></div>' +
|
|
84
|
+
'<div class="context-menu-item delete" data-action="deletePre">🗑 コードブロックを削除</div>' +
|
|
85
|
+
'</div>';
|
|
86
|
+
|
|
87
|
+
// 引用用
|
|
88
|
+
var blockquoteMenu = '<div class="context-menu" id="blockquoteContextMenu">' + commonItems +
|
|
89
|
+
'<div class="context-menu-divider"></div>' +
|
|
90
|
+
'<div class="context-menu-item delete" data-action="deleteBlockquote">🗑 引用を削除</div>' +
|
|
91
|
+
'</div>';
|
|
92
|
+
|
|
93
|
+
return tableMenu + h1Menu + headingMenu + paragraphMenu + listMenu + preMenu + blockquoteMenu;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ========== 外部ライブラリ遅延読み込み ==========
|
|
97
|
+
var libraryPromises = {};
|
|
98
|
+
|
|
99
|
+
function loadScript(src) {
|
|
100
|
+
if (libraryPromises[src]) return libraryPromises[src];
|
|
101
|
+
|
|
102
|
+
libraryPromises[src] = new Promise(function(resolve, reject) {
|
|
103
|
+
var script = document.createElement('script');
|
|
104
|
+
script.src = src;
|
|
105
|
+
script.onload = resolve;
|
|
106
|
+
script.onerror = reject;
|
|
107
|
+
document.head.appendChild(script);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
return libraryPromises[src];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function ensurePdfLibraries() {
|
|
114
|
+
if (!window.jspdf) {
|
|
115
|
+
await loadScript('https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js');
|
|
116
|
+
}
|
|
117
|
+
if (!window.html2canvas) {
|
|
118
|
+
await loadScript('https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js');
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function ensureExcelLibrary() {
|
|
123
|
+
if (!window.ExcelJS) {
|
|
124
|
+
await loadScript('https://cdnjs.cloudflare.com/ajax/libs/exceljs/4.3.0/exceljs.min.js');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ========== 初期化 ==========
|
|
5
129
|
document.addEventListener('DOMContentLoaded', function() {
|
|
6
130
|
var container = document.getElementById('editorContainer');
|
|
7
|
-
if (!container) return;
|
|
131
|
+
if (!container) return;
|
|
132
|
+
|
|
133
|
+
// ツールバー挿入
|
|
134
|
+
container.insertAdjacentHTML('afterbegin', getToolbarHtml());
|
|
8
135
|
|
|
136
|
+
// コンテキストメニュー挿入(bodyの末尾に配置)
|
|
137
|
+
document.body.insertAdjacentHTML('beforeend', getContextMenusHtml());
|
|
138
|
+
|
|
139
|
+
// ボタン参照取得
|
|
9
140
|
var editModeBtn = document.getElementById('editMode');
|
|
10
141
|
var toggleSidebarBtn = document.getElementById('toggleSidebar');
|
|
11
142
|
var saveHtmlBtn = document.getElementById('saveHtml');
|
|
@@ -47,7 +178,25 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
47
178
|
var wasEditMode = isEditMode;
|
|
48
179
|
if (isEditMode && editModeBtn) editModeBtn.click();
|
|
49
180
|
|
|
50
|
-
|
|
181
|
+
// ツールバーとコンテキストメニューを一時的に非表示
|
|
182
|
+
var toolbar = container.querySelector('.toolbar');
|
|
183
|
+
var contextMenus = document.querySelectorAll('.context-menu');
|
|
184
|
+
|
|
185
|
+
if (toolbar) toolbar.style.display = 'none';
|
|
186
|
+
contextMenus.forEach(function(menu) { menu.style.display = 'none'; });
|
|
187
|
+
|
|
188
|
+
// HTML取得(ツールバーとコンテキストメニューを除外したクリーンなHTML)
|
|
189
|
+
var docClone = document.documentElement.cloneNode(true);
|
|
190
|
+
var cloneToolbar = docClone.querySelector('.toolbar');
|
|
191
|
+
var cloneMenus = docClone.querySelectorAll('.context-menu');
|
|
192
|
+
if (cloneToolbar) cloneToolbar.remove();
|
|
193
|
+
cloneMenus.forEach(function(menu) { menu.remove(); });
|
|
194
|
+
|
|
195
|
+
var html = '<!DOCTYPE html>\n' + docClone.outerHTML;
|
|
196
|
+
|
|
197
|
+
// 表示を復元
|
|
198
|
+
if (toolbar) toolbar.style.display = '';
|
|
199
|
+
contextMenus.forEach(function(menu) { menu.style.display = ''; });
|
|
51
200
|
|
|
52
201
|
if (wasEditMode && editModeBtn) editModeBtn.click();
|
|
53
202
|
|
|
@@ -104,7 +253,7 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
104
253
|
var toolbar = content.querySelector('.toolbar');
|
|
105
254
|
if (toolbar) toolbar.remove();
|
|
106
255
|
|
|
107
|
-
//
|
|
256
|
+
// 右クリックメニューを除去(念のため)
|
|
108
257
|
content.querySelectorAll('.context-menu').forEach(function(menu) {
|
|
109
258
|
menu.remove();
|
|
110
259
|
});
|
|
@@ -130,41 +279,23 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
130
279
|
var h1 = container.querySelector('h1');
|
|
131
280
|
var title = h1 ? h1.textContent.trim() : 'Document';
|
|
132
281
|
|
|
133
|
-
// CSS
|
|
134
|
-
var styleEl = document.querySelector('style');
|
|
135
|
-
var css = '';
|
|
136
|
-
if (styleEl) {
|
|
137
|
-
css = styleEl.textContent
|
|
138
|
-
.replace(/\.sidebar[\s\S]*?\}\n/g, '')
|
|
139
|
-
.replace(/\.sidebar [^{]*\{[\s\S]*?\}\n/g, '')
|
|
140
|
-
.replace(/\.resizer[\s\S]*?\}\n/g, '')
|
|
141
|
-
.replace(/\.toolbar[\s\S]*?\}\n/g, '')
|
|
142
|
-
.replace(/\.toolbar [^{]*\{[\s\S]*?\}\n/g, '')
|
|
143
|
-
.replace(/\.context-menu[\s\S]*?\}\n/g, '')
|
|
144
|
-
.replace(/\.context-menu[^{]*\{[\s\S]*?\}\n/g, '')
|
|
145
|
-
.replace(/\.edit-mode[\s\S]*?\}\n/g, '')
|
|
146
|
-
.replace(/\.edit-mode [^{]*\{[\s\S]*?\}\n/g, '')
|
|
147
|
-
.replace(/@media[^{]*\{[\s\S]*?\}\s*\}/g, '')
|
|
148
|
-
.replace(/\n\s*\n/g, '\n')
|
|
149
|
-
.trim();
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// 完全なHTML構造(CSS含む、ラッパー構造含む)
|
|
282
|
+
// 完全なHTML構造(外部CSS/JS参照付き)
|
|
153
283
|
var html = '<!DOCTYPE html>\n' +
|
|
154
284
|
'<html lang="ja">\n' +
|
|
155
285
|
'<head>\n' +
|
|
156
|
-
'
|
|
157
|
-
'
|
|
158
|
-
'<
|
|
286
|
+
'<meta charset="UTF-8">\n' +
|
|
287
|
+
'<title>' + title + '</title>\n' +
|
|
288
|
+
'<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/sunny-html-editor/html-editor.css">\n' +
|
|
159
289
|
'</head>\n' +
|
|
160
290
|
'<body>\n' +
|
|
161
291
|
'<div class="layout">\n' +
|
|
162
|
-
'
|
|
163
|
-
'
|
|
292
|
+
'<main class="main">\n' +
|
|
293
|
+
'<div class="container" id="editorContainer">\n' +
|
|
164
294
|
innerHtml + '\n' +
|
|
165
|
-
' </div>\n' +
|
|
166
|
-
' </main>\n' +
|
|
167
295
|
'</div>\n' +
|
|
296
|
+
'</main>\n' +
|
|
297
|
+
'</div>\n' +
|
|
298
|
+
'<script src="https://cdn.jsdelivr.net/npm/sunny-html-editor/html-editor.js"><\/script>\n' +
|
|
168
299
|
'</body>\n' +
|
|
169
300
|
'</html>';
|
|
170
301
|
|
|
@@ -1371,6 +1502,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
1371
1502
|
exportPdfBtn.textContent = '...';
|
|
1372
1503
|
|
|
1373
1504
|
try {
|
|
1505
|
+
// ライブラリ遅延読み込み
|
|
1506
|
+
await ensurePdfLibraries();
|
|
1507
|
+
|
|
1374
1508
|
// jsPDFインスタンス作成
|
|
1375
1509
|
var { jsPDF } = window.jspdf;
|
|
1376
1510
|
var pdf = new jsPDF({
|
|
@@ -1573,6 +1707,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|
|
1573
1707
|
});
|
|
1574
1708
|
|
|
1575
1709
|
async function convertToExcel() {
|
|
1710
|
+
// ライブラリ遅延読み込み
|
|
1711
|
+
await ensureExcelLibrary();
|
|
1712
|
+
|
|
1576
1713
|
var content = container.querySelector('.content');
|
|
1577
1714
|
if (!content) content = container;
|
|
1578
1715
|
|