Moved textbox1 building into TextConflictHelper on edit conflicts
authorWMDE-Fisch <christoph.jauera@wikimedia.de>
Wed, 6 Dec 2017 14:25:39 +0000 (15:25 +0100)
committerWMDE-Fisch <christoph.jauera@wikimedia.de>
Thu, 4 Jan 2018 18:21:13 +0000 (18:21 +0000)
Factored out some minor parts about building editor CSS classes.

getEditConflictMainTextBox() mainly mirrors showTextbox1 parts not
included were moved to the EditPage.

Change-Id: I671e095acc08382dd0a1c3d167fdaaa623ec5499

includes/EditPage.php
includes/editpage/TextConflictHelper.php
includes/editpage/TextboxBuilder.php
tests/phpunit/includes/editpage/TextboxBuilderTest.php

index bcaab3a..3c109f6 100644 (file)
@@ -2861,7 +2861,14 @@ class EditPage {
                        // and fallback to the raw wpTextbox1 since editconflicts can't be
                        // resolved between page source edits and custom ui edits using the
                        // custom edit ui.
-                       $this->showTextbox1();
+                       $conflictTextBoxAttribs = [];
+                       if ( $this->wasDeletedSinceLastEdit() ) {
+                               $conflictTextBoxAttribs['style'] = 'display:none;';
+                       } elseif ( $this->isOldRev ) {
+                               $conflictTextBoxAttribs['class'] = 'mw-textarea-oldrev';
+                       }
+
+                       $out->addHTML( $editConflictHelper->getEditConflictMainTextBox( $conflictTextBoxAttribs ) );
                        $out->addHTML( $editConflictHelper->getEditFormHtmlAfterContent() );
                } else {
                        $this->showContentForm();
@@ -3339,22 +3346,9 @@ class EditPage {
                if ( $this->wasDeletedSinceLastEdit() && $this->formtype == 'save' ) {
                        $attribs = [ 'style' => 'display:none;' ];
                } else {
-                       $classes = []; // Textarea CSS
-                       if ( $this->mTitle->isProtected( 'edit' ) &&
-                               MWNamespace::getRestrictionLevels( $this->mTitle->getNamespace() ) !== [ '' ]
-                       ) {
-                               # Is the title semi-protected?
-                               if ( $this->mTitle->isSemiProtected() ) {
-                                       $classes[] = 'mw-textarea-sprotected';
-                               } else {
-                                       # Then it must be protected based on static groups (regular)
-                                       $classes[] = 'mw-textarea-protected';
-                               }
-                               # Is the title cascade-protected?
-                               if ( $this->mTitle->isCascadeProtected() ) {
-                                       $classes[] = 'mw-textarea-cprotected';
-                               }
-                       }
+                       $builder = new TextboxBuilder();
+                       $classes = $builder->getTextboxProtectionCSSClasses( $this->getTitle() );
+
                        # Is an old revision being edited?
                        if ( $this->isOldRev ) {
                                $classes[] = 'mw-textarea-oldrev';
@@ -3366,12 +3360,7 @@ class EditPage {
                                $attribs += $customAttribs;
                        }
 
-                       if ( count( $classes ) ) {
-                               if ( isset( $attribs['class'] ) ) {
-                                       $classes[] = $attribs['class'];
-                               }
-                               $attribs['class'] = implode( ' ', $classes );
-                       }
+                       $attribs = $builder->mergeClassesIntoAttributes( $classes, $attribs );
                }
 
                $this->showTextbox(
index 6e7e7ee..b447b18 100644 (file)
@@ -162,6 +162,33 @@ class TextConflictHelper {
                );
        }
 
+       /**
+        * HTML to build the textbox1 on edit conflicts
+        *
+        * @param mixed[]|null $customAttribs
+        * @return string HTML
+        */
+       public function getEditConflictMainTextBox( $customAttribs = [] ) {
+               $builder = new TextboxBuilder();
+               $classes = $builder->getTextboxProtectionCSSClasses( $this->title );
+
+               $attribs = [ 'tabindex' => 1 ];
+               $attribs += $customAttribs;
+
+               $attribs = $builder->mergeClassesIntoAttributes( $classes, $attribs );
+
+               $attribs = $builder->buildTextboxAttribs(
+                       'wpTextbox1',
+                       $attribs,
+                       $this->out->getUser(),
+                       $this->title
+               );
+
+               $this->out->addHTML(
+                       Html::textarea( 'wpTextbox1', $builder->addNewLineAtEnd( $this->storedversion ), $attribs )
+               );
+       }
+
        /**
         * Content to go in the edit form before textbox1
         *
index a6ae9bc..d0a2f8f 100644 (file)
@@ -24,6 +24,7 @@
 
 namespace MediaWiki\EditPage;
 
+use MWNamespace;
 use Title;
 use User;
 
@@ -50,6 +51,49 @@ class TextboxBuilder {
                return $wikitext;
        }
 
+       /**
+        * @param string[] $classes
+        * @param mixed[] $attribs
+        * @return mixed[]
+        */
+       public function mergeClassesIntoAttributes( array $classes, array $attribs ) {
+               if ( !count( $classes ) ) {
+                       return $attribs;
+               }
+
+               if ( isset( $attribs['class'] ) ) {
+                       $classes[] = $attribs['class'];
+               }
+               $attribs['class'] = implode( ' ', $classes );
+
+               return $attribs;
+       }
+
+       /**
+        * @param Title $title
+        * @return string[]
+        */
+       public function getTextboxProtectionCSSClasses( Title $title ) {
+               $classes = []; // Textarea CSS
+               if ( $title->isProtected( 'edit' ) &&
+                       MWNamespace::getRestrictionLevels( $title->getNamespace() ) !== [ '' ]
+               ) {
+                       # Is the title semi-protected?
+                       if ( $title->isSemiProtected() ) {
+                               $classes[] = 'mw-textarea-sprotected';
+                       } else {
+                               # Then it must be protected based on static groups (regular)
+                               $classes[] = 'mw-textarea-protected';
+                       }
+                       # Is the title cascade-protected?
+                       if ( $title->isCascadeProtected() ) {
+                               $classes[] = 'mw-textarea-cprotected';
+                       }
+               }
+
+               return $classes;
+       }
+
        /**
         * @param string $name
         * @param mixed[] $customAttribs
index 668badd..b9bf5b9 100644 (file)
@@ -86,4 +86,120 @@ class TextboxBuilderTest extends MediaWikiTestCase {
                // classes ok when nothing to be merged
                $this->assertSame( 'mw-editfont-monospace', $attribs3['class'] );
        }
+
+       public function provideMergeClassesIntoAttributes() {
+               return [
+                       [
+                               [],
+                               [],
+                               [],
+                       ],
+                       [
+                               [ 'mw-new-classname' ],
+                               [],
+                               [ 'class' => 'mw-new-classname' ],
+                       ],
+                       [
+                               [],
+                               [ 'title' => 'My Title' ],
+                               [ 'title' => 'My Title' ],
+                       ],
+                       [
+                               [ 'mw-new-classname' ],
+                               [ 'title' => 'My Title' ],
+                               [ 'title' => 'My Title', 'class' => 'mw-new-classname' ],
+                       ],
+                       [
+                               [ 'mw-new-classname' ],
+                               [ 'class' => 'mw-existing-classname' ],
+                               [ 'class' => 'mw-new-classname mw-existing-classname' ],
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideMergeClassesIntoAttributes
+        */
+       public function testMergeClassesIntoAttributes( $inputClasses, $inputAttributes, $expected ) {
+               $builder = new TextboxBuilder();
+               $this->assertSame(
+                       $expected,
+                       $builder->mergeClassesIntoAttributes( $inputClasses, $inputAttributes )
+               );
+       }
+
+       public function provideGetTextboxProtectionCSSClasses() {
+               return [
+                       [
+                               [ '' ],
+                               [ 'isProtected' ],
+                               [],
+                       ],
+                       [
+                               true,
+                               [],
+                               [],
+                       ],
+                       [
+                               true,
+                               [ 'isProtected' ],
+                               [ 'mw-textarea-protected' ]
+                       ],
+                       [
+                               true,
+                               [ 'isProtected', 'isSemiProtected' ],
+                               [ 'mw-textarea-sprotected' ],
+                       ],
+                       [
+                               true,
+                               [ 'isProtected', 'isCascadeProtected' ],
+                               [ 'mw-textarea-protected', 'mw-textarea-cprotected' ],
+                       ],
+                       [
+                               true,
+                               [ 'isProtected', 'isCascadeProtected', 'isSemiProtected' ],
+                               [ 'mw-textarea-sprotected', 'mw-textarea-cprotected' ],
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider provideGetTextboxProtectionCSSClasses
+        */
+       public function testGetTextboxProtectionCSSClasses(
+               $restrictionLevels,
+               $protectionModes,
+               $expected
+       ) {
+               $this->setMwGlobals( [
+                       // set to trick MWNamespace::getRestrictionLevels
+                       'wgRestrictionLevels' => $restrictionLevels
+               ] );
+
+               $builder = new TextboxBuilder();
+               $this->assertSame( $expected, $builder->getTextboxProtectionCSSClasses(
+                       $this->mockProtectedTitle( $protectionModes )
+               ) );
+       }
+
+       /**
+        * @return Title
+        */
+       private function mockProtectedTitle( $methodsToReturnTrue ) {
+               $title = $this->getMockBuilder( Title::class )
+                       ->disableOriginalConstructor()
+                       ->getMock();
+
+               $title->expects( $this->any() )
+                       ->method( 'getNamespace' )
+                       ->will( $this->returnValue( 1 ) );
+
+               foreach ( $methodsToReturnTrue as $method ) {
+                       $title->expects( $this->any() )
+                               ->method( $method )
+                               ->will( $this->returnValue( true ) );
+               }
+
+               return $title;
+       }
 }