Merge fixes to ?preload= from /branches/conrad/ (cf. bug 5210, r62864, r62035)
authorConrad Irwin <conrad@users.mediawiki.org>
Wed, 3 Mar 2010 02:41:14 +0000 (02:41 +0000)
committerConrad Irwin <conrad@users.mediawiki.org>
Wed, 3 Mar 2010 02:41:14 +0000 (02:41 +0000)
RELEASE-NOTES
includes/Defines.php
includes/EditPage.php
includes/parser/Parser.php
maintenance/parserTests.inc
maintenance/parserTests.txt

index 06e0c01..920e879 100644 (file)
@@ -30,6 +30,7 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN
 * (bug 22606) The body of e-mail address confirmation message is now different
   when the address changed
 * (bug 22664) Special:Userrights now accepts '0' as a valid user name
+* (bug 5210) preload parser now parses <noinclude>, <includeonly> and redirects
 
 == API changes in 1.17 ==
 
index 7be569a..5fa510c 100644 (file)
@@ -209,6 +209,7 @@ define( 'OT_HTML', 1 );
 define( 'OT_WIKI', 2 );
 define( 'OT_PREPROCESS', 3 );
 define( 'OT_MSG' , 3 );  // b/c alias for OT_PREPROCESS
+define( 'OT_PLAIN', 4 );
 
 # Flags for Parser::setFunctionHook
 define( 'SFH_NO_HASH', 1 );
index e92b43b..d25e0f2 100644 (file)
@@ -220,30 +220,39 @@ class EditPage {
        }
 
        /**
-        * Get the contents of a page from its title and remove includeonly tags
+        * Get the contents to be preloaded into the box, either set by
+        * an earlier setPreloadText() or by loading the given page.
         *
-        * @param $preload String: the title of the page.
-        * @return string The contents of the page.
+        * @param $preload String: representing the title to preload from.
+        * @return String
         */
        protected function getPreloadedText( $preload ) {
+               global $wgUser, $wgParser;
                if ( !empty( $this->mPreloadText ) ) {
                        return $this->mPreloadText;
-               } elseif ( $preload === '' ) {
-                       return '';
-               } else {
-                       $preloadTitle = Title::newFromText( $preload );
-                       if ( isset( $preloadTitle ) && $preloadTitle->userCanRead() ) {
-                               $rev = Revision::newFromTitle( $preloadTitle );
-                               if ( is_object( $rev ) ) {
-                                       $text = $rev->getText();
-                                       // TODO FIXME: AAAAAAAAAAA, this shouldn't be implementing
-                                       // its own mini-parser! -ævar
-                                       $text = preg_replace( '~</?includeonly>~', '', $text );
-                                       return $text;
-                               } else
-                                       return '';
+               } elseif ( $preload !== '' ) {
+                       $title = Title::newFromText( $preload );
+                       # Check for existence to avoid getting MediaWiki:Noarticletext
+                       if ( isset( $title ) && $title->exists() && $title->userCanRead() ) {
+                               $article = new Article( $title );
+
+                               if ( $article->isRedirect() ) {
+                                       $title = Title::newFromRedirectRecurse( $article->getContent() );
+                                       # Redirects to missing titles are displayed, to hidden pages are followed
+                                       # Copying observed behaviour from ?action=view
+                                       if ( $title->exists() ) {
+                                               if ($title->userCanRead() ) {
+                                                       $article = new Article( $title );
+                                               } else {
+                                                       return "";
+                                               }
+                                       }
+                               }
+                               $parserOptions = ParserOptions::newFromUser( $wgUser );
+                               return $wgParser->getPreloadText( $article->getContent(), $title, $parserOptions );
                        }
                }
+               return '';
        }
 
        /*
index 06d4ac5..e2173fd 100644 (file)
@@ -26,6 +26,8 @@
  *   Cleans a signature before saving it to preferences
  * extractSections()
  *   Extracts sections from an article for section editing
+ * getPreloadText()
+ *   Removes <noinclude> sections, and <includeonly> tags.
  *
  * Globals used:
  *    objects:   $wgLang, $wgContLang
@@ -78,10 +80,11 @@ class Parser
 
        // Allowed values for $this->mOutputType
        // Parameter to startExternalParse().
-       const OT_HTML = 1;
-       const OT_WIKI = 2;
-       const OT_PREPROCESS = 3;
+       const OT_HTML = 1; // like parse()
+       const OT_WIKI = 2; // like preSaveTransform()
+       const OT_PREPROCESS = 3; // like preprocess()
        const OT_MSG = 3;
+       const OT_PLAIN = 4; // like extractSections() - portions of the original are returned unchanged.
 
        // Marker Suffix needs to be accessible staticly.
        const MARKER_SUFFIX = "-QINU\x7f";
@@ -249,6 +252,7 @@ class Parser
                        'html' => $ot == self::OT_HTML,
                        'wiki' => $ot == self::OT_WIKI,
                        'pre' => $ot == self::OT_PREPROCESS,
+                       'plain' => $ot == self::OT_PLAIN,
                );
        }
 
@@ -488,6 +492,24 @@ class Parser
                return $text;
        }
 
+       /**
+        * Process the wikitext for the ?preload= feature. (bug 5210)
+        *
+        * <noinclude>, <includeonly> etc. are parsed as for template transclusion, 
+        * comments, templates, arguments, tags hooks and parser functions are untouched.
+        */
+       public function getPreloadText( $text, $title, $options ) {
+               // Parser (re)initialisation
+               $this->clearState();
+               $this->setOutputType( self::OT_PLAIN );
+               $this->mOptions = $options;
+               $this->setTitle( $title ); 
+
+               $flags = PPFrame::NO_ARGS | PPFrame::NO_TEMPLATES;
+               $dom = $this->preprocessToDom( $text, self::PTD_FOR_INCLUSION );
+               return $this->getPreprocessor()->newFrame()->expand( $dom, $flags );
+       }
+
        /**
         * Get a random string
         *
@@ -4741,7 +4763,7 @@ class Parser
                $this->clearState();
                $this->setTitle( $wgTitle ); // not generally used but removes an ugly failure mode
                $this->mOptions = new ParserOptions;
-               $this->setOutputType( self::OT_WIKI );
+               $this->setOutputType( self::OT_PLAIN );
                $outText = '';
                $frame = $this->getPreprocessor()->newFrame();
 
index 6526da9..186bf95 100644 (file)
@@ -366,6 +366,8 @@ class ParserTest {
                } elseif( isset( $opts['comment'] ) ) {
                        $linker = $user->getSkin();
                        $out = $linker->formatComment( $input, $title, $local );
+               } elseif( isset( $opts['preload'] ) ) {
+                       $out = $parser->getpreloadText( $input, $title, $options );
                } else {
                        $output = $parser->parse( $input, $title, $options, true, true, 1337 );
                        $out = $output->getText();
@@ -1716,4 +1718,4 @@ class TestFileIterator implements Iterator {
                }
                return false;
        }
-}
\ No newline at end of file
+}
index 860b589..14ce80e 100644 (file)
@@ -7731,7 +7731,46 @@ Screen
 <p>this is not the the title
 </p>
 !! end
+!! test
+preload: check <noinclude> and <includeonly>
+!! options
+preload
+!! input
+Hello <noinclude>cruel</noinclude><includeonly>kind</includeonly> world.
+!! result
+Hello kind world.
+!! end
+!! test
+preload: check <onlyinclude>
+!! options
+preload
+!! input
+Goodbye <onlyinclude>Hello world</onlyinclude>
+!! result
+Hello world
+!! end
 
+!! test
+preload: can pass tags through if we want to
+!! options
+preload
+!! input
+<includeonly><</includeonly>includeonly>Hello world<includeonly><</includeonly>/includeonly>
+!! result
+<includeonly>Hello world</includeonly>
+!! end
+
+!! test
+preload: check that it doesn't try to do tricks
+!! options
+preload
+!! input
+* <!-- Hello --> ''{{world}}'' {{<includeonly>subst:</includeonly>How are you}}{{ {{{|safesubst:}}} #if:1|2|3}}
+!! result
+* <!-- Hello --> ''{{world}}'' {{subst:How are you}}{{ {{{|safesubst:}}} #if:1|2|3}}
+!! end
 
 TODO:
 more images