diff --git a/images/xinha-red-95.png b/images/xinha-red-95.png new file mode 100644 index 0000000..71e6a77 Binary files /dev/null and b/images/xinha-red-95.png differ diff --git a/include/util.php b/include/util.php index fe3465d..0fff4d7 100644 --- a/include/util.php +++ b/include/util.php @@ -693,7 +693,7 @@ function HtmlAreaLoaderScript($aTextareas) echo ' - + + * + */ + + function xinha_pass_to_php_backend($Data, $KeyLocation = 'Xinha:BackendKey') + { + + $bk = array(); + $bk['data'] = serialize($Data); + + @session_start(); + if(!isset($_SESSION[$KeyLocation])) + { + $_SESSION[$KeyLocation] = uniqid('Key_'); + } + + $bk['session_name'] = session_name(); + $bk['key_location'] = $KeyLocation; + $bk['hash'] = + function_exists('sha1') ? + sha1($_SESSION[$KeyLocation] . $bk['data']) + : md5($_SESSION[$KeyLocation] . $bk['data']); + + + // The data will be passed via a postback to the + // backend, we want to make sure these are going to come + // out from the PHP as an array like $bk above, so + // we need to adjust the keys. + $backend_data = array(); + foreach($bk as $k => $v) + { + $backend_data["backend_data[$k]"] = $v; + } + + // The session_start() above may have been after data was sent, so cookies + // wouldn't have worked. + $backend_data[session_name()] = session_id(); + + echo 'backend_data = ' . xinha_to_js($backend_data) . "; \n"; + + } + + /** Convert PHP data structure to Javascript */ + + function xinha_to_js($var, $tabs = 0) + { + if(is_numeric($var)) + { + return $var; + } + + if(is_string($var)) + { + return "'" . xinha_js_encode($var) . "'"; + } + + if(is_array($var)) + { + $useObject = false; + foreach(array_keys($var) as $k) { + if(!is_numeric($k)) $useObject = true; + } + $js = array(); + foreach($var as $k => $v) + { + $i = ""; + if($useObject) { + if(preg_match('#^[a-zA-Z]+[a-zA-Z0-9]*$#', $k)) { + $i .= "$k: "; + } else { + $i .= "'$k': "; + } + } + $i .= xinha_to_js($v, $tabs + 1); + $js[] = $i; + } + if($useObject) { + $ret = "{\n" . xinha_tabify(implode(",\n", $js), $tabs) . "\n}"; + } else { + $ret = "[\n" . xinha_tabify(implode(",\n", $js), $tabs) . "\n]"; + } + return $ret; + } + + return 'null'; + } + + /** Like htmlspecialchars() except for javascript strings. */ + + function xinha_js_encode($string) + { + static $strings = "\\,\",',%,&,<,>,{,},@,\n,\r"; + + if(!is_array($strings)) + { + $tr = array(); + foreach(explode(',', $strings) as $chr) + { + $tr[$chr] = sprintf('\x%02X', ord($chr)); + } + $strings = $tr; + } + + return strtr($string, $strings); + } + + + /** Used by plugins to get the config passed via + * xinha_pass_to_backend() + * returns either the structure given, or NULL + * if none was passed or a security error was encountered. + */ + + function xinha_read_passed_data() + { + if(isset($_REQUEST['backend_data']) && is_array($_REQUEST['backend_data'])) + { + $bk = $_REQUEST['backend_data']; + session_name($bk['session_name']); + @session_start(); + if(!isset($_SESSION[$bk['key_location']])) return NULL; + + if($bk['hash'] === + function_exists('sha1') ? + sha1($_SESSION[$bk['key_location']] . $bk['data']) + : md5($_SESSION[$bk['key_location']] . $bk['data'])) + { + return unserialize(ini_get('magic_quotes_gpc') ? stripslashes($bk['data']) : $bk['data']); + } + } + + return NULL; + } + + /** Used by plugins to get a query string that can be sent to the backend + * (or another part of the backend) to send the same data. + */ + + function xinha_passed_data_querystring() + { + $qs = array(); + if(isset($_REQUEST['backend_data']) && is_array($_REQUEST['backend_data'])) + { + foreach($_REQUEST['backend_data'] as $k => $v) + { + $v = ini_get('magic_quotes_gpc') ? stripslashes($v) : $v; + $qs[] = "backend_data[" . rawurlencode($k) . "]=" . rawurlencode($v); + } + } + + $qs[] = session_name() . '=' . session_id(); + return implode('&', $qs); + } + + + /** Just space-tab indent some text */ + function xinha_tabify($text, $tabs) + { + if($text) + { + return str_repeat(" ", $tabs) . preg_replace('/\n(.)/', "\n" . str_repeat(" ", $tabs) . "\$1", $text); + } + } + + /** Return upload_max_filesize value from php.ini in kilobytes (function adapted from php.net)**/ + function upload_max_filesize_kb() + { + $val = ini_get('upload_max_filesize'); + $val = trim($val); + $last = strtolower($val{strlen($val)-1}); + switch($last) + { + // The 'G' modifier is available since PHP 5.1.0 + case 'g': + $val *= 1024; + case 'm': + $val *= 1024; + } + return $val; +} +?> \ No newline at end of file diff --git a/xinha/dialog.js b/xinha/dialog.js deleted file mode 100644 index b6e7b20..0000000 --- a/xinha/dialog.js +++ /dev/null @@ -1,76 +0,0 @@ -// htmlArea v3.0 - Copyright (c) 2003-2004 interactivetools.com, inc. -// This copyright notice MUST stay intact for use (see license.txt). -// -// Portions (c) dynarch.com, 2003-2004 -// -// A free WYSIWYG editor replacement for fields. -// For full source code and docs, visit http://www.interactivetools.com/ -// -// Version 3.0 developed by Mihai Bazon. -// http://dynarch.com/mishoo -// -// $Id$ - -// Though "Dialog" looks like an object, it isn't really an object. Instead -// it's just namespace for protecting global symbols. - -function Dialog(url, action, init) { - if (typeof init == "undefined") { - init = window; // pass this window object by default - } - Dialog._geckoOpenModal(url, action, init); -} - -Dialog._parentEvent = function(ev) { - setTimeout( function() { if (Dialog._modal && !Dialog._modal.closed) { Dialog._modal.focus() } }, 50); - if (Dialog._modal && !Dialog._modal.closed) { - HTMLArea._stopEvent(ev); - } -}; - - -// should be a function, the return handler of the currently opened dialog. -Dialog._return = null; - -// constant, the currently opened dialog -Dialog._modal = null; - -// the dialog will read it's args from this variable -Dialog._arguments = null; - -Dialog._geckoOpenModal = function(url, action, init) { - var dlg = window.open(url, "hadialog", - "toolbar=no,menubar=no,personalbar=no,width=10,height=10," + - "scrollbars=no,resizable=yes,modal=yes,dependable=yes"); - Dialog._modal = dlg; - Dialog._arguments = init; - - // capture some window's events - function capwin(w) { - HTMLArea._addEvent(w, "click", Dialog._parentEvent); - HTMLArea._addEvent(w, "mousedown", Dialog._parentEvent); - HTMLArea._addEvent(w, "focus", Dialog._parentEvent); - } - // release the captured events - function relwin(w) { - HTMLArea._removeEvent(w, "click", Dialog._parentEvent); - HTMLArea._removeEvent(w, "mousedown", Dialog._parentEvent); - HTMLArea._removeEvent(w, "focus", Dialog._parentEvent); - } - capwin(window); - // capture other frames, note the exception trapping, this is because - // we are not permitted to add events to frames outside of the current - // window's domain. - for (var i = 0; i < window.frames.length; i++) {try { capwin(window.frames[i]); } catch(e) { } }; - // make up a function to be called when the Dialog ends. - Dialog._return = function (val) { - if (val && action) { - action(val); - } - relwin(window); - // capture other frames - for (var i = 0; i < window.frames.length; i++) { try { relwin(window.frames[i]); } catch(e) { } }; - Dialog._modal = null; - }; - Dialog._modal.focus(); -}; \ No newline at end of file diff --git a/xinha/examples/Extended.html b/xinha/examples/Extended.html index 24e671c..69aedda 100644 --- a/xinha/examples/Extended.html +++ b/xinha/examples/Extended.html @@ -15,14 +15,55 @@ function getAbsolutePos(el) { return r; }; -function comboSelectValue(c, val) { - var ops = c.getElementsByTagName("option"); - for (var i = ops.length; --i >= 0;) { - var op = ops[i]; - op.selected = (op.value == val); - } - c.value = val; -}; +function getSelectedValue(el) { + if(!el) + return ""; + return el[el.selectedIndex].value; +} + +function setSelectedValue(el, val) { + if(!el) + return ""; + var ops = el.getElementsByTagName("option"); + for (var i = ops.length; --i >= 0;) { + var op = ops[i]; + op.selected = (op.value == val); + } + el.value = val; +} + +function getCheckedValue(el) { + if(!el) + return ""; + var radioLength = el.length; + if(radioLength == undefined) + if(el.checked) + return el.value; + else + return "false"; + for(var i = 0; i < radioLength; i++) { + if(el[i].checked) { + return el[i].value; + } + } + return ""; +} + +function setCheckedValue(el, val) { + if(!el) + return; + var radioLength = el.length; + if(radioLength == undefined) { + el.checked = (el.value == val.toString()); + return; + } + for(var i = 0; i < radioLength; i++) { + el[i].checked = false; + if(el[i].value == val.toString()) { + el[i].checked = true; + } + } +} function __dlg_onclose() { opener.Dialog._return(null); @@ -84,50 +125,77 @@ function __dlg_init(bottom) { document.body.onkeypress = __dlg_close_on_esc; }; +function placeFocus() { +var bFound = false; + // for each form + for (f=0; f < document.forms.length; f++) { + // for each element in each form + for(i=0; i < document.forms[f].length; i++) { + // if it's not a hidden element + if (document.forms[f][i].type != "hidden") { + // and it's not disabled + if (document.forms[f][i].disabled != true) { + // set the focus to it + document.forms[f][i].focus(); + var bFound = true; + } + } + // if found in this element, stop looking + if (bFound == true) + break; + } + // if found in this form, stop looking + if (bFound == true) + break; + } +} + function Init() { __dlg_init(); var param = window.dialogArguments; - if (param) { - document.getElementById("width").value = param["width"]; - document.getElementById("height").value = param["height"]; - document.getElementById("sizeIncludesBars").checked = (param["sizeIncludesBars"] == 'true'); - document.getElementById("statusBar").checked = (param["statusBar"] == 'true'); - document.getElementById("mozParaHandler").value = param["mozParaHandler"]; - document.getElementById("undoSteps").value = param["undoSteps"]; - document.getElementById("baseHref").value = param["baseHref"]; - document.getElementById("stripBaseHref").checked = (param["stripBaseHref"] == 'true'); - document.getElementById("stripSelfNamedAnchors").checked = (param["stripSelfNamedAnchors"] == 'true'); - document.getElementById("only7BitPrintablesInURLs").checked = (param["only7BitPrintablesInURLs"] == 'true'); - document.getElementById("sevenBitClean").checked = (param["sevenBitClean"] == 'true'); - document.getElementById("killWordOnPaste").checked = (param["killWordOnPaste"] == 'true'); - document.getElementById("flowToolbars").checked = (param["flowToolbars"] == 'true'); - document.getElementById("CharacterMapMode").value = param["CharacterMapMode"]; - document.getElementById("ListTypeMode").value = param["ListTypeMode"]; - + if(param) { + var el; + for (var field in param) { + //alert(field + '="' + param[field] + '"'); + el = document.getElementById(field); + if (el.tagName.toLowerCase()=="input"){ + if ((el.type.toLowerCase()=="radio") || (el.type.toLowerCase()=="checkbox")){ + setCheckedValue(el, param[field]); + } else { + el.value = param[field]; + } + } else if (el.tagName.toLowerCase()=="select"){ + setSelectedValue(el, param[field]); + } else if (el.tagName.toLowerCase()=="textarea"){ + el.value = param[field]; + } + } } - document.getElementById("width").focus(); - window.resizeTo(420, 500); + placeFocus(); }; +// pass data back to the calling window function onOK() { - // pass data back to the calling window - var param = { width: document.getElementById("width").value, - height: document.getElementById("height").value, - sizeIncludesBars: (document.getElementById("sizeIncludesBars").checked?true:""), - statusBar: (document.getElementById("statusBar").checked?true:""), - mozParaHandler: document.getElementById("mozParaHandler").value, - undoSteps: document.getElementById("undoSteps").value, - baseHref: document.getElementById("baseHref").value, - stripBaseHref: (document.getElementById("stripBaseHref").checked?true:""), - stripSelfNamedAnchors: (document.getElementById("stripSelfNamedAnchors").checked?true:""), - only7BitPrintablesInURLs: (document.getElementById("only7BitPrintablesInURLs").checked?true:""), - sevenBitClean: (document.getElementById("sevenBitClean").checked?true:""), - killWordOnPaste: (document.getElementById("killWordOnPaste").checked?true:""), - flowToolbars: (document.getElementById("flowToolbars").checked?true:""), - CharacterMapMode: document.getElementById("CharacterMapMode").value, - ListTypeOptions: document.getElementById("ListTypeMode").value - }; - __dlg_close(param); + var param = new Object(); + var el = document.getElementsByTagName('input'); + for (var i=0; i - + Settings Editor width: @@ -154,10 +222,10 @@ function onCancel() { Size includes bars - + Status Bar - + Mozilla Parameter Handler: @@ -173,48 +241,59 @@ function onCancel() { Strip base href - + Strip self named anchors - + only 7bit printables in URLs - + 7bit Clean - + kill Word on paste - + flow toolbars - + + + show loading + - CharacterMap mode : - + CharacterMap mode : + popup panel - + - + ListType mode : - + toolbar panel - - + + + + + CharCounter (showChar) : + CharCounter (showWord) : + CharCounter (showHtml) : + + + OK Cancel - \ No newline at end of file +