diff --git a/admin/css/style.css b/admin/css/style.css index 488a22e1..58bd6af4 100644 --- a/admin/css/style.css +++ b/admin/css/style.css @@ -1022,26 +1022,24 @@ a.operate-reply { * Upload */ #upload-panel { + border: 1px dashed #D9D9D6; + background-color: #FFF; color: #999; font-size: .92857em; } - #upload-panel.drag, #upload-panel.drag .upload-area { + #upload-panel.drag { background-color: #FFFBCC; } .upload-area { - padding: 12px; - border: 1px dashed #D9D9D6; - background-color: #FFF; + padding: 15px; text-align: center; } #file-list { list-style: none; - margin: 0; + margin: 0 12px; padding: 0; } #file-list li { - padding: 6px; - border-top: 1px solid #EEE; } - #file-list li:first-child { - border: none; } + padding: 8px 0; + border-top: 1px dashed #D9D9D6; } #file-list .file { margin-left: 5px; } #file-list .insert { @@ -1053,9 +1051,6 @@ a.operate-reply { #file-list .info { text-transform: uppercase; } -#tab-files #file-list { - min-height: 180px; } - /** * 附件管理 */ diff --git a/admin/media.php b/admin/media.php index 642050f8..5df9c585 100644 --- a/admin/media.php +++ b/admin/media.php @@ -77,15 +77,19 @@ $(document).ready(function() { }); function fileUploadStart (file, id) { + $('').appendTo('#upload-panel'); $('
  • ' + file + '
  • ').prependTo('#file-list'); } function fileUploadComplete (id, url, data) { + var img = $('.typecho-attachment-photo').get(0); + img.src = 'attachment->url(); ?>?' + Math.random(); + $('#' + id).html(''.replace('%s', data.title)) .effect('highlight', 1000, function () { $(this).remove(); - window.location.reload(); + $('#file-list').remove(); }); } @@ -96,14 +100,14 @@ $(document).ready(function() { onUpload : fileUploadStart, onError : function (id) { $('#' + id).remove(); + $('#file-list').remove(); alert(errorWord); }, onComplete : fileUploadComplete }); $('#upload-panel').filedrop({ - url : 'index('/action/upload' - . (isset($fileParentContent) ? '?cid=' . $fileParentContent->cid : '')); ?>', + url : 'index('/action/upload?do=modify&cid=' . $attachment->cid); ?>', allowedfileextensions : ['.attachment->type(); ?>'], maxfilesize : teardown(); $text = preg_replace_callback("/<\/?(\!doctype|html|head|body|link|title|input|select|button|textarea|style|noscript)[^>]*>/is", - array(&$this, '_doEscape_callback'), $text); + array($this, '_doEscape_callback'), $text); return $text . "\n"; } @@ -200,7 +200,7 @@ class Markdown { )? # title is optional (?:\n+|\Z) }xm', - array(&$this, '_stripLinkDefinitions_callback'), + array($this, '_stripLinkDefinitions_callback'), $text); return $text; } @@ -347,7 +347,7 @@ class Markdown { ) )}Sxmi', - array(&$this, '_hashHTMLBlocks_callback'), + array($this, '_hashHTMLBlocks_callback'), $text); return $text; @@ -491,7 +491,7 @@ class Markdown { protected function doHardBreaks($text) { # Do hard breaks: return preg_replace_callback('/ {2,}\n/', - array(&$this, '_doHardBreaks_callback'), $text); + array($this, '_doHardBreaks_callback'), $text); } protected function _doHardBreaks_callback($matches) { return $this->hashPart("empty_element_suffix\n"); @@ -522,7 +522,7 @@ class Markdown { \] ) }xs', - array(&$this, '_doAnchors_reference_callback'), $text); + array($this, '_doAnchors_reference_callback'), $text); # # Next, inline-style links: [link text](url "optional title") @@ -549,7 +549,7 @@ class Markdown { \) ) }xs', - array(&$this, '_doAnchors_inline_callback'), $text); + array($this, '_doAnchors_inline_callback'), $text); # # Last, handle reference-style shortcuts: [link text] @@ -563,7 +563,7 @@ class Markdown { \] ) }xs', - array(&$this, '_doAnchors_reference_callback'), $text); + array($this, '_doAnchors_reference_callback'), $text); $this->in_anchor = false; return $text; @@ -645,7 +645,7 @@ class Markdown { ) }xs', - array(&$this, '_doImages_reference_callback'), $text); + array($this, '_doImages_reference_callback'), $text); # # Next, handle inline images: ![alt text](url "optional title") @@ -674,7 +674,7 @@ class Markdown { \) ) }xs', - array(&$this, '_doImages_inline_callback'), $text); + array($this, '_doImages_inline_callback'), $text); return $text; } @@ -734,7 +734,7 @@ class Markdown { # -------- # $text = preg_replace_callback('{ ^(.+?)[ ]*\n(=+|-+)[ ]*\n+ }mx', - array(&$this, '_doHeaders_callback_setext'), $text); + array($this, '_doHeaders_callback_setext'), $text); # atx-style headers: # # Header 1 @@ -751,7 +751,7 @@ class Markdown { \#* # optional closing #\'s (not counted) \n+ }xm', - array(&$this, '_doHeaders_callback_atx'), $text); + array($this, '_doHeaders_callback_atx'), $text); return $text; } @@ -824,14 +824,14 @@ class Markdown { ^ '.$whole_list_re.' }mx', - array(&$this, '_doLists_callback'), $text); + array($this, '_doLists_callback'), $text); } else { $text = preg_replace_callback('{ (?:(?<=\n)\n|\A\n?) # Must eat the newline '.$whole_list_re.' }mx', - array(&$this, '_doLists_callback'), $text); + array($this, '_doLists_callback'), $text); } } @@ -898,7 +898,7 @@ class Markdown { (?:(\n+(?=\n))|\n) # tailing blank line = $5 (?= \n* (\z | \2 ('.$marker_any_re.') (?:[ ]+|(?=\n)))) }xm', - array(&$this, '_processListItems_callback'), $list_str); + array($this, '_processListItems_callback'), $list_str); $this->list_level--; return $list_str; @@ -942,7 +942,7 @@ class Markdown { ) ((?=^[ ]{0,'.$this->tab_width.'}\S)|\Z) # Lookahead for non-space at line-start, or end of doc }xm', - array(&$this, '_doCodeBlocks_callback'), $text); + array($this, '_doCodeBlocks_callback'), $text); return $text; } @@ -1142,7 +1142,7 @@ class Markdown { )+ ) /xm', - array(&$this, '_doBlockQuotes_callback'), $text); + array($this, '_doBlockQuotes_callback'), $text); return $text; } @@ -1156,7 +1156,7 @@ class Markdown { # These leading spaces cause problem with
     content, 
     		# so we need to fix that:
     		$bq = preg_replace_callback('{(\s*
    .+?
    )}sx', - array(&$this, '_doBlockQuotes_callback2'), $bq); + array($this, '_doBlockQuotes_callback2'), $bq); return "\n". $this->hashBlock("
    \n$bq\n
    ")."\n\n"; } @@ -1271,9 +1271,9 @@ class Markdown { protected function doAutoLinks($text) { $text = preg_replace_callback('/(="|<)?\b(https?|ftp)(:\/\/[-A-Z0-9+&@#\/%?=~_|\[\]\(\)!:,\.;]*[-A-Z0-9+&@#\/%=~_|\[\])])(?=$|\W)/i', - array(&$this, '_doAutoLinks_url_callback'), $text); + array($this, '_doAutoLinks_url_callback'), $text); $text = preg_replace_callback('{<((https?|ftp|dict):[^\'">\s]+)>}i', - array(&$this, '_doAutoLinks_url_callback_replace'), $text); + array($this, '_doAutoLinks_url_callback_replace'), $text); # Email addresses: $text = preg_replace_callback('{ @@ -1294,7 +1294,7 @@ class Markdown { ) > }xi', - array(&$this, '_doAutoLinks_email_callback'), $text); + array($this, '_doAutoLinks_email_callback'), $text); return $text; } @@ -1304,6 +1304,8 @@ class Markdown { return $this->hashPart($link); } + private $tail; + protected function _doAutoLinks_url_callback($matches) { list ($wholeMatch, $lookbehind, $protocol, $link) = $matches; @@ -1330,24 +1332,26 @@ class Markdown { } } - $tail = ''; + $this->tail = ''; if ($level < 0) { - $link = preg_replace("/\){1," . (- $level) . "}$/", $link, function ($matches) use (&$tail) { - $tail = $matches[0]; - return ''; - }); + $link = preg_replace("/\){1," . (- $level) . "}$/", $link, array($this, '_doAutoLinks_url_callback_callback')); } $url = $this->encodeAttribute($matches[2] . $matches[3]); $link = "$url"; - return '<' . $protocol . $link . '>' . $tail; + return '<' . $protocol . $link . '>' . $this->tail; } + protected function _doAutoLinks_email_callback($matches) { $address = $matches[1]; $link = $this->encodeEmailAddress($address); return $this->hashPart($link); } + protected function _doAutoLinks_url_callback_callback($matches) { + $this->tail = $matches[0]; + return ''; + } protected function encodeEmailAddress($addr) { # @@ -1495,7 +1499,7 @@ class Markdown { # appropriate number of space between each blocks. $text = preg_replace_callback('/^.*\t.*$/m', - array(&$this, '_detab_callback'), $text); + array($this, '_detab_callback'), $text); return $text; } @@ -1535,7 +1539,7 @@ class Markdown { # Swap back in all the tags hashed by _HashHTMLBlocks. # return preg_replace_callback('/(.)\x1A[0-9]+\1/', - array(&$this, '_unhash_callback'), $text); + array($this, '_unhash_callback'), $text); } protected function _unhash_callback($matches) { return $this->html_hashes[trim($matches[0])]; @@ -1543,7 +1547,7 @@ class Markdown { protected function unhashHTMLBlocks($text) { return preg_replace_callback("/\n\n(.)\\x1A[0-9]+\\1\n\n/", - array(&$this, '_unhash_callback'), $text); + array($this, '_unhash_callback'), $text); } } @@ -1744,7 +1748,7 @@ class MarkdownExtra extends Markdown { (?:[ ]* '.$this->id_class_attr_catch_re.' )? # $5 = extra id & class attr (?:\n+|\Z) }xm', - array(&$this, '_stripLinkDefinitions_callback'), + array($this, '_stripLinkDefinitions_callback'), $text); return $text; } @@ -2249,7 +2253,7 @@ class MarkdownExtra extends Markdown { \] ) }xs', - array(&$this, '_doAnchors_reference_callback'), $text); + array($this, '_doAnchors_reference_callback'), $text); # # Next, inline-style links: [link text](url "optional title") @@ -2277,7 +2281,7 @@ class MarkdownExtra extends Markdown { (?:[ ]? '.$this->id_class_attr_catch_re.' )? # $8 = id/class attributes ) }xs', - array(&$this, '_doAnchors_inline_callback'), $text); + array($this, '_doAnchors_inline_callback'), $text); # # Last, handle reference-style shortcuts: [link text] @@ -2291,7 +2295,7 @@ class MarkdownExtra extends Markdown { \] ) }xs', - array(&$this, '_doAnchors_reference_callback'), $text); + array($this, '_doAnchors_reference_callback'), $text); $this->in_anchor = false; return $text; @@ -2378,7 +2382,7 @@ class MarkdownExtra extends Markdown { ) }xs', - array(&$this, '_doImages_reference_callback'), $text); + array($this, '_doImages_reference_callback'), $text); # # Next, handle inline images: ![alt text](url "optional title") @@ -2408,7 +2412,7 @@ class MarkdownExtra extends Markdown { (?:[ ]? '.$this->id_class_attr_catch_re.' )? # $8 = id/class attributes ) }xs', - array(&$this, '_doImages_inline_callback'), $text); + array($this, '_doImages_inline_callback'), $text); return $text; } @@ -2480,7 +2484,7 @@ class MarkdownExtra extends Markdown { (?:[ ]+ '.$this->id_class_attr_catch_re.' )? # $3 = id/class attributes [ ]*\n(=+|-+)[ ]*\n+ # $3: Header footer }mx', - array(&$this, '_doHeaders_callback_setext'), $text); + array($this, '_doHeaders_callback_setext'), $text); # atx-style headers: # # Header 1 {#header1} @@ -2499,7 +2503,7 @@ class MarkdownExtra extends Markdown { [ ]* \n+ }xm', - array(&$this, '_doHeaders_callback_atx'), $text); + array($this, '_doHeaders_callback_atx'), $text); return $text; } @@ -2550,7 +2554,7 @@ class MarkdownExtra extends Markdown { ) (?=\n|\Z) # Stop at final double newline. }xm', - array(&$this, '_doTable_leadingPipe_callback'), $text); + array($this, '_doTable_leadingPipe_callback'), $text); # # Find tables without leading pipe. @@ -2576,7 +2580,7 @@ class MarkdownExtra extends Markdown { ) (?=\n|\Z) # Stop at final double newline. }xm', - array(&$this, '_DoTable_callback'), $text); + array($this, '_DoTable_callback'), $text); return $text; } @@ -2700,7 +2704,7 @@ class MarkdownExtra extends Markdown { (?>\A\n?|(?<=\n\n)) '.$whole_list_re.' }mx', - array(&$this, '_doDefLists_callback'), $text); + array($this, '_doDefLists_callback'), $text); return $text; } @@ -2738,7 +2742,7 @@ class MarkdownExtra extends Markdown { (?=\n?[ ]{0,3}:[ ]) # lookahead for following line feed # with a definition mark. }xm', - array(&$this, '_processDefListItems_callback_dt'), $list_str); + array($this, '_processDefListItems_callback_dt'), $list_str); # Process actual definitions. $list_str = preg_replace_callback('{ @@ -2755,7 +2759,7 @@ class MarkdownExtra extends Markdown { ) ) }xm', - array(&$this, '_processDefListItems_callback_dd'), $list_str); + array($this, '_processDefListItems_callback_dd'), $list_str); return $list_str; } @@ -2823,7 +2827,7 @@ class MarkdownExtra extends Markdown { # Closing marker. \1 [ ]* \n }xm', - array(&$this, '_doFencedCodeBlocks_callback'), $text); + array($this, '_doFencedCodeBlocks_callback'), $text); return $text; } @@ -2833,7 +2837,7 @@ class MarkdownExtra extends Markdown { $codeblock = $matches[4]; $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); $codeblock = preg_replace_callback('/^\n+/', - array(&$this, '_doFencedCodeBlocks_newlines'), $codeblock); + array($this, '_doFencedCodeBlocks_newlines'), $codeblock); if ($classname != "") { if ($classname{0} == '.') @@ -2936,7 +2940,7 @@ class MarkdownExtra extends Markdown { )* ) }xm', - array(&$this, '_stripFootnotes_callback'), + array($this, '_stripFootnotes_callback'), $text); return $text; } @@ -2964,7 +2968,7 @@ class MarkdownExtra extends Markdown { # Append footnote list to text. # $text = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', - array(&$this, '_appendFootnotes_callback'), $text); + array($this, '_appendFootnotes_callback'), $text); if (!empty($this->footnotes_ordered)) { $text .= "\n\n"; @@ -2996,7 +3000,7 @@ class MarkdownExtra extends Markdown { $footnote .= "\n"; # Need to append newline before parsing. $footnote = $this->runBlockGamut("$footnote\n"); $footnote = preg_replace_callback('{F\x1Afn:(.*?)\x1A:}', - array(&$this, '_appendFootnotes_callback'), $footnote); + array($this, '_appendFootnotes_callback'), $footnote); $attr = str_replace("%%", ++$num, $attr); $note_id = $this->encodeAttribute($note_id); @@ -3079,7 +3083,7 @@ class MarkdownExtra extends Markdown { ^[ ]{0,'.$less_than_tab.'}\*\[(.+?)\][ ]?: # abbr_id = $1 (.*) # text = $2 (no blank lines allowed) }xm', - array(&$this, '_stripAbbreviations_callback'), + array($this, '_stripAbbreviations_callback'), $text); return $text; } @@ -3106,7 +3110,7 @@ class MarkdownExtra extends Markdown { '(?:'.$this->abbr_word_re.')'. '(?![\w\x1A])'. '}', - array(&$this, '_doAbbreviations_callback'), $text); + array($this, '_doAbbreviations_callback'), $text); } return $text; } @@ -3130,9 +3134,9 @@ class MarkdownExtra extends Markdown { // https://github.com/egil/php-markdown-extra-extended class MarkdownExtraExtended extends MarkdownExtra { # Tags that are always treated as block tags: - var $block_tags_re = 'figure|figcaption|p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend'; + protected $block_tags_re = 'figure|figcaption|p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|address|form|fieldset|iframe|hr|legend'; - function __construct() { + public function __construct() { $this->block_gamut += array( "doFencedFigures" => 7, ); @@ -3153,28 +3157,28 @@ class MarkdownExtraExtended extends MarkdownExtra { return $parser->transform($text); } - function doHardBreaks($text) { + public function doHardBreaks($text) { # Do hard breaks: # EXTENDED: changed to allow breaks without two spaces and just one new line # original code /* return preg_replace_callback('/ {2,}\n/', */ return preg_replace_callback('/ *\n/', - array(&$this, '_doHardBreaks_callback'), $text); + array($this, '_doHardBreaks_callback'), $text); } - function doBlockQuotes($text) { + public function doBlockQuotes($text) { $text = preg_replace_callback('/ (?>^[ ]*>[ ]? (?:\((.+?)\))? [ ]*(.+\n(?:.+\n)*) )+ /xm', - array(&$this, '_doBlockQuotes_callback'), $text); + array($this, '_doBlockQuotes_callback'), $text); return $text; } - function _doBlockQuotes_callback($matches) { + public function _doBlockQuotes_callback($matches) { $cite = $matches[1]; $bq = '> ' . $matches[2]; # trim one level of quoting - trim whitespace-only lines @@ -3185,7 +3189,7 @@ class MarkdownExtraExtended extends MarkdownExtra { # These leading spaces cause problem with
     content, 
     		# so we need to fix that:
     		$bq = preg_replace_callback('{(\s*
    .+?
    )}sx', - array(&$this, '_doBlockQuotes_callback2'), $bq); + array($this, '_doBlockQuotes_callback2'), $bq); $res = "" : " cite=\"$cite\">"; @@ -3193,7 +3197,7 @@ class MarkdownExtraExtended extends MarkdownExtra { return "\n". $this->hashBlock($res)."\n\n"; } - function doFencedCodeBlocks($text) { + public function doFencedCodeBlocks($text) { $less_than_tab = $this->tab_width; $text = preg_replace_callback('{ @@ -3216,16 +3220,16 @@ class MarkdownExtraExtended extends MarkdownExtra { # Closing marker. \1 [ ]* \n }xm', - array(&$this, '_doFencedCodeBlocks_callback'), $text); + array($this, '_doFencedCodeBlocks_callback'), $text); return $text; } - function _doFencedCodeBlocks_callback($matches) { + public function _doFencedCodeBlocks_callback($matches) { $codeblock = $this->unhashHTMLBlocks($matches[4]); $codeblock = htmlspecialchars($codeblock, ENT_NOQUOTES); $codeblock = preg_replace_callback('/^\n+/', - array(&$this, '_doFencedCodeBlocks_newlines'), $codeblock); + array($this, '_doFencedCodeBlocks_newlines'), $codeblock); //$codeblock = "
    $codeblock
    "; //$cb = "
    hashBlock($cb)."\n\n";
     	}
     
    -	function doFencedFigures($text){
    +	public function doFencedFigures($text){
     		$text = preg_replace_callback('{
     			(?:\n|\A)
     			# 1: Opening marker
    @@ -3254,12 +3258,12 @@ class MarkdownExtraExtended extends MarkdownExtra {
     			
     			# Closing marker.
     			\1 [ ]?(?:\[([^\]]+)\])?[ ]* \n
    -		}xm', array(&$this, '_doFencedFigures_callback'), $text);		
    +		}xm', array($this, '_doFencedFigures_callback'), $text);		
     		
     		return $text;	
     	}
     	
    -	function _doFencedFigures_callback($matches) {
    +	public function _doFencedFigures_callback($matches) {
     		# get figcaption
     		$topcaption = empty($matches[2]) ? null : $this->runBlockGamut($matches[2]);
     		$bottomcaption = empty($matches[5]) ? null : $this->runBlockGamut($matches[5]);
    @@ -3270,7 +3274,7 @@ class MarkdownExtraExtended extends MarkdownExtra {
     		# These leading spaces cause problem with 
     content, 
     		# so we need to fix that - reuse blockqoute code to handle this:
     		$figure = preg_replace_callback('{(\s*
    .+?
    )}sx', - array(&$this, '_doBlockQuotes_callback2'), $figure); + array($this, '_doBlockQuotes_callback2'), $figure); $res = "
    "; if(!empty($topcaption)){ diff --git a/var/Typecho/Common.php b/var/Typecho/Common.php index 76f4758d..eb766d8e 100644 --- a/var/Typecho/Common.php +++ b/var/Typecho/Common.php @@ -560,6 +560,8 @@ EOF; */ public static function stripTags($html, $allowableTags = NULL) { + static $dom; + $normalizeTags = ''; $allowableAttributes = array(); @@ -573,8 +575,11 @@ EOF; } $html = strip_tags($html, $normalizeTags); - $dom = new DOMDocument('1.0', self::$charset); - $dom->xmlStandalone = false; + + if (empty($dom)) { + $dom = new DOMDocument('1.0', self::$charset); + $dom->xmlStandalone = false; + } @$dom->loadHTML('' . $html); foreach($dom->getElementsByTagName('*') as $node){ diff --git a/var/Widget/Upload.php b/var/Widget/Upload.php index 950c0a50..629dfa8a 100644 --- a/var/Widget/Upload.php +++ b/var/Widget/Upload.php @@ -30,7 +30,7 @@ class Widget_Upload extends Widget_Abstract_Contents implements Widget_Interface */ private static function makeUploadDir($path) { - if (!@mkdir($path)) { + if (!@mkdir($path, 0777, true)) { return false; } @@ -75,7 +75,8 @@ class Widget_Upload extends Widget_Abstract_Contents implements Widget_Interface $options = Typecho_Widget::widget('Widget_Options'); $date = new Typecho_Date($options->gmtTime); - $path = Typecho_Common::url(self::UPLOAD_PATH, __TYPECHO_ROOT_DIR__); + $path = Typecho_Common::url(self::UPLOAD_PATH, __TYPECHO_ROOT_DIR__) + . '/' . $date->year . '/' . $date->month; //创建上传目录 if (!is_dir($path)) { @@ -84,20 +85,6 @@ class Widget_Upload extends Widget_Abstract_Contents implements Widget_Interface } } - //创建年份目录 - if (!is_dir($path = $path . '/' . $date->year)) { - if (!self::makeUploadDir($path)) { - return false; - } - } - - //创建月份目录 - if (!is_dir($path = $path . '/' . $date->month)) { - if (!self::makeUploadDir($path)) { - return false; - } - } - //获取文件名 $fileName = sprintf('%u', crc32(uniqid())) . '.' . $ext; $path = $path . '/' . $fileName; @@ -105,7 +92,7 @@ class Widget_Upload extends Widget_Abstract_Contents implements Widget_Interface if (isset($file['tmp_name'])) { //移动上传文件 - if (!move_uploaded_file($file['tmp_name'], $path)) { + if (!@move_uploaded_file($file['tmp_name'], $path)) { return false; } } else if (isset($file['bytes'])) { @@ -166,13 +153,21 @@ class Widget_Upload extends Widget_Abstract_Contents implements Widget_Interface } $path = Typecho_Common::url($content['attachment']->path, __TYPECHO_ROOT_DIR__); + $dir = dirname($path); + + //创建上传目录 + if (!is_dir($dir)) { + if (!self::makeUploadDir($dir)) { + return false; + } + } if (isset($file['tmp_name'])) { @unlink($path); //移动上传文件 - if (!move_uploaded_file($file['tmp_name'], $path)) { + if (!@move_uploaded_file($file['tmp_name'], $path)) { return false; } } else if (isset($file['bytes'])) {