|
|
var aceeditor='';
|
|
|
var ke_edit_h = 0;
|
|
|
var ke_edit_w = 0;
|
|
|
var isfullscreen=false;
|
|
|
KindEditor.plugin('ace', function(K) {
|
|
|
var editor = this, name = 'ace',clickcount=0;
|
|
|
//单击按钮, clickcount=0显示ace编辑器,clickcount=1隐藏ace编辑器
|
|
|
editor.clickToolbar(name, function(){
|
|
|
if (clickcount==0) {
|
|
|
var need_clear=false;
|
|
|
if (editor.html()=='') {
|
|
|
need_clear=true;
|
|
|
};
|
|
|
//在文字视图中选中的内容
|
|
|
var selectedHtml=editor.selectedHtml();
|
|
|
var isnoselection=false;
|
|
|
if (!selectedHtml) {
|
|
|
editor.insertHtml('<!--wozhedoushiweiledingweia-->');
|
|
|
selectedHtml='<!--wozhedoushiweiledingweia-->';
|
|
|
isnoselection=true;
|
|
|
};
|
|
|
//判断ace编辑器是否已存在,不存在则重新初始化
|
|
|
if($("#ace-editor").length==0) {
|
|
|
showace();
|
|
|
}
|
|
|
//根据全屏与否设置调试信息容器位置
|
|
|
fullscreen_set();
|
|
|
//设置ace编辑器内容及其样式
|
|
|
if (need_clear) {
|
|
|
aceeditor.setValue('');
|
|
|
}else{
|
|
|
aceeditor.setValue(editor.html());
|
|
|
}
|
|
|
|
|
|
if (!isnoselection) {
|
|
|
//判断是否图片、图片的话用图片路径判断
|
|
|
if (selectedHtml.match(/<img(.*)>/g)) {
|
|
|
var ispicture=selectedHtml.match(/src="([^">]+)/g);
|
|
|
selectedHtml=ispicture[0];
|
|
|
};
|
|
|
|
|
|
//选择多段落时分开搜索
|
|
|
selectedHtml=selectedHtml.replace(/<\/ul>/g,'');
|
|
|
selectedHtml=selectedHtml.replace(/<ul.*?>/ig,'');
|
|
|
selectedHtml=selectedHtml.replace(/<\/li>/g,'<p>');
|
|
|
selectedHtml=selectedHtml.replace(/<li.*?>/ig,'');
|
|
|
|
|
|
selectedHtml=selectedHtml.replace(/<\/h.*?>/g,'<p>');
|
|
|
selectedHtml=selectedHtml.replace(/<h.*?>/ig,'');
|
|
|
selectedHtml=selectedHtml.replace(/ data-ke-src=\".*?\"/ig,'');
|
|
|
selectedHtml=selectedHtml.replace(/&/ig,'&');
|
|
|
|
|
|
selectedHtml=selectedHtml.replace(/<p.*?>/g,'<p>');
|
|
|
var duanluo=selectedHtml.split('<p>');
|
|
|
setTimeout(function(){
|
|
|
for (var i =0;i<duanluo.length; i++) {
|
|
|
duanluo[i]=duanluo[i].replace(/<\/p>/,'');
|
|
|
if (duanluo[i]!='') {
|
|
|
selectedHtml=duanluo[i];
|
|
|
dingwei(selectedHtml,false);
|
|
|
};
|
|
|
};
|
|
|
},100);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
setTimeout(dingwei(selectedHtml,true),100);
|
|
|
}
|
|
|
|
|
|
$(".ke-toolbar>span").addClass("ke-disabled").css({"opacity":"0.5"});
|
|
|
$(".ke-icon-ace").parent("span").removeClass("ke-disabled").css({"opacity":"1.0"});
|
|
|
$(".ke-statusbar").hide();
|
|
|
$("#tecate-errors").show();
|
|
|
clickcount=1;
|
|
|
}else{
|
|
|
//aceeditor.insert('<em id="conghtmldingweidaoshejishitu"></em>');
|
|
|
editor.html(aceeditor.getValue());
|
|
|
//var $dingweiyuansu=$("iframe.ke-edit-iframe").contents().find("#conghtmldingweidaoshejishitu");
|
|
|
//$("iframe.ke-edit-iframe").contents().find(".ke-content").scrollTop($dingweiyuansu.offset().top-200);
|
|
|
//$dingweiyuansu.remove();
|
|
|
|
|
|
$("#ace-editor,#tecate-errors").hide();
|
|
|
$(".ke-toolbar>span").removeClass("ke-disabled").css({"opacity":"1.0"});
|
|
|
$(".ke-statusbar").show();
|
|
|
if(is_fullscreen()==false)$(".ke-edit").css({"height":ke_edit_h-100});
|
|
|
clickcount=0;
|
|
|
}
|
|
|
//实时同步内容、并检测html完整性
|
|
|
aceeditor.getSession().on('change', function(e) {
|
|
|
editor.html(aceeditor.getValue());
|
|
|
//validatehtml(aceeditor.getValue());
|
|
|
});
|
|
|
aceeditor.getSession().setUseWrapMode(true);
|
|
|
});
|
|
|
});
|
|
|
//查找指定内容
|
|
|
function dingwei(selectedHtml,isnoselection)
|
|
|
{
|
|
|
var range=aceeditor.find(selectedHtml, {
|
|
|
skipCurrent: true,
|
|
|
backwards: false,
|
|
|
wrap: true,
|
|
|
regExp: false,
|
|
|
caseSensitive: false,
|
|
|
wholeWord: false
|
|
|
});
|
|
|
if (range) {
|
|
|
var haha=range.toString();
|
|
|
var start=haha.indexOf('[');
|
|
|
var end=haha.indexOf(']');
|
|
|
haha=haha.substr((start+1));
|
|
|
var linenum=haha.split('/')[0];
|
|
|
aceeditor.gotoLine(++linenum);
|
|
|
aceeditor.session.highlight(aceeditor.$search.$options.re);
|
|
|
isnoselection==true && aceeditor.replace('',selectedHtml);
|
|
|
aceeditor.addSelectionMarker(range);
|
|
|
setTimeout(function(){
|
|
|
aceeditor.removeSelectionMarker(range);
|
|
|
},1800);
|
|
|
};
|
|
|
}
|
|
|
|
|
|
//ace编辑器初始化
|
|
|
function showace()
|
|
|
{
|
|
|
var ace_style ='margin:0;position:absolute;top:0;left:0;';
|
|
|
$(".ke-edit-iframe").after('<div id="ace-editor" style="'+ace_style+'"></div>');
|
|
|
$(".ke-edit").css({"position":"relative"});
|
|
|
aceeditor = ace.edit("ace-editor");
|
|
|
aceeditor.setTheme("ace/theme/dreamweaver");
|
|
|
aceeditor.getSession().setMode("ace/mode/html");
|
|
|
$("<div id='tecate-errors'></div>").appendTo(".ke-edit");
|
|
|
}
|
|
|
//根据全屏与否设置调试信息容器位置
|
|
|
function fullscreen_set()
|
|
|
{
|
|
|
ke_edit_h = $(".ke-edit-iframe").height();
|
|
|
ke_edit_w = $(".ke-edit-iframe").width();
|
|
|
if(is_fullscreen()){
|
|
|
ke_edit_h=ke_edit_h-90;
|
|
|
$("#ace-editor").css({"width":ke_edit_w,"height":ke_edit_h,"display":"block"});
|
|
|
$("#tecate-errors").css({height:"50px"});
|
|
|
}else{
|
|
|
$("#ace-editor").css({"width":ke_edit_w,"height":ke_edit_h,"display":"block"});
|
|
|
$(".ke-edit").css({"height":ke_edit_h=ke_edit_h+80});
|
|
|
$("#tecate-errors").css({height:"40px"});
|
|
|
}
|
|
|
$("#tecate-errors").css({
|
|
|
position:"absolute",
|
|
|
bottom:0,
|
|
|
left:0,
|
|
|
width:"100%",
|
|
|
padding: "10px 0px",
|
|
|
"border-top":"10px solid #e8e8e8",
|
|
|
"border-bottom":"10px solid #e8e8e8",
|
|
|
backgroundColor: '#f2dede',
|
|
|
color: '#b94a48',
|
|
|
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
|
|
|
fontSize: '14px',
|
|
|
"overflow-y": "scroll"
|
|
|
});
|
|
|
}
|
|
|
//html完整性检测
|
|
|
function validatehtml(htmldata)
|
|
|
{
|
|
|
$('#tecate-errors').html('');
|
|
|
Tecate.getPageSource(Tecate.evaluateHTML,htmldata);
|
|
|
}
|
|
|
|
|
|
function is_fullscreen(){
|
|
|
if($("div.ke-container").css("position")=="absolute"){
|
|
|
return true;
|
|
|
}else{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//html完整性检测具体过程
|
|
|
var Tecate = Tecate || {};
|
|
|
//可用的html元素
|
|
|
Tecate.validHTMLElements = [ "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", "b", "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br", "button", "canvas", "caption", "center", "cite", "code", "colgroup", "del", "details", "dfn", "dir", "div", "dl", "!doctype", "dt","dd", "em", "embed", "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", "i", "iframe", "img", "input", "ins", "kbd", "keygen", "label", "legend", "li", "link", "listing", "map", "mark", "marquee", "menu", "meta", "meter", "nav", "noscript", "object", "ol", "optgroup", "option", "output", "p", "param", "plaintext", "pre", "progress", "q", "ruby", "s", "samp", "script", "section", "select", "small", "source", "span", "strike", "strong", "style", "sub", "summary", "sup", "table", "tbody", "td", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", "u", "ul", "var", "video", "wbr", "xmp" ];
|
|
|
|
|
|
Tecate.missingClosingBracket = {
|
|
|
'regex': new RegExp("(<[^>]+<)", "g"),
|
|
|
'message': "Opening bracket with no closing bracket"
|
|
|
},
|
|
|
Tecate.invalidHTMLElement = {
|
|
|
'regex': new RegExp("(<(?!/\?" + Tecate.validHTMLElements.join("\\b|/\?") + "\\b)[^ \n>]+)", "gi"),
|
|
|
'message': "Opening HTML tag without a valid element name"
|
|
|
},
|
|
|
Tecate.missingEquals = {
|
|
|
'regex': new RegExp("(<[^=>]+['\"]\\S+['\"]([^>]*>)?)", "g"),
|
|
|
'message': "Missing equals sign for attribute"
|
|
|
},
|
|
|
Tecate.missingQuoteAfterEquals = {
|
|
|
'regex': new RegExp("( [^\"']+=[^'\"]+['\"])[ >]", "g"),
|
|
|
'message': "Missing quote after equals sign for attribute"
|
|
|
},
|
|
|
Tecate.missingQuoteAtEndOfAttribute = {
|
|
|
'regex': new RegExp("(\\S+=['\"][^'\">]+(>|['\"][^ />]))", "g"),
|
|
|
'message': "Missing quote at the end of the attribute"
|
|
|
};
|
|
|
|
|
|
Tecate.errors = [
|
|
|
Tecate.missingQuoteAtEndOfAttribute,
|
|
|
Tecate.missingQuoteAfterEquals,
|
|
|
Tecate.missingClosingBracket,
|
|
|
Tecate.missingEquals,
|
|
|
Tecate.invalidHTMLElement
|
|
|
];
|
|
|
|
|
|
Tecate.getPageSource = function(callback,htmldata) {
|
|
|
return callback(htmldata);
|
|
|
};
|
|
|
|
|
|
Tecate.insertErrorDiv = function() {
|
|
|
var list = $("<ul id='tecate-errors-list'></ul>").css({
|
|
|
padding: "0 10px",
|
|
|
backgroundColor: '#f2dede',
|
|
|
margin: 0
|
|
|
});
|
|
|
$('#tecate-errors').html(list);
|
|
|
};
|
|
|
|
|
|
Tecate.htmlEscapes = {
|
|
|
'&': '&',
|
|
|
'<': '<',
|
|
|
'>': '>',
|
|
|
'"': '"',
|
|
|
"'": ''',
|
|
|
'/': '/'
|
|
|
};
|
|
|
|
|
|
Tecate.htmlEscaper = /[&<>"'\/]/g;
|
|
|
|
|
|
// Escape a string for HTML interpolation.
|
|
|
Tecate.escapeHTML = function(unsafe) {
|
|
|
return ('' + unsafe).replace(Tecate.htmlEscaper, function(match) {
|
|
|
return Tecate.htmlEscapes[match];
|
|
|
});
|
|
|
};
|
|
|
|
|
|
Tecate.appendError = function(error) {
|
|
|
$("#tecate-errors-list").append($("<li>" + error.errorString + ': <code>' + Tecate.escapeHTML(error.error) + '</code> on line ' + error.line + "</li>"));
|
|
|
};
|
|
|
|
|
|
Tecate.showErrors = function(errorsList) {
|
|
|
if (errorsList.length === 0) {
|
|
|
return;
|
|
|
}
|
|
|
Tecate.insertErrorDiv();
|
|
|
for (var i = 0; i < errorsList.length; i++) {
|
|
|
Tecate.appendError(errorsList[i]);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
Tecate.getErrorLines = function(idx, html) {
|
|
|
var lines = html.split('\n');
|
|
|
var count = 0;
|
|
|
for (var i = 0; i < lines.length; i++) {
|
|
|
count = count + lines[i].length;
|
|
|
if (idx <= count) {
|
|
|
return i + 1;
|
|
|
}
|
|
|
}
|
|
|
return lines.length;
|
|
|
};
|
|
|
|
|
|
Tecate.stripComments = function(html) {
|
|
|
return html.replace(/<!--([\s\S]*)--(\s*)>/g, "");
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
* Note, this is dumb - won't get dynamically inserted scripts or anything
|
|
|
*/
|
|
|
Tecate.stripTag = function(html, tagName) {
|
|
|
return html.replace(new RegExp(
|
|
|
"<" + tagName + "[^>]*>([\\s\\S]*)</" + tagName + ">", "g"), "");
|
|
|
};
|
|
|
|
|
|
// XXX this should return the errorsList and delegate to another function to
|
|
|
// render
|
|
|
Tecate.evaluateHTML = function(html) {
|
|
|
var result;
|
|
|
var errorsList = [];
|
|
|
var noScripts = Tecate.stripTag(html, 'script');
|
|
|
var noStyles = Tecate.stripTag(noScripts, 'style');
|
|
|
var commentFreeHtml = Tecate.stripComments(noStyles);
|
|
|
for (var i = 0; i < Tecate.errors.length; i++) {
|
|
|
var error = Tecate.errors[i];
|
|
|
while ((result = error.regex.exec(commentFreeHtml)) !== null) {
|
|
|
errorsList.push({
|
|
|
'errorString': error.message,
|
|
|
'error': result[1],
|
|
|
'line': Tecate.getErrorLines(html.indexOf(result[1]), html),
|
|
|
'html': html
|
|
|
});
|
|
|
}
|
|
|
}
|
|
|
Tecate.showErrors(errorsList);
|
|
|
}; |