Files
hustoj/web/include/vditor-adapter.js

1056 lines
32 KiB
JavaScript

(function (global) {
'use strict';
var documentRef = global.document;
if (!documentRef) {
return;
}
var currentScriptRef = documentRef.currentScript || (function () {
var scripts = documentRef.getElementsByTagName('script');
return scripts.length > 0 ? scripts[scripts.length - 1] : null;
})();
var DEFAULT_CDN = global.HUSTOJ_VDITOR_CDN || getLocalCdnBase();
global.HUSTOJ_VDITOR_CDN = DEFAULT_CDN;
var assetsPromise = null;
var styleInjected = false;
function getLocalCdnBase() {
var scriptSrc = currentScriptRef && currentScriptRef.src;
if (!scriptSrc) {
return 'include/vditor';
}
return scriptSrc.replace(/\/vditor-adapter\.js(?:[?#].*)?$/, '/vditor');
}
function injectAdapterStyle() {
var style;
if (styleInjected) {
return;
}
style = documentRef.createElement('style');
style.type = 'text/css';
style.setAttribute('data-hustoj-vditor', 'adapter-style');
style.textContent = [
'.hustoj-vditor-hidden{display:none !important;}',
'.hustoj-vditor-wrapper{width:100%;margin:0 0 12px;}',
'.hustoj-vditor-code{--hustoj-vditor-font-size:18px;text-align:left;}',
'.hustoj-vditor-code .vditor-toolbar{display:none !important;}',
'.hustoj-vditor-code .vditor-reset,',
'.hustoj-vditor-code .vditor-content,',
'.hustoj-vditor-code .vditor,',
'.hustoj-vditor-code textarea{text-align:left !important;font-family:Consolas,Monaco,"Courier New",monospace !important;font-size:var(--hustoj-vditor-font-size) !important;line-height:1.5 !important;}',
'.hustoj-vditor-code .vditor-sv,',
'.hustoj-vditor-code .vditor-ir{min-height:100%;}',
'.hustoj-vditor-dark .vditor{background:#272822;border-color:#4a4a4a;}',
'.hustoj-vditor-dark .vditor-reset,',
'.hustoj-vditor-dark .vditor-content,',
'.hustoj-vditor-dark textarea{color:#f8f8f2 !important;background:#272822 !important;}',
'.hustoj-vditor-dark .vditor-toolbar svg{fill:#f8f8f2;}',
'.hustoj-vditor-mail .vditor-toolbar{border-bottom:1px solid #ddd;}',
'.hustoj-vditor-mail .vditor{height:100%;min-height:180px;}',
'.hustoj-vditor-preview .vditor-reset pre{position:relative;margin:16px 0;padding:16px 18px;border:1px solid #cfd7e6;border-radius:12px;background:linear-gradient(180deg,#f9fbff 0%,#f3f7ff 100%);box-shadow:0 8px 20px rgba(15,23,42,0.06);}',
'.hustoj-vditor-preview .vditor-reset pre code{display:block;font-size:15px;line-height:1.7;}',
'.hustoj-vditor-preview .vditor-copy{display:block !important;position:absolute;top:12px;right:12px;z-index:2;}',
'.hustoj-vditor-preview .vditor-copy span{display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border:1px solid #c8d3e6;border-radius:999px;background:rgba(255,255,255,0.96);box-shadow:0 4px 12px rgba(15,23,42,0.08);font-size:12px;font-weight:600;color:#2f4f7f;}',
'.hustoj-vditor-preview .vditor-copy span::after{content:attr(aria-label);}',
'.hustoj-vditor-preview .vditor-copy svg{width:14px !important;height:14px !important;color:currentColor;}',
'.hustoj-vditor-preview .vditor-reset .language-mermaid,',
'.hustoj-vditor-preview .vditor-reset .language-flowchart{margin:18px 0;padding:14px;border:1px solid #d7dce5;border-radius:12px;background:#fff;overflow:auto;text-align:center;}',
'.hustoj-vditor-preview .vditor-reset .language-mermaid svg,',
'.hustoj-vditor-preview .vditor-reset .language-flowchart svg{display:block;max-width:100%;height:auto !important;overflow:visible;}',
'.hustoj-vditor-preview .vditor-reset .language-mermaid foreignObject,',
'.hustoj-vditor-preview .vditor-reset .language-flowchart foreignObject,',
'.hustoj-vditor-preview .vditor-reset .language-mermaid .label,',
'.hustoj-vditor-preview .vditor-reset .language-flowchart .label{overflow:visible;}',
'.hustoj-vditor-preview .vditor-reset .language-mermaid .label div,',
'.hustoj-vditor-preview .vditor-reset .language-flowchart .label div,',
'.hustoj-vditor-preview .vditor-reset .language-mermaid .edgeLabel,',
'.hustoj-vditor-preview .vditor-reset .language-flowchart .edgeLabel{white-space:normal !important;line-height:1.4 !important;}',
'.hustoj-vditor-preview .vditor-reset .language-mermaid .nodeLabel,',
'.hustoj-vditor-preview .vditor-reset .language-flowchart .nodeLabel,',
'.hustoj-vditor-preview .vditor-reset .language-mermaid .nodeLabel *,',
'.hustoj-vditor-preview .vditor-reset .language-flowchart .nodeLabel *,',
'.hustoj-vditor-preview .vditor-reset .language-mermaid svg text,',
'.hustoj-vditor-preview .vditor-reset .language-mermaid svg tspan,',
'.hustoj-vditor-preview .vditor-reset .language-flowchart svg text,',
'.hustoj-vditor-preview .vditor-reset .language-flowchart svg tspan{font-family:"Cascadia Mono","JetBrains Mono",Consolas,"Noto Sans SC","Microsoft YaHei",sans-serif !important;font-variant-ligatures:none;letter-spacing:0.01em;text-rendering:geometricPrecision;}',
'.hustoj-vditor-preview .vditor-reset .language-mermaid .nodeLabel p,',
'.hustoj-vditor-preview .vditor-reset .language-flowchart .nodeLabel p{margin:0;line-height:1.4 !important;}'
].join('');
documentRef.head.appendChild(style);
styleInjected = true;
}
function ensureStyleTag(href) {
var existing = documentRef.querySelector('link[data-hustoj-vditor-css="' + href + '"]');
if (existing) {
return;
}
var link = documentRef.createElement('link');
link.rel = 'stylesheet';
link.href = href;
link.setAttribute('data-hustoj-vditor-css', href);
documentRef.head.appendChild(link);
}
function ensureScript(src) {
return new Promise(function (resolve, reject) {
var existing = documentRef.querySelector('script[data-hustoj-vditor-js="' + src + '"]');
if (existing) {
if (global.Vditor) {
resolve(global.Vditor);
} else {
existing.addEventListener('load', function () {
resolve(global.Vditor);
}, { once: true });
existing.addEventListener('error', reject, { once: true });
}
return;
}
var script = documentRef.createElement('script');
script.src = src;
script.async = true;
script.setAttribute('data-hustoj-vditor-js', src);
script.onload = function () {
resolve(global.Vditor);
};
script.onerror = function () {
reject(new Error('Failed to load ' + src));
};
documentRef.head.appendChild(script);
});
}
function ensureAssets(options) {
var cdn = (options && options.cdn) || DEFAULT_CDN;
global.HUSTOJ_VDITOR_CDN = cdn;
if (global.Vditor) {
injectAdapterStyle();
return Promise.resolve(global.Vditor);
}
if (assetsPromise) {
return assetsPromise;
}
ensureStyleTag(cdn + '/dist/index.css');
injectAdapterStyle();
assetsPromise = ensureScript(cdn + '/dist/index.js').then(function () {
return global.Vditor;
});
return assetsPromise;
}
function resolveElement(target) {
if (!target) {
return null;
}
if (typeof target === 'string') {
return documentRef.getElementById(target) || documentRef.querySelector(target);
}
return target;
}
function getElementValue(element) {
if (!element) {
return '';
}
if (typeof element.value === 'string') {
return element.value;
}
return element.textContent || '';
}
function computeHeight(element, fallbackHeight) {
var computed;
var rows;
var height;
if (element && global.getComputedStyle) {
computed = global.getComputedStyle(element);
height = parseInt(computed.height, 10);
if (!height) {
height = parseInt(computed.minHeight, 10);
}
}
if (!height && element) {
rows = parseInt(element.getAttribute('rows'), 10);
if (rows) {
height = Math.max(rows * 24, fallbackHeight || 320);
}
}
return height || fallbackHeight || 360;
}
function aceThemeToVditorTheme(themeName) {
if (!themeName) {
return 'classic';
}
if (themeName.indexOf('monokai') !== -1 || themeName.indexOf('dark') !== -1) {
return 'dark';
}
return 'classic';
}
function aceThemeToContentTheme(themeName) {
return aceThemeToVditorTheme(themeName) === 'dark' ? 'dark' : 'light';
}
function normalizeMode(modeName) {
if (!modeName) {
return '';
}
return String(modeName).replace(/^ace\/mode\//, '');
}
function dispatchNativeEvent(element, eventName) {
var eventObject;
if (!element || typeof Event === 'undefined') {
return;
}
eventObject = new Event(eventName, { bubbles: true });
element.dispatchEvent(eventObject);
}
function syncFieldValue(field, value, onChange) {
if (!field) {
if (typeof onChange === 'function') {
onChange(value, null);
}
if (typeof global.sync === 'function') {
global.sync();
}
return;
}
field.value = value;
dispatchNativeEvent(field, 'input');
dispatchNativeEvent(field, 'change');
if (typeof onChange === 'function') {
onChange(value, field);
}
if (typeof global.sync === 'function') {
global.sync();
}
}
function decodeHtmlEntities(text) {
var textarea = documentRef.createElement('textarea');
textarea.innerHTML = typeof text === 'string' ? text : '';
return textarea.value;
}
function toElementArray(target) {
var resolved;
if (!target) {
return [];
}
if (typeof target === 'string') {
return Array.prototype.slice.call(documentRef.querySelectorAll(target));
}
if (target.nodeType === 1) {
return [target];
}
if (typeof target.length === 'number') {
return Array.prototype.slice.call(target).map(function (item) {
return resolveElement(item);
}).filter(function (item) {
return !!item;
});
}
resolved = resolveElement(target);
return resolved ? [resolved] : [];
}
function mergeObjects(target, source) {
var key;
if (!source) {
return target;
}
for (key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
return target;
}
function getMarkdownSource(element, options) {
var rawSource;
var source;
if (!element) {
return '';
}
if (!options.refreshSource && typeof element._hustojVditorSource === 'string') {
return element._hustojVditorSource;
}
if (typeof options.getSource === 'function') {
rawSource = options.getSource(element);
} else if (options.useTextContent) {
rawSource = element.textContent || '';
} else {
rawSource = element.innerHTML || '';
}
source = String(rawSource || '');
if (options.decodeEntities !== false) {
source = decodeHtmlEntities(source);
}
element._hustojVditorSource = source;
return source;
}
function buildPreviewOptions(options, afterRender) {
var previewOptions = {
cdn: options.cdn || DEFAULT_CDN,
mode: options.mode || 'light',
anchor: typeof options.anchor === 'undefined' ? 0 : options.anchor,
speech: {
enable: false
},
hljs: {
style: options.codeTheme || 'github'
},
markdown: {
autoSpace: false,
fixTermTypo: false,
toc: false,
codeBlockPreview: true,
mathBlockPreview: true,
sanitize: false
},
math: {
inlineDigit: true
},
after: afterRender
};
if (options.previewOptions) {
mergeObjects(previewOptions, options.previewOptions);
if (options.previewOptions.speech) {
previewOptions.speech = mergeObjects(previewOptions.speech, options.previewOptions.speech);
}
if (options.previewOptions.hljs) {
previewOptions.hljs = mergeObjects(previewOptions.hljs, options.previewOptions.hljs);
}
if (options.previewOptions.markdown) {
previewOptions.markdown = mergeObjects(previewOptions.markdown, options.previewOptions.markdown);
}
if (options.previewOptions.math) {
previewOptions.math = mergeObjects(previewOptions.math, options.previewOptions.math);
}
}
previewOptions.after = afterRender;
return previewOptions;
}
function decorateRenderedPreview(element) {
if (!element || !element.classList) {
return;
}
element.classList.add('hustoj-vditor-preview');
Array.prototype.forEach.call(
element.querySelectorAll('.language-mermaid, .language-flowchart'),
function (diagramContainer) {
Array.prototype.forEach.call(diagramContainer.querySelectorAll('svg'), function (svgElement) {
svgElement.style.maxWidth = '100%';
svgElement.style.height = 'auto';
svgElement.style.overflow = 'visible';
});
Array.prototype.forEach.call(
diagramContainer.querySelectorAll('foreignObject, .label, .label div, .edgeLabel, .nodeLabel, .nodeLabel p'),
function (node) {
if (node.tagName === 'FOREIGNOBJECT') {
node.style.overflow = 'visible';
}
if (node.tagName === 'DIV' || node.tagName === 'SPAN') {
node.style.whiteSpace = 'normal';
}
if (node.tagName === 'P') {
node.style.margin = '0';
node.style.lineHeight = '1.4';
}
if (node.classList && node.classList.contains('nodeLabel')) {
node.style.lineHeight = '1.4';
}
}
);
}
);
}
function renderMarkdownBlocks(target, options) {
var renderOptions = options || {};
return ensureAssets(renderOptions).then(function () {
var elements = toElementArray(target);
var tasks = [];
elements.forEach(function (element) {
var source = getMarkdownSource(element, renderOptions);
if (!source && !renderOptions.renderEmpty) {
return;
}
tasks.push(new Promise(function (resolve, reject) {
var previewOptions = buildPreviewOptions(renderOptions, function () {
decorateRenderedPreview(element);
if (typeof renderOptions.afterEach === 'function') {
renderOptions.afterEach(element, source);
}
resolve(element);
});
try {
global.Vditor.preview(element, source, previewOptions);
} catch (error) {
reject(error);
}
}));
});
return Promise.all(tasks).then(function (result) {
if (typeof renderOptions.afterAll === 'function') {
renderOptions.afterAll(result);
}
return result;
});
});
}
function editorUploadFormatter(files, responseText) {
var payload;
var fileName = 'upload';
var result;
try {
payload = JSON.parse(responseText);
} catch (error) {
return JSON.stringify({
msg: '上传返回解析失败',
code: 1,
data: { errFiles: [fileName], succMap: {} }
});
}
if (files && files.length > 0 && files[0] && files[0].name) {
fileName = files[0].name;
}
if (typeof payload.code !== 'undefined' && payload.data) {
return responseText;
}
if (payload.error === 0 && payload.url) {
result = {
msg: '',
code: 0,
data: {
errFiles: [],
succMap: {}
}
};
result.data.succMap[fileName] = payload.url;
return JSON.stringify(result);
}
return JSON.stringify({
msg: payload.message || payload.msg || '上传失败',
code: 1,
data: {
errFiles: [fileName],
succMap: {}
}
});
}
function buildUploadOptions(options) {
if (!options || !options.uploadUrl) {
return undefined;
}
return {
url: options.uploadUrl,
max: options.uploadMax || 400 * 1024 * 1024,
multiple: false,
fieldName: options.fieldName || 'imgFile',
accept: options.accept || '*/*',
format: function (files, responseText) {
return editorUploadFormatter(files, responseText);
}
};
}
function getDefaultMarkdownToolbar() {
return [
'emoji',
'headings',
'bold',
'italic',
'strike',
'|',
'line',
'quote',
'list',
'ordered-list',
'check',
'|',
'link',
'upload',
'table',
'code',
'inline-code',
'|',
'undo',
'redo',
'fullscreen',
'outline'
];
}
function getDefaultMailToolbar() {
return [
'emoji',
'headings',
'bold',
'italic',
'strike',
'|',
'link',
'upload',
'code',
'inline-code',
'|',
'undo',
'redo',
'|',
'fullscreen'
];
}
function createTextareaEditor(textarea, options) {
var wrapper = documentRef.createElement('div');
var height = computeHeight(textarea, options.height || 360);
var vditor;
wrapper.className = 'hustoj-vditor-wrapper hustoj-vditor-markdown';
textarea.classList.add('hustoj-vditor-hidden');
textarea.parentNode.insertBefore(wrapper, textarea.nextSibling);
return new Promise(function (resolve) {
vditor = new global.Vditor(wrapper, {
cdn: options.cdn || DEFAULT_CDN,
cache: { enable: false },
mode: options.mode || 'sv',
value: textarea.value || '',
lang: options.lang || 'zh_CN',
theme: options.theme || 'classic',
icon: options.icon || 'ant',
width: options.width || '100%',
minHeight: options.minHeight || Math.min(height, 320),
height: options.height || height,
toolbar: options.toolbar || getDefaultMarkdownToolbar(),
toolbarConfig: options.toolbarConfig || { pin: true },
resize: options.resize || { enable: true, position: 'bottom' },
outline: options.outline || { enable: false },
preview: options.preview || {
mode: 'both',
delay: 0,
actions: [],
markdown: {
sanitize: false,
autoSpace: false,
codeBlockPreview: true,
mathBlockPreview: true,
fixTermTypo: false
}
},
upload: buildUploadOptions(options),
ctrlEnter: function (value) {
var form;
syncFieldValue(textarea, value, options.onChange);
if (!options.ctrlEnterFormName) {
return;
}
form = documentRef.querySelector('form[name="' + options.ctrlEnterFormName + '"]');
if (form) {
form.submit();
}
},
input: function (value) {
syncFieldValue(textarea, value, options.onChange);
},
blur: function (value) {
syncFieldValue(textarea, value, options.onChange);
},
after: function () {
syncFieldValue(textarea, vditor.getValue(), options.onChange);
resolve(vditor);
}
});
});
}
function createCodeEditor(options) {
return ensureAssets(options).then(function () {
var container = resolveElement(options.container);
var hiddenField = resolveElement(options.hiddenField);
var sourceField = resolveElement(options.sourceField);
var initialValue = options.initialValue;
var adapter = null;
var vditor = null;
var session = null;
var state;
if (!container) {
throw new Error('Vditor code editor container not found');
}
if (typeof initialValue === 'undefined') {
initialValue = getElementValue(sourceField || container);
}
state = {
theme: options.theme || 'ace/theme/chrome',
fontSize: parseInt(options.fontSize, 10) || 18,
mode: normalizeMode(options.mode || ''),
wrap: true
};
container.classList.add('hustoj-vditor-code');
container.style.setProperty('--hustoj-vditor-font-size', state.fontSize + 'px');
container.classList.toggle('hustoj-vditor-dark', aceThemeToVditorTheme(state.theme) === 'dark');
if (sourceField && sourceField !== container) {
sourceField.classList.add('hustoj-vditor-hidden');
}
container.textContent = '';
function applyTheme() {
var editorTheme = aceThemeToVditorTheme(state.theme);
var contentTheme = aceThemeToContentTheme(state.theme);
container.classList.toggle('hustoj-vditor-dark', editorTheme === 'dark');
if (vditor && typeof vditor.setTheme === 'function') {
vditor.setTheme(editorTheme, contentTheme, 'github');
}
}
function applyFontSize() {
container.style.setProperty('--hustoj-vditor-font-size', state.fontSize + 'px');
}
function syncSourceValue(value) {
if (sourceField && sourceField !== container && typeof sourceField.value === 'string') {
sourceField.value = value;
}
if (hiddenField && typeof hiddenField.value === 'string') {
hiddenField.value = value;
}
if (typeof options.onChange === 'function') {
options.onChange(value);
}
}
session = {
setMode: function (modeName) {
state.mode = normalizeMode(modeName);
},
getValue: function () {
return adapter.getValue();
},
setValue: function (value) {
adapter.setValue(value);
}
};
return new Promise(function (resolve) {
vditor = new global.Vditor(container, {
cdn: options.cdn || DEFAULT_CDN,
cache: { enable: false },
mode: options.editorMode || 'sv',
lang: options.lang || 'zh_CN',
value: initialValue || '',
icon: options.icon || 'ant',
theme: aceThemeToVditorTheme(state.theme),
width: options.width || '100%',
minHeight: options.minHeight || computeHeight(container, 420),
height: options.height || computeHeight(container, 420),
toolbar: options.toolbar || [],
toolbarConfig: options.toolbarConfig || { hide: true, pin: false },
resize: options.resize || { enable: false },
outline: options.outline || { enable: false },
counter: options.counter || { enable: false },
preview: options.preview || {
mode: 'editor',
delay: 0,
actions: [],
markdown: {
sanitize: false,
autoSpace: false,
codeBlockPreview: false,
mathBlockPreview: false,
fixTermTypo: false
}
},
input: function (value) {
syncSourceValue(value);
},
blur: function (value) {
syncSourceValue(value);
},
after: function () {
adapter = {
getValue: function () {
return vditor.getValue();
},
setValue: function (value) {
var nextValue = typeof value === 'undefined' ? '' : String(value);
vditor.setValue(nextValue, true);
syncSourceValue(nextValue);
return nextValue;
},
getSession: function () {
return session;
},
session: session,
setTheme: function (themeName) {
state.theme = themeName || state.theme;
applyTheme();
},
getTheme: function () {
return state.theme;
},
setOptions: function (editorOptions) {
if (!editorOptions) {
return;
}
if (editorOptions.fontSize) {
this.setFontSize(editorOptions.fontSize);
}
if (typeof editorOptions.readOnly !== 'undefined') {
this.setReadOnly(editorOptions.readOnly);
}
},
setOption: function (name, value) {
if (name === 'wrap') {
state.wrap = value !== 'off';
}
},
resize: function () {
applyFontSize();
},
getFontSize: function () {
return String(state.fontSize);
},
setFontSize: function (fontSize) {
state.fontSize = parseInt(fontSize, 10) || state.fontSize;
applyFontSize();
},
setReadOnly: function (readOnly) {
if (readOnly) {
vditor.disabled();
} else {
vditor.enable();
}
},
focus: function () {
vditor.focus();
},
_vditor: vditor
};
applyTheme();
applyFontSize();
if (options.readOnly) {
adapter.setReadOnly(true);
}
syncSourceValue(vditor.getValue());
resolve(adapter);
}
});
});
});
}
function createDeferredCodeEditor(options) {
var initialElement = resolveElement(options && (options.sourceField || options.container));
var proxy = {
_impl: null,
_theme: (options && options.theme) || 'ace/theme/chrome',
_fontSize: parseInt(options && options.fontSize, 10) || 18,
_value: typeof options !== 'undefined' && typeof options.initialValue !== 'undefined' ? options.initialValue : getElementValue(initialElement),
_mode: normalizeMode(options && options.mode),
_options: null,
_readOnly: typeof options !== 'undefined' ? options.readOnly : undefined,
_wrap: 'free'
};
function getProxySession() {
return {
setMode: function (modeName) {
proxy._mode = normalizeMode(modeName);
if (proxy._impl) {
proxy._impl.getSession().setMode(modeName);
}
},
getValue: function () {
return proxy.getValue();
},
setValue: function (value) {
proxy.setValue(value);
}
};
}
proxy.getValue = function () {
if (proxy._impl) {
return proxy._impl.getValue();
}
if (typeof proxy._value !== 'undefined' && proxy._value !== null && proxy._value !== '') {
return proxy._value;
}
return getElementValue(resolveElement(options && (options.sourceField || options.container)));
};
proxy.setValue = function (value) {
proxy._value = value;
if (proxy._impl) {
return proxy._impl.setValue(value);
}
return value;
};
proxy.getSession = function () {
return getProxySession();
};
proxy.session = getProxySession();
proxy.setTheme = function (themeName) {
proxy._theme = themeName || proxy._theme;
if (proxy._impl) {
proxy._impl.setTheme(proxy._theme);
}
};
proxy.getTheme = function () {
if (proxy._impl) {
return proxy._impl.getTheme();
}
return proxy._theme;
};
proxy.setOptions = function (editorOptions) {
proxy._options = editorOptions;
if (editorOptions && editorOptions.fontSize) {
proxy._fontSize = parseInt(editorOptions.fontSize, 10) || proxy._fontSize;
}
if (proxy._impl) {
proxy._impl.setOptions(editorOptions);
}
};
proxy.setOption = function (name, value) {
if (name === 'wrap') {
proxy._wrap = value;
}
if (proxy._impl) {
proxy._impl.setOption(name, value);
}
};
proxy.resize = function () {
if (proxy._impl) {
proxy._impl.resize();
}
};
proxy.getFontSize = function () {
if (proxy._impl) {
return proxy._impl.getFontSize();
}
return String(proxy._fontSize);
};
proxy.setFontSize = function (fontSize) {
proxy._fontSize = parseInt(fontSize, 10) || proxy._fontSize;
if (proxy._impl) {
proxy._impl.setFontSize(proxy._fontSize);
}
};
proxy.setReadOnly = function (readOnly) {
proxy._readOnly = readOnly;
if (proxy._impl) {
proxy._impl.setReadOnly(readOnly);
}
};
proxy.focus = function () {
if (proxy._impl) {
proxy._impl.focus();
}
};
createCodeEditor(options || {}).then(function (instance) {
proxy._impl = instance;
instance.setTheme(proxy._theme);
instance.setFontSize(proxy._fontSize);
if (proxy._options) {
instance.setOptions(proxy._options);
}
if (proxy._mode) {
instance.getSession().setMode('ace/mode/' + proxy._mode);
}
if (typeof proxy._readOnly !== 'undefined') {
instance.setReadOnly(proxy._readOnly);
}
instance.setOption('wrap', proxy._wrap);
if (typeof proxy._value !== 'undefined' && proxy._value !== null) {
instance.setValue(proxy._value);
}
}).catch(function (error) {
console.error('Failed to initialize deferred Vditor code editor.', error);
});
return proxy;
}
function createRichTextEditor(options) {
return ensureAssets(options).then(function () {
var container = resolveElement(options.container);
var hiddenField = resolveElement(options.hiddenField);
var initialValue = options.initialValue || '';
var vditor = null;
var adapter = null;
if (!container) {
throw new Error('Vditor rich editor container not found');
}
container.classList.add('hustoj-vditor-mail');
container.textContent = '';
function syncHtml() {
var html = vditor.getHTML();
if (hiddenField && typeof hiddenField.value === 'string') {
hiddenField.value = html;
}
if (typeof options.onChange === 'function') {
options.onChange(html);
}
}
return new Promise(function (resolve) {
vditor = new global.Vditor(container, {
cdn: options.cdn || DEFAULT_CDN,
cache: { enable: false },
mode: options.mode || 'wysiwyg',
lang: options.lang || 'zh_CN',
value: initialValue,
theme: options.theme || 'classic',
icon: options.icon || 'ant',
width: options.width || '100%',
minHeight: options.minHeight || computeHeight(container, 200),
height: options.height || computeHeight(container, 200),
toolbar: options.toolbar || getDefaultMailToolbar(),
toolbarConfig: options.toolbarConfig || { pin: true },
preview: options.preview || {
mode: 'editor',
delay: 0,
actions: [],
markdown: {
sanitize: false,
autoSpace: false,
fixTermTypo: false
}
},
upload: buildUploadOptions(options),
input: syncHtml,
blur: syncHtml,
after: function () {
adapter = {
getHTML: function () {
return vditor.getHTML();
},
getValue: function () {
return vditor.getValue();
},
setValue: function (value) {
vditor.setValue(value || '', true);
syncHtml();
},
focus: function () {
vditor.focus();
},
txt: {
html: function () {
return vditor.getHTML();
}
},
_vditor: vditor
};
syncHtml();
resolve(adapter);
}
});
});
});
}
function initTextareaVditors(options) {
return ensureAssets(options).then(function () {
var selector = (options && options.selector) || 'textarea.vditor-editor';
var textareas = documentRef.querySelectorAll(selector);
var tasks = [];
Array.prototype.forEach.call(textareas, function (textarea) {
tasks.push(createTextareaEditor(textarea, options || {}));
});
return Promise.all(tasks);
});
}
global.HustOJVditor = {
ensureAssets: ensureAssets,
initTextareaVditors: initTextareaVditors,
createCodeEditor: createCodeEditor,
createDeferredCodeEditor: createDeferredCodeEditor,
createRichTextEditor: createRichTextEditor,
renderMarkdownBlocks: renderMarkdownBlocks,
aceThemeToVditorTheme: aceThemeToVditorTheme,
decodeHtmlEntities: decodeHtmlEntities,
editorUploadFormatter: editorUploadFormatter
};
})(window);