WYSIWYG - A purebasic and javascript approach

Everything else that doesn't fall into one of the other PB categories.
Dare
Addict
Addict
Posts: 1965
Joined: Mon May 29, 2006 1:01 am
Location: Outback

WYSIWYG - A purebasic and javascript approach

Post by Dare »

This is a proof of concept.

Using routines released by Freak here:
http://www.purebasic.fr/english/viewtopic.php?t=16968

And some javascript written by me (this, being translated, means klunkie code) :)

It shows how we can expose the DOM of an html document and so use it to do WYSIWYG editing.

The file is available here:
http://www.gemcutters.net/pbOddments/wysiwyg.zip

It contains source purebasic and js/html. You will need to remove the end from the purebasic to make it run.


I have had a few private messages recently asking if I had a solution to WYSIWYG. I do, but they all cost money. :)

So I klurged this.

I have forgotten who all I spoke to so if you contacted me then I hope you see this and I hope it helps.

On the "hope" front:

Hopefully this has merit - and if so, then hopefully smarter programmers than I will evolve this into something worthwhile and share the evolutionary process with us all.

I believe that because the DOM is exposed just about anything can be done via this approach, from basic HTML editing to full CSS driven editing.


Note: It is not a full blown HTML editor, just a proof of concept.
Dare2 cut down to size
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Post by DarkDragon »

Huh? Another one searching for a multi platform solution?

Just a few weeks before I made this:

Code: Select all

Global defaultCode.s

defaultCode = "<!DOCTYPE HTML PUBLIC " + Chr(34) + "-//W3C//DTD HTML 4.01 Transitional//EN" + Chr(34) + " " + Chr(34) + "http://www.w3.org/TR/html4/loose.dtd" + Chr(34) + ">"
defaultCode + Chr(10) + "<html>"
defaultCode + Chr(10) + " <head>"
defaultCode + Chr(10) + "  <title>JavaScript Test</title>"
defaultCode + Chr(10) + "  <meta HTTP-EQUIV=" + Chr(34) + "Content-Type" + Chr(34) + " CONTENT=" + Chr(34) + "text/html; charset=ISO-8859-1" + Chr(34) + ">"
defaultCode + Chr(10) + "  <meta name=" + Chr(34) + "generator" + Chr(34) + " content=" + Chr(34) + "HTML Studio" + Chr(34) + ">"
defaultCode + Chr(10) + "<style type=" + Chr(34) + "text/css" + Chr(34) + ">"
defaultCode + Chr(10) + "<!--"
defaultCode + Chr(10) + "#wysiwyg_iframe {"
defaultCode + Chr(10) + " width : 800px;"
defaultCode + Chr(10) + " height: 600px;"
defaultCode + Chr(10) + " border: 1px solid #000000;"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + "-->"
defaultCode + Chr(10) + "</style>"
defaultCode + Chr(10) + " </head>"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "<script language=" + Chr(34) + "JavaScript" + Chr(34) + ">"
defaultCode + Chr(10) + "//<!--"
defaultCode + Chr(10) + "var usedTag = " + Chr(34) + "wysiwyg_iframe" + Chr(34) + ";"
defaultCode + Chr(10) + "var usedDocument = document;"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function replaceEx(txt, srch, rplc) {"
defaultCode + Chr(10) + "  for(var i = 0; i < txt.length - srch.length + 1; i++) {"
defaultCode + Chr(10) + "    if(txt.substr(i, srch.length) == srch) {"
defaultCode + Chr(10) + "      txt = txt.substr(0, i) + rplc + txt.substring(i + srch.length, txt.length);"
defaultCode + Chr(10) + "    }"
defaultCode + Chr(10) + "  }"
defaultCode + Chr(10) + "  return txt;"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function Init() {"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "  if(navigator.appName.search(" + Chr(34) + "Microsoft Internet Explorer" + Chr(34) + ") != -1) {"
defaultCode + Chr(10) + "    parent.frames[" + Chr(34) + "wysiwyg" + Chr(34) + "].document.designMode = " + Chr(34) + "on" + Chr(34) + ";"
defaultCode + Chr(10) + "    usedDocument = parent.frames[" + Chr(34) + "wysiwyg" + Chr(34) + "].document;"
defaultCode + Chr(10) + "  }else{"
defaultCode + Chr(10) + "    usedTag = " + Chr(34) + "wysiwyg_iframe" + Chr(34) + ";"
defaultCode + Chr(10) + "    document.getElementById(usedTag).contentDocument.designMode = " + Chr(34) + "on" + Chr(34) + ";"
defaultCode + Chr(10) + "    usedDocument = parent.frames[" + Chr(34) + "wysiwyg" + Chr(34) + "].document;"
defaultCode + Chr(10) + "  }"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function Bold() {"
defaultCode + Chr(10) + "  usedDocument.execCommand(" + Chr(34) + "bold" + Chr(34) + ", false, null);"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function Italic() {"
defaultCode + Chr(10) + "  usedDocument.execCommand(" + Chr(34) + "italic" + Chr(34) + ", false, null);"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function Underline() {"
defaultCode + Chr(10) + "  usedDocument.execCommand(" + Chr(34) + "underline" + Chr(34) + ", false, null);"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function StrikeThrough() {"
defaultCode + Chr(10) + "  usedDocument.execCommand(" + Chr(34) + "strikethrough" + Chr(34) + ", false, null);"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function GetBackColor() {"
defaultCode + Chr(10) + "  return usedDocument.queryCommandValue(" + Chr(34) + "backcolor" + Chr(34) + ");"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function SetBackColor(Color) {"
defaultCode + Chr(10) + "  usedDocument.execCommand(" + Chr(34) + "backcolor" + Chr(34) + ", false, Color);"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function GetForeColor() {"
defaultCode + Chr(10) + "  return usedDocument.queryCommandValue(" + Chr(34) + "forecolor" + Chr(34) + ");"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function SetForeColor(Color) {"
defaultCode + Chr(10) + "  usedDocument.execCommand(" + Chr(34) + "forecolor" + Chr(34) + ", false, Color);"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function GetFontSize() {"
defaultCode + Chr(10) + "  return usedDocument.queryCommandValue(" + Chr(34) + "fontsize" + Chr(34) + ");"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function SetFontSize(Color) {"
defaultCode + Chr(10) + "  usedDocument.execCommand(" + Chr(34) + "fontsize" + Chr(34) + ", false, Color);"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function GetFontName() {"
defaultCode + Chr(10) + "  return usedDocument.queryCommandValue(" + Chr(34) + "fontname" + Chr(34) + ");"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function SetFontName(Color) {"
defaultCode + Chr(10) + "  usedDocument.execCommand(" + Chr(34) + "fontname" + Chr(34) + ", false, Color);"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function Justify(Where) {"
defaultCode + Chr(10) + "  usedDocument.execCommand(" + Chr(34) + "justify" + Chr(34) + "+Where.toLowerCase(), false, null);"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function InsertImage(Source) {"
defaultCode + Chr(10) + "  usedDocument.execCommand(" + Chr(34) + "insertimage" + Chr(34) + ", false, Source);"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function GetHTMLText() {"
defaultCode + Chr(10) + "  return usedDocument.body.innerHTML;"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function SetHTMLText(sText) {"
defaultCode + Chr(10) + "  usedDocument.body.innerHTML = sText;"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function ChangeFont() {"
defaultCode + Chr(10) + "  SetFontName(document.getElementById(" + Chr(34) + "wysiwyg_font" + Chr(34) + ").value);"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function ChangeColor() {"
defaultCode + Chr(10) + "  SetForeColor(document.getElementById(" + Chr(34) + "wysiwyg_color" + Chr(34) + ").value);"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "function RefreshHTML() {"
defaultCode + Chr(10) + "  html = GetHTMLText();"
defaultCode + Chr(10) + "  if(document.title != html) {"
defaultCode + Chr(10) + "    ohtml = html"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "    if(navigator.appName.search(" + Chr(34) + "Microsoft Internet Explorer" + Chr(34) + ") != -1) {"
defaultCode + Chr(10) + "      html  = replaceEx(replaceEx(replaceEx(html, " + Chr(34) + "<P>&nbsp;</P>" + Chr(34) + ", " + Chr(34) + "<br>" + Chr(34) + "), " + Chr(34) + "<P>" + Chr(34) + ", " + Chr(34) + "" + Chr(34) + "), " + Chr(34) + "</P>" + Chr(34) + ", " + Chr(34) + "" + Chr(34) + ");"
defaultCode + Chr(10) + "    }"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "    document.title = " + Chr(34) + "<!--" + Chr(34) + " + " + Chr(34) + "CODE START" + Chr(34) + " + " + Chr(34) + "-->" + Chr(34) + " + html + " + Chr(34) + "<!--" + Chr(34) + " + " + Chr(34) + "CODE END" + Chr(34) + " + " + Chr(34) + "-->" + Chr(34) + ";"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "    if(ohtml != html) {"
defaultCode + Chr(10) + "      SetHTMLText(html);"
defaultCode + Chr(10) + "    }"
defaultCode + Chr(10) + "  }"
defaultCode + Chr(10) + "  window.setTimeout(" + Chr(34) + "RefreshHTML()" + Chr(34) + ", 100);"
defaultCode + Chr(10) + "}"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "window.setTimeout(" + Chr(34) + "RefreshHTML()" + Chr(34) + ", 100);"
defaultCode + Chr(10) + "//-->"
defaultCode + Chr(10) + "</script>"
defaultCode + Chr(10) + " <body onLoad=" + Chr(34) + "Init()" + Chr(34) + " bgcolor=" + Chr(34) + "#FFFFFF" + Chr(34) + ">"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "<input type=" + Chr(34) + "button" + Chr(34) + " value=" + Chr(34) + "Bold" + Chr(34) + " onClick=" + Chr(34) + "Bold()" + Chr(34) + ">"
defaultCode + Chr(10) + "<input type=" + Chr(34) + "button" + Chr(34) + " value=" + Chr(34) + "Italic" + Chr(34) + " onClick=" + Chr(34) + "Italic()" + Chr(34) + ">"
defaultCode + Chr(10) + "<input type=" + Chr(34) + "button" + Chr(34) + " value=" + Chr(34) + "Underlined" + Chr(34) + " onClick=" + Chr(34) + "Underline()" + Chr(34) + ">"
defaultCode + Chr(10) + "<input type=" + Chr(34) + "button" + Chr(34) + " value=" + Chr(34) + "Strike" + Chr(34) + " onClick=" + Chr(34) + "StrikeThrough()" + Chr(34) + ">&nbsp;"
defaultCode + Chr(10) + "<input type=" + Chr(34) + "button" + Chr(34) + " value=" + Chr(34) + "left" + Chr(34) + " onClick=" + Chr(34) + "Justify('left')" + Chr(34) + ">"
defaultCode + Chr(10) + "<input type=" + Chr(34) + "button" + Chr(34) + " value=" + Chr(34) + "center" + Chr(34) + " onClick=" + Chr(34) + "Justify('center')" + Chr(34) + ">"
defaultCode + Chr(10) + "<input type=" + Chr(34) + "button" + Chr(34) + " value=" + Chr(34) + "right" + Chr(34) + " onClick=" + Chr(34) + "Justify('right')" + Chr(34) + ">"
defaultCode + Chr(10) + "<input type=" + Chr(34) + "button" + Chr(34) + " value=" + Chr(34) + "block" + Chr(34) + " onClick=" + Chr(34) + "Justify('full')" + Chr(34) + ">"
defaultCode + Chr(10) + "<input type=" + Chr(34) + "button" + Chr(34) + " value=" + Chr(34) + "Image" + Chr(34) + " onClick=" + Chr(34) + "InsertImage('http://www.bradan.eu/title.gif')" + Chr(34) + ">"
defaultCode + Chr(10) + "<select size=" + Chr(34) + "1" + Chr(34) + " id=" + Chr(34) + "wysiwyg_font" + Chr(34) + " onChange=" + Chr(34) + "ChangeFont()" + Chr(34) + ">"
defaultCode + Chr(10) + "<option value=" + Chr(34) + "Arial" + Chr(34) + ">Arial</option>"
defaultCode + Chr(10) + "<option value=" + Chr(34) + "Verdana" + Chr(34) + ">Verdana</option>"
defaultCode + Chr(10) + "<option value=" + Chr(34) + "Courier" + Chr(34) + ">Courier</option>"
defaultCode + Chr(10) + "</select>"
defaultCode + Chr(10) + "<select size=" + Chr(34) + "1" + Chr(34) + " id=" + Chr(34) + "wysiwyg_color" + Chr(34) + " onChange=" + Chr(34) + "ChangeColor()" + Chr(34) + ">"
defaultCode + Chr(10) + "<option value=" + Chr(34) + "#000000" + Chr(34) + " style=" + Chr(34) + "color:#000000" + Chr(34) + ">Black</option>"
defaultCode + Chr(10) + "<option value=" + Chr(34) + "#FFFFFF" + Chr(34) + " style=" + Chr(34) + "color:#FFFFFF" + Chr(34) + ">White</option>"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "<option value=" + Chr(34) + "#FF0000" + Chr(34) + " style=" + Chr(34) + "color:#FF0000" + Chr(34) + ">Red</option>"
defaultCode + Chr(10) + "<option value=" + Chr(34) + "#00FF00" + Chr(34) + " style=" + Chr(34) + "color:#00FF00" + Chr(34) + ">Green</option>"
defaultCode + Chr(10) + "<option value=" + Chr(34) + "#0000FF" + Chr(34) + " style=" + Chr(34) + "color:#0000FF" + Chr(34) + ">Blue</option>"
defaultCode + Chr(10) + "<option value=" + Chr(34) + "#FFFF00" + Chr(34) + " style=" + Chr(34) + "color:#FFFF00" + Chr(34) + ">Yellow</option>"
defaultCode + Chr(10) + "</select>"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "<br>"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + "<div id=" + Chr(34) + "wysiwyg_edit" + Chr(34) + " style=" + Chr(34) + "width: 760px; height: 530px; overflow: scroll; position:absolute; z-index: 1;" + Chr(34) + "><iframe id=" + Chr(34) + "wysiwyg_iframe" + Chr(34) + " name=" + Chr(34) + "wysiwyg" + Chr(34) + "></iframe></div>"
defaultCode + Chr(10) + ""
defaultCode + Chr(10) + " </body>"



If OpenWindow(0, 0, 0, 800, 600, "WebGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
  WebGadget(0, 0, 0, 800, 600, "about:blank")
  
  Repeat
    Select WaitWindowEvent(500)
      Case #WM_KEYUP
        Debug GetGadgetItemText(0, #PB_Web_PageTitle)
      Case #PB_Event_CloseWindow
        Break
      Case #PB_Event_Gadget
        If EventType() = #PB_EventType_DownloadEnd
          If abc = 0
            SetGadgetItemText(0, #PB_Web_HtmlCode, defaultCode)
            abc = 1
          EndIf
        EndIf
    EndSelect
  ForEver
EndIf
bye,
Daniel
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

Nice one Daniel, THNX :o
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Dare
Addict
Addict
Posts: 1965
Joined: Mon May 29, 2006 1:01 am
Location: Outback

Post by Dare »

Hi Darkdragon,

Nice.

I also went that way for a time but prefer to have the main control of the thing in Purebasic and so kept the JS down to a minimum.

You can whack an HTMLarea (or similar) page in and get a wysiwyg look-alike as well.

Any thoughts on using the hooks via Freak's code? It makes life easier (I think) and it would be neat if a linux guru could provide something similar for that OS.
Dare2 cut down to size
DarkDragon
Addict
Addict
Posts: 2344
Joined: Mon Jun 02, 2003 9:16 am
Location: Germany
Contact:

Post by DarkDragon »

Dare wrote:Hi Darkdragon,

Nice.

I also went that way for a time but prefer to have the main control of the thing in Purebasic and so kept the JS down to a minimum.

You can whack an HTMLarea (or similar) page in and get a wysiwyg look-alike as well.

Any thoughts on using the hooks via Freak's code? It makes life easier (I think) and it would be neat if a linux guru could provide something similar for that OS.
Yes I also thought about that, but I don't think it's easy to port it, because what are GUIDs on Linux, how to get the Midas interfaces, ...?

I found a few nice pages about the Mozilla editing thing:

http://www.mozilla.org/editor/midas-spec.html
http://www.mozilla.org/editor/

On the second page you can find some shared objects and dlls. Maybe that would even be smarter than using IE wysiwyg and Mozilla (Gecko) separately.
bye,
Daniel
Post Reply