summaryrefslogtreecommitdiff
path: root/includes/diff
diff options
context:
space:
mode:
authorLuke Shumaker <LukeShu@sbcglobal.net>2014-01-28 09:50:25 -0500
committerLuke Shumaker <LukeShu@sbcglobal.net>2014-01-28 09:50:25 -0500
commit5744df39e15f85c6cc8a9faf8924d77e76d2b216 (patch)
treea8c8dd40a94d1fa0d5377566aa5548ae55a163da /includes/diff
parent4bb2aeca1d198391ca856aa16c40b8559c68daec (diff)
parent224b22a051051f6c2e494c3a2fb4adb42898e2d1 (diff)
Merge branch 'archwiki'
Conflicts: extensions/FluxBBAuthPlugin.php extensions/SyntaxHighlight_GeSHi/README extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.class.php extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.i18n.php extensions/SyntaxHighlight_GeSHi/SyntaxHighlight_GeSHi.php extensions/SyntaxHighlight_GeSHi/geshi/docs/CHANGES extensions/SyntaxHighlight_GeSHi/geshi/docs/THANKS extensions/SyntaxHighlight_GeSHi/geshi/docs/TODO extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractClass.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractClass_logo.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractMethod.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractPrivateClass.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractPrivateClass_logo.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/AbstractPrivateMethod.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Class.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Class_logo.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Constant.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Constructor.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Destructor.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Function.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Global.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/I.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Index.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Interface.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Interface_logo.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/L.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Lminus.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Lplus.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Method.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Page.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Page_logo.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/PrivateClass.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/PrivateClass_logo.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/PrivateMethod.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/PrivateVariable.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/StaticMethod.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/StaticVariable.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/T.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Tminus.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Tplus.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/Variable.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/blank.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/class_folder.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/file.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/folder.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/function_folder.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/next_button.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/next_button_disabled.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/package.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/package_folder.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/previous_button.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/previous_button_disabled.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/private_class_logo.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/tutorial.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/tutorial_folder.png extensions/SyntaxHighlight_GeSHi/geshi/docs/api/media/images/up_button.png extensions/SyntaxHighlight_GeSHi/geshi/docs/geshi-doc.html extensions/SyntaxHighlight_GeSHi/geshi/docs/geshi-doc.txt extensions/SyntaxHighlight_GeSHi/geshi/geshi.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/4cs.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/6502acme.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/6502kickass.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/6502tasm.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/68000devpac.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/abap.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/actionscript.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/actionscript3.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/ada.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/algol68.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/apache.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/applescript.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/apt_sources.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/asm.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/asp.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/autoconf.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/autohotkey.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/autoit.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/avisynth.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/awk.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/bascomavr.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/bash.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/basic4gl.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/bf.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/bibtex.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/blitzbasic.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/bnf.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/boo.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/c.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/c_loadrunner.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/c_mac.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/caddcl.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/cadlisp.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/cfdg.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/cfm.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/chaiscript.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/cil.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/clojure.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/cmake.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/cobol.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/coffeescript.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/cpp-qt.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/cpp.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/csharp.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/css.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/cuesheet.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/d.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/dcs.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/delphi.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/diff.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/div.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/dos.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/dot.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/e.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/ecmascript.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/eiffel.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/email.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/epc.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/erlang.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/euphoria.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/f1.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/falcon.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/fo.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/fortran.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/freebasic.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/fsharp.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/gambas.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/gdb.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/genero.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/genie.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/gettext.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/glsl.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/gml.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/gnuplot.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/go.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/groovy.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/gwbasic.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/haskell.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/hicest.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/hq9plus.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/html4strict.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/html5.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/icon.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/idl.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/ini.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/inno.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/intercal.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/io.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/j.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/java.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/java5.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/javascript.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/jquery.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/kixtart.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/klonec.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/klonecpp.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/latex.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/lb.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/lisp.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/llvm.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/locobasic.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/logtalk.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/lolcode.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/lotusformulas.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/lotusscript.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/lscript.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/lsl2.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/lua.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/m68k.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/magiksf.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/make.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/mapbasic.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/matlab.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/mirc.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/mmix.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/modula2.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/modula3.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/mpasm.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/mxml.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/mysql.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/newlisp.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/nsis.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/oberon2.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/objc.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/objeck.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/ocaml-brief.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/ocaml.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/oobas.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/oracle11.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/oracle8.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/oxygene.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/oz.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/pascal.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/pcre.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/per.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/perl.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/perl6.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/pf.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/php-brief.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/php.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/pic16.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/pike.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/pixelbender.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/pli.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/plsql.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/postgresql.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/povray.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/powerbuilder.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/powershell.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/proftpd.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/progress.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/prolog.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/properties.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/providex.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/purebasic.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/pycon.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/python.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/q.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/qbasic.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/rails.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/rebol.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/reg.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/robots.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/rpmspec.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/rsplus.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/ruby.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/sas.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/scala.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/scheme.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/scilab.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/sdlbasic.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/smalltalk.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/smarty.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/sql.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/systemverilog.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/tcl.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/teraterm.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/text.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/thinbasic.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/tsql.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/typoscript.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/unicon.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/uscript.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/vala.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/vb.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/vbnet.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/verilog.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/vhdl.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/vim.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/visualfoxpro.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/visualprolog.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/whitespace.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/whois.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/winbatch.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/xbasic.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/xml.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/xorg_conf.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/xpp.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/yaml.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/z80.php extensions/SyntaxHighlight_GeSHi/geshi/geshi/zxbasic.php
Diffstat (limited to 'includes/diff')
-rw-r--r--includes/diff/DairikiDiff.php117
-rw-r--r--includes/diff/DifferenceEngine.php364
-rw-r--r--includes/diff/WikiDiff3.php5
3 files changed, 301 insertions, 185 deletions
diff --git a/includes/diff/DairikiDiff.php b/includes/diff/DairikiDiff.php
index 72eb5d3c..298d7240 100644
--- a/includes/diff/DairikiDiff.php
+++ b/includes/diff/DairikiDiff.php
@@ -5,6 +5,21 @@
* Copyright © 2000, 2001 Geoffrey T. Dairiki <dairiki@dairiki.org>
* You may copy this code freely under the conditions of the GPL.
*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
* @ingroup DifferenceEngine
* @defgroup DifferenceEngine DifferenceEngine
@@ -28,14 +43,14 @@ class _DiffOp {
* @return int
*/
function norig() {
- return $this->orig ? sizeof( $this->orig ) : 0;
+ return $this->orig ? count( $this->orig ) : 0;
}
/**
* @return int
*/
function nclosing() {
- return $this->closing ? sizeof( $this->closing ) : 0;
+ return $this->closing ? count( $this->closing ) : 0;
}
}
@@ -152,7 +167,7 @@ class _DiffOp_Change extends _DiffOp {
*/
class _DiffEngine {
- const MAX_XREF_LENGTH = 10000;
+ const MAX_XREF_LENGTH = 10000;
protected $xchanged, $ychanged;
@@ -168,7 +183,7 @@ class _DiffEngine {
* @param $to_lines
* @return array
*/
- function diff ( $from_lines, $to_lines ) {
+ function diff( $from_lines, $to_lines ) {
wfProfileIn( __METHOD__ );
// Diff and store locally
@@ -179,8 +194,8 @@ class _DiffEngine {
$this->_shift_boundaries( $to_lines, $this->ychanged, $this->xchanged );
// Compute the edit operations.
- $n_from = sizeof( $from_lines );
- $n_to = sizeof( $to_lines );
+ $n_from = count( $from_lines );
+ $n_to = count( $to_lines );
$edits = array();
$xi = $yi = 0;
@@ -206,7 +221,7 @@ class _DiffEngine {
}
$add = array();
- while ( $yi < $n_to && $this->ychanged[$yi] ) {
+ while ( $yi < $n_to && $this->ychanged[$yi] ) {
$add[] = $to_lines[$yi++];
}
@@ -226,7 +241,7 @@ class _DiffEngine {
* @param $from_lines
* @param $to_lines
*/
- function diff_local ( $from_lines, $to_lines ) {
+ function diff_local( $from_lines, $to_lines ) {
global $wgExternalDiffEngine;
wfProfileIn( __METHOD__ );
@@ -239,8 +254,8 @@ class _DiffEngine {
unset( $wikidiff3 );
} else {
// old diff
- $n_from = sizeof( $from_lines );
- $n_to = sizeof( $to_lines );
+ $n_from = count( $from_lines );
+ $n_to = count( $to_lines );
$this->xchanged = $this->ychanged = array();
$this->xv = $this->yv = array();
$this->xind = $this->yind = array();
@@ -256,7 +271,8 @@ class _DiffEngine {
$this->xchanged[$skip] = $this->ychanged[$skip] = false;
}
// Skip trailing common lines.
- $xi = $n_from; $yi = $n_to;
+ $xi = $n_from;
+ $yi = $n_to;
for ( $endskip = 0; --$xi > $skip && --$yi > $skip; $endskip++ ) {
if ( $from_lines[$xi] !== $to_lines[$yi] ) {
break;
@@ -288,7 +304,7 @@ class _DiffEngine {
}
// Find the LCS.
- $this->_compareseq( 0, sizeof( $this->xv ), 0, sizeof( $this->yv ) );
+ $this->_compareseq( 0, count( $this->xv ), 0, count( $this->yv ) );
}
wfProfileOut( __METHOD__ );
}
@@ -311,7 +327,7 @@ class _DiffEngine {
* [XOFF, XLIM) and [YOFF, YLIM) into NCHUNKS approximately equally
* sized segments.
*
- * Returns (LCS, PTS). LCS is the length of the LCS. PTS is an
+ * Returns (LCS, PTS). LCS is the length of the LCS. PTS is an
* array of NCHUNKS+1 (X, Y) indexes giving the diving points between
* sub sequences. The first sub-sequence is contained in [X0, X1),
* [Y0, Y1), the second in [X1, X2), [Y1, Y2) and so on. Note
@@ -379,7 +395,7 @@ class _DiffEngine {
break;
}
}
- while ( list ( , $y ) = each( $matches ) ) {
+ while ( list( , $y ) = each( $matches ) ) {
if ( $y > $this->seq[$k -1] ) {
assert( '$y < $this->seq[$k]' );
// Optimization: this is a common case:
@@ -454,10 +470,9 @@ class _DiffEngine {
* @param $yoff
* @param $ylim
*/
- function _compareseq ( $xoff, $xlim, $yoff, $ylim ) {
+ function _compareseq( $xoff, $xlim, $yoff, $ylim ) {
// Slide down the bottom initial diagonal.
- while ( $xoff < $xlim && $yoff < $ylim
- && $this->xv[$xoff] == $this->yv[$yoff] ) {
+ while ( $xoff < $xlim && $yoff < $ylim && $this->xv[$xoff] == $this->yv[$yoff] ) {
++$xoff;
++$yoff;
}
@@ -476,8 +491,7 @@ class _DiffEngine {
// $nchunks = sqrt(min($xlim - $xoff, $ylim - $yoff) / 2.5);
// $nchunks = max(2,min(8,(int)$nchunks));
$nchunks = min( 7, $xlim - $xoff, $ylim - $yoff ) + 1;
- list ( $lcs, $seps )
- = $this->_diag( $xoff, $xlim, $yoff, $ylim, $nchunks );
+ list( $lcs, $seps ) = $this->_diag( $xoff, $xlim, $yoff, $ylim, $nchunks );
}
if ( $lcs == 0 ) {
@@ -494,7 +508,7 @@ class _DiffEngine {
reset( $seps );
$pt1 = $seps[0];
while ( $pt2 = next( $seps ) ) {
- $this->_compareseq ( $pt1[0], $pt2[0], $pt1[1], $pt2[1] );
+ $this->_compareseq( $pt1[0], $pt2[0], $pt1[1], $pt2[1] );
$pt1 = $pt2;
}
}
@@ -518,9 +532,9 @@ class _DiffEngine {
$i = 0;
$j = 0;
- assert( 'sizeof($lines) == sizeof($changed)' );
- $len = sizeof( $lines );
- $other_len = sizeof( $other_changed );
+ assert( 'count($lines) == count($changed)' );
+ $len = count( $lines );
+ $other_len = count( $other_changed );
while ( 1 ) {
/*
@@ -540,9 +554,11 @@ class _DiffEngine {
while ( $i < $len && ! $changed[$i] ) {
assert( '$j < $other_len && ! $other_changed[$j]' );
- $i++; $j++;
- while ( $j < $other_len && $other_changed[$j] )
+ $i++;
$j++;
+ while ( $j < $other_len && $other_changed[$j] ) {
+ $j++;
+ }
}
if ( $i == $len ) {
@@ -676,7 +692,7 @@ class Diff {
/**
* Check for empty diff.
*
- * @return bool True iff two sequences were identical.
+ * @return bool True if two sequences were identical.
*/
function isEmpty() {
foreach ( $this->edits as $edit ) {
@@ -698,7 +714,7 @@ class Diff {
$lcs = 0;
foreach ( $this->edits as $edit ) {
if ( $edit->type == 'copy' ) {
- $lcs += sizeof( $edit->orig );
+ $lcs += count( $edit->orig );
}
}
return $lcs;
@@ -717,7 +733,7 @@ class Diff {
foreach ( $this->edits as $edit ) {
if ( $edit->orig ) {
- array_splice( $lines, sizeof( $lines ), 0, $edit->orig );
+ array_splice( $lines, count( $lines ), 0, $edit->orig );
}
}
return $lines;
@@ -736,7 +752,7 @@ class Diff {
foreach ( $this->edits as $edit ) {
if ( $edit->closing ) {
- array_splice( $lines, sizeof( $lines ), 0, $edit->closing );
+ array_splice( $lines, count( $lines ), 0, $edit->closing );
}
}
return $lines;
@@ -766,7 +782,6 @@ class Diff {
trigger_error( "Reversed closing doesn't match", E_USER_ERROR );
}
-
$prevtype = 'none';
foreach ( $this->edits as $edit ) {
if ( $prevtype == $edit->type ) {
@@ -814,23 +829,23 @@ class MappedDiff extends Diff {
$mapped_from_lines, $mapped_to_lines ) {
wfProfileIn( __METHOD__ );
- assert( 'sizeof( $from_lines ) == sizeof( $mapped_from_lines )' );
- assert( 'sizeof( $to_lines ) == sizeof( $mapped_to_lines )' );
+ assert( 'count( $from_lines ) == count( $mapped_from_lines )' );
+ assert( 'count( $to_lines ) == count( $mapped_to_lines )' );
parent::__construct( $mapped_from_lines, $mapped_to_lines );
$xi = $yi = 0;
- for ( $i = 0; $i < sizeof( $this->edits ); $i++ ) {
+ for ( $i = 0; $i < count( $this->edits ); $i++ ) {
$orig = &$this->edits[$i]->orig;
if ( is_array( $orig ) ) {
- $orig = array_slice( $from_lines, $xi, sizeof( $orig ) );
- $xi += sizeof( $orig );
+ $orig = array_slice( $from_lines, $xi, count( $orig ) );
+ $xi += count( $orig );
}
$closing = &$this->edits[$i]->closing;
if ( is_array( $closing ) ) {
- $closing = array_slice( $to_lines, $yi, sizeof( $closing ) );
- $yi += sizeof( $closing );
+ $closing = array_slice( $to_lines, $yi, count( $closing ) );
+ $yi += count( $closing );
}
}
wfProfileOut( __METHOD__ );
@@ -885,7 +900,7 @@ class DiffFormatter {
foreach ( $diff->edits as $edit ) {
if ( $edit->type == 'copy' ) {
if ( is_array( $block ) ) {
- if ( sizeof( $edit->orig ) <= $nlead + $ntrail ) {
+ if ( count( $edit->orig ) <= $nlead + $ntrail ) {
$block[] = $edit;
} else {
if ( $ntrail ) {
@@ -901,9 +916,9 @@ class DiffFormatter {
$context = $edit->orig;
} else {
if ( !is_array( $block ) ) {
- $context = array_slice( $context, sizeof( $context ) - $nlead );
- $x0 = $xi - sizeof( $context );
- $y0 = $yi - sizeof( $context );
+ $context = array_slice( $context, count( $context ) - $nlead );
+ $x0 = $xi - count( $context );
+ $y0 = $yi - count( $context );
$block = array();
if ( $context ) {
$block[] = new _DiffOp_Copy( $context );
@@ -913,10 +928,10 @@ class DiffFormatter {
}
if ( $edit->orig ) {
- $xi += sizeof( $edit->orig );
+ $xi += count( $edit->orig );
}
if ( $edit->closing ) {
- $yi += sizeof( $edit->closing );
+ $yi += count( $edit->closing );
}
}
@@ -1096,7 +1111,7 @@ class ArrayDiffFormatter extends DiffFormatter {
$newline = 1;
$retval = array();
foreach ( $diff->edits as $edit ) {
- switch( $edit->type ) {
+ switch ( $edit->type ) {
case 'add':
foreach ( $edit->closing as $l ) {
$retval[] = array(
@@ -1191,7 +1206,7 @@ class _HWLDF_WordAccumulator {
* @param $words
* @param $tag string
*/
- function addWords ( $words, $tag = '' ) {
+ function addWords( $words, $tag = '' ) {
if ( $tag != $this->_tag ) {
$this->_flushGroup( $tag );
}
@@ -1231,7 +1246,7 @@ class WordLevelDiff extends MappedDiff {
* @param $orig_lines
* @param $closing_lines
*/
- function __construct ( $orig_lines, $closing_lines ) {
+ function __construct( $orig_lines, $closing_lines ) {
wfProfileIn( __METHOD__ );
list( $orig_words, $orig_stripped ) = $this->_split( $orig_lines );
@@ -1269,8 +1284,12 @@ class WordLevelDiff extends MappedDiff {
if ( preg_match_all( '/ ( [^\S\n]+ | [0-9_A-Za-z\x80-\xff]+ | . ) (?: (?!< \n) [^\S\n])? /xs',
$line, $m ) )
{
- $words = array_merge( $words, $m[0] );
- $stripped = array_merge( $stripped, $m[1] );
+ foreach ( $m[0] as $word ) {
+ $words[] = $word;
+ }
+ foreach ( $m[1] as $stripped_word ) {
+ $stripped[] = $stripped_word;
+ }
}
}
}
@@ -1350,7 +1369,7 @@ class TableDiffFormatter extends DiffFormatter {
*/
function _block_header( $xbeg, $xlen, $ybeg, $ylen ) {
$r = '<tr><td colspan="2" class="diff-lineno"><!--LINE ' . $xbeg . "--></td>\n" .
- '<td colspan="2" class="diff-lineno"><!--LINE ' . $ybeg . "--></td></tr>\n";
+ '<td colspan="2" class="diff-lineno"><!--LINE ' . $ybeg . "--></td></tr>\n";
return $r;
}
diff --git a/includes/diff/DifferenceEngine.php b/includes/diff/DifferenceEngine.php
index c7156fb2..e436f58d 100644
--- a/includes/diff/DifferenceEngine.php
+++ b/includes/diff/DifferenceEngine.php
@@ -38,14 +38,17 @@ class DifferenceEngine extends ContextSource {
* @private
*/
var $mOldid, $mNewid;
- var $mOldtext, $mNewtext;
+ var $mOldTags, $mNewTags;
+ /**
+ * @var Content
+ */
+ var $mOldContent, $mNewContent;
protected $mDiffLang;
/**
* @var Title
*/
var $mOldPage, $mNewPage;
- var $mRcidMarkPatrolled;
/**
* @var Revision
@@ -78,7 +81,7 @@ class DifferenceEngine extends ContextSource {
* @param $context IContextSource context to use, anything else will be ignored
* @param $old Integer old ID we want to show and diff with.
* @param $new String either 'prev' or 'next'.
- * @param $rcid Integer ??? FIXME (default 0)
+ * @param $rcid Integer Deprecated, no longer used!
* @param $refreshCache boolean If set, refreshes the diff cache
* @param $unhide boolean If set, allow viewing deleted revs
*/
@@ -93,7 +96,6 @@ class DifferenceEngine extends ContextSource {
$this->mOldid = $old;
$this->mNewid = $new;
- $this->mRcidMarkPatrolled = intval( $rcid ); # force it to be an integer
$this->mRefreshCache = $refreshCache;
$this->unhide = $unhide;
}
@@ -149,7 +151,7 @@ class DifferenceEngine extends ContextSource {
function deletedLink( $id ) {
if ( $this->getUser()->isAllowed( 'deletedhistory' ) ) {
$dbr = wfGetDB( DB_SLAVE );
- $row = $dbr->selectRow('archive', '*',
+ $row = $dbr->selectRow( 'archive', '*',
array( 'ar_rev_id' => $id ),
__METHOD__ );
if ( $row ) {
@@ -183,10 +185,14 @@ class DifferenceEngine extends ContextSource {
$out = $this->getOutput();
$missing = array();
- if ( $this->mOldRev === null ) {
+ if ( $this->mOldRev === null ||
+ ( $this->mOldRev && $this->mOldContent === null )
+ ) {
$missing[] = $this->deletedIdMarker( $this->mOldid );
}
- if ( $this->mNewRev === null ) {
+ if ( $this->mNewRev === null ||
+ ( $this->mNewRev && $this->mNewContent === null )
+ ) {
$missing[] = $this->deletedIdMarker( $this->mNewid );
}
@@ -220,29 +226,6 @@ class DifferenceEngine extends ContextSource {
throw new PermissionsError( 'read', $permErrors );
}
- # If external diffs are enabled both globally and for the user,
- # we'll use the application/x-external-editor interface to call
- # an external diff tool like kompare, kdiff3, etc.
- if ( ExternalEdit::useExternalEngine( $this->getContext(), 'diff' ) ) {
- $urls = array(
- 'File' => array( 'Extension' => 'wiki', 'URL' =>
- # This should be mOldPage, but it may not be set, see below.
- $this->mNewPage->getCanonicalURL( array(
- 'action' => 'raw', 'oldid' => $this->mOldid ) )
- ),
- 'File2' => array( 'Extension' => 'wiki', 'URL' =>
- $this->mNewPage->getCanonicalURL( array(
- 'action' => 'raw', 'oldid' => $this->mNewid ) )
- ),
- );
-
- $externalEditor = new ExternalEdit( $this->getContext(), $urls );
- $externalEditor->execute();
-
- wfProfileOut( __METHOD__ );
- return;
- }
-
$rollback = '';
$undoLink = '';
@@ -260,6 +243,8 @@ class DifferenceEngine extends ContextSource {
$deleted = $suppressed = false;
$allowed = $this->mNewRev->userCan( Revision::DELETED_TEXT, $user );
+ $revisionTools = array();
+
# mOldRev is false if the difference engine is called with a "vague" query for
# a diff between a version V and its previous version V' AND the version V
# is the first version of that article. In that case, V' does not exist.
@@ -270,11 +255,6 @@ class DifferenceEngine extends ContextSource {
} else {
wfRunHooks( 'DiffViewHeader', array( $this, $this->mOldRev, $this->mNewRev ) );
- $sk = $this->getSkin();
- if ( method_exists( $sk, 'suppressQuickbar' ) ) {
- $sk->suppressQuickbar();
- }
-
if ( $this->mNewPage->equals( $this->mOldPage ) ) {
$out->setPageTitle( $this->msg( 'difference-title', $this->mNewPage->getPrefixedText() ) );
$samePage = true;
@@ -287,20 +267,23 @@ class DifferenceEngine extends ContextSource {
if ( $samePage && $this->mNewPage->quickUserCan( 'edit', $user ) ) {
if ( $this->mNewRev->isCurrent() && $this->mNewPage->userCan( 'rollback', $user ) ) {
- $out->preventClickjacking();
- $rollback = '&#160;&#160;&#160;' . Linker::generateRollback( $this->mNewRev, $this->getContext() );
+ $rollbackLink = Linker::generateRollback( $this->mNewRev, $this->getContext() );
+ if ( $rollbackLink ) {
+ $out->preventClickjacking();
+ $rollback = '&#160;&#160;&#160;' . $rollbackLink;
+ }
}
if ( !$this->mOldRev->isDeleted( Revision::DELETED_TEXT ) && !$this->mNewRev->isDeleted( Revision::DELETED_TEXT ) ) {
- $undoLink = ' ' . $this->msg( 'parentheses' )->rawParams(
- Html::element( 'a', array(
- 'href' => $this->mNewPage->getLocalUrl( array(
+ $undoLink = Html::element( 'a', array(
+ 'href' => $this->mNewPage->getLocalURL( array(
'action' => 'edit',
'undoafter' => $this->mOldid,
'undo' => $this->mNewid ) ),
'title' => Linker::titleAttrib( 'undo' )
),
$this->msg( 'editundo' )->text()
- ) )->escaped();
+ );
+ $revisionTools[] = $undoLink;
}
}
@@ -324,12 +307,14 @@ class DifferenceEngine extends ContextSource {
$ldel = $this->revisionDeleteLink( $this->mOldRev );
$oldRevisionHeader = $this->getRevisionHeader( $this->mOldRev, 'complete' );
+ $oldChangeTags = ChangeTags::formatSummaryRow( $this->mOldTags, 'diff' );
$oldHeader = '<div id="mw-diff-otitle1"><strong>' . $oldRevisionHeader . '</strong></div>' .
'<div id="mw-diff-otitle2">' .
Linker::revUserTools( $this->mOldRev, !$this->unhide ) . '</div>' .
'<div id="mw-diff-otitle3">' . $oldminor .
Linker::revComment( $this->mOldRev, !$diffOnly, !$this->unhide ) . $ldel . '</div>' .
+ '<div id="mw-diff-otitle5">' . $oldChangeTags[0] . '</div>' .
'<div id="mw-diff-otitle4">' . $prevlink . '</div>';
if ( $this->mOldRev->isDeleted( Revision::DELETED_TEXT ) ) {
@@ -366,19 +351,30 @@ class DifferenceEngine extends ContextSource {
# Handle RevisionDelete links...
$rdel = $this->revisionDeleteLink( $this->mNewRev );
- $newRevisionHeader = $this->getRevisionHeader( $this->mNewRev, 'complete' ) . $undoLink;
+
+ # Allow extensions to define their own revision tools
+ wfRunHooks( 'DiffRevisionTools', array( $this->mNewRev, &$revisionTools ) );
+ $formattedRevisionTools = array();
+ // Put each one in parentheses (poor man's button)
+ foreach ( $revisionTools as $tool ) {
+ $formattedRevisionTools[] = $this->msg( 'parentheses' )->rawParams( $tool )->escaped();
+ }
+ $newRevisionHeader = $this->getRevisionHeader( $this->mNewRev, 'complete' ) . ' ' . implode( ' ', $formattedRevisionTools );
+ $newChangeTags = ChangeTags::formatSummaryRow( $this->mNewTags, 'diff' );
$newHeader = '<div id="mw-diff-ntitle1"><strong>' . $newRevisionHeader . '</strong></div>' .
'<div id="mw-diff-ntitle2">' . Linker::revUserTools( $this->mNewRev, !$this->unhide ) .
" $rollback</div>" .
'<div id="mw-diff-ntitle3">' . $newminor .
Linker::revComment( $this->mNewRev, !$diffOnly, !$this->unhide ) . $rdel . '</div>' .
+ '<div id="mw-diff-ntitle5">' . $newChangeTags[0] . '</div>' .
'<div id="mw-diff-ntitle4">' . $nextlink . $this->markPatrolledLink() . '</div>';
if ( $this->mNewRev->isDeleted( Revision::DELETED_TEXT ) ) {
$deleted = true; // new revisions text is hidden
- if ( $this->mNewRev->isDeleted( Revision::DELETED_RESTRICTED ) )
+ if ( $this->mNewRev->isDeleted( Revision::DELETED_RESTRICTED ) ) {
$suppressed = true; // also suppressed
+ }
}
# If the diff cannot be shown due to a deleted revision, then output
@@ -394,7 +390,7 @@ class DifferenceEngine extends ContextSource {
array( $msg ) );
} else {
# Give explanation and add a link to view the diff...
- $link = $this->getTitle()->getFullUrl( $this->getRequest()->appendQueryValue( 'unhide', '1', true ) );
+ $link = $this->getTitle()->getFullURL( $this->getRequest()->appendQueryValue( 'unhide', '1', true ) );
$msg = $suppressed ? 'rev-suppressed-unhide-diff' : 'rev-deleted-unhide-diff';
$out->wrapWikiMsg( "<div id='mw-$msg' class='mw-warning plainlinks'>\n$1\n</div>\n", array( $msg, $link ) );
}
@@ -417,49 +413,54 @@ class DifferenceEngine extends ContextSource {
/**
* Get a link to mark the change as patrolled, or '' if there's either no
* revision to patrol or the user is not allowed to to it.
- * Side effect: this method will call OutputPage::preventClickjacking()
- * when a link is builded.
+ * Side effect: When the patrol link is build, this method will call
+ * OutputPage::preventClickjacking() and load mediawiki.page.patrol.ajax.
*
* @return String
*/
protected function markPatrolledLink() {
- global $wgUseRCPatrol;
+ global $wgUseRCPatrol, $wgEnableAPI, $wgEnableWriteAPI;
+ $user = $this->getUser();
if ( $this->mMarkPatrolledLink === null ) {
// Prepare a change patrol link, if applicable
- if ( $wgUseRCPatrol && $this->mNewPage->quickUserCan( 'patrol', $this->getUser() ) ) {
- // If we've been given an explicit change identifier, use it; saves time
- if ( $this->mRcidMarkPatrolled ) {
- $rcid = $this->mRcidMarkPatrolled;
- $rc = RecentChange::newFromId( $rcid );
- // Already patrolled?
- $rcid = is_object( $rc ) && !$rc->getAttribute( 'rc_patrolled' ) ? $rcid : 0;
+ if (
+ // Is patrolling enabled and the user allowed to?
+ $wgUseRCPatrol && $this->mNewPage->quickUserCan( 'patrol', $user ) &&
+ // Only do this if the revision isn't more than 6 hours older
+ // than the Max RC age (6h because the RC might not be cleaned out regularly)
+ RecentChange::isInRCLifespan( $this->mNewRev->getTimestamp(), 21600 )
+ ) {
+ // Look for an unpatrolled change corresponding to this diff
+
+ $db = wfGetDB( DB_SLAVE );
+ $change = RecentChange::newFromConds(
+ array(
+ 'rc_timestamp' => $db->timestamp( $this->mNewRev->getTimestamp() ),
+ 'rc_this_oldid' => $this->mNewid,
+ 'rc_patrolled' => 0
+ ),
+ __METHOD__,
+ array( 'USE INDEX' => 'rc_timestamp' )
+ );
+
+ if ( $change && $change->getPerformer()->getName() !== $user->getName() ) {
+ $rcid = $change->getAttribute( 'rc_id' );
} else {
- // Look for an unpatrolled change corresponding to this diff
- $db = wfGetDB( DB_SLAVE );
- $change = RecentChange::newFromConds(
- array(
- // Redundant user,timestamp condition so we can use the existing index
- 'rc_user_text' => $this->mNewRev->getRawUserText(),
- 'rc_timestamp' => $db->timestamp( $this->mNewRev->getTimestamp() ),
- 'rc_this_oldid' => $this->mNewid,
- 'rc_last_oldid' => $this->mOldid,
- 'rc_patrolled' => 0
- ),
- __METHOD__
- );
- if ( $change instanceof RecentChange ) {
- $rcid = $change->mAttribs['rc_id'];
- $this->mRcidMarkPatrolled = $rcid;
- } else {
- // None found
- $rcid = 0;
- }
+ // None found or the page has been created by the current user.
+ // If the user could patrol this it already would be patrolled
+ $rcid = 0;
}
// Build the link
if ( $rcid ) {
$this->getOutput()->preventClickjacking();
- $token = $this->getUser()->getEditToken( $rcid );
+ if ( $wgEnableAPI && $wgEnableWriteAPI
+ && $user->isAllowed( 'writeapi' )
+ ) {
+ $this->getOutput()->addModules( 'mediawiki.page.patrol.ajax' );
+ }
+
+ $token = $user->getEditToken( $rcid );
$this->mMarkPatrolledLink = ' <span class="patrollink">[' . Linker::linkKnown(
$this->mNewPage,
$this->msg( 'markaspatrolleddiff' )->escaped(),
@@ -510,19 +511,23 @@ class DifferenceEngine extends ContextSource {
$out->setRevisionTimestamp( $this->mNewRev->getTimestamp() );
$out->setArticleFlag( true );
+ // NOTE: only needed for B/C: custom rendering of JS/CSS via hook
if ( $this->mNewPage->isCssJsSubpage() || $this->mNewPage->isCssOrJsPage() ) {
// Stolen from Article::view --AG 2007-10-11
// Give hooks a chance to customise the output
- // @TODO: standardize this crap into one function
- if ( wfRunHooks( 'ShowRawCssJs', array( $this->mNewtext, $this->mNewPage, $out ) ) ) {
- // Wrap the whole lot in a <pre> and don't parse
- $m = array();
- preg_match( '!\.(css|js)$!u', $this->mNewPage->getText(), $m );
- $out->addHTML( "<pre class=\"mw-code mw-{$m[1]}\" dir=\"ltr\">\n" );
- $out->addHTML( htmlspecialchars( $this->mNewtext ) );
- $out->addHTML( "\n</pre>\n" );
+ // @todo standardize this crap into one function
+ if ( ContentHandler::runLegacyHooks( 'ShowRawCssJs', array( $this->mNewContent, $this->mNewPage, $out ) ) ) {
+ // NOTE: deprecated hook, B/C only
+ // use the content object's own rendering
+ $cnt = $this->mNewRev->getContent();
+ $po = $cnt ? $cnt->getParserOutput( $this->mNewRev->getTitle(), $this->mNewRev->getId() ) : null;
+ $txt = $po ? $po->getText() : '';
+ $out->addHTML( $txt );
}
- } elseif ( !wfRunHooks( 'ArticleViewCustom', array( $this->mNewtext, $this->mNewPage, $out ) ) ) {
+ } elseif ( !wfRunHooks( 'ArticleContentViewCustom', array( $this->mNewContent, $this->mNewPage, $out ) ) ) {
+ // Handled by extension
+ } elseif ( !ContentHandler::runLegacyHooks( 'ArticleViewCustom', array( $this->mNewContent, $this->mNewPage, $out ) ) ) {
+ // NOTE: deprecated hook, B/C only
// Handled by extension
} else {
// Normal page
@@ -536,16 +541,21 @@ class DifferenceEngine extends ContextSource {
$wikiPage = WikiPage::factory( $this->mNewPage );
}
- $parserOptions = $wikiPage->makeParserOptions( $this->getContext() );
+ $parserOutput = $this->getParserOutput( $wikiPage, $this->mNewRev );
- if ( !$this->mNewRev->isCurrent() ) {
- $parserOptions->setEditSection( false );
- }
+ # Also try to load it as a redirect
+ $rt = $this->mNewContent ? $this->mNewContent->getRedirectTarget() : null;
- $parserOutput = $wikiPage->getParserOutput( $parserOptions, $this->mNewid );
+ if ( $rt ) {
+ $article = Article::newFromTitle( $this->mNewPage, $this->getContext() );
+ $out->addHTML( $article->viewRedirect( $rt ) );
- # WikiPage::getParserOutput() should not return false, but just in case
- if( $parserOutput ) {
+ # WikiPage::getParserOutput() should not return false, but just in case
+ if ( $parserOutput ) {
+ # Show categories etc.
+ $out->addParserOutputNoText( $parserOutput );
+ }
+ } elseif ( $parserOutput ) {
$out->addParserOutput( $parserOutput );
}
}
@@ -556,6 +566,17 @@ class DifferenceEngine extends ContextSource {
wfProfileOut( __METHOD__ );
}
+ protected function getParserOutput( WikiPage $page, Revision $rev ) {
+ $parserOptions = $page->makeParserOptions( $this->getContext() );
+
+ if ( !$rev->isCurrent() || !$rev->getTitle()->quickUserCan( "edit" ) ) {
+ $parserOptions->setEditSection( false );
+ }
+
+ $parserOutput = $page->getParserOutput( $parserOptions, $rev->getId() );
+ return $parserOutput;
+ }
+
/**
* Get the diff text, send it to the OutputPage object
* Returns false if the diff could not be generated, otherwise returns true
@@ -584,9 +605,9 @@ class DifferenceEngine extends ContextSource {
/**
* Get complete diff table, including header
*
- * @param $otitle Title: old title
- * @param $ntitle Title: new title
- * @param $notice String: HTML between diff header and body
+ * @param string|bool $otitle Header for old text or false
+ * @param string|bool $ntitle Header for new text or false
+ * @param string $notice HTML between diff header and body
* @return mixed
*/
function getDiff( $otitle, $ntitle, $notice = '' ) {
@@ -595,6 +616,10 @@ class DifferenceEngine extends ContextSource {
return false;
} else {
$multi = $this->getMultiNotice();
+ // Display a message when the diff is empty
+ if ( $body === '' ) {
+ $notice .= '<div class="mw-diff-empty">' . $this->msg( 'diff-empty' )->parse() . "</div>\n";
+ }
return $this->addHeader( $body, $otitle, $ntitle, $multi, $notice );
}
}
@@ -620,7 +645,6 @@ class DifferenceEngine extends ContextSource {
return false;
}
// Short-circuit
- // If mOldRev is false, it means that the
if ( $this->mOldRev === false || ( $this->mOldRev && $this->mNewRev
&& $this->mOldRev->getID() == $this->mNewRev->getID() ) )
{
@@ -652,7 +676,7 @@ class DifferenceEngine extends ContextSource {
return false;
}
- $difftext = $this->generateDiffBody( $this->mOldtext, $this->mNewtext );
+ $difftext = $this->generateContentDiffBody( $this->mOldContent, $this->mNewContent );
// Save to cache for 7 days
if ( !wfRunHooks( 'AbortDiffCache', array( &$this ) ) ) {
@@ -672,31 +696,64 @@ class DifferenceEngine extends ContextSource {
}
/**
- * Make sure the proper modules are loaded before we try to
- * make the diff
+ * Generate a diff, no caching.
+ *
+ * This implementation uses generateTextDiffBody() to generate a diff based on the default
+ * serialization of the given Content objects. This will fail if $old or $new are not
+ * instances of TextContent.
+ *
+ * Subclasses may override this to provide a different rendering for the diff,
+ * perhaps taking advantage of the content's native form. This is required for all content
+ * models that are not text based.
+ *
+ * @param $old Content: old content
+ * @param $new Content: new content
+ *
+ * @return bool|string
+ * @since 1.21
+ * @throws MWException if $old or $new are not instances of TextContent.
*/
- private function initDiffEngines() {
- global $wgExternalDiffEngine;
- if ( $wgExternalDiffEngine == 'wikidiff' && !function_exists( 'wikidiff_do_diff' ) ) {
- wfProfileIn( __METHOD__ . '-php_wikidiff.so' );
- wfDl( 'php_wikidiff' );
- wfProfileOut( __METHOD__ . '-php_wikidiff.so' );
+ function generateContentDiffBody( Content $old, Content $new ) {
+ if ( !( $old instanceof TextContent ) ) {
+ throw new MWException( "Diff not implemented for " . get_class( $old ) . "; "
+ . "override generateContentDiffBody to fix this." );
}
- elseif ( $wgExternalDiffEngine == 'wikidiff2' && !function_exists( 'wikidiff2_do_diff' ) ) {
- wfProfileIn( __METHOD__ . '-php_wikidiff2.so' );
- wfDl( 'wikidiff2' );
- wfProfileOut( __METHOD__ . '-php_wikidiff2.so' );
+
+ if ( !( $new instanceof TextContent ) ) {
+ throw new MWException( "Diff not implemented for " . get_class( $new ) . "; "
+ . "override generateContentDiffBody to fix this." );
}
+
+ $otext = $old->serialize();
+ $ntext = $new->serialize();
+
+ return $this->generateTextDiffBody( $otext, $ntext );
}
/**
* Generate a diff, no caching
*
- * @param $otext String: old text, must be already segmented
- * @param $ntext String: new text, must be already segmented
+ * @param string $otext old text, must be already segmented
+ * @param string $ntext new text, must be already segmented
* @return bool|string
+ * @deprecated since 1.21, use generateContentDiffBody() instead!
*/
function generateDiffBody( $otext, $ntext ) {
+ ContentHandler::deprecated( __METHOD__, "1.21" );
+
+ return $this->generateTextDiffBody( $otext, $ntext );
+ }
+
+ /**
+ * Generate a diff, no caching
+ *
+ * @todo move this to TextDifferenceEngine, make DifferenceEngine abstract. At some point.
+ *
+ * @param string $otext old text, must be already segmented
+ * @param string $ntext new text, must be already segmented
+ * @return bool|string
+ */
+ function generateTextDiffBody( $otext, $ntext ) {
global $wgExternalDiffEngine, $wgContLang;
wfProfileIn( __METHOD__ );
@@ -704,8 +761,6 @@ class DifferenceEngine extends ContextSource {
$otext = str_replace( "\r\n", "\n", $otext );
$ntext = str_replace( "\r\n", "\n", $ntext );
- $this->initDiffEngines();
-
if ( $wgExternalDiffEngine == 'wikidiff' && function_exists( 'wikidiff_do_diff' ) ) {
# For historical reasons, external diff engine expects
# input text to be HTML-escaped already
@@ -800,11 +855,12 @@ class DifferenceEngine extends ContextSource {
}
function localiseLineNumbersCb( $matches ) {
- if ( $matches[1] === '1' && $this->mReducedLineNumbers ) return '';
+ if ( $matches[1] === '1' && $this->mReducedLineNumbers ) {
+ return '';
+ }
return $this->msg( 'lineno' )->numParams( $matches[1] )->escaped();
}
-
/**
* If there are revisions between the ones being compared, return a note saying so.
* @return string
@@ -855,11 +911,11 @@ class DifferenceEngine extends ContextSource {
* Get a header for a specified revision.
*
* @param $rev Revision
- * @param $complete String: 'complete' to get the header wrapped depending
+ * @param string $complete 'complete' to get the header wrapped depending
* the visibility of the revision and a link to edit the page.
* @return String HTML fragment
*/
- private function getRevisionHeader( Revision $rev, $complete = '' ) {
+ protected function getRevisionHeader( Revision $rev, $complete = '' ) {
$lang = $this->getLanguage();
$user = $this->getUser();
$revtimestamp = $rev->getTimestamp();
@@ -932,11 +988,13 @@ class DifferenceEngine extends ContextSource {
$colspan = 1;
$multiColspan = 2;
}
- $header .= "
- <tr style='vertical-align: top;'>
- <td colspan='$colspan' class='diff-otitle'>{$otitle}</td>
- <td colspan='$colspan' class='diff-ntitle'>{$ntitle}</td>
- </tr>";
+ if ( $otitle || $ntitle ) {
+ $header .= "
+ <tr style='vertical-align: top;'>
+ <td colspan='$colspan' class='diff-otitle'>{$otitle}</td>
+ <td colspan='$colspan' class='diff-ntitle'>{$ntitle}</td>
+ </tr>";
+ }
}
if ( $multi != '' ) {
@@ -951,10 +1009,25 @@ class DifferenceEngine extends ContextSource {
/**
* Use specified text instead of loading from the database
+ * @deprecated since 1.21, use setContent() instead.
*/
function setText( $oldText, $newText ) {
- $this->mOldtext = $oldText;
- $this->mNewtext = $newText;
+ ContentHandler::deprecated( __METHOD__, "1.21" );
+
+ $oldContent = ContentHandler::makeContent( $oldText, $this->getTitle() );
+ $newContent = ContentHandler::makeContent( $newText, $this->getTitle() );
+
+ $this->setContent( $oldContent, $newContent );
+ }
+
+ /**
+ * Use specified text instead of loading from the database
+ * @since 1.21
+ */
+ function setContent( Content $oldContent, Content $newContent ) {
+ $this->mOldContent = $oldContent;
+ $this->mNewContent = $newContent;
+
$this->mTextLoaded = 2;
$this->mRevisionsLoaded = true;
}
@@ -1062,6 +1135,25 @@ class DifferenceEngine extends ContextSource {
$this->mOldPage = $this->mOldRev->getTitle();
}
+ // Load tags information for both revisions
+ $dbr = wfGetDB( DB_SLAVE );
+ if ( $this->mOldid !== false ) {
+ $this->mOldTags = $dbr->selectField(
+ 'tag_summary',
+ 'ts_tags',
+ array( 'ts_rev_id' => $this->mOldid ),
+ __METHOD__
+ );
+ } else {
+ $this->mOldTags = false;
+ }
+ $this->mNewTags = $dbr->selectField(
+ 'tag_summary',
+ 'ts_tags',
+ array( 'ts_rev_id' => $this->mNewid ),
+ __METHOD__
+ );
+
return true;
}
@@ -1073,26 +1165,29 @@ class DifferenceEngine extends ContextSource {
function loadText() {
if ( $this->mTextLoaded == 2 ) {
return true;
- } else {
- // Whether it succeeds or fails, we don't want to try again
- $this->mTextLoaded = 2;
}
+ // Whether it succeeds or fails, we don't want to try again
+ $this->mTextLoaded = 2;
+
if ( !$this->loadRevisionData() ) {
return false;
}
+
if ( $this->mOldRev ) {
- $this->mOldtext = $this->mOldRev->getText( Revision::FOR_THIS_USER );
- if ( $this->mOldtext === false ) {
+ $this->mOldContent = $this->mOldRev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
+ if ( $this->mOldContent === null ) {
return false;
}
}
+
if ( $this->mNewRev ) {
- $this->mNewtext = $this->mNewRev->getText( Revision::FOR_THIS_USER );
- if ( $this->mNewtext === false ) {
+ $this->mNewContent = $this->mNewRev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
+ if ( $this->mNewContent === null ) {
return false;
}
}
+
return true;
}
@@ -1104,13 +1199,16 @@ class DifferenceEngine extends ContextSource {
function loadNewText() {
if ( $this->mTextLoaded >= 1 ) {
return true;
- } else {
- $this->mTextLoaded = 1;
}
+
+ $this->mTextLoaded = 1;
+
if ( !$this->loadRevisionData() ) {
return false;
}
- $this->mNewtext = $this->mNewRev->getText( Revision::FOR_THIS_USER );
+
+ $this->mNewContent = $this->mNewRev->getContent( Revision::FOR_THIS_USER, $this->getUser() );
+
return true;
}
}
diff --git a/includes/diff/WikiDiff3.php b/includes/diff/WikiDiff3.php
index 66727445..ea6f6e5d 100644
--- a/includes/diff/WikiDiff3.php
+++ b/includes/diff/WikiDiff3.php
@@ -29,7 +29,7 @@
* (http://citeseer.ist.psu.edu/myers86ond.html) with range compression (see Wu et al.'s
* "An O(NP) Sequence Comparison Algorithm").
*
- * This implementation supports an upper bound on the excution time.
+ * This implementation supports an upper bound on the execution time.
*
* Complexity: O((M + N)D) worst case time, O(M + N + D^2) expected time, O(M + N) space
*
@@ -64,7 +64,7 @@ class WikiDiff3 {
public function diff( /*array*/ $from, /*array*/ $to ) {
// remember initial lengths
- $m = sizeof( $from );
+ $m = count( $from );
$n = count( $to );
$this->heuristicUsed = false;
@@ -490,7 +490,6 @@ class WikiDiff3 {
$temp = array( 0, 0, 0 );
-
$max_progress = array_fill( 0, ceil( max( $forward_end_diag - $forward_start_diag,
$backward_end_diag - $backward_start_diag ) / 2 ), $temp );
$num_progress = 0; // the 1st entry is current, it is initialized