mirror of
https://github.com/Ionaru/easy-markdown-editor
synced 2025-09-24 16:40:55 -06:00
Merge 49e57330cfe1e5964dc4d4efe263fd2d7139f056 into c81e7466fdafabd942606456f7b0e045cac3e54e
This commit is contained in:
commit
dec18a51e7
@ -128,6 +128,9 @@ easyMDE.value('New input for **EasyMDE**');
|
|||||||
- **element**: The DOM element for the TextArea to use. Defaults to the first TextArea on the page.
|
- **element**: The DOM element for the TextArea to use. Defaults to the first TextArea on the page.
|
||||||
- **forceSync**: If set to `true`, force text changes made in EasyMDE to be immediately stored in original text area. Defaults to `false`.
|
- **forceSync**: If set to `true`, force text changes made in EasyMDE to be immediately stored in original text area. Defaults to `false`.
|
||||||
- **hideIcons**: An array of icon names to hide. Can be used to hide specific icons shown by default without completely customizing the toolbar.
|
- **hideIcons**: An array of icon names to hide. Can be used to hide specific icons shown by default without completely customizing the toolbar.
|
||||||
|
- **iconsSet**: the icons set to use. Currently supported icons set are:
|
||||||
|
- `fa`: [Font-Awesome icons](https://fontawesome.com/icons) (default);
|
||||||
|
- `material`: [Material Design icons](https://material.io/tools/icons).
|
||||||
- **indentWithTabs**: If set to `false`, indent using spaces instead of tabs. Defaults to `true`.
|
- **indentWithTabs**: If set to `false`, indent using spaces instead of tabs. Defaults to `true`.
|
||||||
- **initialValue**: If set, will customize the initial value of the editor.
|
- **initialValue**: If set, will customize the initial value of the editor.
|
||||||
- **insertTexts**: Customize how certain buttons that insert text behave. Takes an array with two elements. The first element will be the text inserted before the cursor or highlight, and the second element will be inserted after. For example, this is the default link value: `["[", "](http://)"]`.
|
- **insertTexts**: Customize how certain buttons that insert text behave. Takes an array with two elements. The first element will be the text inserted before the cursor or highlight, and the second element will be inserted after. For example, this is the default link value: `["[", "](http://)"]`.
|
||||||
|
@ -151,29 +151,38 @@
|
|||||||
|
|
||||||
.editor-toolbar button:after {
|
.editor-toolbar button:after {
|
||||||
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
|
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
|
||||||
font-size: 65%;
|
|
||||||
vertical-align: text-bottom;
|
vertical-align: text-bottom;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-toolbar button.fa:after {
|
||||||
|
font-size: 75%;
|
||||||
top: 2px;
|
top: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-toolbar button.heading-1:after {
|
.editor-toolbar button.material-icons:after {
|
||||||
|
font-size: 50%;
|
||||||
|
top: -2px;
|
||||||
|
margin-left: -8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-toolbar button.header-1:after {
|
||||||
content: "1";
|
content: "1";
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-toolbar button.heading-2:after {
|
.editor-toolbar button.header-2:after {
|
||||||
content: "2";
|
content: "2";
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-toolbar button.heading-3:after {
|
.editor-toolbar button.header-3:after {
|
||||||
content: "3";
|
content: "3";
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-toolbar button.heading-bigger:after {
|
.editor-toolbar button.header-bigger:after {
|
||||||
content: "▲";
|
content: "▲";
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-toolbar button.heading-smaller:after {
|
.editor-toolbar button.header-smaller:after {
|
||||||
content: "▼";
|
content: "▼";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ function fixShortcut(name) {
|
|||||||
/**
|
/**
|
||||||
* Create icon element for toolbar.
|
* Create icon element for toolbar.
|
||||||
*/
|
*/
|
||||||
function createIcon(options, enableTooltips, shortcuts) {
|
function createIcon(options, enableTooltips, shortcuts, iconsSet) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var el = document.createElement('button');
|
var el = document.createElement('button');
|
||||||
el.className = options.name;
|
el.className = options.name;
|
||||||
@ -143,7 +143,10 @@ function createIcon(options, enableTooltips, shortcuts) {
|
|||||||
|
|
||||||
// Create icon element and append as a child to the button
|
// Create icon element and append as a child to the button
|
||||||
var icon = document.createElement('i');
|
var icon = document.createElement('i');
|
||||||
icon.className = options.className;
|
el.className = options.className[iconsSet || 'fa'];
|
||||||
|
if(options.textContent) {
|
||||||
|
el.textContent = options.textContent[iconsSet || 'fa'];
|
||||||
|
}
|
||||||
el.appendChild(icon);
|
el.appendChild(icon);
|
||||||
|
|
||||||
return el;
|
return el;
|
||||||
@ -263,7 +266,7 @@ function toggleFullScreen(editor) {
|
|||||||
if (/editor-preview-active-side/.test(sidebyside.className))
|
if (/editor-preview-active-side/.test(sidebyside.className))
|
||||||
toggleSideBySide(editor);
|
toggleSideBySide(editor);
|
||||||
|
|
||||||
if (editor.options.onToggleFullScreen) {
|
if (editor.options.onToggleFullScreen) {
|
||||||
editor.options.onToggleFullScreen(cm.getOption('fullScreen') || false);
|
editor.options.onToggleFullScreen(cm.getOption('fullScreen') || false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1145,58 +1148,114 @@ var toolbarBuiltInButtons = {
|
|||||||
'bold': {
|
'bold': {
|
||||||
name: 'bold',
|
name: 'bold',
|
||||||
action: toggleBold,
|
action: toggleBold,
|
||||||
className: 'fa fa-bold',
|
className: {
|
||||||
|
fa: 'fa fa-bold',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'format_bold'
|
||||||
|
},
|
||||||
title: 'Bold',
|
title: 'Bold',
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
'italic': {
|
'italic': {
|
||||||
name: 'italic',
|
name: 'italic',
|
||||||
action: toggleItalic,
|
action: toggleItalic,
|
||||||
className: 'fa fa-italic',
|
className: {
|
||||||
|
fa: 'fa fa-italic',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'format_italic'
|
||||||
|
},
|
||||||
title: 'Italic',
|
title: 'Italic',
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
'strikethrough': {
|
'strikethrough': {
|
||||||
name: 'strikethrough',
|
name: 'strikethrough',
|
||||||
action: toggleStrikethrough,
|
action: toggleStrikethrough,
|
||||||
className: 'fa fa-strikethrough',
|
className: {
|
||||||
|
fa: 'fa fa-strikethrough',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'format_strikethrough'
|
||||||
|
},
|
||||||
title: 'Strikethrough'
|
title: 'Strikethrough'
|
||||||
},
|
},
|
||||||
'heading': {
|
'heading': {
|
||||||
name: 'heading',
|
name: 'heading',
|
||||||
action: toggleHeadingSmaller,
|
action: toggleHeadingSmaller,
|
||||||
className: 'fa fa-header fa-heading',
|
className: {
|
||||||
|
// We use both fa-header and fa-heading to keep compatibility with FontAwesome 4
|
||||||
|
// See https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4#name-changes
|
||||||
|
fa: 'fa fa-header fa-heading',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'title'
|
||||||
|
},
|
||||||
title: 'Heading',
|
title: 'Heading',
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
'heading-smaller': {
|
'heading-smaller': {
|
||||||
name: 'heading-smaller',
|
name: 'heading-smaller',
|
||||||
action: toggleHeadingSmaller,
|
action: toggleHeadingSmaller,
|
||||||
className: 'fa fa-header fa-heading header-smaller',
|
className: {
|
||||||
|
fa: 'fa fa-header fa-heading header-smaller',
|
||||||
|
material: 'material-icons header-smaller'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'title'
|
||||||
|
},
|
||||||
title: 'Smaller Heading'
|
title: 'Smaller Heading'
|
||||||
},
|
},
|
||||||
'heading-bigger': {
|
'heading-bigger': {
|
||||||
name: 'heading-bigger',
|
name: 'heading-bigger',
|
||||||
action: toggleHeadingBigger,
|
action: toggleHeadingBigger,
|
||||||
className: 'fa fa-header fa-heading header-bigger',
|
className: {
|
||||||
|
fa: 'fa fa-header fa-heading header-bigger',
|
||||||
|
material: 'material-icons header-bigger'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'title'
|
||||||
|
},
|
||||||
title: 'Bigger Heading'
|
title: 'Bigger Heading'
|
||||||
},
|
},
|
||||||
'heading-1': {
|
'heading-1': {
|
||||||
name: 'heading-1',
|
name: 'heading-1',
|
||||||
action: toggleHeading1,
|
action: toggleHeading1,
|
||||||
className: 'fa fa-header fa-heading header-1',
|
className: {
|
||||||
|
fa: 'fa fa-header fa-heading header-1',
|
||||||
|
material: 'material-icons header-1'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'title'
|
||||||
|
},
|
||||||
title: 'Big Heading'
|
title: 'Big Heading'
|
||||||
},
|
},
|
||||||
'heading-2': {
|
'heading-2': {
|
||||||
name: 'heading-2',
|
name: 'heading-2',
|
||||||
action: toggleHeading2,
|
action: toggleHeading2,
|
||||||
className: 'fa fa-header fa-heading header-2',
|
className: {
|
||||||
|
fa: 'fa fa-header fa-heading header-2',
|
||||||
|
material: 'material-icons header-2'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'title'
|
||||||
|
},
|
||||||
title: 'Medium Heading'
|
title: 'Medium Heading'
|
||||||
},
|
},
|
||||||
'heading-3': {
|
'heading-3': {
|
||||||
name: 'heading-3',
|
name: 'heading-3',
|
||||||
action: toggleHeading3,
|
action: toggleHeading3,
|
||||||
className: 'fa fa-header fa-heading header-3',
|
className: {
|
||||||
|
fa: 'fa fa-header fa-heading header-3',
|
||||||
|
material: 'material-icons header-3'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'title'
|
||||||
|
},
|
||||||
title: 'Small Heading'
|
title: 'Small Heading'
|
||||||
},
|
},
|
||||||
'separator-1': {
|
'separator-1': {
|
||||||
@ -1205,34 +1264,64 @@ var toolbarBuiltInButtons = {
|
|||||||
'code': {
|
'code': {
|
||||||
name: 'code',
|
name: 'code',
|
||||||
action: toggleCodeBlock,
|
action: toggleCodeBlock,
|
||||||
className: 'fa fa-code',
|
className: {
|
||||||
|
fa: 'fa fa-code',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'code'
|
||||||
|
},
|
||||||
title: 'Code'
|
title: 'Code'
|
||||||
},
|
},
|
||||||
'quote': {
|
'quote': {
|
||||||
name: 'quote',
|
name: 'quote',
|
||||||
action: toggleBlockquote,
|
action: toggleBlockquote,
|
||||||
className: 'fa fa-quote-left',
|
className: {
|
||||||
|
fa: 'fa fa-quote-left',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'format_quote'
|
||||||
|
},
|
||||||
title: 'Quote',
|
title: 'Quote',
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
'unordered-list': {
|
'unordered-list': {
|
||||||
name: 'unordered-list',
|
name: 'unordered-list',
|
||||||
action: toggleUnorderedList,
|
action: toggleUnorderedList,
|
||||||
className: 'fa fa-list-ul',
|
className: {
|
||||||
|
fa: 'fa fa-list-ul',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'format_list_bulleted'
|
||||||
|
},
|
||||||
title: 'Generic List',
|
title: 'Generic List',
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
'ordered-list': {
|
'ordered-list': {
|
||||||
name: 'ordered-list',
|
name: 'ordered-list',
|
||||||
action: toggleOrderedList,
|
action: toggleOrderedList,
|
||||||
className: 'fa fa-list-ol',
|
className: {
|
||||||
|
fa: 'fa fa-list-ol',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'format_list_numbered'
|
||||||
|
},
|
||||||
title: 'Numbered List',
|
title: 'Numbered List',
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
'clean-block': {
|
'clean-block': {
|
||||||
name: 'clean-block',
|
name: 'clean-block',
|
||||||
action: cleanBlock,
|
action: cleanBlock,
|
||||||
className: 'fa fa-eraser',
|
className: {
|
||||||
|
fa: 'fa fa-eraser',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'backspace'
|
||||||
|
},
|
||||||
title: 'Clean block'
|
title: 'Clean block'
|
||||||
},
|
},
|
||||||
'separator-2': {
|
'separator-2': {
|
||||||
@ -1241,27 +1330,51 @@ var toolbarBuiltInButtons = {
|
|||||||
'link': {
|
'link': {
|
||||||
name: 'link',
|
name: 'link',
|
||||||
action: drawLink,
|
action: drawLink,
|
||||||
className: 'fa fa-link',
|
className: {
|
||||||
|
fa: 'fa fa-link',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'insert_link'
|
||||||
|
},
|
||||||
title: 'Create Link',
|
title: 'Create Link',
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
'image': {
|
'image': {
|
||||||
name: 'image',
|
name: 'image',
|
||||||
action: drawImage,
|
action: drawImage,
|
||||||
className: 'fa fa-image',
|
className: {
|
||||||
|
fa: 'fa fa-image',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'insert_photo'
|
||||||
|
},
|
||||||
title: 'Insert Image',
|
title: 'Insert Image',
|
||||||
default: true
|
default: true
|
||||||
},
|
},
|
||||||
'table': {
|
'table': {
|
||||||
name: 'table',
|
name: 'table',
|
||||||
action: drawTable,
|
action: drawTable,
|
||||||
className: 'fa fa-table',
|
className: {
|
||||||
|
fa: 'fa fa-table',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'table_chart'
|
||||||
|
},
|
||||||
title: 'Insert Table'
|
title: 'Insert Table'
|
||||||
},
|
},
|
||||||
'horizontal-rule': {
|
'horizontal-rule': {
|
||||||
name: 'horizontal-rule',
|
name: 'horizontal-rule',
|
||||||
action: drawHorizontalRule,
|
action: drawHorizontalRule,
|
||||||
className: 'fa fa-minus',
|
className: {
|
||||||
|
fa: 'fa fa-minus',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'power_input'
|
||||||
|
},
|
||||||
title: 'Insert Horizontal Line'
|
title: 'Insert Horizontal Line'
|
||||||
},
|
},
|
||||||
'separator-3': {
|
'separator-3': {
|
||||||
@ -1270,7 +1383,13 @@ var toolbarBuiltInButtons = {
|
|||||||
'preview': {
|
'preview': {
|
||||||
name: 'preview',
|
name: 'preview',
|
||||||
action: togglePreview,
|
action: togglePreview,
|
||||||
className: 'fa fa-eye',
|
className: {
|
||||||
|
fa: 'fa fa-eye',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'remove_red_eye'
|
||||||
|
},
|
||||||
noDisable: true,
|
noDisable: true,
|
||||||
title: 'Toggle Preview',
|
title: 'Toggle Preview',
|
||||||
default: true
|
default: true
|
||||||
@ -1278,7 +1397,13 @@ var toolbarBuiltInButtons = {
|
|||||||
'side-by-side': {
|
'side-by-side': {
|
||||||
name: 'side-by-side',
|
name: 'side-by-side',
|
||||||
action: toggleSideBySide,
|
action: toggleSideBySide,
|
||||||
className: 'fa fa-columns',
|
className: {
|
||||||
|
fa: 'fa fa-columns',
|
||||||
|
material: 'material-icons no-disable no-mobile'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'vertical_split'
|
||||||
|
},
|
||||||
noDisable: true,
|
noDisable: true,
|
||||||
noMobile: true,
|
noMobile: true,
|
||||||
title: 'Toggle Side by Side',
|
title: 'Toggle Side by Side',
|
||||||
@ -1287,7 +1412,13 @@ var toolbarBuiltInButtons = {
|
|||||||
'fullscreen': {
|
'fullscreen': {
|
||||||
name: 'fullscreen',
|
name: 'fullscreen',
|
||||||
action: toggleFullScreen,
|
action: toggleFullScreen,
|
||||||
className: 'fa fa-arrows-alt',
|
className: {
|
||||||
|
fa: 'fa fa-arrows-alt',
|
||||||
|
material: 'material-icons no-disable no-mobile'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'fullscreen'
|
||||||
|
},
|
||||||
noDisable: true,
|
noDisable: true,
|
||||||
noMobile: true,
|
noMobile: true,
|
||||||
title: 'Toggle Fullscreen',
|
title: 'Toggle Fullscreen',
|
||||||
@ -1299,7 +1430,13 @@ var toolbarBuiltInButtons = {
|
|||||||
'guide': {
|
'guide': {
|
||||||
name: 'guide',
|
name: 'guide',
|
||||||
action: 'https://www.markdownguide.org/basic-syntax/',
|
action: 'https://www.markdownguide.org/basic-syntax/',
|
||||||
className: 'fa fa-question-circle',
|
className: {
|
||||||
|
fa: 'fa fa-question-circle',
|
||||||
|
material: 'material-icons'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'help'
|
||||||
|
},
|
||||||
noDisable: true,
|
noDisable: true,
|
||||||
title: 'Markdown Guide',
|
title: 'Markdown Guide',
|
||||||
default: true
|
default: true
|
||||||
@ -1310,14 +1447,26 @@ var toolbarBuiltInButtons = {
|
|||||||
'undo': {
|
'undo': {
|
||||||
name: 'undo',
|
name: 'undo',
|
||||||
action: undo,
|
action: undo,
|
||||||
className: 'fa fa-undo',
|
className: {
|
||||||
|
fa: 'fa fa-undo',
|
||||||
|
material: 'material-icons no-disable'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'undo'
|
||||||
|
},
|
||||||
noDisable: true,
|
noDisable: true,
|
||||||
title: 'Undo'
|
title: 'Undo'
|
||||||
},
|
},
|
||||||
'redo': {
|
'redo': {
|
||||||
name: 'redo',
|
name: 'redo',
|
||||||
action: redo,
|
action: redo,
|
||||||
className: 'fa fa-repeat fa-redo',
|
className: {
|
||||||
|
fa: 'fa fa-repeat fa-redo',
|
||||||
|
material: 'material-icons no-disable'
|
||||||
|
},
|
||||||
|
textContent: {
|
||||||
|
material: 'redo'
|
||||||
|
},
|
||||||
noDisable: true,
|
noDisable: true,
|
||||||
title: 'Redo'
|
title: 'Redo'
|
||||||
}
|
}
|
||||||
@ -1657,23 +1806,23 @@ EasyMDE.prototype.autosave = function () {
|
|||||||
console.log('EasyMDE: You must set a uniqueId to use the autosave feature');
|
console.log('EasyMDE: You must set a uniqueId to use the autosave feature');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.options.autosave.binded !== true) {
|
if(this.options.autosave.binded !== true) {
|
||||||
if (easyMDE.element.form != null && easyMDE.element.form != undefined) {
|
if (easyMDE.element.form != null && easyMDE.element.form != undefined) {
|
||||||
easyMDE.element.form.addEventListener('submit', function () {
|
easyMDE.element.form.addEventListener('submit', function () {
|
||||||
clearTimeout(easyMDE.autosaveTimeoutId);
|
clearTimeout(easyMDE.autosaveTimeoutId);
|
||||||
easyMDE.autosaveTimeoutId = undefined;
|
easyMDE.autosaveTimeoutId = undefined;
|
||||||
|
|
||||||
localStorage.removeItem('smde_' + easyMDE.options.autosave.uniqueId);
|
localStorage.removeItem('smde_' + easyMDE.options.autosave.uniqueId);
|
||||||
|
|
||||||
// Restart autosaving in case the submit will be cancelled down the line
|
// Restart autosaving in case the submit will be cancelled down the line
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
easyMDE.autosave();
|
easyMDE.autosave();
|
||||||
}, easyMDE.options.autosave.delay || 10000);
|
}, easyMDE.options.autosave.delay || 10000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.options.autosave.binded = true;
|
this.options.autosave.binded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.options.autosave.loaded !== true) {
|
if (this.options.autosave.loaded !== true) {
|
||||||
@ -1824,7 +1973,7 @@ EasyMDE.prototype.createToolbar = function (items) {
|
|||||||
if (item === '|') {
|
if (item === '|') {
|
||||||
el = createSep();
|
el = createSep();
|
||||||
} else {
|
} else {
|
||||||
el = createIcon(item, self.options.toolbarTips, self.options.shortcuts);
|
el = createIcon(item, self.options.toolbarTips, self.options.shortcuts, self.options.iconsSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind events, special for info
|
// bind events, special for info
|
||||||
|
Loading…
x
Reference in New Issue
Block a user