tinymce-plugin
Version:
tinymce-plugin
457 lines (434 loc) • 16.1 kB
JavaScript
/**
* upfile 1.1v
* The tinymce-plugins is used to upfile
*
* https://github.com/Five-great/tinymce-plugins
*
* Copyright 2020, Five(Li Hailong) The Chengdu, China https://www.fivecc.cn/
*
* Licensed under MIT
*/
tinymce.PluginManager.add('upfile', function(editor, url) {
var pluginName='上传文件';
window.upfile={}; //扔外部公共变量,也可以扔一个自定义的位置
window.upfile.file_callback = editor.getParam('file_callback', undefined, 'function');
window.upfile.tinymce = tinymce;
window.upfile.res={};
var openDialog = function() {
return editor.windowManager.open({
title: pluginName,
body: {
type: 'panel', // The root body type - a Panel or TabPanel
items: [ // A list of panel components
{
type: 'iframe', // component type
name: 'upfile_iframe', // identifier
label: ' ', // text for the iframe's title attribute
sandboxed: true,
}
]
},
initialData: {
upfile_iframe: `
<html>
<head>
<meta charset="utf-8" />
<title>upfile</title>
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="format-detection" content="telephone=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<style>
html,body{height:100%;margin:0;padding:0;background:#fff;}
ul{margin:0;padding:0;list-style:none;}
#wrap{padding:10px;}
#topbar{padding:10px 0;border-bottom:1px solid #ccc;text-align:right;}
.tox *:not(svg):not(rect) {
box-sizing: inherit;
color: inherit;
cursor: inherit;
direction: inherit;
font-family: inherit;
font-size: inherit;
font-style: inherit;
font-weight: inherit;
line-height: inherit;
-webkit-tap-highlight-color: inherit;
text-align: inherit;
text-decoration: inherit;
text-shadow: inherit;
text-transform: inherit;
vertical-align: inherit;
white-space: inherit;
}
.tox *:not(svg):not(rect) {
/* stylelint-disable-line no-duplicate-selectors */
background: transparent;
border: 0;
float: none;
height: auto;
margin: 0;
max-width: none;
outline: 0;
padding: 0;
position: static;
width: auto;
}
.tox .tox-form__group {
box-sizing: border-box;
margin-bottom: 4px;
}
.tox .tox-label, .tox .tox-toolbar-label {
color: rgba(34,47,62,.7);
display: block;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 1.3;
padding: 0 8px 0 0;
text-transform: none;
white-space: nowrap;
}
.tox .tox-selectfield select, .tox .tox-textarea, .tox .tox-textfield, .tox .tox-toolbar-textfield {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
background-color: #fff;
border-color: #ccc;
border-radius: 3px;
border-style: solid;
border-width: 1px;
box-shadow: none;
box-sizing: border-box;
color: #222f3e;
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
font-size: 16px;
line-height: 24px;
margin: 0;
min-height: 34px;
outline: 0;
padding: 5px 4.75px;
resize: none;
width: 100%;
}
.tox .tox-dialog__body-content {
box-sizing: border-box;
display: flex;
flex: 1;
flex-direction: column;
-ms-flex-preferred-size: auto;
max-height: 650px;
overflow: auto;
-webkit-overflow-scrolling: touch;
padding: 16px 16px;
}
.tox .tox-dialog__body-content {
box-sizing: border-box;
display: flex;
flex: 1;
flex-direction: column;
-ms-flex-preferred-size: auto;
max-height: 650px;
overflow: auto;
-webkit-overflow-scrolling: touch;
padding: 16px 16px;
}
.tox .tox-dialog__body-content > * {
margin-bottom: 0;
margin-top: 16px;
}
.tox .tox-dialog__body-content > *:first-child {
margin-top: 0;
}
.tox .tox-dialog__body-content > *:last-child {
margin-bottom: 0;
}
.tox .tox-dialog__body-content > *:only-child {
margin-bottom: 0;
margin-top: 0;
}
.tox .tox-dialog__body-content a {
color: #207ab7;
cursor: pointer;
text-decoration: none;
}
.tox .tox-dialog__body-content a:hover,
.tox .tox-dialog__body-content a:focus {
color: #185d8c;
text-decoration: none;
}
.tox .tox-dialog__body-content a:active {
color: #185d8c;
text-decoration: none;
}
.tox .tox-dialog__body-content svg {
fill: #222f3e;
}
.tox .tox-form__group--stretched {
display: flex;
flex: 1;
flex-direction: column;
-ms-flex-preferred-size: auto;
}
.tox .tox-form__group {
box-sizing: border-box;
margin-bottom: 4px;
}
.tox .tox-dropzone-container {
display: flex;
flex: 1;
}
element.style {
}
.tox .tox-dropzone {
cursor: pointer;
align-items: center;
background: #fff;
border: 2px dashed #ccc;
box-sizing: border-box;
display: flex;
flex-direction: column;
flex-grow: 1;
justify-content: center;
min-height: 100px;
padding: 10px;
}
.tox .tox-button {
background-color: #207ab7;
background-image: none;
background-position: 0 0;
background-repeat: repeat;
border-color: #207ab7;
border-radius: 3px;
border-style: solid;
border-width: 1px;
box-shadow: none;
box-sizing: border-box;
color: #fff;
cursor: pointer;
display: inline-block;
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
font-size: 14px;
font-weight: 700;
letter-spacing: normal;
line-height: 24px;
margin: 0;
outline: 0;
padding: 4px 16px;
text-align: center;
text-decoration: none;
text-transform: capitalize;
white-space: nowrap;
}
.tox .tox-button[disabled] {
background-color: #207ab7;
background-image: none;
border-color: #207ab7;
box-shadow: none;
color: rgba(255, 255, 255, 0.5);
cursor: not-allowed;
}
.tox .tox-button:focus:not(:disabled) {
background-color: #1c6ca1;
background-image: none;
border-color: #1c6ca1;
box-shadow: none;
color: #fff;
}
.tox .tox-button:hover:not(:disabled) {
background-color: #1c6ca1;
background-image: none;
border-color: #1c6ca1;
box-shadow: none;
color: #fff;
}
.tox .tox-button:active:not(:disabled) {
background-color: #185d8c;
background-image: none;
border-color: #185d8c;
box-shadow: none;
color: #fff;
}
.tox .tox-button--secondary {
background-color: #f0f0f0;
background-image: none;
background-position: 0 0;
background-repeat: repeat;
border-color: #f0f0f0;
border-radius: 3px;
border-style: solid;
border-width: 1px;
box-shadow: none;
color: #222f3e;
outline: 0;
padding: 4px 16px;
text-decoration: none;
text-transform: capitalize;
}
.tox .tox-button--secondary[disabled] {
background-color: #f0f0f0;
background-image: none;
border-color: #f0f0f0;
box-shadow: none;
cursor: pointer;
color: rgba(34, 47, 62, 0.5);
}
.tox .tox-button--secondary:focus:not(:disabled) {
background-color: #e3e3e3;
background-image: none;
border-color: #e3e3e3;
box-shadow: none;
color: #222f3e;
}
.tox .tox-button--secondary:hover:not(:disabled) {
background-color: #e3e3e3;
background-image: none;
border-color: #e3e3e3;
box-shadow: none;
color: #222f3e;
}
.tox .tox-button--secondary:active:not(:disabled) {
background-color: #d6d6d6;
background-image: none;
border-color: #d6d6d6;
box-shadow: none;
color: #222f3e;
}
</style>
</head>
<body>
<div id="wrap">
<ul id="file_list" class="tox">
<div role="tabpanel" class="tox-dialog__body-content" style="height: 336px; flex-basis: 210px;" aria-labelledby="aria_5965197812761603939544315">
<div class="tox-form">
<div class="tox-form__group">
<label class="tox-label" for="form-field_8471486645261603941857554">链接</label>
<div class="tox-form__controls-h-stack">
<div class="tox-control-wrap">
<input type="url" aria-errormessage="aria-invalid_348682591591603941621447" role="combobox" aria-autocomplete="list" aria-haspopup="true" tabindex="-1" data-alloy-tabstop="true" class="tox-textfield" aria-expanded="false" id="upFileUrlID">
</div>
</div>
</div>
<div class="tox-form__group">
<label class="tox-label" for="form-field_2497330145271603941857555">显示文字</label>
<input type="text" tabindex="-1" data-alloy-tabstop="true" class="tox-textfield" id="upFileTextID">
</div>
<div style="height: 10px;"></div>
<div class="tox-form__group tox-form__group--stretched">
<div class="tox-dropzone-container">
<div class="tox-dropzone">
<p style="margin: 10px auto;color:rgba(34,47,62,.7)">拖放一张文件至此</p>
<button id="upfileID" type="button" onclick="getFile()" data-alloy-tabstop="true" tabindex="-1" class="tox-button tox-button--secondary" style="position: relative; min-height: 30px; overflow: visible;">浏览文件<input type="file" accept="image/*" style="display: none;"></button>
<input id="upfileNameID" style="margin: 5px auto;font-size: 12px; color:rgba(34,47,62,.7); width: 300px; text-align: center;" type="text" value="">
</div>
</div>
</div>
</div>
<button title="上传文件" type="button" onclick="sendUpFile()" style="width: 80%;position: absolute;bottom:10px;left: 43px; margin: 0 auto;letter-spacing: 2px; display: block;" class="tox-button"><svg width="24" height="24" style="margin-top:5px;" ><path fill="#fff" d="M19 4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-4v-2h4V8H5v10h4v2H5a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h14zm-8 9.4l-2.3 2.3a1 1 0 1 1-1.4-1.4l4-4a1 1 0 0 1 1.4 0l4 4a1 1 0 0 1-1.4 1.4L13 13.4V20a1 1 0 0 1-2 0v-6.6z" fill-rule="nonzero"></path></svg><span style="top:-6px; position: relative; margin-left:5px;">开始上传</span></button>
</div>
</ul>
</div>
<script>
var editor=parent.upfile.tinymce.activeEditor;
var upfile=parent.upfile;
var upload_handler = upfile.file_callback;
typeof upload_handler == 'function'?'': editor
var upfileData = ""
var upfileUrl = null
function addFile(file){
upfileData = file[0];
document.getElementById('upfileNameID').value=file[0].name;
}
let inputUrl = document.getElementById('upFileUrlID');
let inputText = document.getElementById('upFileTextID');
function sendUpFile(){
upload_handler(upfileData,function(url,_obj){
inputUrl.value = url;
inputText.value ?'': inputText.value = url;
_obj&&_obj.text?inputText.value=_obj.text:'';
upfile.res.url = upfileUrl = url;
upfile.res.text = inputText.value;
})
}
inputUrl.oninput = function(){upfile.res.url = inputUrl.value; upfileUrl=== null?inputText.value=inputUrl.value:'' }
inputText.oninput = function(){upfile.res.text=inputText.value;upfileUrl="123";}
//拖拽添加
document.addEventListener('dragover', function(e){
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
});
document.addEventListener('drop', function(e){
e.stopPropagation();
e.preventDefault();
if(!e.dataTransfer.files){return false;}
var dropfiles = e.dataTransfer.files;
if(!(dropfiles.length>0)){return false;}
addFile(dropfiles);
});
var global$1 = upfile.tinymce.util.Tools.resolve('tinymce.util.Promise');var global$2 = upfile.tinymce.util.Tools.resolve('tinymce.Env');var global$3 = upfile.tinymce.util.Tools.resolve('tinymce.util.Delay');
var pickFile=function(a){return new global$1(function(e){var c=document.createElement("input");c.type="file";c.style.position="fixed";c.style.left="0";c.style.top="0";c.style.opacity="0.001";document.body.appendChild(c);var b=function(f){e(Array.prototype.slice.call(f.target.files))};c.addEventListener("change",b);var d=function(g){var f=function(){e([]);c.parentNode.removeChild(c)};if(global$2.os.isAndroid()&&g.type!=="remove"){global$3.setEditorTimeout(a,f,0)}else{f()}a.off("focusin remove",d)};a.on("focusin remove",d);c.click()})};
function getFile(){
pickFile(editor).then(function (files){
addFile(files);
})
}
</script>
</body>
</html>
`
},
buttons: [
{
type: 'cancel',
text: 'Close'
},
{
type: 'custom',
text: 'Save',
name: 'save',
primary: true
},
],
onAction: function (api, details) {
switch (details.name) {
case 'save':
var res = upfile.res;
var html = '<span class="attachment" contenteditable="false"><a href="'+res.url+'" target="_blank" title="'+res.text+'" >'+res.text+'<a></span>';
editor.insertContent(html);
upfile.res={};
api.close();
break;
default:
break;
}
}
});
};
editor.ui.registry.getAll().icons.upfile || editor.ui.registry.addIcon('upfile','<svg t="1603858123045" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2812" width="24" height="24"><path fill-rule="evenodd" fill="#000" d="M909 897H115a50 50 0 0 1-50-50V177a50 50 0 0 1 50-50h370a50 50 0 0 1 50 50v62a10 10 0 0 0 10 10h241a50 50 0 0 1 50 50v58h73a50 50 0 0 1 50 50v440a50 50 0 0 1-50 50zM505 309a30 30 0 0 1-30-30v-72a20 20 0 0 0-20-20H145a20 20 0 0 0-20 20v610c0 11.046 9.377 20 20.422 20H209a20 20 0 0 0 20-20V407a50 50 0 0 1 50-50h497v-28a20 20 0 0 0-20-20H535m364 128a20 20 0 0 0-20-20H309a20 20 0 0 0-20 20v400h590a20 20 0 0 0 20-20V437zM650.659 615.8l-26.618-26.53V737a30 30 0 0 1-30 30h-0.113a30 30 0 0 1-30-30V589.275L537.309 615.8a30.006 30.006 0 0 1-42.509-42.36l77.928-77.669a30.127 30.127 0 0 1 42.506 0l77.929 77.669a30.007 30.007 0 0 1-42.504 42.36z" p-id="2813"></path></svg>');
editor.ui.registry.addButton('upfile', {
icon: 'upfile',
tooltip: pluginName,
onAction: function() {
openDialog()
let fv_doc = document.querySelector('iframe[srcdoc]').style.height = '360px';
}
});
editor.ui.registry.addMenuItem('upfile', {
icon: 'upfileicon',
text: '图片上传...',
onAction: function() {
openDialog()
document.querySelector('iframe[srcdoc]').style.height = '360px'
}
});
return {
getMetadata: function() {
return {
name: pluginName,
url: "https://github.com/Five-great/tinymce-plugins",
};
}
};
});