800 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			800 lines
		
	
	
		
			25 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*
 | |
| Product Name: dhtmlxSuite 
 | |
| Version: 5.2.0 
 | |
| Edition: Professional 
 | |
| License: content of this file is covered by DHTMLX Commercial or Enterprise license. Usage without proper license is prohibited. To obtain it contact sales@dhtmlx.com
 | |
| Copyright UAB Dinamenta http://www.dhtmlx.com
 | |
| */
 | |
| 
 | |
| function dhtmlXEditor(base, skin) {
 | |
| 	
 | |
| 	var that = this;
 | |
| 	
 | |
| 	this.conf = {
 | |
| 		// set content after load
 | |
| 		content: "", // first if set
 | |
| 		contentHTML: "", // second
 | |
| 		// resize
 | |
| 		resizeTM: null,
 | |
| 		resizeTMTime: 100,
 | |
| 		// readonly
 | |
| 		roMode: false,
 | |
| 		// extended toolbar
 | |
| 		toolbar: false,
 | |
| 		iconsPath: "",
 | |
| 		// frame events
 | |
| 		evs: ["focus", "blur", "keydown", "keyup", "keypress", "mouseup", "mousedown", "click", "touchend"], // touchend is dev_event for fix on iOS/iPad
 | |
| 		// focus fix on iOS/iPad
 | |
| 		iOSfix: (navigator.userAgent.match(/Mobile/gi) != null && navigator.userAgent.match(/iPad/gi) != null && navigator.userAgent.match(/AppleWebKit/gi) != null),
 | |
| 		// extended font conf
 | |
| 		extra_css: "",
 | |
| 		font: {family: "Tahoma", size: "12px", color: "black"}
 | |
| 	};
 | |
| 	
 | |
| 	this._doOnFocusChanged = null;
 | |
| 	this._doOnAccess = null;
 | |
| 	
 | |
| 	if (typeof(base) == "object" && base != null && base.tagName == null) {
 | |
| 		skin = base.skin;
 | |
| 		if (base.content != null) this.conf.content = base.content;
 | |
| 		if (base.contentHTML != null) this.conf.contentHTML = base.contentHTML;
 | |
| 		if (base.iconsPath != null) this.conf.iconsPath = base.iconsPath;
 | |
| 		if (base.extraCss != null) this.conf.extra_css = base.extraCss;
 | |
| 		if (base.toolbar != null) this.conf.toolbar = window.dhx4.s2b(base.toolbar);
 | |
| 		if (base.onFocusChanged != null) this._doOnFocusChanged = base.onFocusChanged;
 | |
| 		if (base.onAccess != null) this._doOnAccess = base.onAccess;
 | |
| 		base = base.parent;
 | |
| 	}
 | |
| 	
 | |
| 	// skin config
 | |
| 	this.conf.skin = (skin||window.dhx4.skin||(typeof(dhtmlx)!="undefined"?dhtmlx.skin:null)||window.dhx4.skinDetect("dhxeditor")||"material");
 | |
| 	
 | |
| 	// configure base
 | |
| 	if (typeof(base) == "string") base = document.getElementById(base);
 | |
| 	this.base = base;
 | |
| 	this.base.className += " dhxeditor_"+this.conf.skin;
 | |
| 	
 | |
| 	while (this.base.childNodes.length > 0) this.base.removeChild(this.base.childNodes[0]);
 | |
| 	
 | |
| 	// configure base for dhxcont
 | |
| 	var pos = (window.dhx4.isIE ? this.base.currentStyle["position"] : (window.getComputedStyle != null? window.getComputedStyle(this.base, null).getPropertyValue("position") : "" ));
 | |
| 	if (!(pos == "relative" || pos == "absolute")) this.base.style.position = "relative";
 | |
| 	
 | |
| 	// init dhxcont
 | |
| 	this.cell = new dhtmlXEditorCell(window.dhx4.newId(), this);
 | |
| 	this.base.appendChild(this.cell.cell);
 | |
| 	
 | |
| 	this.cBlock = document.createElement("DIV");
 | |
| 	this.cBlock.className = "dhxcont_content_blocker";
 | |
| 	this.cBlock.style.display = "none";
 | |
| 	this.base.appendChild(this.cBlock);
 | |
| 	
 | |
| 	// editable area
 | |
| 	this.editor = document.createElement("IFRAME");
 | |
| 	this.editor.className = "dhxeditor_mainiframe";
 | |
| 	this.editor.frameBorder = 0;
 | |
| 	if (window.dhx4.isOpera) this.editor.scrolling = "yes";
 | |
| 	
 | |
| 	// adjust self
 | |
| 	this.setSizes();
 | |
| 	
 | |
| 	// onAccess event - focus/blue as param
 | |
| 	var fr = this.editor;
 | |
| 	if (typeof(window.addEventListener) != "undefined") {
 | |
| 		fr.onload = function() {
 | |
| 			for (var q=0; q<that.conf.evs.length; q++) {
 | |
| 				fr.contentWindow.addEventListener(that.conf.evs[q], that._ev, false);
 | |
| 			}
 | |
| 		}
 | |
| 	} else {
 | |
| 		fr.onreadystatechange = function(a) {
 | |
| 			if (typeof(fr.readyState) != "undefined" && fr.readyState == "complete") {
 | |
| 				try {
 | |
| 					for (var q=0; q<that.conf.evs.length; q++) {
 | |
| 						fr.contentWindow.document.body.attachEvent("on"+that.conf.evs[q], that._ev);
 | |
| 					}
 | |
| 				} catch(e){};
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	this._ev = function(e) {
 | |
| 		e = e||event;
 | |
| 		var type = e.type;
 | |
| 		if (that.conf.iOSfix == true && type == "touchend") {
 | |
| 			that.editor.contentWindow.focus();
 | |
| 			return;
 | |
| 		}
 | |
| 		that.callEvent("onAccess", [type, e]);
 | |
| 		if (typeof(that._doOnAccess) == "function") {
 | |
| 			that._doOnAccess(type, e);
 | |
| 		} else if (typeof(that._doOnAccess) == "string" && typeof(window[that._doOnAccess]) == "function") {
 | |
| 			window[that._doOnAccess](type, e);
 | |
| 		}
 | |
| 	}
 | |
| 	this._focus = function() {
 | |
| 		if (window.dhx4.isIE) {
 | |
| 			this.editor.contentWindow.document.body.focus();
 | |
| 		} else {
 | |
| 			this.editor.contentWindow.focus();
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	this.cell.attachObject(this.editor);
 | |
| 	this.edWin = this.editor.contentWindow;
 | |
| 	this.edDoc = this.edWin.document;
 | |
| 	
 | |
| 	this._prepareContent = function(saveContent, roMode) {
 | |
| 		
 | |
| 		var storedContent = "";
 | |
| 		if (saveContent === true && this.getContent != null) storedContent = this.getContent();
 | |
| 		
 | |
| 		var edDoc = this.editor.contentWindow.document;
 | |
| 		edDoc.open("text/html", "replace");
 | |
| 		if (window.dhx4.isOpera) {
 | |
| 			edDoc.write("<html><head>"+this.conf.extra_css+
 | |
| 					"<style> html, body { overflow:auto;-webkit-overflow-scrolling: touch; padding:0px; height:100%; margin:0px; background-color:#ffffff; "+this._fontConf()+"} </style>"+
 | |
| 					"</head><body "+(roMode!==true?"contenteditable='true'":"")+" tabindex='0'></body></html>");
 | |
| 		} else {
 | |
| 			if (window.dhx4.isKHTML) {
 | |
| 				edDoc.write("<html><head>"+this.conf.extra_css+
 | |
| 						"<style> html {overflow-x: auto;-webkit-overflow-scrolling: touch; overflow-y: auto;} body { overflow: auto; overflow-y: scroll;} "+
 | |
| 							"html,body { padding:0px; height:100%; margin:0px; background-color:#ffffff; "+this._fontConf()+"} </style>"+
 | |
| 						"</head><body "+(roMode!==true?"contenteditable='true'":"")+" tabindex='0'></body></html>");
 | |
| 			} else {
 | |
| 				if (window.dhx4.isIE) {
 | |
| 					// && navigator.appVersion.indexOf("MSIE 9.0")!= -1
 | |
| 					edDoc.write("<html><head>"+this.conf.extra_css+
 | |
| 							"<style> html {overflow-y: auto;} body {overflow-y: scroll;-webkit-overflow-scrolling: touch;} "+
 | |
| 								"html,body { overflow-x: auto; padding:0px; height:100%; margin:0px; background-color: #ffffff; outline: none; "+this._fontConf()+"} </style>"+
 | |
| 							"</head><body "+(roMode!==true?"contenteditable='true'":"")+" tabindex='0'></body></html>");
 | |
| 				} else {
 | |
| 					edDoc.write("<html><head>"+this.conf.extra_css+
 | |
| 							"<style> html,body { overflow-x: auto; overflow-y:-webkit-overflow-scrolling: touch; scroll; "+
 | |
| 								"padding:0px; height:100%; margin:0px; background-color:#ffffff; "+this._fontConf()+"} </style>"+
 | |
| 							"</head><body "+(roMode!==true?"contenteditable='true'":"")+" tabindex='0'></body></html>");
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		edDoc.close();
 | |
| 		
 | |
| 		if (window.dhx4.isIE) edDoc.contentEditable = (roMode!==true); else edDoc.designMode = (roMode!==true?"On":"Off");
 | |
| 		if (window.dhx4.isFF) try { edDoc.execCommand("useCSS", false, true); } catch(e) {}
 | |
| 		if (saveContent === true && this.setContent != null) this.setContent(storedContent);
 | |
| 		
 | |
| 	}
 | |
| 	
 | |
| 	// fix
 | |
| 	this._prepareContent();
 | |
| 	
 | |
| 	// resize
 | |
| 	this._doOnResize = function() {
 | |
| 		window.clearTimeout(that.conf.resizeTM);
 | |
| 		that.conf.resizeTM = window.setTimeout(function(){if(that.setSizes)that.setSizes();}, that.conf.resizeTMTime);
 | |
| 	}
 | |
| 	
 | |
| 	// toolbar buttons
 | |
| 	this._runCommand = function(name,param){
 | |
| 		if (this.conf.roMode === true) return;
 | |
| 		if (arguments.length < 2) param = null;
 | |
| 		if (window.dhx4.isIE) this.edWin.focus();
 | |
| 		try {
 | |
| 			var edDoc = this.editor.contentWindow.document
 | |
| 			edDoc.execCommand(name,false,param);
 | |
| 		} catch(e){}
 | |
| 		if (window.dhx4.isIE) {
 | |
| 			this.edWin.focus();
 | |
| 			var self = this;
 | |
| 			window.setTimeout(function(){
 | |
| 				self.edWin.focus();
 | |
| 				self = null;
 | |
| 			},1);
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	// commands
 | |
| 	this.applyBold = function() {
 | |
| 		this._runCommand("Bold");
 | |
| 	}
 | |
| 	this.applyItalic = function() {
 | |
| 		this._runCommand("Italic");
 | |
| 	}
 | |
| 	this.applyUnderscore = function() {
 | |
| 		this._runCommand("Underline");
 | |
| 	}
 | |
| 	this.clearFormatting = function() {
 | |
| 		this._runCommand("RemoveFormat");
 | |
| 		var k = this.getContent();
 | |
| 		k = k.replace(/<\/?h\d>/gi, "");
 | |
| 		this.setContent(k);
 | |
| 	}
 | |
| 	
 | |
| 	this._doOnClick = function(e) {
 | |
| 		var ev = e||window.event;
 | |
| 		var el = ev.target||ev.srcElement;
 | |
| 		that._showInfo(el);
 | |
| 	}
 | |
| 	
 | |
| 	this._doOnMouseDown = function(e) { // opera only
 | |
| 		var ev = e||window.event;
 | |
| 		var el = ev.target||ev.srcElement;
 | |
| 		that._showInfo(el);
 | |
| 	}
 | |
| 	
 | |
| 	this._doOnKeyUp = function(e) {
 | |
| 		var ev = e||window.event;
 | |
| 		var key = ev.keyCode;
 | |
| 		var el = ev.target||ev.srcElement;
 | |
| 		if ({37:1,38:1,39:1,40:1,13:1}[key] == 1) that._showInfo(el);
 | |
| 	}
 | |
| 	
 | |
| 
 | |
| 	this._getParentByTag = function(node, tag_name) {
 | |
| 		tag_name = tag_name.toLowerCase();
 | |
| 		var p = node;
 | |
| 		do {
 | |
| 			if (tag_name == '' || p.nodeName.toLowerCase() == tag_name) return p;
 | |
| 		} while (p = p.parentNode);
 | |
| 		return node;
 | |
| 	}
 | |
| 	
 | |
| 	this._isStyleProperty = function(node, tag_name, name, value){
 | |
| 		tag_name = tag_name.toLowerCase();
 | |
| 		var n = node;
 | |
| 		do {
 | |
| 			if ((n.nodeName.toLowerCase() == tag_name) && (n.style[name] == value)) return true;
 | |
|    		} while (n = n.parentNode);
 | |
|    		return false;
 | |
| 	}
 | |
| 	
 | |
| 	this._setStyleProperty = function(el, prop) {
 | |
| 		this.style[prop] = false;
 | |
| 		var n = this._getParentByTag(el, prop);
 | |
| 		if (n && (n.tagName.toLowerCase() == prop)) this.style[prop] = true;
 | |
| 		if (prop == "del" && this._getParentByTag(el, "strike") && this._getParentByTag(el,"strike").tagName.toLowerCase() == "strike") this.style.del = true;
 | |
| 	}
 | |
| 	
 | |
| 	this._showInfo = function(el) {
 | |
| 		
 | |
| 		var el = (this._getSelectionBounds().end)?this._getSelectionBounds().end : el;
 | |
| 		if (!el || !this._setStyleProperty) return;
 | |
| 		
 | |
| 		try {
 | |
| 			if (this.edWin.getComputedStyle) {
 | |
| 				var st = this.edWin.getComputedStyle(el, null);
 | |
| 				var fw = ((st.getPropertyValue("font-weight")==401)?700:st.getPropertyValue("font-weight"));
 | |
| 				this.style = {
 | |
| 					fontStyle	: st.getPropertyValue("font-style"),
 | |
| 					fontSize	: st.getPropertyValue("font-size"),
 | |
| 					textDecoration	: st.getPropertyValue("text-decoration"),
 | |
| 					fontWeight	: fw,
 | |
| 					fontFamily	: st.getPropertyValue("font-family"),
 | |
| 					textAlign	: st.getPropertyValue("text-align")
 | |
| 				};
 | |
| 				if (window.dhx4.isKHTML) { // safari
 | |
| 					this.style.fontStyle = st.getPropertyValue("font-style");
 | |
| 					this.style.vAlign = st.getPropertyValue("vertical-align");
 | |
| 					this.style.del = this._isStyleProperty(el,"span","textDecoration","line-through");
 | |
| 					this.style.u = this._isStyleProperty(el,"span","textDecoration","underline");
 | |
| 				}
 | |
| 			} else {
 | |
| 				var st = el.currentStyle;
 | |
| 				this.style = {
 | |
| 					fontStyle	: st.fontStyle,
 | |
| 					fontSize	: st.fontSize,
 | |
| 					textDecoration	: st.textDecoration,
 | |
| 					fontWeight	:  st.fontWeight,
 | |
| 					fontFamily	: st.fontFamily,
 | |
| 					textAlign	: st.textAlign
 | |
| 				};
 | |
| 			}
 | |
| 			this._setStyleProperty(el,"h1");
 | |
| 			this._setStyleProperty(el,"h2");
 | |
| 			this._setStyleProperty(el,"h3");
 | |
| 			this._setStyleProperty(el,"h4");
 | |
| 			if (!window.dhx4.isKHTML) {
 | |
| 				this._setStyleProperty(el,"del");
 | |
| 				this._setStyleProperty(el,"sub");
 | |
| 				this._setStyleProperty(el,"sup");
 | |
| 				this._setStyleProperty(el,"u");
 | |
| 			}
 | |
| 			this.callEvent("onFocusChanged", [this.style, st])
 | |
| 		} catch(e){ return null; }
 | |
| 	}
 | |
| 	
 | |
| 	this._getSelectionBounds = function() {
 | |
|    		var range, root, start, end;
 | |
| 		if (this.edWin.getSelection) {
 | |
| 			var selection = this.edWin.getSelection();
 | |
| 			if (window.dhx4.isEdge && selection.rangeCount == 0) return {root: null, start: null, end: null};
 | |
| 			range = selection.getRangeAt(selection.rangeCount-1);
 | |
| 			start = range.startContainer;
 | |
| 			end = range.endContainer;
 | |
| 			root = range.commonAncestorContainer;
 | |
| 			if (start.nodeName == "#text") root = root.parentNode;
 | |
| 			if (start.nodeName == "#text") start = start.parentNode;
 | |
| 			if (start.nodeName.toLowerCase() == "body") start = start.firstChild;
 | |
| 			if (end.nodeName == "#text") end = end.parentNode;
 | |
| 			if (end.nodeName.toLowerCase() == "body") end = end.lastChild;
 | |
| 			if (start == end) root = start;
 | |
| 			return {
 | |
| 				root: root,
 | |
| 				start: start,
 | |
| 				end: end
 | |
| 			};
 | |
| 		} else if (this.edWin.document.selection) {
 | |
| 			range = this.edDoc.selection.createRange()
 | |
| 			if(!range.duplicate) return null;
 | |
| 			root = range.parentElement();
 | |
| 			var r1 = range.duplicate();
 | |
| 			var r2 = range.duplicate();
 | |
| 			r1.collapse(true);
 | |
| 			r2.moveToElementText(r1.parentElement());
 | |
| 			r2.setEndPoint("EndToStart",r1);
 | |
| 			start = r1.parentElement();
 | |
| 			r1 = range.duplicate();
 | |
| 			r2 = range.duplicate();
 | |
| 			r2.collapse(false);
 | |
| 			r1.moveToElementText(r2.parentElement());
 | |
| 			r1.setEndPoint("StartToEnd", r2);
 | |
| 			end = r2.parentElement();
 | |
| 	   		if (start.nodeName.toLowerCase() == "body") start = start.firstChild;
 | |
| 			if (end.nodeName.toLowerCase() == "body") end = end.lastChild;
 | |
| 			
 | |
| 			if (start == end) root = start;
 | |
| 			return {
 | |
| 				root: root,
 | |
| 				start: start,
 | |
| 				end: end
 | |
| 			};
 | |
|    		}
 | |
|    		return null;
 | |
| 	}
 | |
| 	
 | |
| 	this.getContent = function(){
 | |
| 		if (!this.edDoc.body) {
 | |
| 			return "";
 | |
| 		} else {
 | |
| 			if (window.dhx4.isFF || window.dhx4.isChrome) return this.editor.contentWindow.document.body.innerHTML.replace(/<\/{0,}br\/{0,}>\s{0,}$/gi,"");
 | |
| 			if (window.dhx4.isIE && this.edDoc.body.innerText.length == 0) return "";
 | |
| 			return this.edDoc.body.innerHTML;
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	this.setContent = function(str){
 | |
| 		str = str||"";
 | |
| 		if (this.edDoc.body) {
 | |
| 			var ffTest = false;
 | |
| 			if (window.dhx4.isFF) {
 | |
| 				var k = navigator.userAgent.match(/Firefox\/(\d*)/);
 | |
| 				ffTest = (k != null && k[1] < 28);
 | |
| 			}
 | |
| 			if (ffTest) {
 | |
| 				if (typeof(this.conf.ffTest) == "undefined") {
 | |
| 					this.editor.contentWindow.document.body.innerHTML = "";
 | |
| 					this._runCommand("InsertHTML", "test");
 | |
| 					this.conf.ffTest = (this.editor.contentWindow.document.body.innerHTML.length > 0);
 | |
| 				}
 | |
| 				if (this.conf.ffTest) {
 | |
| 					// FF 4.x+
 | |
| 					this.editor.contentWindow.document.body.innerHTML = str;
 | |
| 				} else {
 | |
| 					// FF 2.x, 3.x
 | |
| 					this.editor.contentWindow.document.body.innerHTML = "";
 | |
| 					if (str.length == 0) str=" ";
 | |
| 					this._runCommand("InsertHTML", str);
 | |
| 				}
 | |
| 			} else {
 | |
| 				this.editor.contentWindow.document.body.innerHTML = str;
 | |
| 			}
 | |
| 			this.callEvent("onContentSet",[]);
 | |
| 		} else {
 | |
| 			if (!this.conf.firstLoadEv) {
 | |
| 				this.conf.firstLoadEv = true;
 | |
| 				this.conf.firstLoadData = str;
 | |
| 				this._onFirstLoad = function() {
 | |
| 					that.setContent(that.conf.firstLoadData);
 | |
| 					if (typeof(window.addEventListener) == "function") {
 | |
| 						that.edWin.removeEventListener("load", that._onFirstLoad, false);
 | |
| 					} else {
 | |
| 						that.edWin.detachEvent("onload", that._onFirstLoad);
 | |
| 					}
 | |
| 					that.conf.firstLoadData = null;
 | |
| 					that.conf.firstLoadEv = false;
 | |
| 					that._onFirstLoad = null;
 | |
| 				}
 | |
| 				if (typeof(window.addEventListener) == "function") {
 | |
| 					this.edWin.addEventListener("load", this._onFirstLoad, false);
 | |
| 				} else {
 | |
| 					this.edWin.attachEvent("onload", this._onFirstLoad);
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	
 | |
| 	this.setContentHTML = function(url) {
 | |
| 		window.dhx4.ajax.get(url, function(r) {
 | |
| 			if (r.xmlDoc.responseText != null) that.setContent(r.xmlDoc.responseText);
 | |
| 		});
 | |
| 	}
 | |
| 	
 | |
| 	// events
 | |
| 	window.dhx4._eventable(this);
 | |
| 	
 | |
| 	this.attachEvent("onFocusChanged", function(state){
 | |
| 		if (typeof(this._doOnFocusChanged) == "function") {
 | |
| 			this._doOnFocusChanged(state);
 | |
| 		} else if (typeof(this._doOnFocusChanged) == "string" && typeof(window[this._doOnFocusChanged]) == "function") {
 | |
| 			window[this._doOnFocusChanged](state);
 | |
| 		}
 | |
| 	});
 | |
| 	
 | |
| 	if (typeof(window.addEventListener) == "function") {
 | |
| 		window.addEventListener("resize", this._doOnResize, false);
 | |
| 		this.edDoc.addEventListener("click", this._doOnClick, false);
 | |
| 		this.edDoc.addEventListener("keyup", this._doOnKeyUp, false);
 | |
| 		if (window.dhx4.isOpera) this.edDoc.addEventListener("mousedown", this._doOnMouseDown, false);
 | |
| 	} else {
 | |
| 		window.attachEvent("onresize", this._doOnResize);
 | |
| 		this.edDoc.attachEvent("onclick", this._doOnClick);
 | |
| 		this.edDoc.attachEvent("onkeyup", this._doOnKeyUp);
 | |
| 	}
 | |
| 	
 | |
| 	this.unload = function() {
 | |
| 		
 | |
| 		// first detach events from iframe
 | |
| 		if (typeof(window.addEventListener) == "function") {
 | |
| 			window.removeEventListener("resize", this._doOnResize, false);
 | |
| 			this.edDoc.removeEventListener("click", this._doOnClick, false);
 | |
| 			this.edDoc.removeEventListener("keyup", this._doOnKeyUp, false);
 | |
| 			if (window.dhx4.isOpera) this.edDoc.removeEventListener("mousedown", this._doOnMouseDown, false);
 | |
| 			// editor's
 | |
| 			for (var q=0; q<that.conf.evs.length; q++) {
 | |
| 				fr.contentWindow.removeEventListener(that.conf.evs[q], that._ev, false);
 | |
| 			}
 | |
| 			// iOS fix
 | |
| 			if (this.tb != null && this.conf.iOSfix == true) {
 | |
| 				this.tb.cont.removeEventListener("touchend", this._doOnIOSFix, false);
 | |
| 				this._doOnIOSFix = null;
 | |
| 			}
 | |
| 		} else {
 | |
| 			window.detachEvent("onresize", this._doOnResize, false);
 | |
| 			this.edDoc.detachEvent("onclick", this._doOnClick);
 | |
| 			this.edDoc.detachEvent("onkeyup", this._doOnKeyUp);
 | |
| 			// editor's
 | |
| 			for (var q=0; q<that.conf.evs.length; q++) {
 | |
| 				fr.contentWindow.document.body.detachEvent("on"+that.conf.evs[q], that._ev);
 | |
| 			}
 | |
| 		}
 | |
| 		
 | |
| 		this._doOnAccess = null;
 | |
| 		this._doOnFocusChanged = null;
 | |
| 		
 | |
| 		// remove editor
 | |
| 		if (typeof(window.addEventListener) == "function") {
 | |
| 			this.editor.onload = null;
 | |
| 		} else {
 | |
| 			this.editor.onreadystatechange = null;
 | |
| 		}
 | |
| 		this.editor.parentNode.removeChild(this.editor);
 | |
| 		this.editor = null;
 | |
| 		this.edDoc = null;
 | |
| 		this.edWin = null;
 | |
| 		
 | |
| 		// unload cell
 | |
| 		this.cell._unload();
 | |
| 		this.cell = null;
 | |
| 		
 | |
| 		// extended toolbar
 | |
| 		this.tb = null;
 | |
| 		
 | |
| 		window.dhx4._eventable(this, "clear");
 | |
| 		
 | |
| 		this.cBlock.parentNode.removeChild(this.cBlock);
 | |
| 		this.cBlock = null;
 | |
| 		
 | |
| 		// clear container features
 | |
| 		this.base.className = String(this.base.className).replace(new RegExp("\\s{0,}dhxeditor_"+this.conf.skin),"");
 | |
| 		while (this.base.childNodes.length > 0) this.base.removeChild(this.base.childNodes[0]);
 | |
| 		this.base = null;
 | |
| 		
 | |
| 		this._doOnClick = null;
 | |
| 		this._doOnKeyUp = null;
 | |
| 		this._doOnMouseDown = null;
 | |
| 		
 | |
| 		this._ev = null;
 | |
| 		this._focus = null;
 | |
| 		this._prepareContent = null;
 | |
| 		this._doOnResize = null;
 | |
| 		this.setIconsPath = null;
 | |
| 		this.init = null;
 | |
| 		this.setSizes = null;
 | |
| 		this._runCommand = null;
 | |
| 		this.applyBold = null;
 | |
| 		this.applyItalic = null;
 | |
| 		this.applyUnderscore = null;
 | |
| 		this.clearFormatting = null;
 | |
| 		this._showInfo = null;
 | |
| 		this._getSelectionBounds = null;
 | |
| 		this.getContent = null;
 | |
| 		this.setContent = null;
 | |
| 		this.setContentHTML = null;
 | |
| 		this.setReadonly = null;
 | |
| 		this.isReadonly = null;
 | |
| 		this.unload = null;
 | |
| 		
 | |
| 		that = fr = null;
 | |
| 	}
 | |
| 	
 | |
| 	// load extended toolbar if any
 | |
| 	if (this.conf.toolbar == true && typeof(this.attachToolbar) == "function" && typeof(window.dhtmlXToolbarObject) == "function") {
 | |
| 		this.attachToolbar(this.conf.iconsPath);
 | |
| 		if (this.conf.iOSfix == true) {
 | |
| 			this._doOnIOSFix = function() { that.editor.contentWindow.focus(); }
 | |
| 			this.tb.cont.addEventListener("touchend", this._doOnIOSFix, false);
 | |
| 		}
 | |
| 	}
 | |
| 	this.setIconsPath = function(iconsPath) {
 | |
| 		this.conf.iconsPath = iconsPath;
 | |
| 	}
 | |
| 	
 | |
| 	// load content if any
 | |
| 	if (this.conf.content.length > 0) {
 | |
| 		this.setContent(this.conf.content);
 | |
| 		this.conf.content = "";
 | |
| 	} else if (this.conf.contentHTML.length > 0) {
 | |
| 		this.setContentHTML(this.conf.contentHTML);
 | |
| 		this.conf.contentHTML = "";
 | |
| 	}
 | |
| 	
 | |
| 	return this;
 | |
| };
 | |
| 
 | |
| dhtmlXEditor.prototype.setSizes = function() {
 | |
| 	this.cell._setSize(0, 0, this.base.clientWidth, this.base.clientHeight);
 | |
| 	if (this.editor != null) {
 | |
| 		this.editor.style.left = "5px";
 | |
| 		this.editor.style.width = this.base.clientWidth-5+"px";
 | |
| 	}
 | |
| };
 | |
| 
 | |
| dhtmlXEditor.prototype.setReadonly = function(mode) {
 | |
| 	this.conf.roMode = (mode===true);
 | |
| 	this._prepareContent(true, this.conf.roMode);
 | |
| 	this.cBlock.style.display = (this.conf.roMode?"":"none");
 | |
| };
 | |
| 
 | |
| dhtmlXEditor.prototype.isReadonly = function(mode) {
 | |
| 	return (this.conf.roMode||false);
 | |
| };
 | |
| 
 | |
| dhtmlXEditor.prototype.setSkin = function(skin) {
 | |
| 	this.base.className = String(this.base.className).replace(new RegExp("dhxeditor_"+this.conf.skin),"dhxeditor_"+skin);
 | |
| 	this.conf.skin = this.cell.conf.skin = skin;
 | |
| 	if (this.tb) {
 | |
| 		this.cell.detachToolbar(skin);
 | |
| 		this.tb = null;
 | |
| 		this.attachToolbar();
 | |
| 	}
 | |
| 	this.setSizes();
 | |
| };
 | |
| 
 | |
| dhtmlXEditor.prototype._fontConf = function() {
 | |
| 	if (this.conf.skin == "") {
 | |
| 		var data = {family: this.conf.font.family, size: this.conf.font.size, color: this.conf.font.color};
 | |
| 	} else {
 | |
| 		var data = {family: "Roboto, Arial, Helvetica", size: "14px", color: "#404040"};
 | |
| 	}
 | |
| 	return window.dhx4.template("font-size: #size#; font-family: #family#; color: #color#;", data);
 | |
| };
 | |
| window.dhtmlXEditorCell = function(id, editor) {
 | |
| 	
 | |
| 	dhtmlXCellObject.apply(this, [id, "_editor"]);
 | |
| 	
 | |
| 	var that = this;
 | |
| 	this.editor = editor;
 | |
| 	
 | |
| 	this.conf.skin = this.editor.conf.skin;
 | |
| 	
 | |
| 	this.attachEvent("_onCellUnload", function(){
 | |
| 		
 | |
| 		// unload simple toolbar
 | |
| 		this._stbUnload();
 | |
| 		
 | |
| 		this.editor = null;
 | |
| 		that = null;
 | |
| 		
 | |
| 	});
 | |
| 	
 | |
| 	// simple toolbar init
 | |
| 	this._stbInit();
 | |
| 	
 | |
| 	return this;
 | |
| };
 | |
| 
 | |
| dhtmlXEditorCell.prototype = new dhtmlXCellObject();
 | |
| 
 | |
| // simple toolbar
 | |
| dhtmlXEditorCell.prototype._stbInit = function() {
 | |
| 	
 | |
| 	var that = this;
 | |
| 	
 | |
| 	var t = document.createElement("DIV");
 | |
| 	t.className = "dhx_cell_stb"+(dhx4.isIE6||dhx4.isIE7||dhx4.isIE8?"":" dhx_cell_stb_shadow");
 | |
| 	this.cell.insertBefore(t, this.cell.childNodes[this.conf.idx.cont]);
 | |
| 	
 | |
| 	t.onselectstart = function(e) {
 | |
| 		e = e||event;
 | |
| 		e.cancelBubble = true;
 | |
| 		if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
 | |
| 		return false;
 | |
| 	}
 | |
| 	
 | |
| 	var items = {
 | |
| 		bold: "applyBold",
 | |
| 		italic: "applyItalic",
 | |
| 		underline: "applyUnderscore",
 | |
| 		clearformat: "clearFormatting"
 | |
| 	};
 | |
| 	
 | |
| 	for (var k in items) {
 | |
| 		
 | |
| 		var a = document.createElement("A");
 | |
| 		a.href = "javascript:void(0);";
 | |
| 		a.tabIndex = -1;
 | |
| 		t.appendChild(a);
 | |
| 		
 | |
| 		a.onmousedown = a.onclick = function(e){
 | |
| 			e = e||event;
 | |
| 			if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
 | |
| 			return false;
 | |
| 		}
 | |
| 		
 | |
| 		var d = document.createElement("DIV");
 | |
| 		d.className = "dhx_cell_stb_button btn_"+k;
 | |
| 		d._actv = k.charAt(0);
 | |
| 		d._cmd = items[k];
 | |
| 		a.appendChild(d);
 | |
| 		
 | |
| 		d.onclick = function(e){
 | |
| 			e = e||event;
 | |
| 			if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
 | |
| 			return false;
 | |
| 		}
 | |
| 		d.onmousedown = function(e){
 | |
| 			e = e||event;
 | |
| 			if (e.preventDefault) e.preventDefault(); else e.returnValue = false;
 | |
| 			that.editor[this._cmd]();
 | |
| 			that.editor.callEvent("onToolbarClick",[this._actv]);
 | |
| 		}
 | |
| 		
 | |
| 		d = a = null;
 | |
| 	}
 | |
| 	
 | |
| 	t = null;
 | |
| 	
 | |
| 	this._stbUnload = function() {
 | |
| 		
 | |
| 		var t = this.cell.childNodes[this.conf.idx.stb];
 | |
| 		t.onselectstart = null;
 | |
| 		
 | |
| 		while (t.childNodes.length > 0) {
 | |
| 			t.lastChild.onmousedown = t.lastChild.onclick = null;
 | |
| 			t.lastChild.firstChild.onmousedown = t.lastChild.firstChild.onclick = null;
 | |
| 			t.lastChild.firstChild._actv = t.lastChild.firstChild._cmd = null;
 | |
| 			t.lastChild.removeChild(t.lastChild.firstChild);
 | |
| 			t.removeChild(t.lastChild);
 | |
| 		}
 | |
| 		t.parentNode.removeChild(t);
 | |
| 		t = that = null;
 | |
| 		
 | |
| 		this.conf.idx_data.stb = this.conf.ofs_nodes.t._getStbHeight = null;
 | |
| 		delete this.conf.ofs_nodes.t._getStbHeight
 | |
| 		delete this.conf.idx_data.stb;
 | |
| 		
 | |
| 		this._updateIdx();
 | |
| 		
 | |
| 	};
 | |
| 	
 | |
| 	this.conf.stb_visible = true;
 | |
| 	
 | |
| 	// include into content top offset calculation
 | |
| 	this.conf.ofs_nodes.t._getStbHeight = "func";
 | |
| 	
 | |
| 	// include into index
 | |
| 	this.conf.idx_data.stb = "dhx_cell_stb";
 | |
| 	this._updateIdx();
 | |
| 	
 | |
| };
 | |
| 
 | |
| dhtmlXEditorCell.prototype._stbHide = function() {
 | |
| 	this.cell.childNodes[this.conf.idx.stb].style.display = "none";
 | |
| 	this.conf.stb_visible = false;
 | |
| };
 | |
| 
 | |
| dhtmlXEditorCell.prototype._getStbHeight = function() {
 | |
| 	if (this.conf.stb_visible == true && this.conf.skin == "material") {
 | |
| 		if (this.conf.stb_height == null) {
 | |
| 			this.conf.stb_height = window.dhx4.readFromCss("dhxeditor_material stb_height_detect", "scrollHeight", "<div class='dhx_cell_editor'><div class='dhx_cell_stb'></div></div>");
 | |
| 		}
 | |
| 		return this.conf.stb_height;
 | |
| 	}
 | |
| 	return this.cell.childNodes[this.conf.idx.stb].offsetHeight;
 | |
| };
 | |
| 
 | |
| dhtmlXCellObject.prototype.attachEditor = function(conf) {
 | |
| 	
 | |
| 	this.callEvent("_onBeforeContentAttach",["editor"]);
 | |
| 	
 | |
| 	var obj = document.createElement("DIV");
 | |
| 	obj.style.width = "100%";
 | |
| 	obj.style.height = "100%";
 | |
| 	obj.style.position = "relative";
 | |
| 	obj.style.overflow = "hidden";
 | |
| 	this._attachObject(obj);
 | |
| 	
 | |
| 	if (!(typeof(conf) == "object" && conf != null)) conf = {};
 | |
| 	conf.parent = obj;
 | |
| 	
 | |
| 	this.dataType = "editor";
 | |
| 	this.dataObj = new dhtmlXEditor(conf);
 | |
| 	
 | |
| 	obj = null;
 | |
| 	conf.parent = null;
 | |
| 	conf = null;
 | |
| 	
 | |
| 	// attach to portal extended logic
 | |
| 	if (typeof(window.dhtmlXPortalCell) == "function" && this instanceof window.dhtmlXPortalCell) {
 | |
| 		
 | |
| 		if (this.portal.conf.editor_ev == null) {
 | |
| 			
 | |
| 			var e1 = this.portal.attachEvent("onBeforeDrag", function(id) {
 | |
| 				if (this.cdata[id].dataType == "editor") {
 | |
| 					this.cdata[id].conf.editor_cont = this.cdata[id].dataObj.getContent();
 | |
| 				}
 | |
| 				return true;
 | |
| 			});
 | |
| 			
 | |
| 			var e2 = this.portal.attachEvent("onDrop", function(id) {
 | |
| 				if (this.cdata[id].dataType == "editor") {
 | |
| 					this.cdata[id].dataObj.setContent(this.cdata[id].conf.editor_cont);
 | |
| 					this.cdata[id].dataObj._prepareContent(true);
 | |
| 					this.cdata[id].conf.editor_cont = null;
 | |
| 				}
 | |
| 			});
 | |
| 			
 | |
| 			this.portal.conf.editor_ev = [e1, e2];
 | |
| 		}
 | |
| 		
 | |
| 		this.conf.editor_ev = this.attachEvent("_onBeforeContentDetach", function(){
 | |
| 			
 | |
| 			this.detachEvent(this.conf.editor_ev);
 | |
| 			this.conf.editor_ev = null;
 | |
| 			
 | |
| 			if (this instanceof window.dhtmlXPortalCell) {
 | |
| 				
 | |
| 				var ed = false;
 | |
| 				for (var a in this.portal.cdata) {
 | |
| 					if (this.portal.cdata[a] != this && this.portal.cdata[a].dataType == "editor") {
 | |
| 						ed = true; // portal still have attached editors
 | |
| 					}
 | |
| 				}
 | |
| 				// no more editors, clear events
 | |
| 				if (ed == false) {
 | |
| 					for (var q=0; q<this.portal.conf.editor_ev.length; q++) {
 | |
| 						this.portal.detachEvent(this.portal.conf.editor_ev[q]);
 | |
| 					}
 | |
| 					this.portal.conf.editor_ev = null;
 | |
| 				}
 | |
| 			}
 | |
| 		});
 | |
| 		
 | |
| 	}
 | |
| 	
 | |
| 	this.callEvent("_onContentAttach",[]);
 | |
| 	
 | |
| 	return this.dataObj;
 | |
| 	
 | |
| };
 | |
| 
 |