
Wyszedłem z nieco innego założenia:
1. mamy niewidoczne textarea (białe, czcionka biała)
2. onKeypress tego textarea jego zawartość leci ajaxem do serwera (biedny serwer)
3. serwer robi highlight_string lub coś i ajaxem aktualizuje treść diva
4. ten div ma określone położenie - dokładnie nad textarea

oto zarys koncepcji który "działa": demo
plik.php
IF(isset($_POST['code'])) { highlight_string("<?php\n".stripslashes($_POST['code'])."\n?>"); // albo geshi kolorujący html ze smartym itd. :) } else { echo '<html><head> <style> body { border: 0px; padding: 0px; margin:0px; } .contentarea { position: absolute; top: 0%; left: 0%; font-size:12px; font-family:verdana; } .textarea { position: absolute; top: 2%; left: 0%; opacity:10%; color: white; border: 0px; font-size:12px; font-family:verdana; background-color: transparent; white; } </style> <!-- //Basic Ajax Routine- Author: Dynamic Drive (http://www.dynamicdrive.com) --><script language="JavaScript" src="ajaxroutine.js" charset="utf-8"></script></head><body>'; echo '<textarea id="textarea" class="textarea" rows="100" cols="90" onKeypress="ajaxpack.postAjaxRequest('plik.php', 'code='+document.getElementById('textarea').value, processGetPost(), 'txt');"></textarea>'; echo '<div id="contentarea" class="contentarea"></div></body></html>'; }
ajaxroutine.js
Kod
//Basic Ajax Routine- Author: Dynamic Drive (http://www.dynamicdrive.com)
//Last updated: Jan 15th, 06'
function createAjaxObj()
{
var httprequest=false
if (window.XMLHttpRequest)
{ // if Mozilla, Safari etc
httprequest=new XMLHttpRequest()
if (httprequest.overrideMimeType)
httprequest.overrideMimeType('text/xml')
}
else if (window.ActiveXObject)
{ // if IE
try
{
httprequest=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
httprequest=new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{}
}
}
return httprequest
}
var ajaxpack=new Object()
ajaxpack.basedomain="http://"+window.location.hostname
ajaxpack.ajaxobj=createAjaxObj()
ajaxpack.filetype="txt"
ajaxpack.addrandomnumber=0 //Set to 1 or 0. See documentation.
ajaxpack.getAjaxRequest=function(url, parameters, callbackfunc, filetype)
{
ajaxpack.ajaxobj=createAjaxObj() //recreate ajax object to defeat cache problem in IE
if (ajaxpack.addrandomnumber==1) //Further defeat caching problem in IE?
var parameters=parameters+"&ajaxcachebust="+new Date().getTime()
if (this.ajaxobj)
{
this.filetype=filetype
this.ajaxobj.onreadystatechange=callbackfunc
this.ajaxobj.open('GET', url+"?"+parameters, true)
this.ajaxobj.send(null)
}
}
ajaxpack.postAjaxRequest=function(url, parameters, callbackfunc, filetype)
{
ajaxpack.ajaxobj=createAjaxObj() //recreate ajax object to defeat cache problem in IE
if (this.ajaxobj)
{
this.filetype=filetype
this.ajaxobj.onreadystatechange = callbackfunc;
this.ajaxobj.open('POST', url, true);
this.ajaxobj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
this.ajaxobj.setRequestHeader("Content-length", parameters.length);
this.ajaxobj.setRequestHeader("Connection", "close");
this.ajaxobj.send(parameters);
}
}
var bustcachevar=1 //bust potential caching of external pages after initial request? (1=yes, 0=no)
var loadedobjects=""
var rootdomain="http://"+window.location.hostname
function ajaxpage(url, containerid)
{
var page_request = false
if (window.XMLHttpRequest) // if Mozilla, Safari etc
page_request = new XMLHttpRequest()
else if (window.ActiveXObject)
{ // if IE
try
{
page_request = new ActiveXObject("Msxml2.XMLHTTP")
}
catch (e)
{
try
{
page_request = new ActiveXObject("Microsoft.XMLHTTP")
}
catch (e)
{}
}
}
else
return false
page_request.onreadystatechange=function()
{
loadpage(page_request, containerid)
}
if (bustcachevar) //if bust caching of external page
var bustcacheparameter=(url.indexOf("?")!=-1)? "&"+new Date().getTime() : "?"+new Date().getTime()
page_request.open('GET', url+bustcacheparameter, true)
page_request.send(null)
}
function loadpage(page_request, containerid)
{
if (page_request.readyState == 4 && (page_request.status==200 || window.location.href.indexOf("http")==-1))
document.getElementById(containerid).innerHTML=page_request.responseText
}
function loadobjs()
{
if (!document.getElementById)
return
for (i=0; i<arguments.length; i++)
{
var file=arguments[i]
var fileref=""
if (loadedobjects.indexOf(file)==-1)
{ //Check to see if this object has not already been added to page before proceeding
if (file.indexOf(".js")!=-1)
{ //If object is a js file
fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", file);
}
else if (file.indexOf(".css")!=-1)
{ //If object is a css file
fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", file);
}
}
if (fileref!="")
{
document.getElementsByTagName("head").item(0).appendChild(fileref)
loadedobjects+=file+" " //Remember this object as being already added to page
}
}
}
function processGetPost(code)
{
var myajax=ajaxpack.ajaxobj
var myfiletype=ajaxpack.filetype
if (myajax.readyState == 4)
{ //if request of file completed
if (myajax.status==200 || window.location.href.indexOf("http")==-1)
{ //if request was successful or running script locally
if (myfiletype=="txt")
{
document.getElementById('contentarea').innerHTML=myajax.responseText
}
else if (myfiletype=="xml")
{
return interact(myajax.responseXml, code)
}
}
}
}
//Last updated: Jan 15th, 06'
function createAjaxObj()
{
var httprequest=false
if (window.XMLHttpRequest)
{ // if Mozilla, Safari etc
httprequest=new XMLHttpRequest()
if (httprequest.overrideMimeType)
httprequest.overrideMimeType('text/xml')
}
else if (window.ActiveXObject)
{ // if IE
try
{
httprequest=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
httprequest=new ActiveXObject("Microsoft.XMLHTTP");
}
catch (e)
{}
}
}
return httprequest
}
var ajaxpack=new Object()
ajaxpack.basedomain="http://"+window.location.hostname
ajaxpack.ajaxobj=createAjaxObj()
ajaxpack.filetype="txt"
ajaxpack.addrandomnumber=0 //Set to 1 or 0. See documentation.
ajaxpack.getAjaxRequest=function(url, parameters, callbackfunc, filetype)
{
ajaxpack.ajaxobj=createAjaxObj() //recreate ajax object to defeat cache problem in IE
if (ajaxpack.addrandomnumber==1) //Further defeat caching problem in IE?
var parameters=parameters+"&ajaxcachebust="+new Date().getTime()
if (this.ajaxobj)
{
this.filetype=filetype
this.ajaxobj.onreadystatechange=callbackfunc
this.ajaxobj.open('GET', url+"?"+parameters, true)
this.ajaxobj.send(null)
}
}
ajaxpack.postAjaxRequest=function(url, parameters, callbackfunc, filetype)
{
ajaxpack.ajaxobj=createAjaxObj() //recreate ajax object to defeat cache problem in IE
if (this.ajaxobj)
{
this.filetype=filetype
this.ajaxobj.onreadystatechange = callbackfunc;
this.ajaxobj.open('POST', url, true);
this.ajaxobj.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
this.ajaxobj.setRequestHeader("Content-length", parameters.length);
this.ajaxobj.setRequestHeader("Connection", "close");
this.ajaxobj.send(parameters);
}
}
var bustcachevar=1 //bust potential caching of external pages after initial request? (1=yes, 0=no)
var loadedobjects=""
var rootdomain="http://"+window.location.hostname
function ajaxpage(url, containerid)
{
var page_request = false
if (window.XMLHttpRequest) // if Mozilla, Safari etc
page_request = new XMLHttpRequest()
else if (window.ActiveXObject)
{ // if IE
try
{
page_request = new ActiveXObject("Msxml2.XMLHTTP")
}
catch (e)
{
try
{
page_request = new ActiveXObject("Microsoft.XMLHTTP")
}
catch (e)
{}
}
}
else
return false
page_request.onreadystatechange=function()
{
loadpage(page_request, containerid)
}
if (bustcachevar) //if bust caching of external page
var bustcacheparameter=(url.indexOf("?")!=-1)? "&"+new Date().getTime() : "?"+new Date().getTime()
page_request.open('GET', url+bustcacheparameter, true)
page_request.send(null)
}
function loadpage(page_request, containerid)
{
if (page_request.readyState == 4 && (page_request.status==200 || window.location.href.indexOf("http")==-1))
document.getElementById(containerid).innerHTML=page_request.responseText
}
function loadobjs()
{
if (!document.getElementById)
return
for (i=0; i<arguments.length; i++)
{
var file=arguments[i]
var fileref=""
if (loadedobjects.indexOf(file)==-1)
{ //Check to see if this object has not already been added to page before proceeding
if (file.indexOf(".js")!=-1)
{ //If object is a js file
fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", file);
}
else if (file.indexOf(".css")!=-1)
{ //If object is a css file
fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", file);
}
}
if (fileref!="")
{
document.getElementsByTagName("head").item(0).appendChild(fileref)
loadedobjects+=file+" " //Remember this object as being already added to page
}
}
}
function processGetPost(code)
{
var myajax=ajaxpack.ajaxobj
var myfiletype=ajaxpack.filetype
if (myajax.readyState == 4)
{ //if request of file completed
if (myajax.status==200 || window.location.href.indexOf("http")==-1)
{ //if request was successful or running script locally
if (myfiletype=="txt")
{
document.getElementById('contentarea').innerHTML=myajax.responseText
}
else if (myfiletype=="xml")
{
return interact(myajax.responseXml, code)
}
}
}
}
Problemy
- Jak zrobić by textarea nie miała suwaków, widocznych granic (wszystko zlewało się z tłem)
- zrobić by wskaźnik pozycji w textarea był widoczny (ładny czarny i migający

- ustawić czcionki tak by w IE/Mozilla/Opera były identyczne w textarea jak i w zwracanym tekście (tj. żeby jedno z drugim się pokrywało)
Może macie inne pomysły jak to rozwiązać.
PS. ten lib od ajaxa jest jakiś lewy.. łapie "opóźnienia" jakieś... trzeba to zrobić z prototype'm