gibney.org
:
Technology
:
Javascript
:
Bookmarklets
:
Editor
(Entry Nr. 58, by user 1 |
edit
)
search
ge_require_once('http://javascript.gibney.org/view.js'); ge_require_once('http://javascript.gibney.org/dynamic_html_elements.js'); ge_require_once('http://javascript.gibney.org/outerhtml.js'); // Global Variables ----------------------------------------------------------------------------------------- var isDOM = document.getElementById && !document.all; // ====================================================================== // = JS Loader t be used in loaction bar =============================== /*javascript: ge_bookmarklet_loader("editor"); function % 20ge_bookmarklet_loader(name) { if (typeof(ge_bookmarklets) == "undefined") ge_bookmarklets = {}; if (typeof ge_bookmarklets[name] == "undefined") ge_bookmarklets[name] = {}; else if(ge_bookmarklets[name].active) % 20return; ge_bookmarklets[name].parameter = "%s"; ge_bookmarklets.currentName = name; ge_bookmarklets[name].active = true; var head = document.getElementsByTagName("head").item(0); var script = document.createElement("script"); script.src = "http://js.gibney.org/" + name + ".js"; script.type = "text/javascript"; head.appendChild(script); }*/ // ====================================================================== // ge_Highlighter ------------------------------------------------------------------------------------------- function ge_Highlighter(instanceName) { this.instanceName = instanceName; this.lastObj = false; this.lastObjBackgroundColor = false; this.lastObjBackgroundImage = false; // for color cycling this.colorAngle = 0; this.colorAmplitude = 15; this.colorCurrent = '#ebebdc'; this.cycleId = false; this.activate = function() { this.cycleId = window.setInterval(this.instanceName + ".setBackground()", 250); document.onmousemove = new Function("e", this.instanceName + ".highlight(e);"); } this.deactivate = function() { window.clearInterval(this.cycleId); document.onmousemove = null; this.restoreObjState(); } this.highlight = function(e) { var Obj = isDOM ? e.target: event.srcElement; this.restoreObjState(); this.lastObj = Obj; this.saveObjState(); if (Obj.style) { this.lastObj.style.backgroundColor = this.colorCurrent; this.lastObj.style.backgroundImage = 'none'; } } this.setBackground = function() { if (!this.lastObj) return; if (!this.lastObj.style) return; var dec = (250 - this.colorAmplitude) + (this.colorAmplitude * Math.sin(this.colorAngle)); dec = Math.floor(dec); var hex = dec.toString(16); if (hex.length == 1) { hex = '0' + hex; } this.colorCurrent = '#' + hex + hex + 'dc' this.lastObj.style.backgroundColor = this.colorCurrent; this.colorAngle += 0.5; } this.restoreObjState = function() { if (this.lastObjBackgroundColor !== false) { this.lastObj.style.backgroundColor = this.lastObjBackgroundColor; this.lastObj.style.backgroundImage = this.lastObjBackgroundImage; } } this.saveObjState = function() { if (this.lastObj.style && this.lastObj.style) { this.lastObjBackgroundColor = this.lastObj.style.backgroundColor; if (!this.lastObjBackgroundColor) { this.lastObjBackground = 'transparent' }; this.lastObjBackgroundImage = this.lastObj.style.backgroundImage; if (!this.lastObjBackgroundImage) { this.lastObjBackgroundImage = '' }; } else { this.lastObjBackgroundColor = false; this.lastObjBackgroundImage = false; } } } // ge_Editor ------------------------------------------------------------------------------------------------- function ge_Editor(instanceName) { this.instanceName = instanceName; this.editObj = false; this.editorDiv = false; // add highlighting of the current element this.highlighter = new ge_Highlighter(this.instanceName + '.highlighter'); this.enterEditMode = function() { this.highlighter.deactivate(); removeDiv('ge_editor_div'); document.onclick = null; document.onkeyup = null; // trap clicks, so one cannot accidentaly move away from the page while editing: document.onclick = new Function("e", this.instanceName + ".onClickInEditMode(e); return false;"); } this.leaveEditMode = function() { this.highlighter.activate(); document.onclick = new Function("e", this.instanceName + ".edit(e); return false;"); document.onkeyup = new Function("e", this.instanceName + ".deactivateOnEsc(e); return false;"); } this.activate = function() { this.highlighter.activate(); document.onclick = new Function("e", this.instanceName + ".edit(e); return false;"); document.onkeyup = new Function("e", this.instanceName + ".deactivateOnEsc(e); return false;"); this.name = ge_bookmarklets.currentName; ge_bookmarklets[this.name].active = true; } this.deactivate = function() { this.highlighter.deactivate(); removeDiv('ge_editor_div'); document.onclick = null; document.onkeyup = null; if (ge_bookmarklets[this.name].active == true) { delete ge_bookmarklets[this.name]['active']; } } this.onClickInEditMode = function(e) { // we dont do anything here. Clicks are handled by the onclick events // of the editor dialog. } this.deactivateOnEsc = function(e) { if (!e) { e = window.event; } if (e.keyCode == 27) { this.deactivate(); } } this.o this.edit = function(e) { // this.deactivate(); this.enterEditMode(); document.onkeyup = new Function("e", this.instanceName + ".deactivateOnEsc(e); return false;"); this.editObj = isDOM ? e.target: event.srcElement; var editorWidth = 400; var editorHeight = 300; var editorX = ge_view_getScrollX() + (ge_view_getWidth() / 2) - (editorWidth / 2); var editorY = ge_view_getScrollY() + (ge_view_getHeight() / 2) - (editorHeight / 2); this.setEditValue = function(e){ switch (e.tagName) { case 'INPUT' : editValue = e.value; break; case 'IMG' : editValue = e.src; if(e.parentNode.nodeName == 'A') { editLink = e.parentNode; } break; case 'A' : editValue = e.innerHTML; editLink = e.href; break; default : editValue = e.innerHTML; } } var editValue; var editLink; this.setEditValue(this.editObj); this.setBreadcrumb = function(e) { var allParents = getParents(e); var path = '<a href="#" title="'; for(value in allParents) { switch(allParents[value].nodeName) { case undefined: break; case '#document': break; case 'HTML': path += allParents[value].nodeName; break; default: path += allParents[value].nodeName + '<'; break; } } path += ' ">' + e.nodeName + '</a>'; return path; } var content = '<div style="border:1px solid #000;background-color: #fff;padding:10px;">'; content += '<div id="breadcrumb">' + this.setBreadcrumb(this.editObj) + '</div>'; content += '<textarea class="downDOM" id="ge_editor_obj_edit" style="border:1px solid #000;min-height:0px;min-width:0px;height:' + editorHeight + 'px;width:' + editorWidth + 'px;border=1px solid #000;">'; content += editValue.replace(/</gi, '<'); content += '</text'+'area><br>'; if(editLink != undefined) { content += '<div><input style="border:1px solid #000;min-height:0px;min-width:0px;width:' + editorWidth + 'px;border=1px solid #000;"' + editorWidth + 'px;background-color:#fff;text-align:right;" id="ge_editor_link_edit" value="' + editLink + '"/></div>'; }else{ content += '<div style="display:none"><input style="border:1px solid #000;min-height:0px;min-width:0px;width:' + editorWidth + 'px;border=1px solid #000;"' + editorWidth + 'px;background-color:#fff;text-align:right;" id="ge_editor_link_edit" value=""/></div>'; } content+='<div style="width:'+editorWidth+'px;background-color:#fff;text-align:right;">'; content += '<a href="#" id="htmlToggle" class="innerHTML" onclick="' + this.instanceName + '.htmlToggle(event);return false;" style="color:#090; text-decoration:none;">o</a> '; content += '<a href="#" id="upDOM" onclick="' + this.instanceName + '.upDOM(event);return false;" style="color:#090; text-decoration:none;">+</a> '; content += '<a href="#" id="downDOM" onclick="' + this.instanceName + '.downDOM(event);return false;" style="color:#090; text-decoration:none;">-</a> '; content += '<a href="#" onclick="' + this.instanceName + '.confirmEdit(event);return false;" style="color:#090; text-decoration:none;">OK</a> '; content += '<a href="#" onclick="' + this.instanceName + '.cancelEdit(event);return false;" style="color:#900; text-decoration:none;">X</a></div>'; content += '</div>'; this.editorDiv = createDiv('ge_editor_div', editorX, editorY, content); this.editorDiv.style.zIndex = 9999; var childTest = checkChild(this.editObj); if( childTest['cancelDown'] == true ) { document.getElementById('downDOM').setAttribute('onclick', 'return false;'); document.getElementById('downDOM').setAttribute('style', 'color:gray; text-decoration:none;'); } } this.htmlToggle = function(e) { if(document.getElementById('htmlToggle').getAttribute('class') == "innerHTML") { document.getElementById('ge_editor_obj_edit').value = this.editObj.outerHTML; document.getElementById('htmlToggle').setAttribute('class', 'outerHTML'); document.getElementById('htmlToggle').innerHTML = 'i'; } else if (document.getElementById('htmlToggle').getAttribute('class') == "outerHTML") { document.getElementById('ge_editor_obj_edit').value = this.editObj.innerHTML; document.getElementById('htmlToggle').setAttribute('class', 'innerHTML'); document.getElementById('htmlToggle').innerHTML = 'o'; } } this.downDOM = function(e) { //refactor this in to a function //setting htmlToggle back to outer document.getElementById('htmlToggle').setAttribute('class', 'innerHTML'); document.getElementById('htmlToggle').innerHTML = 'o'; var editValueNew = checkChild(this.editObj); if(editValueNew['editValue'] != null) { switch(editValueNew['editValue'].tagName) { case 'A': document.getElementById('ge_editor_link_edit').value = editValueNew['editValue'].href; document.getElementById('ge_editor_link_edit').parentNode.setAttribute('style', 'display:block;'); break; case 'IMG': document.getElementById('ge_editor_link_edit').value = editValueNew['editValue'].src; document.getElementById('ge_editor_link_edit').parentNode.setAttribute('style', 'display:block;'); break; default: break; } document.getElementById('ge_editor_obj_edit').value = editValueNew['editValue'].innerHTML; this.editObj = editValueNew['editValue']; var breadcrumb = this.setBreadcrumb(this.editObj); document.getElementById('breadcrumb').innerHTML = breadcrumb; document.getElementById('upDOM').setAttribute('onclick', '' + this.instanceName + '.upDOM(event);return false;'); document.getElementById('upDOM').setAttribute('style', 'color:#090; text-decoration:none;'); } if(editValueNew['cancelDown'] == true) { document.getElementById('downDOM').setAttribute('onclick', 'return false;'); document.getElementById('downDOM').setAttribute('style', 'color:gray; text-decoration:none;'); } if(editValueNew['cancelDown'] == false) { document.getElementById('downDOM').setAttribute('onclick', '' + this.instanceName + '.downDOM(event);return false;'); document.getElementById('downDOM').setAttribute('style', 'color:#090; text-decoration:none;'); } return false; } this.upDOM = function(e) { //refactor this in to a function //setting htmlToggle back to outer document.getElementById('htmlToggle').setAttribute('class', 'innerHTML'); document.getElementById('htmlToggle').innerHTML = 'o'; var editValueNew = this.editObj.parentNode; document.getElementById('ge_editor_obj_edit').value = editValueNew.innerHTML; if(this.editObj.parentNode.tagName == 'BODY') { document.getElementById('upDOM').setAttribute('onclick', 'return false;'); document.getElementById('upDOM').setAttribute('style', 'color:gray; text-decoration:none;'); } if( this.editObj.parentNode.tagName != 'A' || this.editObj.parentNode.tagName != 'IMG') { document.getElementById('ge_editor_link_edit').value = undefined; document.getElementById('ge_editor_link_edit').parentNode.setAttribute('style', 'display:none;'); } this.editObj = this.editObj.parentNode; var breadcrumb = this.setBreadcrumb(this.editObj); document.getElementById('breadcrumb').innerHTML = breadcrumb; document.getElementById('downDOM').setAttribute('onclick', '' + this.instanceName + '.downDOM(event);return false;'); document.getElementById('downDOM').setAttribute('style', 'color:#090; text-decoration:none;'); } this.confirmEdit = function(e) { var editValue = document.getElementById('ge_editor_obj_edit').value; switch (this.editObj.tagName) { case 'INPUT' : this.editObj.value = editValue; break; case 'IMG' : this.editObj.src = editValue; if(document.getElementById('ge_editor_link_edit')) { var editLinkValue = document.getElementById('ge_editor_link_edit').value; this.editObj.parentNode.href = editLinkValue; } break; case 'A' : var editLinkValue = document.getElementById('ge_editor_link_edit').value; this.editObj.href = editLinkValue; if(document.getElementById('htmlToggle').getAttribute('class') == "innerHTML") { this.editObj.innerHTML = editValue; } else if (document.getElementById('htmlToggle').getAttribute('class') == "outerHTML") { this.editObj.outerHTML = editValue; } break; default : if(document.getElementById('htmlToggle').getAttribute('class') == "innerHTML") { this.editObj.innerHTML = editValue; } else if (document.getElementById('htmlToggle').getAttribute('class') == "outerHTML") { this.editObj.outerHTML = editValue; } } if (!e) var e = window.event; e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); removeDiv('ge_editor_div'); this.leaveEditMode(); } this.cancelEdit = function(e) { if (!e) var e = window.event; e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation(); removeDiv('ge_editor_div'); this.leaveEditMode(); } } // Functions ------------------------------------------------------------------------------------------------- //get parent elements of obj function getParents(obj) { var results = []; while(obj.parentNode) { obj = obj.parentNode; results.push(obj); } return results; } //check if childNode is defined //if it is we return the child as an object //if not go to next //if none defined return false function checkChild(obj) { var editValueNew = new Object(); editValueNew['editValue'] = null; editValueNew['cancelDown'] = true; if(obj.childNodes[1] == undefined){return editValueNew;}else{ for( value in obj.childNodes) { value = parseInt(value); if( obj.childNodes[value].tagName !== null) { if( obj.childNodes[value].tagName == 'IMG' || obj.childNodes[value].tagName == 'A') { editValueNew['editValue'] = obj.childNodes[value]; editValueNew['cancelDown'] = true; break; }; }; if( obj.childNodes[value].innerHTML != undefined) { editValueNew['editValue'] = obj.childNodes[value]; editValueNew['cancelDown'] = false; break; }; if(obj.childNodes[value].innerHTML == undefined) { editValueNew['editValue'] = null; editValueNew['cancelDown'] = true; }; if(obj.childNodes[value] == undefined){ editValueNew['editValue'] = null; editValueNew['cancelDown'] = true; }; };//end for( value in this.editObj.childNodes) loop }; return editValueNew; }; function getMouseX(e) { var r = 0; if (isDOM) r = e.pageX; else r = event.clientX + document.body.scrollLeft; if (r < 0) r = 0; return r; } function getMouseY(e) { var r = 0; if (isDOM) r = e.pageY; else r = event.clientY + document.body.scrollTop; if (r < 0) r = 0; return r; } function getTop(Element) { if (Element.offsetParent) return Element.offsetTop + getTop(Element.offsetParent); else return Element.offsetTop; } function getLeft(Element) { if (Element.offsetParent) return Element.offsetLeft + getLeft(Element.offsetParent) else return Element.offsetLeft; } function getWidth(Element) { return Element.offsetWidth; } function getHeight(Element) { return Element.offsetHeight; } // ----------------------------------------------------------------- // Main // ----------------------------------------------------------------- function main() { if ("undefined" != typeof(ge_bookmarklet_include_mode)) return; editor = new ge_Editor('editor'); editor.activate(); message = createDiv('ge_editor_info_div', (10 + ge_view_getScrollX()), (10 + ge_view_getScrollY()), '<table style="background-color:#ffffff;border:1px solid #000000;color:#000000;"><tr><td style="padding: 0.5em;"><a href="http://en.gibney.org/bookmarklets/" target=_blank><img src="http://en.gibney.org/elements/images/mg-sign.gif" style="border: 0;"></a></td><td style="padding: 0.5em;"><b style="color: #008000;">The Editor</b> is active.<br><b>Left</b>-click on any element to edit it.<br>Press <b>ESC</b> to deactivate.</td></tr></table>'); message.style.zIndex = 9999; window.setTimeout("removeDiv('ge_editor_info_div')", 2000); } startMain();
Create a new entry at this position: