vue2-bbl-editor 1.3.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/CHANGELOG.md +659 -0
- package/COMPONENT_USAGE_GUIDE.md +2590 -0
- package/CONTENT_WRAPPER_GUIDE.md +385 -0
- package/EXTERNAL_HTML_RENDERING.md +266 -0
- package/EXTERNAL_INTEGRATION_GUIDE.md +833 -0
- package/INSTALLATION.md +282 -0
- package/LICENSE +21 -0
- package/PACKAGE_DOCUMENTATION.md +1386 -0
- package/QUICK_SETUP.md +99 -0
- package/README.md +1694 -0
- package/dist/demo.html +10 -0
- package/dist/vue2-bbl-editor.common.js +24486 -0
- package/dist/vue2-bbl-editor.common.js.map +1 -0
- package/dist/vue2-bbl-editor.css +1 -0
- package/dist/vue2-bbl-editor.umd.js +24497 -0
- package/dist/vue2-bbl-editor.umd.js.map +1 -0
- package/dist/vue2-bbl-editor.umd.min.js +6 -0
- package/dist/vue2-bbl-editor.umd.min.js.map +1 -0
- package/package.json +172 -0
- package/types/index.d.ts +266 -0
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
# Content Wrapper Guide
|
|
2
|
+
|
|
3
|
+
This guide explains how to use the `bbl-html-section` wrapper functionality in both Options API and Composition API components.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The vue2-premium-bbl-editor automatically wraps HTML output with the `bbl-html-section` class to ensure proper styling when using the CDN CSS. This makes it easy to render editor content in external projects with consistent styling.
|
|
8
|
+
|
|
9
|
+
## Automatic Wrapping
|
|
10
|
+
|
|
11
|
+
By default, HTML output is automatically wrapped with the `bbl-html-section` class:
|
|
12
|
+
|
|
13
|
+
```javascript
|
|
14
|
+
// Default behavior - content is wrapped
|
|
15
|
+
const content = editor.getContent()
|
|
16
|
+
// Returns: <div class="bbl-html-section"><p>Your content here</p></div>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Options API Usage
|
|
20
|
+
|
|
21
|
+
### Basic Usage
|
|
22
|
+
|
|
23
|
+
```vue
|
|
24
|
+
<template>
|
|
25
|
+
<div>
|
|
26
|
+
<PremiumBblEditorOptionsAPI
|
|
27
|
+
v-model="content"
|
|
28
|
+
ref="editor"
|
|
29
|
+
/>
|
|
30
|
+
|
|
31
|
+
<div class="output-section">
|
|
32
|
+
<h3>Wrapped Output (Default)</h3>
|
|
33
|
+
<div v-html="wrappedContent"></div>
|
|
34
|
+
|
|
35
|
+
<h3>Unwrapped Output</h3>
|
|
36
|
+
<div class="bbl-html-section" v-html="unwrappedContent"></div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<script>
|
|
42
|
+
import { PremiumBblEditorOptionsAPI } from 'vue2-premium-bbl-editor'
|
|
43
|
+
|
|
44
|
+
export default {
|
|
45
|
+
components: {
|
|
46
|
+
PremiumBblEditorOptionsAPI
|
|
47
|
+
},
|
|
48
|
+
data() {
|
|
49
|
+
return {
|
|
50
|
+
content: '<p>Hello World!</p>'
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
computed: {
|
|
54
|
+
wrappedContent() {
|
|
55
|
+
// Automatically wrapped with bbl-html-section
|
|
56
|
+
return this.$refs.editor?.getContent() || ''
|
|
57
|
+
},
|
|
58
|
+
unwrappedContent() {
|
|
59
|
+
// Get content without wrapper
|
|
60
|
+
return this.$refs.editor?.getContent('html', false) || ''
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
</script>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Disabling Auto-Wrap
|
|
68
|
+
|
|
69
|
+
```vue
|
|
70
|
+
<template>
|
|
71
|
+
<PremiumBblEditorOptionsAPI
|
|
72
|
+
v-model="content"
|
|
73
|
+
:wrap-with-content-class="false"
|
|
74
|
+
ref="editor"
|
|
75
|
+
/>
|
|
76
|
+
</template>
|
|
77
|
+
|
|
78
|
+
<script>
|
|
79
|
+
export default {
|
|
80
|
+
data() {
|
|
81
|
+
return {
|
|
82
|
+
content: '<p>Content without auto-wrap</p>'
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
methods: {
|
|
86
|
+
getContent() {
|
|
87
|
+
// Returns unwrapped content when wrap-with-content-class is false
|
|
88
|
+
return this.$refs.editor.getContent()
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
</script>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Composition API Usage
|
|
96
|
+
|
|
97
|
+
### Basic Usage
|
|
98
|
+
|
|
99
|
+
```vue
|
|
100
|
+
<template>
|
|
101
|
+
<div>
|
|
102
|
+
<PremiumBblEditor
|
|
103
|
+
v-model="content"
|
|
104
|
+
ref="editor"
|
|
105
|
+
/>
|
|
106
|
+
|
|
107
|
+
<div class="output-section">
|
|
108
|
+
<h3>Wrapped Output (Default)</h3>
|
|
109
|
+
<div v-html="wrappedContent"></div>
|
|
110
|
+
|
|
111
|
+
<h3>Unwrapped Output</h3>
|
|
112
|
+
<div class="bbl-html-section" v-html="unwrappedContent"></div>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
</template>
|
|
116
|
+
|
|
117
|
+
<script>
|
|
118
|
+
import { ref, computed } from '@vue/composition-api'
|
|
119
|
+
import { PremiumBblEditor } from 'vue2-premium-bbl-editor'
|
|
120
|
+
|
|
121
|
+
export default {
|
|
122
|
+
components: {
|
|
123
|
+
PremiumBblEditor
|
|
124
|
+
},
|
|
125
|
+
setup() {
|
|
126
|
+
const content = ref('<p>Hello World!</p>')
|
|
127
|
+
const editor = ref(null)
|
|
128
|
+
|
|
129
|
+
const wrappedContent = computed(() => {
|
|
130
|
+
// Automatically wrapped with bbl-html-section
|
|
131
|
+
return editor.value?.getContent() || ''
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
const unwrappedContent = computed(() => {
|
|
135
|
+
// Get content without wrapper
|
|
136
|
+
return editor.value?.getContent('html', false) || ''
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
content,
|
|
141
|
+
editor,
|
|
142
|
+
wrappedContent,
|
|
143
|
+
unwrappedContent
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
</script>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Disabling Auto-Wrap
|
|
151
|
+
|
|
152
|
+
```vue
|
|
153
|
+
<template>
|
|
154
|
+
<PremiumBblEditor
|
|
155
|
+
v-model="content"
|
|
156
|
+
:wrap-with-content-class="false"
|
|
157
|
+
ref="editor"
|
|
158
|
+
/>
|
|
159
|
+
</template>
|
|
160
|
+
|
|
161
|
+
<script>
|
|
162
|
+
import { ref } from '@vue/composition-api'
|
|
163
|
+
import { PremiumBblEditor } from 'vue2-premium-bbl-editor'
|
|
164
|
+
|
|
165
|
+
export default {
|
|
166
|
+
components: {
|
|
167
|
+
PremiumBblEditor
|
|
168
|
+
},
|
|
169
|
+
setup() {
|
|
170
|
+
const content = ref('<p>Content without auto-wrap</p>')
|
|
171
|
+
const editor = ref(null)
|
|
172
|
+
|
|
173
|
+
const getContent = () => {
|
|
174
|
+
// Returns unwrapped content when wrap-with-content-class is false
|
|
175
|
+
return editor.value?.getContent()
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
content,
|
|
180
|
+
editor,
|
|
181
|
+
getContent
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
</script>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Method Signatures
|
|
189
|
+
|
|
190
|
+
### getContent Method
|
|
191
|
+
|
|
192
|
+
Both components support the enhanced `getContent` method:
|
|
193
|
+
|
|
194
|
+
```javascript
|
|
195
|
+
// Get wrapped HTML (default)
|
|
196
|
+
const wrappedHtml = editor.getContent()
|
|
197
|
+
const wrappedHtml2 = editor.getContent('html')
|
|
198
|
+
const wrappedHtml3 = editor.getContent('html', true)
|
|
199
|
+
|
|
200
|
+
// Get unwrapped HTML
|
|
201
|
+
const unwrappedHtml = editor.getContent('html', false)
|
|
202
|
+
|
|
203
|
+
// Get JSON (wrapping doesn't apply to JSON)
|
|
204
|
+
const jsonContent = editor.getContent('json')
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Props
|
|
208
|
+
|
|
209
|
+
| Prop | Type | Default | Description |
|
|
210
|
+
|------|------|---------|-------------|
|
|
211
|
+
| `wrapWithContentClass` | Boolean | `true` | Whether to automatically wrap HTML output with `bbl-html-section` class |
|
|
212
|
+
|
|
213
|
+
## External Project Integration
|
|
214
|
+
|
|
215
|
+
### React Example
|
|
216
|
+
|
|
217
|
+
```jsx
|
|
218
|
+
import React, { useState } from 'react';
|
|
219
|
+
|
|
220
|
+
function BlogPost({ editorContent }) {
|
|
221
|
+
// Content is already wrapped with bbl-html-section from Vue editor
|
|
222
|
+
return (
|
|
223
|
+
<article>
|
|
224
|
+
<div dangerouslySetInnerHTML={{ __html: editorContent }} />
|
|
225
|
+
</article>
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Or if you have unwrapped content
|
|
230
|
+
function BlogPostUnwrapped({ editorContent }) {
|
|
231
|
+
return (
|
|
232
|
+
<article>
|
|
233
|
+
<div
|
|
234
|
+
className="bbl-html-section"
|
|
235
|
+
dangerouslySetInnerHTML={{ __html: editorContent }}
|
|
236
|
+
/>
|
|
237
|
+
</article>
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Vue 3 Example
|
|
243
|
+
|
|
244
|
+
```vue
|
|
245
|
+
<template>
|
|
246
|
+
<article>
|
|
247
|
+
<!-- Content already wrapped -->
|
|
248
|
+
<div v-html="editorContent"></div>
|
|
249
|
+
|
|
250
|
+
<!-- Or manually wrap unwrapped content -->
|
|
251
|
+
<div class="bbl-html-section" v-html="unwrappedContent"></div>
|
|
252
|
+
</article>
|
|
253
|
+
</template>
|
|
254
|
+
|
|
255
|
+
<script setup>
|
|
256
|
+
defineProps({
|
|
257
|
+
editorContent: String,
|
|
258
|
+
unwrappedContent: String
|
|
259
|
+
});
|
|
260
|
+
</script>
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Angular Example
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
@Component({
|
|
267
|
+
selector: 'app-blog-post',
|
|
268
|
+
template: `
|
|
269
|
+
<!-- Content already wrapped -->
|
|
270
|
+
<article [innerHTML]="editorContent"></article>
|
|
271
|
+
|
|
272
|
+
<!-- Or manually wrap unwrapped content -->
|
|
273
|
+
<article>
|
|
274
|
+
<div class="bbl-html-section" [innerHTML]="unwrappedContent"></div>
|
|
275
|
+
</article>
|
|
276
|
+
`
|
|
277
|
+
})
|
|
278
|
+
export class BlogPostComponent {
|
|
279
|
+
@Input() editorContent: string = '';
|
|
280
|
+
@Input() unwrappedContent: string = '';
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Best Practices
|
|
285
|
+
|
|
286
|
+
### 1. Use Auto-Wrap for External Projects
|
|
287
|
+
|
|
288
|
+
When content will be rendered in external projects, keep auto-wrap enabled:
|
|
289
|
+
|
|
290
|
+
```javascript
|
|
291
|
+
// Good - content ready for external use
|
|
292
|
+
const content = editor.getContent() // Wrapped with bbl-html-section
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### 2. Disable Auto-Wrap for Internal Processing
|
|
296
|
+
|
|
297
|
+
When processing content internally or storing in database:
|
|
298
|
+
|
|
299
|
+
```javascript
|
|
300
|
+
// Good - clean content for storage
|
|
301
|
+
const content = editor.getContent('html', false) // No wrapper
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
### 3. Consistent CDN Usage
|
|
305
|
+
|
|
306
|
+
Always include the CDN CSS when rendering wrapped content:
|
|
307
|
+
|
|
308
|
+
```html
|
|
309
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vue2-premium-bbl-editor/dist/editor-content.css" />
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### 4. Manual Wrapping
|
|
313
|
+
|
|
314
|
+
If you have unwrapped content, manually add the wrapper:
|
|
315
|
+
|
|
316
|
+
```html
|
|
317
|
+
<div class="bbl-html-section">
|
|
318
|
+
<!-- Your unwrapped content here -->
|
|
319
|
+
</div>
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Migration Guide
|
|
323
|
+
|
|
324
|
+
### From v1.2.x to v1.3.x
|
|
325
|
+
|
|
326
|
+
The wrapper functionality is backward compatible. Existing code will continue to work, but HTML output will now be wrapped by default.
|
|
327
|
+
|
|
328
|
+
**If you don't want wrapping:**
|
|
329
|
+
|
|
330
|
+
```vue
|
|
331
|
+
<!-- Add this prop to disable wrapping -->
|
|
332
|
+
<PremiumBblEditor :wrap-with-content-class="false" />
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
**If you want to control wrapping programmatically:**
|
|
336
|
+
|
|
337
|
+
```javascript
|
|
338
|
+
// Old way (still works)
|
|
339
|
+
const content = editor.getContent()
|
|
340
|
+
|
|
341
|
+
// New way with explicit control
|
|
342
|
+
const wrappedContent = editor.getContent('html', true)
|
|
343
|
+
const unwrappedContent = editor.getContent('html', false)
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## Troubleshooting
|
|
347
|
+
|
|
348
|
+
### Content Not Styled Properly
|
|
349
|
+
|
|
350
|
+
1. Ensure CDN CSS is loaded
|
|
351
|
+
2. Check that content has `bbl-html-section` wrapper
|
|
352
|
+
3. Verify no CSS conflicts
|
|
353
|
+
|
|
354
|
+
### Double Wrapping
|
|
355
|
+
|
|
356
|
+
If you see nested `bbl-html-section` divs:
|
|
357
|
+
|
|
358
|
+
```javascript
|
|
359
|
+
// Wrong - will create double wrapper
|
|
360
|
+
const content = `<div class="bbl-html-section">${editor.getContent()}</div>`
|
|
361
|
+
|
|
362
|
+
// Right - let editor handle wrapping
|
|
363
|
+
const content = editor.getContent()
|
|
364
|
+
|
|
365
|
+
// Or get unwrapped and wrap manually
|
|
366
|
+
const content = `<div class="bbl-html-section">${editor.getContent('html', false)}</div>`
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### TypeScript Support
|
|
370
|
+
|
|
371
|
+
The wrapper functionality is fully typed:
|
|
372
|
+
|
|
373
|
+
```typescript
|
|
374
|
+
interface EditorMethods {
|
|
375
|
+
getContent(format?: 'html' | 'json', wrapContent?: boolean): string | object
|
|
376
|
+
}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
## Examples Repository
|
|
380
|
+
|
|
381
|
+
For complete working examples, see:
|
|
382
|
+
- [React Integration Example](examples/react-integration.md)
|
|
383
|
+
- [Vue 3 Integration Example](examples/vue3-integration.md)
|
|
384
|
+
- [Angular Integration Example](examples/angular-integration.md)
|
|
385
|
+
- [Vanilla HTML Example](dist/cdn-demo.html)
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# External HTML Rendering Guide
|
|
2
|
+
|
|
3
|
+
This guide shows how to use the vue2-premium-bbl-editor styles for rendering HTML content in external projects (React, Vue, Angular, vanilla HTML, etc.).
|
|
4
|
+
|
|
5
|
+
## CDN Usage
|
|
6
|
+
|
|
7
|
+
### Basic Setup
|
|
8
|
+
|
|
9
|
+
Add the CDN link to your HTML head or import it in your project:
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<!-- Global CDN styles for HTML output rendering -->
|
|
13
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vue2-premium-bbl-editor/dist/editor-content.css" />
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### Version-Agnostic URL
|
|
17
|
+
|
|
18
|
+
The CDN URL automatically uses the latest version. If you need a specific version, you can pin it:
|
|
19
|
+
|
|
20
|
+
```html
|
|
21
|
+
<!-- Pinned to specific version (optional) -->
|
|
22
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vue2-premium-bbl-editor@1.3.0/dist/editor-content.css" />
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Usage in Different Frameworks
|
|
26
|
+
|
|
27
|
+
### React
|
|
28
|
+
|
|
29
|
+
```jsx
|
|
30
|
+
import React from 'react';
|
|
31
|
+
|
|
32
|
+
function EditorContent({ htmlContent }) {
|
|
33
|
+
return (
|
|
34
|
+
<div
|
|
35
|
+
className="bbl-html-section"
|
|
36
|
+
dangerouslySetInnerHTML={{ __html: htmlContent }}
|
|
37
|
+
/>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export default EditorContent;
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Vue 3
|
|
45
|
+
|
|
46
|
+
```vue
|
|
47
|
+
<template>
|
|
48
|
+
<div class="bbl-html-section" v-html="htmlContent"></div>
|
|
49
|
+
</template>
|
|
50
|
+
|
|
51
|
+
<script setup>
|
|
52
|
+
defineProps({
|
|
53
|
+
htmlContent: {
|
|
54
|
+
type: String,
|
|
55
|
+
required: true
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
</script>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Vue 2
|
|
62
|
+
|
|
63
|
+
```vue
|
|
64
|
+
<template>
|
|
65
|
+
<div class="bbl-html-section" v-html="htmlContent"></div>
|
|
66
|
+
</template>
|
|
67
|
+
|
|
68
|
+
<script>
|
|
69
|
+
export default {
|
|
70
|
+
props: {
|
|
71
|
+
htmlContent: {
|
|
72
|
+
type: String,
|
|
73
|
+
required: true
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
</script>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Angular
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
// component.ts
|
|
84
|
+
import { Component, Input } from '@angular/core';
|
|
85
|
+
|
|
86
|
+
@Component({
|
|
87
|
+
selector: 'app-editor-content',
|
|
88
|
+
template: `<div class="bbl-html-section" [innerHTML]="htmlContent"></div>`
|
|
89
|
+
})
|
|
90
|
+
export class EditorContentComponent {
|
|
91
|
+
@Input() htmlContent: string = '';
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Vanilla HTML/JavaScript
|
|
96
|
+
|
|
97
|
+
```html
|
|
98
|
+
<!DOCTYPE html>
|
|
99
|
+
<html>
|
|
100
|
+
<head>
|
|
101
|
+
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vue2-premium-bbl-editor/dist/editor-content.css" />
|
|
102
|
+
</head>
|
|
103
|
+
<body>
|
|
104
|
+
<div id="content" class="bbl-html-section">
|
|
105
|
+
<!-- Your editor HTML content goes here -->
|
|
106
|
+
</div>
|
|
107
|
+
|
|
108
|
+
<script>
|
|
109
|
+
// Example: Load content dynamically
|
|
110
|
+
document.getElementById('content').innerHTML = yourEditorHtmlContent;
|
|
111
|
+
</script>
|
|
112
|
+
</body>
|
|
113
|
+
</html>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## CSS Classes Reference
|
|
117
|
+
|
|
118
|
+
The CDN provides styles for the following content types:
|
|
119
|
+
|
|
120
|
+
### Container Class
|
|
121
|
+
- `.bbl-html-section` - Main container class for all editor content
|
|
122
|
+
|
|
123
|
+
### Typography
|
|
124
|
+
- `h1, h2, h3, h4, h5, h6` - Headings with proper spacing and sizing
|
|
125
|
+
- `p` - Paragraphs with consistent margins
|
|
126
|
+
- `strong` - Bold text
|
|
127
|
+
- `em` - Italic text
|
|
128
|
+
- `u` - Underlined text
|
|
129
|
+
- `s` - Strikethrough text
|
|
130
|
+
|
|
131
|
+
### Lists
|
|
132
|
+
- `ul, ol` - Ordered and unordered lists
|
|
133
|
+
- `li` - List items
|
|
134
|
+
- `ul[data-type="taskList"]` - Task lists with checkboxes
|
|
135
|
+
|
|
136
|
+
### Tables
|
|
137
|
+
- `table` - Tables with borders and proper spacing
|
|
138
|
+
- `th, td` - Table headers and cells
|
|
139
|
+
- Responsive table styling for mobile devices
|
|
140
|
+
|
|
141
|
+
### Media
|
|
142
|
+
- `img` - Images with responsive sizing
|
|
143
|
+
- `video` - Videos with responsive sizing
|
|
144
|
+
- `.editor-image` - Specific editor image class
|
|
145
|
+
|
|
146
|
+
### Code
|
|
147
|
+
- `code` - Inline code with syntax highlighting
|
|
148
|
+
- `pre` - Code blocks with dark theme
|
|
149
|
+
- `pre code` - Code within pre blocks
|
|
150
|
+
|
|
151
|
+
### Other Elements
|
|
152
|
+
- `blockquote` - Styled blockquotes with left border
|
|
153
|
+
- `hr` - Horizontal rules
|
|
154
|
+
- `a, .editor-link` - Links with hover effects
|
|
155
|
+
|
|
156
|
+
### Text Alignment
|
|
157
|
+
- `.text-left` - Left-aligned text
|
|
158
|
+
- `.text-center` - Center-aligned text
|
|
159
|
+
- `.text-right` - Right-aligned text
|
|
160
|
+
- `.text-justify` - Justified text
|
|
161
|
+
|
|
162
|
+
## Example Implementation
|
|
163
|
+
|
|
164
|
+
Here's a complete example for a React blog component:
|
|
165
|
+
|
|
166
|
+
```jsx
|
|
167
|
+
import React from 'react';
|
|
168
|
+
|
|
169
|
+
function BlogPost({ title, content, author, date }) {
|
|
170
|
+
return (
|
|
171
|
+
<article>
|
|
172
|
+
<header>
|
|
173
|
+
<h1>{title}</h1>
|
|
174
|
+
<p>By {author} on {date}</p>
|
|
175
|
+
</header>
|
|
176
|
+
|
|
177
|
+
{/* Editor content with proper styling */}
|
|
178
|
+
<div
|
|
179
|
+
className="bbl-html-section"
|
|
180
|
+
dangerouslySetInnerHTML={{ __html: content }}
|
|
181
|
+
/>
|
|
182
|
+
</article>
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
export default BlogPost;
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Security Considerations
|
|
190
|
+
|
|
191
|
+
When rendering HTML content from the editor:
|
|
192
|
+
|
|
193
|
+
1. **Sanitize HTML**: Always sanitize HTML content before rendering to prevent XSS attacks
|
|
194
|
+
2. **Content Security Policy**: Implement proper CSP headers
|
|
195
|
+
3. **Trusted Sources**: Only render content from trusted sources
|
|
196
|
+
|
|
197
|
+
Example with DOMPurify (React):
|
|
198
|
+
|
|
199
|
+
```jsx
|
|
200
|
+
import DOMPurify from 'dompurify';
|
|
201
|
+
|
|
202
|
+
function SafeEditorContent({ htmlContent }) {
|
|
203
|
+
const sanitizedContent = DOMPurify.sanitize(htmlContent);
|
|
204
|
+
|
|
205
|
+
return (
|
|
206
|
+
<div
|
|
207
|
+
className="bbl-html-section"
|
|
208
|
+
dangerouslySetInnerHTML={{ __html: sanitizedContent }}
|
|
209
|
+
/>
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
## Customization
|
|
215
|
+
|
|
216
|
+
You can override the default styles by adding your own CSS after the CDN link:
|
|
217
|
+
|
|
218
|
+
```css
|
|
219
|
+
/* Custom overrides */
|
|
220
|
+
.bbl-html-section {
|
|
221
|
+
font-family: 'Your Custom Font', sans-serif;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.bbl-html-section h1 {
|
|
225
|
+
color: #your-brand-color;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.bbl-html-section table {
|
|
229
|
+
border-color: #your-border-color;
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Browser Support
|
|
234
|
+
|
|
235
|
+
The CSS is compatible with:
|
|
236
|
+
- Chrome 60+
|
|
237
|
+
- Firefox 55+
|
|
238
|
+
- Safari 12+
|
|
239
|
+
- Edge 79+
|
|
240
|
+
- Mobile browsers (iOS Safari, Chrome Mobile)
|
|
241
|
+
|
|
242
|
+
## Performance Tips
|
|
243
|
+
|
|
244
|
+
1. **CDN Caching**: The jsdelivr CDN provides excellent caching and global distribution
|
|
245
|
+
2. **Preload**: Consider preloading the CSS for better performance:
|
|
246
|
+
```html
|
|
247
|
+
<link rel="preload" href="https://cdn.jsdelivr.net/npm/vue2-premium-bbl-editor/dist/editor-content.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
|
248
|
+
```
|
|
249
|
+
3. **Critical CSS**: For above-the-fold content, consider inlining critical styles
|
|
250
|
+
|
|
251
|
+
## Troubleshooting
|
|
252
|
+
|
|
253
|
+
### Styles Not Applied
|
|
254
|
+
- Ensure the CDN link is in the `<head>` section
|
|
255
|
+
- Check that the `.bbl-html-section` class is applied to the container
|
|
256
|
+
- Verify there are no CSS conflicts with existing styles
|
|
257
|
+
|
|
258
|
+
### Content Not Displaying Correctly
|
|
259
|
+
- Check that the HTML structure matches the expected format
|
|
260
|
+
- Ensure proper sanitization isn't removing necessary classes
|
|
261
|
+
- Verify responsive viewport meta tag is present
|
|
262
|
+
|
|
263
|
+
### Version Issues
|
|
264
|
+
- Use the version-agnostic URL for automatic updates
|
|
265
|
+
- Pin to a specific version if you need stability
|
|
266
|
+
- Check the [changelog](CHANGELOG.md) for breaking changes between versions
|