]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/htmlarea.php
experimental WYSIWYG support
[SourceForge/phpwiki.git] / lib / htmlarea.php
1 <?php
2 /**
3  * Output the javascript function to check for MS Internet Explorer >= 5.5 on Windows
4  * and call the real js script then, else just a nil func.
5  * version 2: only for MSIE 5.5 and better
6  * version 3: also Mozilla >= 1.3
7  *
8  * @package WysiwygEdit
9  * @author Reini Urban
10  */
11
12 function Edit_WYSIWYG_Head($name='edit[content]') {
13     //return Edit_HtmlArea2_Head($name);
14     return Edit_HtmlArea3_Head($name);
15 }
16 function Edit_WYSIWYG_Textarea($textarea,$wikitext,$name='edit[content]') {
17     //return Edit_HtmlArea2_Textarea($textarea,$name);
18     return Edit_HtmlArea3_Textarea($textarea,$wikitext,$name);
19 }
20
21 function Edit_HtmlArea2_Head($name='edit[content]') {
22   return JavaScript("_editor_url = \"".DATA_PATH."/themes/default/htmlarea2/\";
23 var win_ie_ver = parseFloat(navigator.appVersion.split(\"MSIE\")[1]);
24 if (navigator.userAgent.indexOf('Mac')        >= 0) { win_ie_ver = 0; }
25 if (navigator.userAgent.indexOf('Windows CE') >= 0) { win_ie_ver = 0; }
26 if (navigator.userAgent.indexOf('Opera')      >= 0) { win_ie_ver = 0; }
27 if (win_ie_ver >= 5.5) {
28   document.write('<scr' + 'ipt src=\"' +_editor_url+ 'editor.js\"');
29   document.write(' language=\"Javascript1.2\"></scr' + 'ipt>');
30 } else {
31   document.write('<scr'+'ipt>function editor_generate() { return false; }</scr'+'ipt>'); 
32 }
33  ",
34                     array('version' => 'JavaScript1.2',
35                           'type' => 'text/javascript'));
36 }
37 // for testing only
38 function Edit_HtmlAreaHead2_IEonly() {
39     return HTML(JavaScript("_editor_url = \"".DATA_PATH."/themes/default/htmlarea2/\""),
40                 "\n",
41                 JavaScript("",
42                            array('version' => 'JavaScript1.2',
43                                  'type' => 'text/javascript',
44                                  'src' => DATA_PATH."/themes/default/htmlarea2/editor.js")));
45 }
46
47 function Edit_HtmlArea3_Head($name='edit[content]') {
48     global $WikiTheme;
49     $WikiTheme->addMoreAttr('body'," onload='initEditor()'");
50     //Todo: language selection from available lang/*.js files
51     return new RawXml('
52 <script type="text/javascript" src="'.DATA_PATH.'/themes/default/htmlarea3/htmlarea.js"></script>
53 <script type="text/javascript" src="'.DATA_PATH.'/themes/default/htmlarea3/lang/en.js"></script>
54 <script type="text/javascript" src="'.DATA_PATH.'/themes/default/htmlarea3/dialog.js"></script> 
55 <style type="text/css">
56 @import url('.DATA_PATH.'/themes/default/htmlarea3/htmlarea.css);
57 </style>
58 <script type="text/javascript">
59 _editor_url = "'.DATA_PATH.'/themes/default/htmlarea3/";
60 var editor = null;
61 function initEditor() {
62   editor = new HTMLArea("'.$name.'");
63
64   // comment the following two lines to see how customization works
65   editor.generate();
66   return false;
67   
68   // BEGIN: code that adds custom buttons
69   var cfg = editor.config; // this is the default configuration
70   function clickHandler(editor, buttonId) {
71     switch (buttonId) {
72       case "my-toc":
73         editor.insertHTML("<h1>Table Of Contents</h1>");
74         break;
75       case "my-date":
76         editor.insertHTML((new Date()).toString());
77         break;
78       case "my-bold-em":
79         editor.execCommand("bold");
80         editor.execCommand("italic");
81         break;
82       case "my-hilite":
83         editor.surroundHTML("<span class=\"hilite\">", "</span>");
84         break;
85     }
86   };
87   cfg.registerButton("my-toc",  "Insert TOC", _editor_url+"ed_custom.gif", false, clickHandler);
88   cfg.registerButton("my-date", "Insert date/time", _editor_url+"ed_custom.gif", false, clickHandler);
89   cfg.registerButton("my-bold-em", "Toggle bold/italic", _editor_url+"ed_custom.gif", false, clickHandler);
90   cfg.registerButton("my-hilite", "Hilite selection", _editor_url+"ed_custom.gif", false, clickHandler);
91   
92   cfg.registerButton("my-sample", "Class: sample", _editor_url+"ed_custom.gif", false,
93     function(editor) {
94       if (HTMLArea.is_ie) {
95         editor.insertHTML("<span class=\"sample\">&nbsp;&nbsp;</span>");
96         var r = editor._doc.selection.createRange();
97         r.move("character", -2);
98         r.moveEnd("character", 2);
99         r.select();
100       } else { // Gecko/W3C compliant
101         var n = editor._doc.createElement("span");
102         n.className = "sample";
103         editor.insertNodeAtSelection(n);
104         var sel = editor._iframe.contentWindow.getSelection();
105         sel.removeAllRanges();
106         var r = editor._doc.createRange();
107         r.setStart(n, 0);
108         r.setEnd(n, 0);
109         sel.addRange(r);
110       }
111     }
112   );
113   
114   //cfg.pageStyle = "body { background-color: #efd; } .hilite { background-color: yellow; } "+
115   //                ".sample { color: green; font-family: monospace; }";
116   // add the new button to the toolbar
117   //cfg.toolbar.push(["linebreak", "my-toc", "my-date", "my-bold-em", "my-hilite", "my-sample"]); 
118   // END: code that adds custom buttons
119
120   editor.generate();
121 }
122 function insertHTML() {
123   var html = prompt("Enter some HTML code here");
124   if (html) {
125     editor.insertHTML(html);
126   }
127 }
128 function highlight() {
129   editor.surroundHTML(\'<span style="background-color: yellow">\', \'</span>\');
130 }
131 </script>
132  ');
133 }
134
135 // to be called after </textarea>
136 // version 2
137 function Edit_HtmlArea2_Textarea($textarea,$wikitext,$name='edit[content]') {
138   $out = HTML($textarea);
139   // some more custom links 
140   //$out->pushContent(HTML::a(array('href'=>"javascript:editor_insertHTML('".$name."',\"<font style='background-color: yellow'>\",'</font>',1)"),_("Highlight selected text")));
141   //$out->pushContent(HTML("\n"));
142   $out->pushContent(JavaScript("editor_generate('".$name."');",
143                                array('version' => 'JavaScript1.2',
144                                      'defer' => 1)));
145   return $out;
146   //return "\n".'<script language="JavaScript1.2" defer> editor_generate(\'CONTENT\'); </script>'."\n";
147 }
148
149 function Edit_HtmlArea3_Textarea($textarea,$wikitext,$name='edit[content]') {
150     $out = HTML($textarea,HTML::div(array("id"=>"editareawiki",'style'=>'display:none'),$wikitext),"\n");
151     //TODO: maybe some more custom links
152     return $out;
153 }
154
155 require_once("lib/InlineParser.php");
156
157 // re-use these classes for the regexp's.
158 // just output strings instead of XmlObjects
159 class Markup_html_br extends Markup_linebreak {
160     function markup ($match) {
161         return $match;
162     }
163 }
164
165 class Markup_html_simple_tag extends Markup_html_emphasis {
166     function markup ($match, $body) {
167         $tag = mb_substr($match, 1, -1);
168         switch ($tag) {
169         case 'b':
170         case 'strong':
171             return "*".$body."*";
172         case 'big': return "<big>".$body."</big>";
173         case 'i':
174         case 'em':
175             return "_".$body."_";
176         }
177     }
178 }
179
180 //'<SPAN style="FONT-WEIGHT: bold">text</SPAN>' => '*text*'
181 class Markup_html_bold extends BalancedMarkup
182 {
183     var $_start_regexp = "<(?:span|SPAN) style=\"FONT-WEIGHT: bold\">";
184
185     function getEndRegexp ($match) {
186         return "<\\/" . mb_substr($match, 1);
187     }
188     function markup ($match, $body) {
189         //Todo: convert style formatting to simplier nested <b><i> tags
190         return "*".$body."*";
191     }
192 }
193
194 class HtmlTransformer extends InlineTransformer
195 {
196     function HtmlTransformer () {
197         $this->InlineTransformer(array('escape',
198                                        'html_br','html_bold','html_simple_tag',
199                                        /*
200                                        'html_a','html_span','html_div',
201                                        'html_table','html_hr','html_pre',
202                                        'html_blockquote',
203                                        'html_indent','html_ol','html_li','html_ul','html_img',
204                                        */));
205     }
206 }
207
208 /**
209  * Handler to convert the Wiki Markup to HTML before editing.
210  * This will be converted back by Edit_HtmlArea_ConvertAfter
211  *  *text* => '<b>text<b>'
212  */
213 function Edit_WYSIWYG_ConvertBefore($text) {
214     return asXML(TransformInline($text, 2.0, false));
215 }
216
217 /**
218  * Handler to convert the HTML formatting back to wiki formatting.
219  * Derived from InlineParser, but returning wiki text instead of HtmlElement objects.
220  * '<b>text<b>' => '<SPAN style="FONT-WEIGHT: bold">text</SPAN>' => '*text*'
221  */
222 function Edit_WYSIWYG_ConvertAfter($text) {
223     static $trfm;
224     if (empty($trfm)) {
225         $trfm = new HtmlTransformer();
226     }
227     $markup = $trfm->parse($text); // version 2.0
228     return $markup;
229 }
230
231 // Local Variables:
232 // mode: php
233 // tab-width: 8
234 // c-basic-offset: 4
235 // c-hanging-comment-ender-p: nil
236 // indent-tabs-mode: nil
237 // End:
238 ?>