/**
*
* 项目核心Js类,负责项目前端模板方面的初始化等操作
*
* @author yadong.zhang (yadong.zhang0415(a)gmail.com)
* @website https://docs.zhyd.me
* @version 1.0
* @date 2018-04-25
* @since 1.0
*/
var editor = null, simplemde = null;
var zhyd = window.zhyd || {
combox: {
init: function (mockComboxCallback) {
$('select[target=combox]').each(function (e) {
var $this = $(this);
var url = $this.data("url");
if (!url) {
return false;
}
var method = $this.data("method") || "get";
$.ajax({
url: url,
type: method,
success: function (json) {
if (json && json.status == 200) {
var optionTpl = '{{#data}}{{#nodes}}{{/nodes}}{{/data}}';
var html = Mustache.render(optionTpl, json);
$this.html(html);
}
}
});
});
$('ul[target=combox], ol[target=combox]').each(function (e) {
var $this = $(this);
var url = $this.data("url");
if (!url) {
return false;
}
var method = $this.data("method") || "get";
$.ajax({
url: url,
type: method,
success: function (json) {
if (json && json.status == 200) {
var liTpl = '{{#data}}
{{name}}{{/data}}';
var html = Mustache.render(liTpl, json);
$this.html(html);
if ($.isFunction(mockComboxCallback)) {
mockComboxCallback();
}
}
}
});
})
}
},
tagsInput: {
init: function () {
setTimeout(function () {
$('select[target="tagsinput"], input[target="tagsinput"]').each(function () {
var $this = $(this);
var $bindBox = $this.data("bind-box");
if (!$bindBox || $bindBox.length <= 0) {
return;
}
$this.tagsinput({
itemValue: 'id',
itemText: 'name',
maxTags: 3,
maxChars: 20,
trimValue: true,
focusClass: 'focus'
});
function add() {
var thisId = $(this).data("value");
var thisText = $(this).text().trim();
console.log(thisText);
$this.tagsinput('add', {"id": thisId, "name": thisText}, {add: false});
}
$($bindBox).find("li").each(function () {
var $li = $(this);
$li.bind('click', add);
});
$(".bootstrap-tagsinput input").bind('keydown', function (event) {
var thisVal = $(this).val();
if (event.key == 'Enter' || event.keyCode == '13') {
$.post('/tag/add', {name: thisVal, description: thisVal}, function (response) {
if (response.status !== 200) {
$.alert.error(response.message);
} else {
var data = response.data;
$this.tagsinput('add', {"id": data.id, "name": data.name}, {addNew: true});
}
});
}
});
$this.on('itemAdded', function (event) {
var tag = event.item;
if (event.options && event.options.addNew) {
$(".bootstrap-tagsinput input").val('');
$('' + tag.name + '').bind('click', add).appendTo($($bindBox));
}
});
})
}, 700);
}
},
initTextSlider: function () {
$.fn.textSlider = function (settings) {
settings = jQuery.extend({
speed: "normal",
line: 2,
timer: 3000
}, settings);
return this.each(function () {
$.fn.textSlider.scllor($(this), settings);
});
};
$.fn.textSlider.scllor = function ($this, settings) {
var ul = $("ul:eq(0)", $this);
var timerID;
var li = ul.children();
var liHight = $(li[0]).height();
var upHeight = 0 - settings.line * liHight;//滚动的高度;
var scrollUp = function () {
ul.animate({marginTop: upHeight}, settings.speed, function () {
for (i = 0; i < settings.line; i++) {
ul.find("li:first", $this).appendTo(ul);
}
ul.css({marginTop: 0});
});
};
var autoPlay = function () {
timerID = window.setInterval(scrollUp, settings.timer);
};
var autoStop = function () {
window.clearInterval(timerID);
};
//事件绑定
ul.hover(autoStop, autoPlay).mouseout();
};
if ($("#scrolldiv")) {
$("#scrolldiv").textSlider({line: 1, speed: 300, timer: 10000});
}
},
wangEditor: {
_instance: window.wangEditor,
defaultConfig: {
container: "#editor",
textareaName: "content",
uploadUrl: "",
uploadFileName: "file",
uploadType: "",
customCss: {}
},
init: function (options) {
var config = $.extend(zhyd.wangEditor.defaultConfig, options);
var E = window.wangEditor;
editor = new E(config.container);
// 配置编辑器 start
// 关闭粘贴样式的过滤
editor.config.pasteFilterStyle = false;
editor.config.zIndex = 100;
editor.config.withCredentials = true;
if (config.textareaName) {
$('').insertAfter($(config.container));
}
var $contentBox = $('textarea[name=' + config.textareaName + ']');
editor.config.onchange = function (html) {
// 监控变化,同步更新到 textarea
$contentBox.val(html);
};
// 注册上传文件插件
zhyd.wangEditor.plugins.registerUpload(editor, config.uploadUrl, config.uploadFileName, config.uploadType, function (result, curEditor) {
// 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
// insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果
if (result.status == 200) {
var imgFullPath = result.data;
curEditor.txt.append('');
// 解决上传完图片如果未进行其他操作,则不会触发编辑器的“change”事件,导致实际文章内容中缺少最后上传的图片文件 2018-07-13
$contentBox.val(editor.txt.html());
} else {
$.alert.error(result.message);
}
});
// 配置编辑器 end
editor.create();
// 注册全屏插件
// 注册图片资源库
zhyd.wangEditor.plugins.registerMaterial(editor, $contentBox);
if (config.customCss) {
// 自定义编辑器的样式
for (var key in config.customCss) {
var value = config.customCss[key];
editor.$textContainerElem.css(key, value);
}
}
},
plugins: {
registerUpload: function (editor, uploadUrl, uploadFileName, uploadType, callback) {
if (uploadUrl) {
// 上传图片到服务器
editor.config.uploadImgServer = uploadUrl;
editor.config.uploadFileName = uploadFileName;
// 将图片大小限制为 50M
editor.config.uploadImgMaxSize = 50 * 1024 * 1024;
// 超时时间
editor.config.uploadImgTimeout = 10000;
// 自定义上传参数
editor.config.uploadImgParams = {
// 如果版本 <=v3.1.0 ,属性值会自动进行 encode ,此处无需 encode
// 如果版本 >=v3.1.1 ,属性值不会自动 encode ,如有需要自己手动 encode
uploadType: uploadType
};
editor.config.customAlert = function (msg) {
$.alert.error(msg);
};
editor.config.uploadImgHooks = {
error: function (xhr, editor) {
$.alert.error("图片上传出错");
},
timeout: function (xhr, editor) {
$.alert.error("请求超时");
},
customInsert: function (insertImg, result, editor) {
if (callback) {
callback(result, editor);
} else {
console.log('upload callback:' + insertImg, result, editor);
}
}
};
}
},
registerMaterial: function (editor, $contentBox) {
$("div[id^='w-e-img']").unbind("click").click(function () {
setTimeout(function () {
// 删掉原来的input#file,防止触发原选中文件的函数
$(".w-e-up-img-container").find("input").remove();
// 重新绑定选中图片按钮的事件
$("div[id^='up-trigger'], div.w-e-up-btn").unbind("click").click(function () {
$.modal.material.open({multiSelect: true, selectable: 10}, function (selectedImageUrls) {
if(!selectedImageUrls) {
return false;
}
for(var i = 0; i < selectedImageUrls.length; i ++){
editor.txt.append('');
$contentBox.val(editor.txt.html());
}
})
})
}, 50);
})
}
}
},
simpleMDE: {
defaultConfig: {
id: "mdEditor",
uploadUrl: "",
uploadType: "",
uniqueId: "mdEditor_1"
},
init: function (options) {
var $op = $.extend(zhyd.wangEditor.defaultConfig, options);
zhyd.simpleMDE.plugins.registerAutosave();
// Powered by https://github.com/sparksuite/simplemde-markdown-editor
simplemde = new SimpleMDE({
// textarea的DOM对象
element: document.getElementById($op.id),
// 自动下载FontAwesome,设为false为不下载(如果设为false则必须手动引入)
autoDownloadFontAwesome: false,
// 自动聚焦输入框
autofocus: true,
// 是否自动保存正在编写的文本
autosave: {
// 启用自动保存功能
enabled: true,
// 自动保存的间隔,以毫秒为单位。默认为15000(15s)
delay: 15000,
// 唯一的字符串标识符(保证每个SimpleMDE编辑器的uniqueId唯一)
uniqueId: $op.uniqueId,
msg: "自动保存成功了"
},
placeholder: "请输入文本内容",
// 如果设置为true,则会出现JS警报窗口,询问链接或图像URL(插入图片或链接弹窗)。默认为false
promptURLs: false,
renderingConfig: {
// 如果设置为true,将使用highlight.js高亮显示。默认为false
codeSyntaxHighlighting: true
},
showIcons: ["code", "table", "clean-block", "horizontal-rule"],
tabSize: 4,
status: false
});
zhyd.simpleMDE.plugins.registerFullscreen();
zhyd.simpleMDE.plugins.registerUpload($op.uploadUrl, simplemde);
zhyd.simpleMDE.plugins.registerMaterial();
$(".editor-preview-side").addClass("markdown-body");
},
plugins: {
registerAutosave: function () {
// js实现aop切面编程,实时保存文章内容
Function.prototype.after = function (afterfn) {
var __self = this;
//保存原函数的引用
return function () {
//返回包含了原函数和新函数的"代理"函数
afterfn.apply(this, arguments);//(1)
//执行新函数,且保证this不被劫持,新函数接受的参数
//也会被原封不动地传入原函数,新函数在原函数之前执行
return __self.apply(this, arguments);//(2)
//执行原函数并返回原函数的执行结果
//并且保证this不被劫持
}
};
var showMsg = function () {
var $div = $('');
$div.css({
'position': 'absolute',
'right': '10px',
'top': 0,
'padding': '5px',
'font-size': '12px',
'color': '#ccc',
'opacity': 0
});
$div.html("自动保存完成");
$div.appendTo($(".CodeMirror"));
$div.animate({opacity: 1}, 1000, function () {
$div.animate({opacity: 0}, 1000, function () {
$(this).remove();
})
})
};
SimpleMDE.prototype.autosave = SimpleMDE.prototype.autosave.after(showMsg);
},
registerFullscreen: function () {
var $fullscreen = $(".editor-toolbar a.fa-arrows-alt, .editor-toolbar a.fa-columns");
$fullscreen.click(function () {
var $this = $(this);
if ($fullscreen.hasClass("active")) {
$(".CodeMirror, .CodeMirror-scroll").css('max-height', 'none');
} else {
$(".CodeMirror, .CodeMirror-scroll").css('max-height', '200px');
}
});
},
registerUpload: function (uploadUrl, simplemde) {
if (uploadUrl) {
inlineAttachment.editors.codemirror4.attach(simplemde.codemirror, {
uploadUrl: uploadUrl
});
}
},
registerMaterial: function () {
function getState(cm, pos) {
pos = pos || cm.getCursor("start");
var stat = cm.getTokenAt(pos);
if(!stat.type) return {};
var types = stat.type.split(" ");
var ret = {},
data, text;
for(var i = 0; i < types.length; i++) {
data = types[i];
if(data === "strong") {
ret.bold = true;
} else if(data === "variable-2") {
text = cm.getLine(pos.line);
if(/^\s*\d+\.\s/.test(text)) {
ret["ordered-list"] = true;
} else {
ret["unordered-list"] = true;
}
} else if(data === "atom") {
ret.quote = true;
} else if(data === "em") {
ret.italic = true;
} else if(data === "quote") {
ret.quote = true;
} else if(data === "strikethrough") {
ret.strikethrough = true;
} else if(data === "comment") {
ret.code = true;
} else if(data === "link") {
ret.link = true;
} else if(data === "tag") {
ret.image = true;
} else if(data.match(/^header(\-[1-6])?$/)) {
ret[data.replace("header", "heading")] = true;
}
}
return ret;
}
function insertHtml(imgUrl){
var cm = simplemde.codemirror;
var state = getState(cm);
var options = simplemde.options;
if(/editor-preview-active/.test(cm.getWrapperElement().lastChild.className))
return;
var text;
var start = options.insertTexts.image[0];
var end = options.insertTexts.image[1];
var startPoint = cm.getCursor("start");
var endPoint = cm.getCursor("end");
if(imgUrl) {
end = end.replace("#url#", imgUrl);
}
if(state.image) {
text = cm.getLine(startPoint.line);
start = text.slice(0, startPoint.ch);
end = text.slice(startPoint.ch);
cm.replaceRange(start + end, {
line: startPoint.line,
ch: 0
});
} else {
text = cm.getSelection();
var img = start + text + end;
cm.replaceSelection(img);
startPoint.ch += img.length;
if(startPoint !== endPoint) {
endPoint.ch += img.length;
}
}
cm.setSelection(startPoint, endPoint);
cm.focus();
}
try {
var insertImage = document.getElementsByClassName("editor-toolbar")[0].getElementsByTagName("a")[9];
insertImage.onclick = function (ev) {
$.modal.material.open({multiSelect: true, selectable: 10}, function (selectedImageUrls) {
if(!selectedImageUrls) {
return false;
}
for(var i = 0; i < selectedImageUrls.length; i ++){
insertHtml(selectedImageUrls[i]);
}
})
}
} catch (e) {
console.error(e);
}
}
}
},
tinymce: {
defaultConfig: {
selector: "tinymceEditor",
uploadUrl: "",
uploadFileName: "file",
textareaName: "content",
},
init: function (options) {
var $op = $.extend(zhyd.tinymce.defaultConfig, options);
if ($op.textareaName) {
$('').insertAfter($($op.selector));
}
var $contentBox = $('textarea[name=' + $op.textareaName + ']');
tinymce.init({
selector: $op.selector,
toolbar_mode: 'floating',
// width: 600,
height: 500,
plugins: [
'powerpaste advlist autolink link image lists charmap print preview hr anchor pagebreak',
'searchreplace wordcount visualblocks visualchars code fullscreen insertdatetime media nonbreaking',
'table emoticons template paste help'
],
menubar: 'file edit view insert format tools table',
toolbar: 'undo redo | styleselect | code | bold italic | alignleft aligncenter alignright alignjustify | ' +
'bullist numlist outdent indent | link image | preview media fullscreen | ' +
'forecolor backcolor emoticons | help',
content_langs: [
{ title: 'English', code: 'en' },
{ title: 'Chinese', code: 'zh' }
],
// language: 'zh_CN',
// directionality: 'rtl',
custom_undo_redo_levels: 10,
images_upload_url: $op.uploadUrl,
images_upload_credentials: true,
automatic_uploads: false,
images_upload_handler: example_image_upload_handler,
init_instance_callback: function(editor) {
editor.on('SetContent', function(e) {
$contentBox.val(zhyd.tinymce.getHtml())
});
editor.on('Change', function(e) {
$contentBox.val(zhyd.tinymce.getHtml())
});
}
});
function example_image_upload_handler (blobInfo, success, failure, progress) {
var xhr, formData;
xhr = new XMLHttpRequest();
xhr.withCredentials = false;
xhr.open('POST', $op.uploadUrl);
xhr.upload.onprogress = function (e) {
progress(e.loaded / e.total * 100);
};
xhr.onload = function() {
var json;
if (xhr.status === 403) {
failure('HTTP Error: ' + xhr.status, { remove: true });
return;
}
if (xhr.status < 200 || xhr.status >= 300) {
failure('HTTP Error: ' + xhr.status);
return;
}
json = JSON.parse(xhr.responseText);
if (!json || typeof json.data != 'string') {
failure('Invalid JSON: ' + xhr.responseText);
return;
}
success(json.data);
};
xhr.onerror = function () {
failure('Image upload failed due to a XHR Transport error. Code: ' + xhr.status);
};
formData = new FormData();
formData.append($op.uploadFileName, blobInfo.blob(), blobInfo.filename());
xhr.send(formData);
}
},
getHtml: function () {
// 只有一个编辑器
return tinymce.activeEditor.getContent();
// 多个编辑器
// return tinymce.editors[0].getContent();
// 不带HTML标记的纯文本内容
// var activeEditor = tinymce.activeEditor;
// var editBody = activeEditor.getBody();
// activeEditor.selection.select(editBody);
// var text = activeEditor.selection.getContent( {'format' : 'text' });
},
setHtml: function (html) {
// 只有一个编辑器
return tinymce.activeEditor.setContent(html);
// 多个编辑器
// return tinymce.editors[0].setContent(html);
}
},
mask: {
_box: '',
_icon: {
load: "fa fa-spinner fa-spin",
lock: "fa fa-lock"
},
_open: function (container, msg, type) {
var html = Mustache.render(this._box, {icon: this._icon[type], text: msg, maskType: type});
$(container).append(html);
},
closeAll: function (container) {
$(container).find("div.mask.load, div.mask.lock").remove();
},
init: function () {
console.log("init mask...");
$(".loading").each(function () {
var $this = $(this);
if (!$this.hasClass("locking")) {
zhyd.mask.loading($this, $this.data("mask"));
}
});
$(".locking").each(function () {
var $this = $(this);
zhyd.mask.locking($this, $this.data("mask"));
});
},
loading: function (container, msg) {
this._open(container, msg || "Loading", "load");
},
locking: function (container, msg) {
this._open(container, msg || "Locking", "lock");
},
closeLoading: function (container) {
$(container).find("div.mask.load").remove();
},
closeLocking: function (container) {
$(container).find("div.mask.lock").remove();
}
}
};
$(document).ready(function () {
zhyd.initTextSlider();
$("img.lazy-img").lazyload({
placeholder: appConfig.staticPath + "/img/loading.gif",
effect: "fadeIn",
threshold: 100
});
$(window).bind("load", function () {
var timeout = setTimeout(function () {
$("img.lazy-img").trigger("sporty");
}, 3000);
});
/**
* 图片预览
* 必须指定预览图片的容器,格式:data-preview-container = "#containerID"
*/
$(".uploadPreview").each(function () {
var $this = $(this);
$this.uploadPreview({imgContainer: $this.data("preview-container")});
});
$("#updPassBtn").click(function () {
var $form = $("#updPassForm");
if (validator.checkAll($form)) {
$form.ajaxSubmit({
type: "POST",
url: '/passport/updatePwd',
success: function (json) {
$.alert.ajaxSuccess(json);
if (json.status == 200) {
setTimeout(function () {
window.location.reload();
}, 2000);
}
},
error: $.alert.ajaxError
});
}
});
zhyd.combox.init(zhyd.tagsInput.init);
zhyd.mask.init();
/**
* 针对shiro框架中, ajax请求时session过期后的页面跳转
*/
$.ajaxSetup({
complete: function (XMLHttpRequest, textStatus) {
if (textStatus === "parsererror") {
$.alert.error("会话已失效!请重新登录!", function () {
window.location.reload();
});
} else if (textStatus === "error") {
$.alert.error("请求超时,请稍后再试!");
}
}
});
var notice = [
'Hi Boy! 前台首页的 “轮播”只会显示“推荐文章”哦',
'要想百度搜索引擎快速收录文章,可以试试“推送”功能哦',
'批量推送文章到百度可以一次提交多篇文章哦',
'碰到页面显示和数据库内容不一致的情况,可以先考虑清下redis缓存哦',
'不可以随便用“文章搬运工”去爬取别人未授权的文章哈',
'使用过程中如果有不能解决的问题,请去提issue哈,在群里消息太多,有时候会看不到消息记录',
'可以通过右上角“系统配置”-“文章编辑器”选择默认的文章发布编辑器'
];
var $noticeBox = $("#notice-box");
var tpl = '{{#data}}'
+ '{{&.}}'
+ '{{/data}}';
var html = Mustache.render(tpl, {"data": $.tool.shuffle(notice)});
$noticeBox.html(html);
/**
* 切换编辑器
*/
$(".changeEditor").click(function () {
var $this = $(this);
$.alert.confirm("确定要切换编辑器吗?切换后本页内容将可能会丢失?", function () {
window.location.href = $this.data("href");
})
})
});