diff --git a/css/redactor.css b/css/redactor.css index 6a5c8df81fb6f5a2c929221d6bbc92a66d84790a..b179cfd42fe90e378a3ed32c0340f07d811a0cbe 100644 --- a/css/redactor.css +++ b/css/redactor.css @@ -82,7 +82,7 @@ body .redactor_box_fullscreen { .redactor_editor blockquote, .redactor_editor pre { font-size: 15px; - line-height: 1.5rem; + line-height: 1.25rem; } .redactor_editor, diff --git a/css/thread.css b/css/thread.css index 9623bcf25466d22155c67ae03b2b6e2a6dddfbdc..cd3ad3d3679ecd816401570ea9ca0264855657fb 100644 --- a/css/thread.css +++ b/css/thread.css @@ -306,7 +306,6 @@ border-left: 5px solid #eeeeee; } .thread-body blockquote p { - font-size: 17.5px; font-weight: 300; line-height: 1.25; } @@ -410,3 +409,9 @@ float: none; display: table-cell; } + +/* Additional style for the mighty Microsoft Office emails "standard" style */ +p.MsoNormal, li.MsoNormal, div.MsoNormal, +p.MsoPlainText, li.MsoPlainText, div.MsoPlainText + {margin:0cm; + margin-bottom:.0001pt;} diff --git a/include/class.format.php b/include/class.format.php index 843033ae205875af379cff31c7c26026df1a2855..f3e78fc8b08884cbf559a2ccdb4fbf11372506f5 100644 --- a/include/class.format.php +++ b/include/class.format.php @@ -138,12 +138,39 @@ class Format { } function safe_html($html) { + // Remove HEAD and STYLE sections + $html = preg_replace(':<(head|style).+</\1>:is','', $html); $config = array( - 'safe' => 1, //Exclude applet, embed, iframe, object and script tags. - 'balance' => 1, //balance and close unclosed tags. - 'comment' => 1, //Remove html comments (OUTLOOK LOVE THEM) - 'schemes' => 'href: aim, feed, file, ftp, gopher, http, https, irc, mailto, news, nntp, sftp, ssh, telnet; *:file, http, https; src: cid, http, https, data' - ); + 'safe' => 1, //Exclude applet, embed, iframe, object and script tags. + 'balance' => 1, //balance and close unclosed tags. + 'comment' => 1, //Remove html comments (OUTLOOK LOVE THEM) + 'deny_attribute' => 'id', + 'schemes' => 'href: aim, feed, file, ftp, gopher, http, https, irc, mailto, news, nntp, sftp, ssh, telnet; *:file, http, https; src: cid, http, https, data', + 'hook_tag' => function ($el, $attributes=0) { + static $eE = array('area'=>1, 'br'=>1, 'col'=>1, 'embed'=>1, + 'hr'=>1, 'img'=>1, 'input'=>1, 'isindex'=>1, 'param'=>1); + if (isset($attributes['class'])) { + $classes = explode(' ', $attributes['class']); + foreach ($classes as $i=>$a) + // Unset all unsupported style classes -- anything by M$ + if (strpos($a, 'Mso') !== 0) + unset($classes[$i]); + if ($classes) + $attributes['class'] = implode(' ', $classes); + else + unset($attributes['class']); + } + $at = ''; + if (is_array($attributes)) { + foreach ($attributes as $k=>$v) + $at .= " $k=\"$v\""; + return "<{$el}{$at}".(isset($eE[$el])?" /":"").">"; + } + else { + return "</{$el}>"; + } + } + ); if (!preg_match('/style="[^"]*white-space:\s*pre/i', $html) !== false) $config['tidy'] = -1; // Clean extra whitspace diff --git a/include/htmLawed.php b/include/htmLawed.php index 28d234824fb4765e4e60544774c64732ef0d4e67..6d25f1f98a714269c3b65d87ca6f3dcb5db96dcb 100644 --- a/include/htmLawed.php +++ b/include/htmLawed.php @@ -1,9 +1,9 @@ <?php /* -htmLawed 1.1.10, 22 October 2011 +htmLawed 1.1.16, 29 August 2013 Copyright Santosh Patnaik -LGPL v3 license +Dual licensed with LGPL 3 and GPL 2+ A PHP Labware internal utility; www.bioinformatics.org/phplabware/internal_utilities/htmLawed See htmLawed_README.txt/htm @@ -68,7 +68,7 @@ $C['css_expression'] = empty($C['css_expression']) ? 0 : 1; $C['direct_list_nest'] = empty($C['direct_list_nest']) ? 0 : 1; $C['hexdec_entity'] = isset($C['hexdec_entity']) ? $C['hexdec_entity'] : 1; $C['hook'] = (!empty($C['hook']) && function_exists($C['hook'])) ? $C['hook'] : 0; -$C['hook_tag'] = (!empty($C['hook_tag']) && function_exists($C['hook_tag'])) ? $C['hook_tag'] : 0; +$C['hook_tag'] = (!empty($C['hook_tag']) && is_callable($C['hook_tag'])) ? $C['hook_tag'] : 0; $C['keep_bad'] = isset($C['keep_bad']) ? $C['keep_bad'] : 6; $C['lc_std_val'] = isset($C['lc_std_val']) ? (bool)$C['lc_std_val'] : 1; $C['make_tag_strict'] = isset($C['make_tag_strict']) ? $C['make_tag_strict'] : 1; @@ -194,7 +194,10 @@ for($i=-1, $ci=count($t); ++$i<$ci;){ echo '<', $s, $e, $a, '>'; } if(isset($x[0])){ - if($do < 3 or isset($ok['#pcdata'])){echo $x;} + if(strlen(trim($x)) && (($ql && isset($cB[$p])) or (isset($cB[$in]) && !$ql))){ + echo '<div>', $x, '</div>'; + } + elseif($do < 3 or isset($ok['#pcdata'])){echo $x;} elseif(strpos($x, "\x02\x04")){ foreach(preg_split('`(\x01\x02[^\x01\x02]+\x02\x01)`', $x, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY) as $v){ echo (substr($v, 0, 2) == "\x01\x02" ? $v : ($do > 4 ? preg_replace('`\S`', '', $v) : '')); @@ -202,14 +205,14 @@ for($i=-1, $ci=count($t); ++$i<$ci;){ }elseif($do > 4){echo preg_replace('`\S`', '', $x);} } // get markup - if(!preg_match('`^(/?)([a-zA-Z1-6]+)([^>]*)>(.*)`sm', $t[$i], $r)){$x = $t[$i]; continue;} + if(!preg_match('`^(/?)([a-z1-6]+)([^>]*)>(.*)`sm', $t[$i], $r)){$x = $t[$i]; continue;} $s = null; $e = null; $a = null; $x = null; list($all, $s, $e, $a, $x) = $r; // close tag if($s){ if(isset($cE[$e]) or !in_array($e, $q)){continue;} // Empty/unopen if($p == $e){array_pop($q); echo '</', $e, '>'; unset($e); continue;} // Last open $add = ''; // Nesting - close open tags that need to be - for($j=-1, $cj=count($q); ++$j<$cj;){ + for($j=-1, $cj=count($q); ++$j<$cj;){ if(($d = array_pop($q)) == $e){break;} else{$add .= "</{$d}>";} } @@ -333,7 +336,7 @@ $c = isset($C['schemes'][$c]) ? $C['schemes'][$c] : $C['schemes']['*']; static $d = 'denied:'; if(isset($c['!']) && substr($p, 0, 7) != $d){$p = "$d$p";} if(isset($c['*']) or !strcspn($p, '#?;') or (substr($p, 0, 7) == $d)){return "{$b}{$p}{$a}";} // All ok, frag, query, param -if(preg_match('`^([a-z\d\-+.&#; ]+?)(:|&#(58|x3a);|%3a|\\\\0{0,4}3a).`i', $p, $m) && !isset($c[strtolower($m[1])])){ // Denied prot +if(preg_match('`^([^:?[@!$()*,=/\'\]]+?)(:|&#(58|x3a);|%3a|\\\\0{0,4}3a).`i', $p, $m) && !isset($c[strtolower($m[1])])){ // Denied prot return "{$b}{$d}{$p}{$a}"; } if($C['abs_url']){ @@ -376,7 +379,7 @@ return $r; function hl_spec($t){ // final $spec $s = array(); -$t = str_replace(array("\t", "\r", "\n", ' '), '', preg_replace('/"(?>(`.|[^"])*)"/sme', 'substr(str_replace(array(";", "|", "~", " ", ",", "/", "(", ")", \'`"\'), array("\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\""), "$0"), 1, -1)', trim($t))); +$t = str_replace(array("\t", "\r", "\n", ' '), '', preg_replace('/"(?>(`.|[^"])*)"/sme', 'substr(str_replace(array(";", "|", "~", " ", ",", "/", "(", ")", \'`"\'), array("\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\""), "$0"), 1, -1)', trim($t))); for($i = count(($t = explode(';', $t))); --$i>=0;){ $w = $t[$i]; if(empty($w) or ($e = strpos($w, '=')) === false or !strlen(($a = substr($w, $e+1)))){continue;} @@ -427,7 +430,7 @@ if($C['make_tag_strict'] && isset($eD[$e])){ // close tag static $eE = array('area'=>1, 'br'=>1, 'col'=>1, 'embed'=>1, 'hr'=>1, 'img'=>1, 'input'=>1, 'isindex'=>1, 'param'=>1); // Empty ele if(!empty($m[1])){ - return (!isset($eE[$e]) ? "</$e>" : (($C['keep_bad'])%2 ? str_replace(array('<', '>'), array('<', '>'), $t) : '')); + return (!isset($eE[$e]) ? (empty($C['hook_tag']) ? "</$e>" : $C['hook_tag']($e)) : (($C['keep_bad'])%2 ? str_replace(array('<', '>'), array('<', '>'), $t) : '')); } // open tag & attr @@ -470,8 +473,8 @@ while(strlen($a)){ $aA[$nm] = ''; } break; case 2: // Val - if(preg_match('`^"[^"]*"`', $a, $m) or preg_match("`^'[^']*'`", $a, $m) or preg_match("`^\s*[^\s\"']+`", $a, $m)){ - $m = $m[0]; $w = 1; $mode = 0; $a = ltrim(substr_replace($a, '', 0, strlen($m))); + if(preg_match('`^((?:"[^"]*")|(?:\'[^\']*\')|(?:\s*[^\s"\']+))(.*)`', $a, $m)){ + $a = ltrim($m[2]); $m = $m[1]; $w = 1; $mode = 0; $aA[$nm] = trim(($m[0] == '"' or $m[0] == '\'') ? substr($m, 1, -1) : $m); } break; @@ -488,7 +491,7 @@ global $S; $rl = isset($S[$e]) ? $S[$e] : array(); $a = array(); $nfr = 0; foreach($aA as $k=>$v){ - if(((isset($C['deny_attribute']['*']) ? isset($C['deny_attribute'][$k]) : !isset($C['deny_attribute'][$k])) or isset($rl[$k])) && ((!isset($rl['n'][$k]) && !isset($rl['n']['*'])) or isset($rl[$k])) && (isset($aN[$k][$e]) or (isset($aNU[$k]) && !isset($aNU[$k][$e])))){ + if(((isset($C['deny_attribute']['*']) ? isset($C['deny_attribute'][$k]) : !isset($C['deny_attribute'][$k])) && (isset($aN[$k][$e]) or (isset($aNU[$k]) && !isset($aNU[$k][$e]))) && !isset($rl['n'][$k]) && !isset($rl['n']['*'])) or isset($rl[$k])){ if(isset($aNE[$k])){$v = $k;} elseif(!empty($lcase) && (($e != 'button' or $e != 'input') or $k == 'type')){ // Rather loose but ?not cause issues $v = (isset($aNL[($v2 = strtolower($v))])) ? $v2 : $v; @@ -622,7 +625,7 @@ if($e == 'u'){$e = 'span'; return 'text-decoration: underline;';} static $fs = array('0'=>'xx-small', '1'=>'xx-small', '2'=>'small', '3'=>'medium', '4'=>'large', '5'=>'x-large', '6'=>'xx-large', '7'=>'300%', '-1'=>'smaller', '-2'=>'60%', '+1'=>'larger', '+2'=>'150%', '+3'=>'200%', '+4'=>'300%'); if($e == 'font'){ $a2 = ''; - if(preg_match('`face\s*=\s*(\'|")([^=]+?)\\1`i', $a, $m) or preg_match('`face\s*=\s*([^"])(\S+)`i', $a, $m)){ + if(preg_match('`face\s*=\s*(\'|")([^=]+?)\\1`i', $a, $m) or preg_match('`face\s*=(\s*)(\S+)`i', $a, $m)){ $a2 .= ' font-family: '. str_replace('"', '\'', trim($m[2])). ';'; } if(preg_match('`color\s*=\s*(\'|")?(.+?)(\\1|\s|$)`i', $a, $m)){ @@ -641,41 +644,50 @@ return ''; function hl_tidy($t, $w, $p){ // Tidy/compact HTM if(strpos(' pre,script,textarea', "$p,")){return $t;} -$t = str_replace(' </', '</', preg_replace(array('`(<\w[^>]*(?<!/)>)\s+`', '`\s+`', '`(<\w[^>]*(?<!/)>) `'), array(' $1', ' ', '$1'), preg_replace_callback(array('`(<(!\[CDATA\[))(.+?)(\]\]>)`sm', '`(<(!--))(.+?)(-->)`sm', '`(<(pre|script|textarea)[^>]*?>)(.+?)(</\2>)`sm'), create_function('$m', 'return $m[1]. str_replace(array("<", ">", "\n", "\r", "\t", " "), array("\x01", "\x02", "\x03", "\x04", "\x05", "\x07"), $m[3]). $m[4];'), $t))); +$t = preg_replace('`\s+`', ' ', preg_replace_callback(array('`(<(!\[CDATA\[))(.+?)(\]\]>)`sm', '`(<(!--))(.+?)(-->)`sm', '`(<(pre|script|textarea)[^>]*?>)(.+?)(</\2>)`sm'), create_function('$m', 'return $m[1]. str_replace(array("<", ">", "\n", "\r", "\t", " "), array("\x01", "\x02", "\x03", "\x04", "\x05", "\x07"), $m[3]). $m[4];'), $t)); if(($w = strtolower($w)) == -1){ return str_replace(array("\x01", "\x02", "\x03", "\x04", "\x05", "\x07"), array('<', '>', "\n", "\r", "\t", ' '), $t); } $s = strpos(" $w", 't') ? "\t" : ' '; $s = preg_match('`\d`', $w, $m) ? str_repeat($s, $m[0]) : str_repeat($s, ($s == "\t" ? 1 : 2)); -$n = preg_match('`[ts]([1-9])`', $w, $m) ? $m[1] : 0; +$N = preg_match('`[ts]([1-9])`', $w, $m) ? $m[1] : 0; $a = array('br'=>1); -$b = array('button'=>1, 'input'=>1, 'option'=>1); +$b = array('button'=>1, 'input'=>1, 'option'=>1, 'param'=>1); $c = array('caption'=>1, 'dd'=>1, 'dt'=>1, 'h1'=>1, 'h2'=>1, 'h3'=>1, 'h4'=>1, 'h5'=>1, 'h6'=>1, 'isindex'=>1, 'label'=>1, 'legend'=>1, 'li'=>1, 'object'=>1, 'p'=>1, 'pre'=>1, 'td'=>1, 'textarea'=>1, 'th'=>1); -$d = array('address'=>1, 'blockquote'=>1, 'center'=>1, 'colgroup'=>1, 'dir'=>1, 'div'=>1, 'dl'=>1, 'fieldset'=>1, 'form'=>1, 'hr'=>1, 'iframe'=>1, 'map'=>1, 'menu'=>1, 'noscript'=>1, 'ol'=>1, 'optgroup'=>1, 'rbc'=>1, 'rtc'=>1, 'ruby'=>1, 'script'=>1, 'select'=>1, 'table'=>1, 'tfoot'=>1, 'thead'=>1, 'tr'=>1, 'ul'=>1); -ob_start(); -if(isset($d[$p])){echo str_repeat($s, ++$n);} -$t = explode('<', $t); -echo ltrim(array_shift($t)); -for($i=-1, $j=count($t); ++$i<$j;){ - $r = ''; list($e, $r) = explode('>', $t[$i]); - $x = $e[0] == '/' ? 0 : (substr($e, -1) == '/' ? 1 : ($e[0] != '!' ? 2 : -1)); - $y = !$x ? ltrim($e, '/') : ($x > 0 ? substr($e, 0, strcspn($e, ' ')) : 0); - $e = "<$e>"; - if(isset($d[$y])){ - if(!$x){echo "\n", str_repeat($s, --$n), "$e\n", str_repeat($s, $n);} - else{echo "\n", str_repeat($s, $n), "$e\n", str_repeat($s, ($x != 1 ? ++$n : $n));} - echo ltrim($r); continue; +$d = array('address'=>1, 'blockquote'=>1, 'center'=>1, 'colgroup'=>1, 'dir'=>1, 'div'=>1, 'dl'=>1, 'fieldset'=>1, 'form'=>1, 'hr'=>1, 'iframe'=>1, 'map'=>1, 'menu'=>1, 'noscript'=>1, 'ol'=>1, 'optgroup'=>1, 'rbc'=>1, 'rtc'=>1, 'ruby'=>1, 'script'=>1, 'select'=>1, 'table'=>1, 'tbody'=>1, 'tfoot'=>1, 'thead'=>1, 'tr'=>1, 'ul'=>1); +$T = explode('<', $t); +$X = 1; +while($X){ + $n = $N; + $t = $T; + ob_start(); + if(isset($d[$p])){echo str_repeat($s, ++$n);} + echo ltrim(array_shift($t)); + for($i=-1, $j=count($t); ++$i<$j;){ + $r = ''; list($e, $r) = explode('>', $t[$i]); + $x = $e[0] == '/' ? 0 : (substr($e, -1) == '/' ? 1 : ($e[0] != '!' ? 2 : -1)); + $y = !$x ? ltrim($e, '/') : ($x > 0 ? substr($e, 0, strcspn($e, ' ')) : 0); + $e = "<$e>"; + if(isset($d[$y])){ + if(!$x){ + if($n){echo "\n", str_repeat($s, --$n), "$e\n", str_repeat($s, $n);} + else{++$N; ob_end_clean(); continue 2;} + } + else{echo "\n", str_repeat($s, $n), "$e\n", str_repeat($s, ($x != 1 ? ++$n : $n));} + echo $r; continue; + } + $f = "\n". str_repeat($s, $n); + if(isset($c[$y])){ + if(!$x){echo $e, $f, $r;} + else{echo $f, $e, $r;} + }elseif(isset($b[$y])){echo $f, $e, $r; + }elseif(isset($a[$y])){echo $e, $f, $r; + }elseif(!$y){echo $f, $e, $f, $r; + }else{echo $e, $r;} } - $f = "\n". str_repeat($s, $n); - if(isset($c[$y])){ - if(!$x){echo $e, $f, ltrim($r);} - else{echo $f, $e, $r;} - }elseif(isset($b[$y])){echo $f, $e, $r; - }elseif(isset($a[$y])){echo $e, $f, ltrim($r); - }elseif(!$y){echo $f, $e, $f, ltrim($r); - }else{echo $e, $r;} -} -$t = preg_replace('`[\n]\s*?[\n]+`', "\n", ob_get_contents()); + $X = 0; +} +$t = str_replace(array("\n ", " \n"), "\n", preg_replace('`[\n]\s*?[\n]+`', "\n", ob_get_contents())); ob_end_clean(); if(($l = strpos(" $w", 'r') ? (strpos(" $w", 'n') ? "\r\n" : "\r") : 0)){ $t = str_replace("\n", $l, $t); @@ -686,7 +698,7 @@ return str_replace(array("\x01", "\x02", "\x03", "\x04", "\x05", "\x07"), array( function hl_version(){ // rel -return '1.1.10'; +return '1.1.16'; // eof } @@ -708,4 +720,4 @@ function kses_hook($t, &$C, &$S){ // kses compat return $t; // eof -} \ No newline at end of file +} diff --git a/include/staff/ticket-view.inc.php b/include/staff/ticket-view.inc.php index a3ef79d5d4d29f0752ef720c41cd769ab318d6df..aecf2edd6f2cfc9fa422b1826eaaafeaace1b981 100644 --- a/include/staff/ticket-view.inc.php +++ b/include/staff/ticket-view.inc.php @@ -444,12 +444,12 @@ if(!$cfg->showNotesInline()) { ?> <input type="hidden" name="msgId" value="<?php echo $msgId; ?>"> <input type="hidden" name="a" value="reply"> <span class="error"></span> - <table border="0" cellspacing="0" cellpadding="3"> + <table style="width:100%" border="0" cellspacing="0" cellpadding="3"> <tr> - <td width="160"> + <td width="120"> <label><strong>TO:</strong></label> </td> - <td width="765"> + <td> <?php $to = $ticket->getReplyToEmail(); if(($name=$ticket->getName()) && !strpos($name,'@')) @@ -463,14 +463,14 @@ if(!$cfg->showNotesInline()) { ?> </tr> <?php if($errors['response']) {?> - <tr><td width="160"> </td><td class="error"><?php echo $errors['response']; ?> </td></tr> + <tr><td width="120"> </td><td class="error"><?php echo $errors['response']; ?> </td></tr> <?php }?> <tr> - <td width="160"> + <td width="120" style="vertical-align:top"> <label><strong>Response:</strong></label> </td> - <td width="765"> + <td> <?php if(($cannedResponses=Canned::responsesByDeptId($ticket->getDeptId()))) {?> <select id="cannedResp" name="cannedResp"> @@ -489,6 +489,7 @@ if(!$cfg->showNotesInline()) { ?> <input type="hidden" name="draft_id" value=""/> <textarea name="response" id="response" cols="50" data-draft-namespace="ticket.response" + placeholder="Start writing your response here. Use canned responses from the drop-down above" data-draft-object-id="<?php echo $ticket->getId(); ?>" rows="9" wrap="soft" class="richtext ifhtml draft"><?php @@ -498,10 +499,10 @@ if(!$cfg->showNotesInline()) { ?> <?php if($cfg->allowAttachments()) { ?> <tr> - <td width="160"> + <td width="120"> <label for="attachment">Attachments:</label> </td> - <td width="765" id="reply_form_attachments" class="attachments"> + <td id="reply_form_attachments" class="attachments"> <div class="canned_attachments"> </div> <div class="uploads"> @@ -514,10 +515,10 @@ if(!$cfg->showNotesInline()) { ?> <?php }?> <tr> - <td width="160"> + <td width="120"> <label for="signature" class="left">Signature:</label> </td> - <td width="765"> + <td> <?php $info['signature']=$info['signature']?$info['signature']:$thisstaff->getDefaultSignatureType(); ?> @@ -540,10 +541,10 @@ if(!$cfg->showNotesInline()) { ?> <?php if($ticket->isClosed() || $thisstaff->canCloseTickets()) { ?> <tr> - <td width="160"> + <td width="120"> <label><strong>Ticket Status:</strong></label> </td> - <td width="765"> + <td> <?php $statusChecked=isset($info['reply_ticket_status'])?'checked="checked"':''; if($ticket->isClosed()) { ?> @@ -573,42 +574,45 @@ if(!$cfg->showNotesInline()) { ?> <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>"> <input type="hidden" name="locktime" value="<?php echo $cfg->getLockTime(); ?>"> <input type="hidden" name="a" value="postnote"> - <table border="0" cellspacing="0" cellpadding="3"> + <table width="100%" border="0" cellspacing="0" cellpadding="3"> <?php if($errors['postnote']) {?> <tr> - <td width="160"> </td> + <td width="120"> </td> <td class="error"><?php echo $errors['postnote']; ?></td> </tr> <?php } ?> <tr> - <td width="160"> - <label><strong>Internal Note:</strong></label> + <td width="120" style="vertical-align:top"> + <label><strong>Internal Note:</strong><span class='error'> *</span></label> </td> - <td width="765"> - <div><span class="faded">Note details</span> - <span class="error">* <?php echo $errors['note']; ?></span> + <td> + <div> + <div class="faded" style="padding-left:0.15em"> + Note title - summary of the note (optional)</div> + <input type="text" name="title" id="title" size="60" value="<?php echo $info['title']; ?>" > + <br/> + <span class="error" <?php echo $errors['title']; ?></span> </div> + <br/> <textarea name="note" id="internal_note" cols="80" + placeholder="Note details" rows="9" wrap="soft" data-draft-namespace="ticket.note" data-draft-object-id="<?php echo $ticket->getId(); ?>" class="richtext ifhtml draft"><?php echo $info['note']; - ?></textarea><br> - <div> - <span class="faded">Note title - summary of the note (optional)</span> - <span class="error" <?php echo $errors['title']; ?></span> - </div> - <input type="text" name="title" id="title" size="60" value="<?php echo $info['title']; ?>" > + ?></textarea> + <span class="error"><?php echo $errors['note']; ?></span> + <br> </td> </tr> <?php if($cfg->allowAttachments()) { ?> <tr> - <td width="160"> + <td width="120"> <label for="attachment">Attachments:</label> </td> - <td width="765" class="attachments"> + <td class="attachments"> <div class="uploads"> </div> <div class="file_input"> @@ -621,10 +625,10 @@ if(!$cfg->showNotesInline()) { ?> ?> <tr><td colspan="2"> </td></tr> <tr> - <td width="160"> + <td width="120"> <label>Ticket Status:</label> </td> - <td width="765"> + <td> <div class="faded"></div> <select name="state"> <option value="" selected="selected">— unchanged —</option> @@ -683,21 +687,21 @@ if(!$cfg->showNotesInline()) { ?> <?php csrf_token(); ?> <input type="hidden" name="ticket_id" value="<?php echo $ticket->getId(); ?>"> <input type="hidden" name="a" value="transfer"> - <table border="0" cellspacing="0" cellpadding="3"> + <table width="100%" border="0" cellspacing="0" cellpadding="3"> <?php if($errors['transfer']) { ?> <tr> - <td width="160"> </td> + <td width="120"> </td> <td class="error"><?php echo $errors['transfer']; ?></td> </tr> <?php } ?> <tr> - <td width="160"> + <td width="120"> <label for="deptId"><strong>Department:</strong></label> </td> - <td width="765"> + <td> <?php echo sprintf('<span class="faded">Ticket is currently in <b>%s</b> department.</span>', $ticket->getDeptName()); ?> @@ -717,15 +721,15 @@ if(!$cfg->showNotesInline()) { ?> </td> </tr> <tr> - <td width="160"> - <label><strong>Comments:</strong></label> + <td width="120" style="vertical-align:top"> + <label><strong>Comments:</strong><span class='error'> *</span></label> </td> - <td width="765"> - <span class="faded">Enter reasons for the transfer.</span> - <span class="error">* <?php echo $errors['transfer_comments']; ?></span><br> + <td> <textarea name="transfer_comments" id="transfer_comments" + placeholder="Enter reasons for the transfer" class="richtext ifhtml no-bar" cols="80" rows="7" wrap="soft"><?php echo $info['transfer_comments']; ?></textarea> + <span class="error"><?php echo $errors['transfer_comments']; ?></span> </td> </tr> </table> @@ -742,31 +746,22 @@ if(!$cfg->showNotesInline()) { ?> <?php csrf_token(); ?> <input type="hidden" name="id" value="<?php echo $ticket->getId(); ?>"> <input type="hidden" name="a" value="assign"> - <table border="0" cellspacing="0" cellpadding="3"> + <table style="width:100%" border="0" cellspacing="0" cellpadding="3"> <?php if($errors['assign']) { ?> <tr> - <td width="160"> </td> + <td width="120"> </td> <td class="error"><?php echo $errors['assign']; ?></td> </tr> <?php } ?> <tr> - <td width="160"> + <td width="120" style="vertical-align:top"> <label for="assignId"><strong>Assignee:</strong></label> </td> - <td width="765"> - <?php - if($ticket->isAssigned() && $ticket->isOpen()) { - echo sprintf('<span class="faded">Ticket is currently assigned to <b>%s</b></span>', - $ticket->getAssignee()); - } else { - echo '<span class="faded">Assigning a closed ticket will <b>reopen</b> it!</span>'; - } - ?> - <br> + <td> <select id="assignId" name="assignId"> <option value="0" selected="selected">— Select Staff Member OR a Team —</option> <?php @@ -803,17 +798,25 @@ if(!$cfg->showNotesInline()) { ?> } ?> </select> <span class='error'>* <?php echo $errors['assignId']; ?></span> + <?php + if($ticket->isAssigned() && $ticket->isOpen()) { + echo sprintf('<div class="faded">Ticket is currently assigned to <b>%s</b></div>', + $ticket->getAssignee()); + } elseif ($ticket->isClosed()) { ?> + <div class="faded">Assigning a closed ticket will <b>reopen</b> it!</div> + <?php } ?> </td> </tr> <tr> - <td width="160"> - <label><strong>Comments:</strong><span class='error'> </span></label> + <td width="120" style="vertical-align:top"> + <label><strong>Comments:</strong><span class='error'> *</span></label> </td> - <td width="765"> - <span class="faded">Enter reasons for the assignment or instructions for assignee.</span> - <span class="error">* <?php echo $errors['assign_comments']; ?></span><br> - <textarea name="assign_comments" id="assign_comments" cols="80" rows="7" wrap="soft" + <td> + <textarea name="assign_comments" id="assign_comments" + cols="80" rows="7" wrap="soft" + placeholder="Enter reasons for the assignment or instructions for assignee" class="richtext ifhtml no-bar"><?php echo $info['assign_comments']; ?></textarea> + <span class="error"><?php echo $errors['assign_comments']; ?></span><br> </td> </tr> </table> diff --git a/include/upgrader/streams/core/d51f303a-dad45ca2.patch.sql b/include/upgrader/streams/core/d51f303a-dad45ca2.patch.sql index 94b8f8aa7fcd59f202bcc281324c58894f160a72..ff5d5e16e4c3a1f0446225bbc90d2657122758fe 100644 --- a/include/upgrader/streams/core/d51f303a-dad45ca2.patch.sql +++ b/include/upgrader/streams/core/d51f303a-dad45ca2.patch.sql @@ -52,6 +52,9 @@ UPDATE `%TABLE_PREFIX%email_template` '\n', '<br/>'), '&', '&'); +UPDATE `%TABLE_PREFIX%email_template` + SET `body` = CONCAT('<div>', `body`, '</div>'); + -- Migrate notes to HTML UPDATE `%TABLE_PREFIX%api_key` SET `notes` = REPLACE( REPLACE( REPLACE( REPLACE( diff --git a/js/redactor-osticket.js b/js/redactor-osticket.js index 0fd53146f7e986b754f48e565476dffcf0dbbe18..486cadd7281d2467a437dbb3af9b6cde0ab3b1a1 100644 --- a/js/redactor-osticket.js +++ b/js/redactor-osticket.js @@ -134,7 +134,9 @@ $(function() { 'focus': false, 'plugins': ['fontcolor','fontfamily'], 'imageGetJson': 'ajax.php/draft/images/browse', - 'syncBeforeCallback': captureImageSizes + 'syncBeforeCallback': captureImageSizes, + 'linebreaks': true, + 'tabFocus': false }; if (el.data('redactor')) return; if (el.hasClass('draft')) { diff --git a/scp/js/ticket.js b/scp/js/ticket.js index cbe042f4435d8bb46af55f4506947a9d04fab0ef..fb9f7370ed84ce178bdc0f233ef2ab16c066d7a4 100644 --- a/scp/js/ticket.js +++ b/scp/js/ticket.js @@ -428,10 +428,18 @@ showImagesInline = function(urls, thread_id) { e = $(el); if (info) { // Add a hover effect with the filename - var caption = $('<div class="image-hover">') + var timeout, caption = $('<div class="image-hover">') .hover( - function() { $(this).find('.caption').slideDown(250); }, - function() { $(this).find('.caption').slideUp(250); } + function() { + var self = this; + timeout = setTimeout( + function() { $(self).find('.caption').slideDown(250); }, + 500); + }, + function() { + clearTimeout(timeout); + $(this).find('.caption').slideUp(250); + } ).append($('<div class="caption">') .append('<span class="filename">'+info.filename+'</span>') .append('<a href="'+info.download_url+'" class="action-button"><i class="icon-download-alt"></i> Download</a>')