Files
assistant-android/app/src/main/assets/rich_editor.js

636 lines
19 KiB
JavaScript

/**
* Copyright (C) 2017 Wasabeef
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// alert("")
var RE = {};
RE.currentSelection = {
"startContainer": 0,
"startOffset": 0,
"endContainer": 0,
"endOffset": 0};
var isDebug = false;
try {
isDebug = window.NativeCallBack.isNativeBuildDebug()
} catch(error) {
}
// 引用远端的JS 和 CSS
var script = document.createElement("script")
document.body.appendChild(script)
if (isDebug) {
script.src = "https://resource.ghzs.com/js/halo_app_test.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000)
} else {
script.src = "https://resource.ghzs.com/js/halo.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
}
var style = document.createElement("link")
style.rel = "stylesheet"
style.type = "text/css"
if (isDebug) {
style.href = "https://resource.ghzs.com/css/halo_app_test.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000)
} else {
style.href = "https://resource.ghzs.com/css/halo.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
}
document.head.appendChild(style)
RE.editor = document.getElementById('editor');
document.addEventListener("selectionchange", function() { RE.backuprange(); });
// Initializations
RE.callback = function() {
window.location.href = "re-callback://" + encodeURIComponent(RE.getHtml());
}
RE.setHtml = function(contents) {
RE.editor.innerHTML = decodeURIComponent(contents.replace(/\+/g, '%20'));
}
// 后续初始化html代码,都用该方法
RE.setHtmlByVideoStatus = function(contents) {
RE.editor.innerHTML = decodeURIComponent(contents.replace(/\+/g, '%20'));
}
// Deprecated
RE.getHtml = function() {
return RE.editor.innerHTML;
}
RE.getText = function() {
return RE.editor.innerText;
}
RE.setBaseTextColor = function(color) {
RE.editor.style.color = color;
}
RE.setBaseFontSize = function(size) {
RE.editor.style.fontSize = size;
}
RE.setPadding = function(left, top, right, bottom) {
RE.editor.style.paddingLeft = left;
RE.editor.style.paddingTop = top;
RE.editor.style.paddingRight = right;
RE.editor.style.paddingBottom = bottom;
}
RE.setBackgroundColor = function(color) {
document.body.style.backgroundColor = color;
}
RE.setBackgroundImage = function(image) {
RE.editor.style.backgroundImage = image;
}
RE.setWidth = function(size) {
RE.editor.style.minWidth = size;
}
RE.setHeight = function(size) {
RE.editor.style.height = size;
}
RE.setTextAlign = function(align) {
RE.editor.style.textAlign = align;
}
RE.setVerticalAlign = function(align) {
RE.editor.style.verticalAlign = align;
}
RE.setPlaceholder = function(placeholder) {
RE.editor.setAttribute("placeholder", placeholder);
}
RE.setEditorFocus = function() {
RE.editor.focus();
}
RE.setInputEnabled = function(inputEnabled) {
RE.editor.contentEditable = String(inputEnabled);
}
RE.formatBlock = function() {
document.execCommand('formatBlock', false, 'p');
}
RE.undo = function() {
document.execCommand('undo', false, null);
}
RE.redo = function() {
document.execCommand('redo', false, null);
}
RE.setBold = function() {
document.execCommand('bold', false, null);
}
RE.setItalic = function() {
document.execCommand('italic', false, null);
}
RE.setSubscript = function() {
document.execCommand('subscript', false, null);
}
RE.setSuperscript = function() {
document.execCommand('superscript', false, null);
}
RE.setStrikeThrough = function() {
document.execCommand('strikeThrough', false, null);
}
RE.setUnderline = function() {
document.execCommand('underline', false, null);
}
RE.setBullets = function() {
document.execCommand('insertUnorderedList', false, null);
}
RE.setNumbers = function() {
document.execCommand('insertOrderedList', false, null);
}
RE.setTextColor = function(color) {
RE.restorerange();
document.execCommand("styleWithCSS", null, true);
document.execCommand('foreColor', false, color);
document.execCommand("styleWithCSS", null, false);
}
RE.setTextBackgroundColor = function(color) {
RE.restorerange();
document.execCommand("styleWithCSS", null, true);
document.execCommand('hiliteColor', false, color);
document.execCommand("styleWithCSS", null, false);
}
RE.setFontSize = function(fontSize){
document.execCommand("fontSize", false, fontSize);
}
RE.setHeading = function(heading) {
document.execCommand('formatBlock', false, '<h'+heading+'>');
RE.sendElementNameToNative()
}
RE.setIndent = function() {
document.execCommand('indent', false, null);
}
RE.setOutdent = function() {
document.execCommand('outdent', false, null);
}
RE.setJustifyLeft = function() {
document.execCommand('justifyLeft', false, null);
}
RE.setJustifyCenter = function() {
document.execCommand('justifyCenter', false, null);
}
RE.setJustifyRight = function() {
document.execCommand('justifyRight', false, null);
}
RE.setBlockquote = function() {
document.execCommand('formatBlock', false, '<blockquote>');
// var blockId = window.getSelection().focusNode.parentNode;
// $(blockId).addClass("haloBlock")
RE.sendElementNameToNative()
}
RE.insertImage = function(url) {
var html = "<div><img src =\"" + url + "\" style=\" max-width: 100%; display:block; margin:15px auto; height: auto;\"></div><br>"
RE.insertHTML(html);
}
// 替换成缩略图
RE.replaceTbImage = function(imgRuleFlag, gifRuleFlag) {
var imgs = document.getElementsByTagName("img");
var index = 0
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
// console.log(imageClassName)
if (imageClassName == "image-link" || img.className == "poster") continue;
if(img.src.indexOf("?") > 0) continue;
// console.log(i)
var tbImg
if(img.src.indexOf(".gif") > 0) {
tbImg = img.src + gifRuleFlag
} else {
tbImg = img.src + imgRuleFlag
}
img.style.cssText = "max-width: 60%; display:block; margin:15px auto; height: auto;"
img.src = tbImg;
if (index == 0) {
var bigImg = document.createElement('img');
bigImg.src = "file:///android_asset/web_load_dfimg_icon.png";
bigImg.style.cssText = "max-width: 20%; margin:15px 0 0 0; height: auto;"
img.parentNode.insertBefore(bigImg, img.parentNode.childNodes[0]);
i++;
if(img.parentNode != null) {
img.parentNode.style.cssText += "text-align: left;"
}
if(img.parentNode != null && img.parentNode.parentNode != null) {
img.parentNode.parentNode.style.cssText += "text-align: left;"
}
}
index ++;
}
}
// 替换成默认图
RE.replaceAllDfImage = function(imgRuleFlag, gifRuleFlag) {
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link" || img.className == "poster") continue;
if(img.src.indexOf("web_load_dfimg_icon") > 0) {
img.parentNode.removeChild(img.parentNode.childNodes[0]);
i--;
} else {
if(img.src.indexOf(".gif") > 0) {
img.src = img.src.split("?")[0] + gifRuleFlag
} else {
img.src = img.src.split("?")[0] + imgRuleFlag
}
}
}
}
// 去除显示大图
RE.hideShowBigPic = function() {
var imgs = document.getElementsByTagName("img");
var j = 0;
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link" || img.className == "poster") continue;
if (img.src.indexOf(".gif") == -1) {
j++;
}
}
// 去除显示大图
if (j == 0) {
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link" || img.className == "poster") continue;
if(img.src.indexOf("web_load_dfimg_icon") > 0) {
img.parentNode.removeChild(img.parentNode.childNodes[0]);
break;
}
}
}
}
RE.replaceDfImageByUrl = function(imgUrl, imgRuleFlag, gifRuleFlag) {
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link" || img.className == "poster") continue;
if (img.src.indexOf(imgUrl) != -1) {
if(img.src.indexOf(".gif") > 0) {
img.src = img.src.split("?")[0] + gifRuleFlag
} else {
img.src = img.src.split("?")[0] + imgRuleFlag
}
}
}
RE.hideShowBigPic();
}
RE.ImageClickListener = function() {
var imgs = document.getElementsByTagName("img");
for (var i = 0; i < imgs.length; i++) {
var img = imgs[i];
var imageClassName = img.className;
if (imageClassName == "image-link"|| img.className == "poster") continue;
window.imagelistener.imageArr(img.src);
img.onclick = function() {
window.imagelistener.imageClick(this.src);
}
}
}
RE.insertHTML = function(html) {
RE.restorerange();
document.execCommand('insertHTML', false, html);
}
RE.insertLink = function(url, title) {
RE.restorerange();
var sel = document.getSelection();
if (sel.toString().length == 0) {
document.execCommand("insertHTML",false,"<a href='"+url+"'>"+title+"</a>");
} else if (sel.rangeCount) {
var el = document.createElement("a");
el.setAttribute("href", url);
el.setAttribute("title", title);
var range = sel.getRangeAt(0).cloneRange();
range.surroundContents(el);
sel.removeAllRanges();
sel.addRange(range);
}
RE.callback();
}
RE.setTodo = function(text) {
var html = '<input type="checkbox" name="'+ text +'" value="'+ text +'"/> &nbsp;';
document.execCommand('insertHTML', false, html);
}
RE.prepareInsert = function() {
RE.backuprange();
}
RE.backuprange = function(){
var selection = window.getSelection();
if (selection.rangeCount > 0) {
var range = selection.getRangeAt(0);
RE.currentSelection = {
"startContainer": range.startContainer,
"startOffset": range.startOffset,
"endContainer": range.endContainer,
"endOffset": range.endOffset};
}
}
RE.restorerange = function(){
try {
var selection = window.getSelection();
selection.removeAllRanges();
var range = document.createRange();
range.setStart(RE.currentSelection.startContainer, RE.currentSelection.startOffset);
range.setEnd(RE.currentSelection.endContainer, RE.currentSelection.endOffset);
selection.addRange(range);
} catch(error) {
}
}
RE.enabledEditingItems = function(e) {
var items = [];
if (document.queryCommandState('bold')) {
items.push('bold');
}
if (document.queryCommandState('italic')) {
items.push('italic');
}
if (document.queryCommandState('subscript')) {
items.push('subscript');
}
if (document.queryCommandState('superscript')) {
items.push('superscript');
}
if (document.queryCommandState('strikeThrough')) {
items.push('strikeThrough');
}
if (document.queryCommandState('underline')) {
items.push('underline');
}
if (document.queryCommandState('insertOrderedList')) {
items.push('orderedList');
}
if (document.queryCommandState('insertUnorderedList')) {
items.push('unorderedList');
}
if (document.queryCommandState('justifyCenter')) {
items.push('justifyCenter');
}
if (document.queryCommandState('justifyFull')) {
items.push('justifyFull');
}
if (document.queryCommandState('justifyLeft')) {
items.push('justifyLeft');
}
if (document.queryCommandState('justifyRight')) {
items.push('justifyRight');
}
if (document.queryCommandState('insertHorizontalRule')) {
items.push('horizontalRule');
}
var formatBlock = document.queryCommandValue('formatBlock');
if (formatBlock.length > 0) {
items.push(formatBlock);
}
window.location.href = "re-state://" + encodeURI(items.join(','));
}
RE.focus = function() {
var range = document.createRange();
range.selectNodeContents(RE.editor);
range.collapse(false);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
RE.editor.focus();
}
RE.blurFocus = function() {
RE.editor.blur();
}
RE.removeFormat = function() {
document.execCommand('removeFormat', false, null);
}
RE.insertCustomStyleLink = function(data) {
var entity = JSON.parse(data)
var html = "<br/><div class='"+ entity.type +"-container'>\n" +
" <a class='"+ entity.type +"' href=\"javascript:void(0);\" contenteditable=\"false\" onclick=\"customLinkgo(this)\" data-datas='"+ data +"'>\n" +
" <div class='flex-container'>\n" +
" <div class='gh-internal-content img-left'>\n" +
" <img class = \"image-link\" src='"+ entity.icon +"' />\n" +
" </div>\n" +
" <div class='gh-internal-content content-right'>\n" +
" <p class='content-title'>"+ entity.title +"</p>\n" +
" <p class='contents'>"+ entity.brief +"</p>\n" +
" </div>\n" +
" </div>\n" +
" </a>\n" +
" </div><br/>"
var tags = "", gameHtml = ""
if (entity.tags != null) {
for (var i = 0; i < entity.tags.length; i++) {
tags += "<label>"+ entity.tags[i]+"</label>"
}
gameHtml = "<br/><div class='"+ entity.type +"-container'>\n" +
" <a class='"+ entity.type +"' href=\"javascript:void(0);\" contenteditable=\"false\" onclick=\"customLinkgo(this)\" data-datas='"+ data +"'>\n" +
" <div class='flex-container'>\n" +
" <div class='gh-internal-content img-left'>\n" +
" <img class='image-link' src='"+ entity.icon +"' />\n" +
" </div>\n" +
" <div class='gh-internal-content content-right'>\n" +
" <p class='content-title'>"+ entity.title +"</p>\n" +
" <p class='tags'>"+ tags +"</p>\n" +
" </div>\n" +
" </div>\n" +
" </a></div><br/>"
}
switch(entity.type) {
case "answer":
document.execCommand("insertHTML",false, html);
break
case "community_article":
document.execCommand("insertHTML",false, html);
break
case "game":
document.execCommand("insertHTML",false, gameHtml);
break
}
RE.callback();
}
RE.showLinkStyle = function() {
var answerElement = document.getElementsByClassName("answer-container");
for (var i=0;i<answerElement.length;i+=1){
answerElement[i].style.display = 'inline';
}
var articleElement = document.getElementsByClassName("community_article-container");
for (var i=0;i<articleElement.length;i+=1){
articleElement[i].style.display = 'inline';
}
var gameElement = document.getElementsByClassName("game-container");
for (var i=0;i<gameElement.length;i+=1){
gameElement[i].style.display = 'inline';
}
}
RE.hideLinkStyle = function() {
var answerElement = document.getElementsByClassName("answer-container");
for (var i=0;i<answerElement.length;i+=1){
answerElement[i].style.display = 'none';
}
var articleElement = document.getElementsByClassName("community_article-container");
for (var i=0;i<articleElement.length;i+=1){
articleElement[i].style.display = 'none';
}
var gameElement = document.getElementsByClassName("game-container");
for (var i=0;i<gameElement.length;i+=1){
gameElement[i].style.display = 'none';
}
}
// Event Listeners
RE.editor.addEventListener("input", RE.callback);
RE.editor.addEventListener("keyup", function(e) {
var KEY_LEFT = 37, KEY_RIGHT = 39;
if (e.which == KEY_LEFT || e.which == KEY_RIGHT) {
RE.enabledEditingItems(e);
}
RE.sendElementNameToNative()
});
RE.editor.addEventListener("click", function(e) {
RE.enabledEditingItems
RE.sendElementNameToNative()
var s = document.getSelection()
var isNeedRemoveR = RE.recursion(e.target)
if (isNeedRemoveR && s.rangeCount) {
s.removeAllRanges()
}
});
document.addEventListener("selectionchange", function(e) {
RE.sendElementNameToNative()
});
RE.recursion = function(dom) {
var parenDom = dom.parentElement
if (parenDom && parenDom instanceof Element &&
typeClassList.indexOf(parenDom.className) > -1) {
return parenDom
} else if(parenDom && parenDom instanceof Element &&
typeClassList.indexOf(parenDom.className) === -1 && parenDom.nodeName !== 'BODY') {
return RE.recursion(parenDom)
} else {
return null
}
}
// 返回组件标签 多个标签以"空格"划分
RE.sendElementNameToNative = function() {
if (window.getSelection) {
var selection = window.getSelection()
if (selection.rangeCount > 0) {
var range = selection.getRangeAt(0);
var container = range.startContainer;
var elements = " " + container.localName + " ";
var parentElement;
while(true) {
if(parentElement != null) {
parentElement = parentElement.parentElement
} else {
parentElement = container.parentElement
}
if (parentElement == null || parentElement.localName == null) {
break;
}
elements = elements + " " + parentElement.localName + " "
}
// console.log(elements)
window.OnCursorChangeListener.onElements(elements);
}
}
}
// android function to open link
function customLinkgo(self) {
var datas = self.dataset.datas
// console.log(datas)
window.OnLinkClickListener.onClick(datas)
}
// 在web页面播放视频
//RE.initArticleVideo = function(){
// initArticleVideo()
//}
function showNativeDialog(title, message, positive, negative, callback) {
var jsCallbackCode = "(" + function (v) {
window.onNativeDialogCallback(v);
delete window.onNativeDialogCallback;
}.toString() + ")";
window.onNativeDialogCallback = callback;
window.NativeCallBack.showDialog(title, message, positive, negative, jsCallbackCode);
}