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
// 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();
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';
$attribs += $customAttribs;
}
- if ( count( $classes ) ) {
- if ( isset( $attribs['class'] ) ) {
- $classes[] = $attribs['class'];
- }
- $attribs['class'] = implode( ' ', $classes );
- }
+ $attribs = $builder->mergeClassesIntoAttributes( $classes, $attribs );
}
$this->showTextbox(
);
}
+ /**
+ * 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
*
namespace MediaWiki\EditPage;
+use MWNamespace;
use Title;
use User;
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
// 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;
+ }
}