26 class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer { |
26 class WP_Text_Diff_Renderer_Table extends Text_Diff_Renderer { |
27 |
27 |
28 /** |
28 /** |
29 * @see Text_Diff_Renderer::_leading_context_lines |
29 * @see Text_Diff_Renderer::_leading_context_lines |
30 * @var int |
30 * @var int |
31 * @access protected |
31 * @access public |
32 * @since 2.6.0 |
32 * @since 2.6.0 |
33 */ |
33 */ |
34 var $_leading_context_lines = 10000; |
34 public $_leading_context_lines = 10000; |
35 |
35 |
36 /** |
36 /** |
37 * @see Text_Diff_Renderer::_trailing_context_lines |
37 * @see Text_Diff_Renderer::_trailing_context_lines |
38 * @var int |
38 * @var int |
39 * @access protected |
39 * @access public |
40 * @since 2.6.0 |
40 * @since 2.6.0 |
41 */ |
41 */ |
42 var $_trailing_context_lines = 10000; |
42 public $_trailing_context_lines = 10000; |
43 |
43 |
44 /** |
44 /** |
45 * {@internal Missing Description}} |
45 * Threshold for when a diff should be saved or omitted. |
46 * |
46 * |
47 * @var float |
47 * @var float |
48 * @access protected |
48 * @access protected |
49 * @since 2.6.0 |
49 * @since 2.6.0 |
50 */ |
50 */ |
51 var $_diff_threshold = 0.6; |
51 protected $_diff_threshold = 0.6; |
52 |
52 |
53 /** |
53 /** |
54 * Inline display helper object name. |
54 * Inline display helper object name. |
55 * |
55 * |
56 * @var string |
56 * @var string |
57 * @access protected |
57 * @access protected |
58 * @since 2.6.0 |
58 * @since 2.6.0 |
59 */ |
59 */ |
60 var $inline_diff_renderer = 'WP_Text_Diff_Renderer_inline'; |
60 protected $inline_diff_renderer = 'WP_Text_Diff_Renderer_inline'; |
61 |
61 |
62 /** |
62 /** |
63 * Should we show the split view or not |
63 * Should we show the split view or not |
64 * |
64 * |
65 * @var string |
65 * @var string |
66 * @access protected |
66 * @access protected |
67 * @since 3.6.0 |
67 * @since 3.6.0 |
68 */ |
68 */ |
69 var $_show_split_view = true; |
69 protected $_show_split_view = true; |
|
70 |
|
71 protected $compat_fields = array( '_show_split_view', 'inline_diff_renderer', '_diff_threshold' ); |
70 |
72 |
71 /** |
73 /** |
72 * Constructor - Call parent constructor with params array. |
74 * Constructor - Call parent constructor with params array. |
73 * |
75 * |
74 * This will set class properties based on the key value pairs in the array. |
76 * This will set class properties based on the key value pairs in the array. |
75 * |
77 * |
76 * @since 2.6.0 |
78 * @since 2.6.0 |
77 * |
79 * |
78 * @param array $params |
80 * @param array $params |
79 */ |
81 */ |
80 function __construct( $params = array() ) { |
82 public function __construct( $params = array() ) { |
81 parent::__construct( $params ); |
83 parent::__construct( $params ); |
82 if ( isset( $params[ 'show_split_view' ] ) ) |
84 if ( isset( $params[ 'show_split_view' ] ) ) |
83 $this->_show_split_view = $params[ 'show_split_view' ]; |
85 $this->_show_split_view = $params[ 'show_split_view' ]; |
84 } |
86 } |
85 |
87 |
87 * @ignore |
89 * @ignore |
88 * |
90 * |
89 * @param string $header |
91 * @param string $header |
90 * @return string |
92 * @return string |
91 */ |
93 */ |
92 function _startBlock( $header ) { |
94 public function _startBlock( $header ) { |
93 return ''; |
95 return ''; |
94 } |
96 } |
95 |
97 |
96 /** |
98 /** |
97 * @ignore |
99 * @ignore |
98 * |
100 * |
99 * @param array $lines |
101 * @param array $lines |
100 * @param string $prefix |
102 * @param string $prefix |
101 */ |
103 */ |
102 function _lines( $lines, $prefix=' ' ) { |
104 public function _lines( $lines, $prefix=' ' ) { |
103 } |
105 } |
104 |
106 |
105 /** |
107 /** |
106 * @ignore |
108 * @ignore |
107 * |
109 * |
108 * @param string $line HTML-escape the value. |
110 * @param string $line HTML-escape the value. |
109 * @return string |
111 * @return string |
110 */ |
112 */ |
111 function addedLine( $line ) { |
113 public function addedLine( $line ) { |
112 return "<td class='diff-addedline'>{$line}</td>"; |
114 return "<td class='diff-addedline'>{$line}</td>"; |
113 |
115 |
114 } |
116 } |
115 |
117 |
116 /** |
118 /** |
117 * @ignore |
119 * @ignore |
118 * |
120 * |
119 * @param string $line HTML-escape the value. |
121 * @param string $line HTML-escape the value. |
120 * @return string |
122 * @return string |
121 */ |
123 */ |
122 function deletedLine( $line ) { |
124 public function deletedLine( $line ) { |
123 return "<td class='diff-deletedline'>{$line}</td>"; |
125 return "<td class='diff-deletedline'>{$line}</td>"; |
124 } |
126 } |
125 |
127 |
126 /** |
128 /** |
127 * @ignore |
129 * @ignore |
128 * |
130 * |
129 * @param string $line HTML-escape the value. |
131 * @param string $line HTML-escape the value. |
130 * @return string |
132 * @return string |
131 */ |
133 */ |
132 function contextLine( $line ) { |
134 public function contextLine( $line ) { |
133 return "<td class='diff-context'>{$line}</td>"; |
135 return "<td class='diff-context'>{$line}</td>"; |
134 } |
136 } |
135 |
137 |
136 /** |
138 /** |
137 * @ignore |
139 * @ignore |
138 * |
140 * |
139 * @return string |
141 * @return string |
140 */ |
142 */ |
141 function emptyLine() { |
143 public function emptyLine() { |
142 return '<td> </td>'; |
144 return '<td> </td>'; |
143 } |
145 } |
144 |
146 |
145 /** |
147 /** |
146 * @ignore |
148 * @ignore |
147 * @access private |
149 * @access public |
148 * |
150 * |
149 * @param array $lines |
151 * @param array $lines |
150 * @param bool $encode |
152 * @param bool $encode |
151 * @return string |
153 * @return string |
152 */ |
154 */ |
153 function _added( $lines, $encode = true ) { |
155 public function _added( $lines, $encode = true ) { |
154 $r = ''; |
156 $r = ''; |
155 foreach ($lines as $line) { |
157 foreach ($lines as $line) { |
156 if ( $encode ) |
158 if ( $encode ) { |
157 $line = htmlspecialchars( $line ); |
159 $processed_line = htmlspecialchars( $line ); |
|
160 |
|
161 /** |
|
162 * Contextually filter a diffed line. |
|
163 * |
|
164 * Filters TextDiff processing of diffed line. By default, diffs are processed with |
|
165 * htmlspecialchars. Use this filter to remove or change the processing. Passes a context |
|
166 * indicating if the line is added, deleted or unchanged. |
|
167 * |
|
168 * @since 4.1.0 |
|
169 * |
|
170 * @param String $processed_line The processed diffed line. |
|
171 * @param String $line The unprocessed diffed line. |
|
172 * @param string null The line context. Values are 'added', 'deleted' or 'unchanged'. |
|
173 */ |
|
174 $line = apply_filters( 'process_text_diff_html', $processed_line, $line, 'added' ); |
|
175 } |
|
176 |
158 if ( $this->_show_split_view ) { |
177 if ( $this->_show_split_view ) { |
159 $r .= '<tr>' . $this->emptyLine() . $this->emptyLine() . $this->addedLine( $line ) . "</tr>\n"; |
178 $r .= '<tr>' . $this->emptyLine() . $this->emptyLine() . $this->addedLine( $line ) . "</tr>\n"; |
160 } else { |
179 } else { |
161 $r .= '<tr>' . $this->addedLine( $line ) . "</tr>\n"; |
180 $r .= '<tr>' . $this->addedLine( $line ) . "</tr>\n"; |
162 } |
181 } |
164 return $r; |
183 return $r; |
165 } |
184 } |
166 |
185 |
167 /** |
186 /** |
168 * @ignore |
187 * @ignore |
169 * @access private |
188 * @access public |
170 * |
189 * |
171 * @param array $lines |
190 * @param array $lines |
172 * @param bool $encode |
191 * @param bool $encode |
173 * @return string |
192 * @return string |
174 */ |
193 */ |
175 function _deleted( $lines, $encode = true ) { |
194 public function _deleted( $lines, $encode = true ) { |
176 $r = ''; |
195 $r = ''; |
177 foreach ($lines as $line) { |
196 foreach ($lines as $line) { |
178 if ( $encode ) |
197 if ( $encode ) { |
179 $line = htmlspecialchars( $line ); |
198 $processed_line = htmlspecialchars( $line ); |
|
199 |
|
200 /** This filter is documented in wp-includes/wp-diff.php */ |
|
201 $line = apply_filters( 'process_text_diff_html', $processed_line, $line, 'deleted' ); |
|
202 } |
180 if ( $this->_show_split_view ) { |
203 if ( $this->_show_split_view ) { |
181 $r .= '<tr>' . $this->deletedLine( $line ) . $this->emptyLine() . $this->emptyLine() . "</tr>\n"; |
204 $r .= '<tr>' . $this->deletedLine( $line ) . $this->emptyLine() . $this->emptyLine() . "</tr>\n"; |
182 } else { |
205 } else { |
183 $r .= '<tr>' . $this->deletedLine( $line ) . "</tr>\n"; |
206 $r .= '<tr>' . $this->deletedLine( $line ) . "</tr>\n"; |
184 } |
207 } |
187 return $r; |
210 return $r; |
188 } |
211 } |
189 |
212 |
190 /** |
213 /** |
191 * @ignore |
214 * @ignore |
192 * @access private |
215 * @access public |
193 * |
216 * |
194 * @param array $lines |
217 * @param array $lines |
195 * @param bool $encode |
218 * @param bool $encode |
196 * @return string |
219 * @return string |
197 */ |
220 */ |
198 function _context( $lines, $encode = true ) { |
221 public function _context( $lines, $encode = true ) { |
199 $r = ''; |
222 $r = ''; |
200 foreach ($lines as $line) { |
223 foreach ($lines as $line) { |
201 if ( $encode ) |
224 if ( $encode ) { |
202 $line = htmlspecialchars( $line ); |
225 $processed_line = htmlspecialchars( $line ); |
|
226 |
|
227 /** This filter is documented in wp-includes/wp-diff.php */ |
|
228 $line = apply_filters( 'process_text_diff_html', $processed_line, $line, 'unchanged' ); |
|
229 } |
203 if ( $this->_show_split_view ) { |
230 if ( $this->_show_split_view ) { |
204 $r .= '<tr>' . $this->contextLine( $line ) . $this->emptyLine() . $this->contextLine( $line ) . "</tr>\n"; |
231 $r .= '<tr>' . $this->contextLine( $line ) . $this->emptyLine() . $this->contextLine( $line ) . "</tr>\n"; |
205 } else { |
232 } else { |
206 $r .= '<tr>' . $this->contextLine( $line ) . "</tr>\n"; |
233 $r .= '<tr>' . $this->contextLine( $line ) . "</tr>\n"; |
207 } |
234 } |
213 * Process changed lines to do word-by-word diffs for extra highlighting. |
240 * Process changed lines to do word-by-word diffs for extra highlighting. |
214 * |
241 * |
215 * (TRAC style) sometimes these lines can actually be deleted or added rows. |
242 * (TRAC style) sometimes these lines can actually be deleted or added rows. |
216 * We do additional processing to figure that out |
243 * We do additional processing to figure that out |
217 * |
244 * |
218 * @access private |
245 * @access public |
219 * @since 2.6.0 |
246 * @since 2.6.0 |
220 * |
247 * |
221 * @param array $orig |
248 * @param array $orig |
222 * @param array $final |
249 * @param array $final |
223 * @return string |
250 * @return string |
224 */ |
251 */ |
225 function _changed( $orig, $final ) { |
252 public function _changed( $orig, $final ) { |
226 $r = ''; |
253 $r = ''; |
227 |
254 |
228 // Does the aforementioned additional processing |
255 // Does the aforementioned additional processing |
229 // *_matches tell what rows are "the same" in orig and final. Those pairs will be diffed to get word changes |
256 // *_matches tell what rows are "the same" in orig and final. Those pairs will be diffed to get word changes |
230 // match is numeric: an index in other column |
257 // match is numeric: an index in other column |
244 $text_diff = new Text_Diff( 'auto', array( array($orig[$o]), array($final[$f]) ) ); |
271 $text_diff = new Text_Diff( 'auto', array( array($orig[$o]), array($final[$f]) ) ); |
245 $renderer = new $this->inline_diff_renderer; |
272 $renderer = new $this->inline_diff_renderer; |
246 $diff = $renderer->render( $text_diff ); |
273 $diff = $renderer->render( $text_diff ); |
247 |
274 |
248 // If they're too different, don't include any <ins> or <dels> |
275 // If they're too different, don't include any <ins> or <dels> |
249 if ( $diff_count = preg_match_all( '!(<ins>.*?</ins>|<del>.*?</del>)!', $diff, $diff_matches ) ) { |
276 if ( preg_match_all( '!(<ins>.*?</ins>|<del>.*?</del>)!', $diff, $diff_matches ) ) { |
250 // length of all text between <ins> or <del> |
277 // length of all text between <ins> or <del> |
251 $stripped_matches = strlen(strip_tags( join(' ', $diff_matches[0]) )); |
278 $stripped_matches = strlen(strip_tags( join(' ', $diff_matches[0]) )); |
252 // since we count lengith of text between <ins> or <del> (instead of picking just one), |
279 // since we count lengith of text between <ins> or <del> (instead of picking just one), |
253 // we double the length of chars not in those tags. |
280 // we double the length of chars not in those tags. |
254 $stripped_diff = strlen(strip_tags( $diff )) * 2 - $stripped_matches; |
281 $stripped_diff = strlen(strip_tags( $diff )) * 2 - $stripped_matches; |
307 * *_rows ( order of rows in each column interleaved with blank rows as |
334 * *_rows ( order of rows in each column interleaved with blank rows as |
308 * necessary ) |
335 * necessary ) |
309 * |
336 * |
310 * @since 2.6.0 |
337 * @since 2.6.0 |
311 * |
338 * |
312 * @param unknown_type $orig |
339 * @param array $orig |
313 * @param unknown_type $final |
340 * @param array $final |
314 * @return unknown |
341 * @return array |
315 */ |
342 */ |
316 function interleave_changed_lines( $orig, $final ) { |
343 public function interleave_changed_lines( $orig, $final ) { |
317 |
344 |
318 // Contains all pairwise string comparisons. Keys are such that this need only be a one dimensional array. |
345 // Contains all pairwise string comparisons. Keys are such that this need only be a one dimensional array. |
319 $matches = array(); |
346 $matches = array(); |
320 foreach ( array_keys($orig) as $o ) { |
347 foreach ( array_keys($orig) as $o ) { |
321 foreach ( array_keys($final) as $f ) { |
348 foreach ( array_keys($final) as $f ) { |
389 while ( $diff_count < 0 ) |
416 while ( $diff_count < 0 ) |
390 array_push($final_rows, $diff_count++); |
417 array_push($final_rows, $diff_count++); |
391 } |
418 } |
392 |
419 |
393 return array($orig_matches, $final_matches, $orig_rows, $final_rows); |
420 return array($orig_matches, $final_matches, $orig_rows, $final_rows); |
394 |
|
395 /* |
|
396 // Debug |
|
397 echo "\n\n\n\n\n"; |
|
398 |
|
399 echo "-- DEBUG Matches: Orig -> Final --"; |
|
400 |
|
401 foreach ( $orig_matches as $o => $f ) { |
|
402 echo "\n\n\n\n\n"; |
|
403 echo "ORIG: $o, FINAL: $f\n"; |
|
404 var_dump($orig[$o],$final[$f]); |
|
405 } |
|
406 echo "\n\n\n\n\n"; |
|
407 |
|
408 echo "-- DEBUG Matches: Final -> Orig --"; |
|
409 |
|
410 foreach ( $final_matches as $f => $o ) { |
|
411 echo "\n\n\n\n\n"; |
|
412 echo "FINAL: $f, ORIG: $o\n"; |
|
413 var_dump($final[$f],$orig[$o]); |
|
414 } |
|
415 echo "\n\n\n\n\n"; |
|
416 |
|
417 echo "-- DEBUG Rows: Orig -- Final --"; |
|
418 |
|
419 echo "\n\n\n\n\n"; |
|
420 foreach ( $orig_rows as $row => $o ) { |
|
421 if ( $o < 0 ) |
|
422 $o = 'X'; |
|
423 $f = $final_rows[$row]; |
|
424 if ( $f < 0 ) |
|
425 $f = 'X'; |
|
426 echo "$o -- $f\n"; |
|
427 } |
|
428 echo "\n\n\n\n\n"; |
|
429 |
|
430 echo "-- END DEBUG --"; |
|
431 |
|
432 echo "\n\n\n\n\n"; |
|
433 |
|
434 return array($orig_matches, $final_matches, $orig_rows, $final_rows); |
|
435 */ |
|
436 } |
421 } |
437 |
422 |
438 /** |
423 /** |
439 * Computes a number that is intended to reflect the "distance" between two strings. |
424 * Computes a number that is intended to reflect the "distance" between two strings. |
440 * |
425 * |
442 * |
427 * |
443 * @param string $string1 |
428 * @param string $string1 |
444 * @param string $string2 |
429 * @param string $string2 |
445 * @return int |
430 * @return int |
446 */ |
431 */ |
447 function compute_string_distance( $string1, $string2 ) { |
432 public function compute_string_distance( $string1, $string2 ) { |
448 // Vectors containing character frequency for all chars in each string |
433 // Vectors containing character frequency for all chars in each string |
449 $chars1 = count_chars($string1); |
434 $chars1 = count_chars($string1); |
450 $chars2 = count_chars($string2); |
435 $chars2 = count_chars($string2); |
451 |
436 |
452 // L1-norm of difference vector. |
437 // L1-norm of difference vector. |
466 * |
451 * |
467 * @param int $a |
452 * @param int $a |
468 * @param int $b |
453 * @param int $b |
469 * @return int |
454 * @return int |
470 */ |
455 */ |
471 function difference( $a, $b ) { |
456 public function difference( $a, $b ) { |
472 return abs( $a - $b ); |
457 return abs( $a - $b ); |
473 } |
458 } |
474 |
459 |
|
460 /** |
|
461 * Make private properties readable for backwards compatibility. |
|
462 * |
|
463 * @since 4.0.0 |
|
464 * @access public |
|
465 * |
|
466 * @param string $name Property to get. |
|
467 * @return mixed Property. |
|
468 */ |
|
469 public function __get( $name ) { |
|
470 if ( in_array( $name, $this->compat_fields ) ) { |
|
471 return $this->$name; |
|
472 } |
|
473 } |
|
474 |
|
475 /** |
|
476 * Make private properties settable for backwards compatibility. |
|
477 * |
|
478 * @since 4.0.0 |
|
479 * @access public |
|
480 * |
|
481 * @param string $name Property to check if set. |
|
482 * @param mixed $value Property value. |
|
483 * @return mixed Newly-set property. |
|
484 */ |
|
485 public function __set( $name, $value ) { |
|
486 if ( in_array( $name, $this->compat_fields ) ) { |
|
487 return $this->$name = $value; |
|
488 } |
|
489 } |
|
490 |
|
491 /** |
|
492 * Make private properties checkable for backwards compatibility. |
|
493 * |
|
494 * @since 4.0.0 |
|
495 * @access public |
|
496 * |
|
497 * @param string $name Property to check if set. |
|
498 * @return bool Whether the property is set. |
|
499 */ |
|
500 public function __isset( $name ) { |
|
501 if ( in_array( $name, $this->compat_fields ) ) { |
|
502 return isset( $this->$name ); |
|
503 } |
|
504 } |
|
505 |
|
506 /** |
|
507 * Make private properties un-settable for backwards compatibility. |
|
508 * |
|
509 * @since 4.0.0 |
|
510 * @access public |
|
511 * |
|
512 * @param string $name Property to unset. |
|
513 */ |
|
514 public function __unset( $name ) { |
|
515 if ( in_array( $name, $this->compat_fields ) ) { |
|
516 unset( $this->$name ); |
|
517 } |
|
518 } |
475 } |
519 } |
476 |
520 |
477 /** |
521 /** |
478 * Better word splitting than the PEAR package provides. |
522 * Better word splitting than the PEAR package provides. |
479 * |
523 * |
488 * |
532 * |
489 * @param string $string |
533 * @param string $string |
490 * @param string $newlineEscape |
534 * @param string $newlineEscape |
491 * @return string |
535 * @return string |
492 */ |
536 */ |
493 function _splitOnWords($string, $newlineEscape = "\n") { |
537 public function _splitOnWords($string, $newlineEscape = "\n") { |
494 $string = str_replace("\0", '', $string); |
538 $string = str_replace("\0", '', $string); |
495 $words = preg_split( '/([^\w])/u', $string, -1, PREG_SPLIT_DELIM_CAPTURE ); |
539 $words = preg_split( '/([^\w])/u', $string, -1, PREG_SPLIT_DELIM_CAPTURE ); |
496 $words = str_replace( "\n", $newlineEscape, $words ); |
540 $words = str_replace( "\n", $newlineEscape, $words ); |
497 return $words; |
541 return $words; |
498 } |
542 } |