tiptapify 0.0.8 → 0.0.9

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.
@@ -55,19 +55,6 @@ export function getFormatItems(editor: Editor) {
55
55
  attrs: {
56
56
  click: () => editor.chain().focus().toggleUnderline().run()
57
57
  }
58
- },
59
- highlight: {
60
- name: 'highlight',
61
- tooltip: 'format.highlight',
62
- icon: mdi.mdiMarker,
63
- enabled: true,
64
- props: {
65
- disabled: computed(() => !editor.can().chain().focus().toggleHighlight().run()),
66
- color: computed(() => editor.isActive('highlight') ? 'primary' : ''),
67
- },
68
- attrs: {
69
- click: () => editor.chain().focus().toggleHighlight().run()
70
- }
71
58
  }
72
59
  }
73
60
  }
@@ -1,7 +1,7 @@
1
1
  import * as mdi from "@mdi/js";
2
2
  import { Editor } from "@tiptap/vue-3";
3
3
  import TableBuilder from "@tiptapify/extensions/components/TableBuilder.vue";
4
- import { computed, markRaw, Ref } from "vue";
4
+ import { computed, markRaw } from "vue";
5
5
 
6
6
  export function getMediaItems(editor: Editor) {
7
7
  return {
@@ -1,6 +1,6 @@
1
1
  import * as mdi from "@mdi/js";
2
2
  import { Editor } from "@tiptap/vue-3";
3
- import { computed, Ref } from "vue";
3
+ import { computed } from "vue";
4
4
 
5
5
  export function getMiscItems(editor: Editor) {
6
6
  return {
@@ -1,14 +1,15 @@
1
1
  import * as mdi from "@mdi/js";
2
2
  import { Editor } from "@tiptap/vue-3";
3
3
  import { fonts } from "@tiptapify/components/Toolbar/fonts";
4
- import { computed, ref } from "vue";
4
+ import StyleColor from "@tiptapify/extensions/components/StyleColor.vue";
5
+ import { computed, markRaw, ref } from "vue";
5
6
 
6
7
  interface MDIIcons {
7
8
  [key: string]: string
8
9
  }
9
10
  const mdiIcons = mdi as MDIIcons
10
11
 
11
- export function getStyleItems(editor: Editor, fontMeasure: string, customHeadingLevels: Array<number> = []) {
12
+ export function getStyleItems(editor: Editor, theme: any, fontMeasure: string, customHeadingLevels: Array<number> = []) {
12
13
  const headingLevels = ref([1, 2, 3, 4, 5, 6])
13
14
  if (customHeadingLevels.length) {
14
15
  customHeadingLevels.forEach(level => {
@@ -141,6 +142,46 @@ export function getStyleItems(editor: Editor, fontMeasure: string, customHeading
141
142
  }
142
143
  }
143
144
  })
145
+ },
146
+ highlight: {
147
+ name: 'highlight',
148
+ tooltip: 'style.color.highlight',
149
+ icon: mdi.mdiFormatColorFill,
150
+ icon2: mdi.mdiColorHelper,
151
+ enabled: true,
152
+ icon2Props: {
153
+ color: computed(() => {
154
+ const defaultColor = theme.global.current.value.dark ? '#fff' : '#000'
155
+ return editor.getAttributes('highlight').color || defaultColor
156
+ }),
157
+ style: 'filter: drop-shadow(rgba(0, 0, 0, .75) 1px 1px 2px);'
158
+ },
159
+ component: markRaw(StyleColor),
160
+ componentProps: {
161
+ fontColor: false,
162
+ backgroundColor: true,
163
+ color: computed(() => editor.getAttributes('highlight').color || ''),
164
+ }
165
+ },
166
+ color: {
167
+ name: 'color',
168
+ tooltip: 'style.color.text',
169
+ icon: mdi.mdiFormatColorText,
170
+ icon2: mdi.mdiColorHelper,
171
+ enabled: true,
172
+ icon2Props: {
173
+ color: computed(() => {
174
+ const defaultColor = theme.global.current.value.dark ? '#fff' : '#000'
175
+ return editor.getAttributes('textStyle').color || defaultColor
176
+ }),
177
+ style: 'filter: drop-shadow(rgba(0, 0, 0, .75) 1px 1px 2px);'
178
+ },
179
+ component: markRaw(StyleColor),
180
+ componentProps: {
181
+ fontColor: true,
182
+ backgroundColor: false,
183
+ color: computed(() => editor.getAttributes('textStyle').color || ''),
184
+ }
144
185
  }
145
186
  }
146
187
  }
@@ -6,7 +6,7 @@ import { getListItems } from "@tiptapify/components/Toolbar/items/list";
6
6
  import { getMediaItems } from "@tiptapify/components/Toolbar/items/media";
7
7
  import { getMiscItems } from "@tiptapify/components/Toolbar/items/misc";
8
8
  import { getStyleItems } from "@tiptapify/components/Toolbar/items/style";
9
- import { ComputedRef, Ref, ref } from "vue";
9
+ import { ComputedRef, ref } from "vue";
10
10
 
11
11
  interface ToolbarItemAttrs {
12
12
  [key: string]: Function | any
@@ -20,12 +20,15 @@ export interface ToolbarItem {
20
20
  name: string|number,
21
21
  tooltip: string,
22
22
  icon: string|ComputedRef<string>,
23
+ icon2?: string|ComputedRef<string>,
23
24
  noI18n?: boolean,
24
25
  enabled: boolean,
25
26
  component?: any,
26
27
  modelValue?: any,
27
28
  group?: boolean,
28
29
  toggle?: boolean,
30
+ icon2Props?: ToolbarItemProps,
31
+ componentProps?: ToolbarItemProps,
29
32
  props?: ToolbarItemProps,
30
33
  attrs?: ToolbarItemAttrs,
31
34
  children?: ToolbarItems|ToolbarItem[],
@@ -47,11 +50,12 @@ export interface ToolbarItemSections {
47
50
 
48
51
  export function toolbarItems(
49
52
  editor: any,
53
+ theme: any,
50
54
  fontMeasure: string,
51
55
  items: { list: Array<string>, exclude: boolean },
52
56
  customHeadingLevels: Array<number>
53
57
  ): ToolbarItemSections {
54
- const styleItems = ref(getStyleItems(editor.value, fontMeasure, customHeadingLevels))
58
+ const styleItems = ref(getStyleItems(editor.value, theme, fontMeasure, customHeadingLevels))
55
59
  const formatItems = ref(getFormatItems(editor.value))
56
60
  const formatExtraItems = ref(getFormatExtraItems(editor.value))
57
61
  const alignmentItems = ref(getAlignmentItems(editor.value))
@@ -64,8 +68,6 @@ export function toolbarItems(
64
68
  /**
65
69
  * todo
66
70
  *
67
- * font color, backgroundcolor
68
- * tables
69
71
  * media (image, video)
70
72
  */
71
73
  style: { group: true, items: styleItems.value },
@@ -69,7 +69,7 @@ export function editorExtensions (placeholder: string, slashCommands: boolean) {
69
69
  Dropcursor,
70
70
  Typography,
71
71
  Underline,
72
- Highlight,
72
+ Highlight.configure({ multicolor: true }),
73
73
  TiptapifyLink.configure({
74
74
  openOnClick: false,
75
75
  defaultProtocol: 'https'
@@ -89,12 +89,8 @@ export function editorExtensions (placeholder: string, slashCommands: boolean) {
89
89
  },
90
90
  })
91
91
  .configure({ lowlight }),
92
- Selection.configure({
93
- className: 'selection',
94
- }),
95
- TextAlign.configure({
96
- types: ['heading', 'paragraph'],
97
- }),
92
+ Selection.configure({ className: 'selection' }),
93
+ TextAlign.configure({ types: ['heading', 'paragraph'] }),
98
94
  Placeholder.configure({ placeholder }),
99
95
  CharacterCount,
100
96
  ViewSource,
@@ -0,0 +1,177 @@
1
+ <script setup lang="ts">
2
+
3
+ import { Editor } from "@tiptap/vue-3";
4
+ import { useI18n } from 'vue-i18n'
5
+
6
+ import { computed, inject, Ref, ref } from 'vue'
7
+
8
+ const { t } = useI18n()
9
+
10
+ defineExpose({ open })
11
+
12
+ const props = defineProps({
13
+ show: { type: Boolean, default: true },
14
+ fontColor: { type: Boolean, default: false },
15
+ backgroundColor: { type: Boolean, default: false },
16
+ color: { type: String, default: '' },
17
+ })
18
+
19
+ const emit = defineEmits(['close'])
20
+
21
+ const editor = inject('tiptapifyEditor') as Ref<Editor>
22
+
23
+ const colorPicker = ref(false)
24
+ const customColor = ref(computed(() => props.color).value)
25
+
26
+ const colors = {
27
+ black: '#000',
28
+ darkgray: '#444',
29
+ gray: '#888',
30
+ lightgray: '#ccc',
31
+ white: '#fff',
32
+ cyan: '#00FFFF',
33
+ light: '#0088ff',
34
+ blue: '#0000ff',
35
+ indigo: '#4b0082',
36
+ purple: '#800080',
37
+ pink: '#ff00ff',
38
+ red: '#ff0000',
39
+ orange: '#ff9900',
40
+ yellow: '#ffff00',
41
+ green: '#00ff00',
42
+ }
43
+
44
+ type Color = { r: number, g: number, b: number, a?: number }
45
+
46
+ function calculateShadowColor(color: string): string {
47
+ const rgb: Color = hexToRgb(color)
48
+
49
+ for (const channel of Object.keys(rgb)) {
50
+ rgb[channel] = Math.round(rgb[channel] * .35)
51
+ }
52
+
53
+ return Object.values(rgb).join(', ')
54
+ }
55
+
56
+ function hexToRgb(hex: string): Color {
57
+ const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
58
+ hex = hex.replace(shorthandRegex, function(m, r, g, b) {
59
+ return r + r + g + g + b + b;
60
+ });
61
+
62
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
63
+ return {
64
+ r: result ? parseInt(result[1], 16) : 0,
65
+ g: result ? parseInt(result[2], 16) : 0,
66
+ b: result ? parseInt(result[3], 16) : 0
67
+ };
68
+ }
69
+
70
+ function setColor(color: string) {
71
+ if (props.fontColor) {
72
+ editor.value.chain().focus().setColor(color).run()
73
+ }
74
+
75
+ if (props.backgroundColor) {
76
+ editor.value.chain().focus().setHighlight({ color }).run()
77
+ }
78
+
79
+ emit('close')
80
+ }
81
+
82
+ function unsetColor() {
83
+ if (props.fontColor) {
84
+ editor.value.chain().focus().unsetColor().run()
85
+ }
86
+
87
+ if (props.backgroundColor) {
88
+ editor.value.chain().focus().unsetHighlight().run()
89
+ }
90
+
91
+ emit('close')
92
+ }
93
+
94
+ function isColorActive(color: string): boolean {
95
+ return props.color === color
96
+ }
97
+ </script>
98
+
99
+ <template>
100
+ <VSheet class="pa-2">
101
+ <div class="tiptapify-style-color-container">
102
+ <template v-for="colorCode in colors">
103
+ <div
104
+ class="tiptapify-style-color-item"
105
+ :class="isColorActive(colorCode) ? 'tiptapify-style-color-item-active' : ''"
106
+ @click="setColor(colorCode)"
107
+ >
108
+ <div
109
+ class="tiptapify-style-color-picker"
110
+ :style="`background-color: ${colorCode}; box-shadow: 1px 1px 4px rgb(${calculateShadowColor(colorCode)});`"
111
+ ></div>
112
+ </div>
113
+ </template>
114
+ </div>
115
+
116
+ <VDivider class="mt-2 mb-2" />
117
+
118
+ <VMenu v-model="colorPicker" :close-on-content-click="false">
119
+ <template #activator="{ props: menuProps }">
120
+ <VBtn v-bind="menuProps" variant="flat" block>
121
+ <template #prepend>
122
+ <div
123
+ class="tiptapify-style-color-picker"
124
+ :style="`background-color: ${customColor}; box-shadow: 1px 1px 4px rgb(0, 0, 0, .35);`"
125
+ >
126
+ </div>
127
+ </template>
128
+ <template #default>
129
+ {{ t('style.color.custom') }}
130
+ </template>
131
+ </VBtn>
132
+ </template>
133
+
134
+ <VCard>
135
+ <VCardItem>
136
+ <VColorPicker v-model="customColor" elevated elevation="24" hide-inputs />
137
+ </VCardItem>
138
+
139
+ <VCardActions>
140
+ <VBtn variant="flat" color="primary" @click="setColor(customColor)">OK</VBtn>
141
+ <VBtn variant="flat" color="grey-400" @click="colorPicker = !colorPicker; customColor = color">Cancel</VBtn>
142
+ </VCardActions>
143
+ </VCard>
144
+ </VMenu>
145
+
146
+ <VDivider class="mt-2 mb-2" />
147
+
148
+ <VBtn @click="unsetColor" block variant="flat">
149
+ {{ t('style.color.unset') }}
150
+ </VBtn>
151
+ </VSheet>
152
+ </template>
153
+
154
+ <style lang="scss" scoped>
155
+ .tiptapify-style-color-container {
156
+ display: grid;
157
+ grid-template-columns: repeat(5, 1fr);
158
+ }
159
+
160
+ .tiptapify-style-color-item {
161
+ cursor: pointer;
162
+ border-radius: 8px;
163
+ padding: 5px;
164
+ transition: background-color .2s;
165
+ }
166
+
167
+ .tiptapify-style-color-item:hover, .tiptapify-style-color-item-active {
168
+ background-color: #dedede;
169
+ }
170
+
171
+ .tiptapify-style-color-picker {
172
+ width: 24px;
173
+ height: 24px;
174
+ margin: 2px;
175
+ border-radius: 4px;
176
+ }
177
+ </style>
@@ -13,7 +13,6 @@ const { ucFirst } = helpers
13
13
  defineExpose({ open })
14
14
 
15
15
  defineProps({
16
- show: { type: Boolean, default: false },
17
16
  maxCols: { type: Number, default: 10 },
18
17
  maxRows: { type: Number, default: 10 },
19
18
  })
@@ -111,7 +110,7 @@ $mutedColor: var(--v-theme-muted-color, #888888);
111
110
  margin: 2px;
112
111
  width: 100%;
113
112
  height: 100%;
114
- border: 1px solid #888;
113
+ border: 1px solid #bbb;
115
114
  background: #fff;
116
115
  border-radius: 4px;
117
116
  filter: drop-shadow(2px 2px 4px #88888888);
@@ -1,4 +1,7 @@
1
1
  {
2
+ "content": {
3
+ "placeholder": "schreib hier etwas..."
4
+ },
2
5
  "style": {
3
6
  "paragraph": "absatz",
4
7
  "heading": "überschrift",
@@ -12,7 +15,13 @@
12
15
  },
13
16
  "fontFamily": "schriftart",
14
17
  "fontSize": "schriftgröße",
15
- "lineHeight": "zeilenhöhe"
18
+ "lineHeight": "zeilenhöhe",
19
+ "color": {
20
+ "highlight": "hervorhebungsfarbe",
21
+ "text": "textfarbe",
22
+ "unset": "farbe zurücksetzen",
23
+ "custom": "benutzerdefinierte farbe"
24
+ }
16
25
  },
17
26
  "format": {
18
27
  "bold": "fett",
@@ -22,7 +31,6 @@
22
31
  "sup": "hochgestellt",
23
32
  "sub": "tiefgestellt",
24
33
  "break": "harter umbruch",
25
- "highlight": "hervorheben",
26
34
  "line": "horizontale linie",
27
35
  "blockquote": "zitat",
28
36
  "code": "code",
@@ -96,5 +104,9 @@
96
104
  "misc": {
97
105
  "source": "quellcode anzeigen",
98
106
  "preview": "vorschau"
107
+ },
108
+ "footer": {
109
+ "words": "wörter",
110
+ "chars": "zeichen"
99
111
  }
100
112
  }
@@ -1,4 +1,7 @@
1
1
  {
2
+ "content": {
3
+ "placeholder": "write something here..."
4
+ },
2
5
  "style": {
3
6
  "paragraph": "paragraph",
4
7
  "heading": "heading",
@@ -12,7 +15,13 @@
12
15
  },
13
16
  "fontFamily": "font family",
14
17
  "fontSize": "font size",
15
- "lineHeight": "line height"
18
+ "lineHeight": "line height",
19
+ "color": {
20
+ "highlight": "highlight color",
21
+ "text": "text color",
22
+ "unset": "unset color",
23
+ "custom": "custom color"
24
+ }
16
25
  },
17
26
  "format": {
18
27
  "bold": "bold",
@@ -22,7 +31,6 @@
22
31
  "sup": "superscript",
23
32
  "sub": "subscript",
24
33
  "break": "hard break",
25
- "highlight": "highlight",
26
34
  "line": "horizontal line",
27
35
  "blockquote": "cite",
28
36
  "code": "code",
@@ -96,5 +104,9 @@
96
104
  "misc": {
97
105
  "source": "view source code",
98
106
  "preview": "preview"
107
+ },
108
+ "footer": {
109
+ "words": "words",
110
+ "chars": "characters"
99
111
  }
100
112
  }
@@ -1,4 +1,7 @@
1
1
  {
2
+ "content": {
3
+ "placeholder": "escribe algo aquí..."
4
+ },
2
5
  "style": {
3
6
  "paragraph": "párrafo",
4
7
  "heading": "encabezado",
@@ -12,7 +15,13 @@
12
15
  },
13
16
  "fontFamily": "familia de fuente",
14
17
  "fontSize": "tamaño de fuente",
15
- "lineHeight": "altura de línea"
18
+ "lineHeight": "altura de línea",
19
+ "color": {
20
+ "highlight": "color de resaltado",
21
+ "text": "color de texto",
22
+ "unset": "quitar color",
23
+ "custom": "color personalizado"
24
+ }
16
25
  },
17
26
  "format": {
18
27
  "bold": "negrita",
@@ -21,8 +30,7 @@
21
30
  "underline": "subrayado",
22
31
  "sup": "superíndice",
23
32
  "sub": "subíndice",
24
- "break": "salto forzado",
25
- "highlight": "resaltar",
33
+ "break": "salto de línea forzado",
26
34
  "line": "línea horizontal",
27
35
  "blockquote": "cita",
28
36
  "code": "código",
@@ -47,7 +55,7 @@
47
55
  "insertColBefore": "insertar columna antes",
48
56
  "insertColAfter": "insertar columna después",
49
57
  "deleteCol": "eliminar columna",
50
- "mergeCells": "combinar celdas",
58
+ "mergeCells": "fusionar celdas",
51
59
  "splitCell": "dividir celda"
52
60
  }
53
61
  },
@@ -64,7 +72,7 @@
64
72
  },
65
73
  "list": "lista",
66
74
  "lists": {
67
- "bullet": "lista desordenada",
75
+ "bullet": "lista no ordenada",
68
76
  "numbered": "lista ordenada",
69
77
  "task": "lista de tareas",
70
78
  "indent": "sangrar elemento de lista",
@@ -76,7 +84,7 @@
76
84
  "close": "cerrar",
77
85
  "image": {
78
86
  "title": "agregar/editar imagen",
79
- "src": "origen",
87
+ "src": "fuente",
80
88
  "alt": "alt",
81
89
  "width": "ancho",
82
90
  "height": "alto"
@@ -86,7 +94,7 @@
86
94
  "href": "dirección del enlace",
87
95
  "target": "abrir en nueva ventana",
88
96
  "rel": "rel",
89
- "class": "clase css"
97
+ "class": "clase CSS"
90
98
  },
91
99
  "source": {
92
100
  "title": "ver código fuente",
@@ -96,5 +104,9 @@
96
104
  "misc": {
97
105
  "source": "ver código fuente",
98
106
  "preview": "vista previa"
107
+ },
108
+ "footer": {
109
+ "words": "palabras",
110
+ "chars": "caracteres"
99
111
  }
100
112
  }
@@ -1,18 +1,27 @@
1
1
  {
2
+ "content": {
3
+ "placeholder": "écrivez quelque chose ici..."
4
+ },
2
5
  "style": {
3
6
  "paragraph": "paragraphe",
4
- "heading": "en-tête",
7
+ "heading": "titre",
5
8
  "headings": {
6
- "h1": "en-tête niveau 1",
7
- "h2": "en-tête niveau 2",
8
- "h3": "en-tête niveau 3",
9
- "h4": "en-tête niveau 4",
10
- "h5": "en-tête niveau 5",
11
- "h6": "en-tête niveau 6"
9
+ "h1": "titre niveau 1",
10
+ "h2": "titre niveau 2",
11
+ "h3": "titre niveau 3",
12
+ "h4": "titre niveau 4",
13
+ "h5": "titre niveau 5",
14
+ "h6": "titre niveau 6"
12
15
  },
13
16
  "fontFamily": "famille de police",
14
17
  "fontSize": "taille de police",
15
- "lineHeight": "hauteur de ligne"
18
+ "lineHeight": "hauteur de ligne",
19
+ "color": {
20
+ "highlight": "couleur de surbrillance",
21
+ "text": "couleur du texte",
22
+ "unset": "réinitialiser la couleur",
23
+ "custom": "couleur personnalisée"
24
+ }
16
25
  },
17
26
  "format": {
18
27
  "bold": "gras",
@@ -21,34 +30,33 @@
21
30
  "underline": "souligné",
22
31
  "sup": "exposant",
23
32
  "sub": "indice",
24
- "break": "saut forcé",
25
- "highlight": "surligner",
33
+ "break": "saut de ligne forcé",
26
34
  "line": "ligne horizontale",
27
35
  "blockquote": "citation",
28
36
  "code": "code",
29
37
  "codeblock": "bloc de code",
30
- "formatClear": "effacer le format"
38
+ "formatClear": "effacer le formatage"
31
39
  },
32
40
  "media": {
33
41
  "link": "lien externe",
34
42
  "image": "image",
35
43
  "tables": {
36
44
  "table": "tableau",
37
- "insertTable": "insérer un tableau",
38
- "deleteTable": "supprimer le tableau",
39
- "insertWithHeaderRow": "insérer un tableau avec ligne d'en-tête",
45
+ "insertTable": "insérer tableau",
46
+ "deleteTable": "supprimer tableau",
47
+ "insertWithHeaderRow": "insérer tableau avec ligne d'en-tête",
40
48
  "rows": "lignes",
41
49
  "row": "ligne",
42
- "insertRowBefore": "insérer une ligne avant",
43
- "insertRowAfter": "insérer une ligne après",
44
- "deleteRow": "supprimer la ligne",
50
+ "insertRowBefore": "insérer ligne avant",
51
+ "insertRowAfter": "insérer ligne après",
52
+ "deleteRow": "supprimer ligne",
45
53
  "cols": "colonnes",
46
54
  "col": "colonne",
47
- "insertColBefore": "insérer une colonne avant",
48
- "insertColAfter": "insérer une colonne après",
49
- "deleteCol": "supprimer la colonne",
50
- "mergeCells": "fusionner les cellules",
51
- "splitCell": "diviser la cellule"
55
+ "insertColBefore": "insérer colonne avant",
56
+ "insertColAfter": "insérer colonne après",
57
+ "deleteCol": "supprimer colonne",
58
+ "mergeCells": "fusionner cellules",
59
+ "splitCell": "diviser cellule"
52
60
  }
53
61
  },
54
62
  "action": {
@@ -58,7 +66,7 @@
58
66
  "alignment": "alignement",
59
67
  "alignments": {
60
68
  "left": "aligner à gauche",
61
- "center": "aligner au centre",
69
+ "center": "centrer",
62
70
  "right": "aligner à droite",
63
71
  "justify": "justifier"
64
72
  },
@@ -67,26 +75,26 @@
67
75
  "bullet": "liste non ordonnée",
68
76
  "numbered": "liste ordonnée",
69
77
  "task": "liste de tâches",
70
- "indent": "indenter l'élément de liste",
71
- "outdent": "désindenter l'élément de liste"
78
+ "indent": "indenter élément de liste",
79
+ "outdent": "désindenter élément de liste"
72
80
  },
73
81
  "dialog": {
74
82
  "apply": "appliquer",
75
83
  "clear": "effacer",
76
84
  "close": "fermer",
77
85
  "image": {
78
- "title": "ajouter/modifier l'image",
86
+ "title": "ajouter/modifier image",
79
87
  "src": "source",
80
88
  "alt": "alt",
81
89
  "width": "largeur",
82
90
  "height": "hauteur"
83
91
  },
84
92
  "link": {
85
- "title": "ajouter/modifier le lien",
93
+ "title": "ajouter/modifier lien",
86
94
  "href": "adresse du lien",
87
95
  "target": "ouvrir dans une nouvelle fenêtre",
88
96
  "rel": "rel",
89
- "class": "classe css"
97
+ "class": "classe CSS"
90
98
  },
91
99
  "source": {
92
100
  "title": "voir le code source",
@@ -96,5 +104,9 @@
96
104
  "misc": {
97
105
  "source": "voir le code source",
98
106
  "preview": "aperçu"
107
+ },
108
+ "footer": {
109
+ "words": "mots",
110
+ "chars": "caractères"
99
111
  }
100
112
  }