WYSIWYG Editor
Version 1.03
written by Gerald Holdsworth

Written primarily for use on the East Sutherland Camera Club website, this is an HTML WYSIWYG (What You See Is What You Get) editor. There are many others available, but this one is customised for the ESCC.

Click here for a demo

Stylesheet for 'WYSIWYG Editor':
body
{
 font-family: 'Arial', sans-serif;
 font-size:13pt;
}
textarea
{
 resize: none;
 border: 0px;
}
.Header
{
 background-color:transparent;
 font-size:16pt;
 color:black;
 font-weight: bold;
}
.Standard
{
 background-color:transparent;
 font-size:13pt;
 color:black;
 font-weight:normal;
}
.Emphasis
{
 background-color: #000077;
 font-size:13pt;
 color: white;
 font-weight:bold;
}
.SubHeader
{
 background-color:transparent;
 font-size:13pt;
 color: #FF0000;
 font-weight:normal;
}
Javascript for 'WYSIWYG Editor':
// Just add
// <textarea id="editor" style="width:750px;height:256px;"></textarea><script type="text/javascript">initEditor(document.getElementById('editor'));</script>
// into your HTML
//
buttons=new Array('Bold','Italic','JustifyFull','JustifyCenter','JustifyLeft','JustifyRight','insertHorizontalRule','removeFormat','Undo','Redo');
styles=new Array('Standard','Emphasis','Header','SubHeader');
vaopts=new Array('bottom','top','middle');
flopts=new Array('none','left','right');
imgcount=0;
if (!('indexOf' in Array.prototype))
{
 Array.prototype.indexOf= function(find, i /*opt*/)
 {
  if (i===undefined) i= 0;
  if (i<0) i+= this.length;
  if (i<0) i= 0;
  for (var n= this.length; i<n; i++)
   if (i in this && this[i]===find)
    return i;
  return -1;
 };
}
function initEditor(el)
{
 window.onscroll=function(){scrollPicture(el.id);};
 var html=el.value;
 var div1=createDiv(el);
 div1.style.height='34px';
 var div2=createDiv(el);
 var iframe=createDiv(el);
 iframe.setAttribute('textEditID',el.id);
 iframe.id='iframe';
 var foot=createDiv(el);
 for (var i=0;i<buttons.length;i++)
  createButton(buttons[i],div1,iframe);
 for (var i=0;i<styles.length;i++)
  createButton(styles[i],div2,iframe);
 createButton('Picture',div1,iframe);
 createButton('Remove HTML',div2,iframe);
 createButton('Save',foot,iframe);
 iframe.contentEditable=true;
 iframe.onkeydown=function(){AutoGrowTextArea(this)};
 iframe.onkeyup=function(){AutoGrowTextArea(this)};
 iframe.className='Standard';
 iframe.style.backgroundColor='#FFFFFF';
 iframe.style.overflow='auto';
 iframe.innerHTML=html;
 //Image Properties Dialog Box
 var div1=createDiv(el);
 div1.id='imgProp';
 div1.style.position='absolute';
 div1.style.visibility='hidden';
 div1.style.top='0px';
 div1.style.left='0px';
 div1.style.height=getViewHeight()+'px';
 div1.style.width=getViewWidth()+'px';
 div1.style.backgroundColor='#333333';
 div1.style.opacity=0.7;
 var imgProp=document.createElement('div');
 div1.appendChild(imgProp);
 imgProp.style.textAlign='left';
 imgProp.style.margin='auto';
 imgProp.style.position='absolute';
 imgProp.style.height='108px';
 imgProp.style.width=el.style.width;
 imgProp.style.top=((getViewHeight()-parseInt(imgProp.style.height))/2)+'px';
 imgProp.style.left=((getViewWidth()-parseInt(imgProp.style.width))/2)+'px';
 imgProp.style.backgroundColor='#FFFFFF';
 imgProp.style.border='1px solid';
 imgProp.style.opacity=1;
 var e=document.createElement('B');
 e.appendChild(document.createTextNode('Show/Edit Image Properties'));
 imgProp.appendChild(e);
 imgProp.appendChild(document.createElement('hr'));
 imgProp.appendChild(document.createTextNode('URL:'));
 e=document.createElement('input');
 e.type='text';
 e.name='url';
 e.maxlength='300';
 e.size='100';
 imgProp.appendChild(e);
 imgProp.appendChild(document.createElement('br'));
 imgProp.appendChild(document.createTextNode('Vertical Align:'));
 e=document.createElement('select');
 e.name='valign';
 for (i=0;i<vaopts.length;i++)
 {
  var opt=document.createElement('option');
  opt.value=i;
  opt.appendChild(document.createTextNode(vaopts[i]));
  e.appendChild(opt);
 }
 imgProp.appendChild(e);
 imgProp.appendChild(document.createTextNode('Float:'));
 e=document.createElement('select');
 e.name='float';
 for (i=0;i<flopts.length;i++)
 {
  var opt=document.createElement('option');
  opt.value=i;
  opt.appendChild(document.createTextNode(flopts[i]));
  e.appendChild(opt);
 }
 imgProp.appendChild(e);
 imgProp.appendChild(document.createElement('br'));
 createButton('OK',imgProp,iframe);
 createButton('Cancel',imgProp,iframe);
 e=document.createElement('input');
 e.type='hidden';
 e.name='cmd';
 e.value='none';
 imgProp.appendChild(e);
 //imgProp.style.visibility='hidden';
 e=document.createElement('input');
 e.type='hidden';
 e.name='imgid';
 e.value='none';
 imgProp.appendChild(e);
 //Adapt the original element as an HTML editor
 el.style.position="absolute";
 var X=0,Y=0;
 el.style.top=Y+'px';
 el.style.left=X+'px';
 el.style.width='300px';
 el.style.height=getViewHeight()/2;
 el.setAttribute('basePosY',Y);
 el.setAttribute('basePosX',X);
 el.onkeydown=function(){AutoGrowTextArea(this)};
 el.onkeyup=function(){AutoGrowTextArea(this)};
 //Resize the edit area
 iframe.focus();
 AutoGrowTextArea(iframe);
}
function getViewWidth()
{
 if (typeof window.innerWidth!='undefined')
  w=window.innerWidth;
 else if (typeof document.documentElement!='undefined' && typeof document.documentElement.clientWidth!='undefined' && document.documentElement.clientWidth!=0)
  w=document.documentElement.clientWidth;
 else w=document.getElementsByTagName('body')[0].clientWidth;
 return w;
}
function getViewHeight()
{
 if (typeof window.innerHeight!='undefined')
  w=window.innerHeight;
 else if (typeof document.documentElement!='undefined' && typeof document.documentElement.clientHeight!='undefined' && document.documentElement.clientHeight!=0)
  w=document.documentElement.clientHeight;
 else w=document.getElementsByTagName('body')[0].clientHeight;
 return w;
}
function createDiv(el)
{
 var div=document.createElement('div');
 div.style.width=el.style.width;
 div.style.height='22px';
 div.style.backgroundColor='#007777';
 div.style.textAlign='left';
 div.style.margin='auto';
 el.parentNode.insertBefore(div,el);
 return div;
}
function createButton(v,div,editControl)
{
 var b=document.createElement('button');
 b.value=v;
 b.onclick=function(){ButtonClick(this,editControl)};
 if (buttons.indexOf(v)>=0 || v=='Picture')
 {
  var i=document.createElement('img');
  i.src=v+'.gif';
  b.appendChild(i);
 }
 else
  b.appendChild(document.createTextNode(v));
 div.appendChild(b);
}
function AutoGrowTextArea(textField)
{
 if (textField.id!='iframe')
 {
  document.getElementById('iframe').innerHTML=textField.value;
  textField=document.getElementById('iframe');
 }
 else
  document.getElementById(textField.getAttribute('textEditID')).value=textField.innerHTML;
 textField.style.height = '512px';
// while (textField.clientHeight < textField.scrollHeight)
//  textField.style.height=(parseInt(textField.style.height)+10)+'px';
// while (textField.clientHeight > textField.scrollHeight)
//  textField.style.height=(parseInt(textField.style.height)-1)+'px';
}
function extractCR(text)
{
 var x=text.split('\n');
 var t=x.join('<br>');
 return t;
}
function ButtonClick(btn,el)
{
 var cmdbtn=btn.value;
 var html=el.innerHTML;
 closeImgProp();
 var select
 if (window.getSelection)
  select= window.getSelection();
 else if (document.selection)
  select= document.selection.createRange();
 if (cmdbtn!='OK') range = getRangeObject(select);
 if (buttons.indexOf(cmdbtn)>=0)
  document.execCommand(cmdbtn,0,'');
 if (styles.indexOf(cmdbtn)>=0)
  document.execCommand('insertHTML',0,'<span class="'+cmdbtn+'">'+range.toString()+'</span>');//Does not work in IE - insertHTML is unsupported
 if (cmdbtn=='Picture')
  openImgProp('Insert','http://www.reptonresourcepage.co.uk/RepLogos/Reptonbig.gif','bottom','none','');
 if (cmdbtn=='OK' && document.getElementsByName('cmd')[0].value=='Insert')
 {
  el.focus();
  var select=document.getElementsByName('url')[0].value;
  if (select!='')
  {
   document.execCommand('insertImage',0,'none');
   html=el.innerHTML;
   var s='<img src="'+select+'" id="image'+imgcount+'" ondblclick="mouseClick(this);"';
   s=s+' style="vertical-align:'+vaopts[document.getElementsByName('valign')[0].value]+';';
   s=s+' float:'+flopts[document.getElementsByName('float')[0].value]+';"';
   html=html.replace('<img src="none"',s);
   imgcount++;
   el.innerHTML=html;
  }
 }
 if (cmdbtn=='OK' && document.getElementsByName('cmd')[0].value=='Edit')
 {
  el.focus();
  var id=document.getElementsByName('imgid')[0].value;
  var imgel=document.getElementById(id);
  imgel.src=document.getElementsByName('url')[0].value;
  imgel.style.verticalAlign=vaopts[document.getElementsByName('valign')[0].value];
  imgel.style.float=flopts[document.getElementsByName('float')[0].value];
 }
 if (cmdbtn=='Remove HTML')
  if (el.innerText) el.innerHTML=extractCR(el.innerText);
  else el.innerHTML=extractCR(el.textContent);
 if (cmdbtn=='Save')
 {
  html=html.replace(' ondblclick="mouseClick(this);"','');
  html=html.replace('</div><div>','<br>');
  html=extractCR(html);
  alert(html);
 }
 el.focus();
 AutoGrowTextArea(el);
}
function getRangeObject(selectionObject)
{
 var saveRange;
 if (selectionObject.getRangeAt)
  saveRange=selectionObject.getRangeAt(0);
 else
 if (document.createRange)
 {
  saveRange = document.createRange();
  saveRange.setStart(selectionObject.anchorNode,selectionObject.anchorOffset);
  saveRange.setEnd(selectionObject.focusNode,selectionObject.focusOffset);
 }
 return saveRange;
}
function mouseClick(el)
{
 openImgProp('Edit',el.src,el.style.verticalAlign || 'bottom',ifloat=el.style.float || 'none',el.id);
}
function openImgProp(cmd,url,valign,ifloat,id)
{
 var title='Invalid Command';
 if (cmd=='Edit') title='Edit Image Properties';
 if (cmd=='Insert') title='Insert New Image';
 var imgProp=document.getElementById('imgProp');
 imgProp.style.visibility='visible';
 imgProp.childNodes[0].style.top=((getViewHeight()-parseInt(imgProp.childNodes[0].style.height))/2)+'px';
 imgProp.childNodes[0].style.left=((getViewWidth()-parseInt(imgProp.childNodes[0].style.width))/2)+'px';
 imgProp.style.height=getViewHeight()+'px';
 imgProp.style.width=getViewWidth()+'px';
 document.getElementsByName('cmd')[0].value=cmd;
 imgProp.childNodes[0].childNodes[0].innerHTML=title;
 document.getElementsByName('valign')[0].value=vaopts.indexOf(valign);
 document.getElementsByName('float')[0].value=flopts.indexOf(ifloat);
 document.getElementsByName('url')[0].value=url;
 document.getElementsByName('url')[0].focus();
 document.getElementsByName('imgid')[0].value=id;
}
function closeImgProp()
{
 document.getElementById('imgProp').style.visibility='hidden';
}
function scrollPicture(id)
{
 var el=document.getElementById(id);
 var X=el.getAttribute('basePosX');
 var Y=el.getAttribute('basePosY');
 el.style.top=parseInt(window.pageYOffset)+parseInt(Y)+'px';
 el.style.left=parseInt(window.pageXOffset)+parseInt(X)+'px';
}
Click here to download.

If you would like to email me, put gerald@ in front of the domain name, insead of www..
©2011-2020 Gerald Holdsworth IT Services