Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ApplicationFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public function getNewAttributeManager( array $validAttributes, array $aliases )
* @param string $id
* @param string $trigger must be safe raw html (best run through {@see Parser::recursiveTagParse})
* @param string $content must be safe raw html (best run through {@see Parser::recursiveTagParse})
* @param ParserOutputHelper $parserOutputHelper
* @param ParserOutputHelper $parserOutputHelper @deprecated unused since the inline-emission modal fix; will be removed in the next major release.
*
* @see ModalBuilder::__construct
*
Expand Down
2 changes: 0 additions & 2 deletions src/BootstrapComponents.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@
*/
class BootstrapComponents {

const EXTENSION_DATA_DEFERRED_CONTENT_KEY = 'bsc_deferredContent';

const EXTENSION_DATA_NO_IMAGE_MODAL = 'bsc_no_image_modal';


Expand Down
45 changes: 5 additions & 40 deletions src/Hooks/OutputPageParserOutput.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

namespace MediaWiki\Extension\BootstrapComponents\Hooks;

use MediaWiki\Extension\BootstrapComponents\BootstrapComponents;
use MediaWiki\Extension\BootstrapComponents\BootstrapComponentsService;
/*
* TODO switch to these, wehen we drop support for mw < 1.40
Expand All @@ -41,25 +40,12 @@
*
* Called after parse, before the HTML is added to the output.
*
* Method delegated to separate class to fix missing (deferred) content in
* {@see \MediaWiki\Extension\BootstrapComponents\Tests\Integration\BootstrapComponentsJSONScriptTestCaseRunnerTest::assertParserOutputForCase}
*
* @see https://www.mediawiki.org/wiki/Manual:Hooks/OutputPageParserOutput
*
* @since 1.2
*/
class OutputPageParserOutput {

/**
* @var string
*/
const INJECTION_PREFIX = '<!-- injected by Extension:BootstrapComponents -->';

/**
* @var string
*/
const INJECTION_SUFFIX = '<!-- /injected by Extension:BootstrapComponents -->';

/**
* @var BootstrapComponentsService
*/
Expand All @@ -72,14 +58,16 @@ class OutputPageParserOutput {

/**
* @var ParserOutput $parserOutput
*
* @deprecated unused since the inline-emission modal fix; will be removed in the next major release.
*/
private ParserOutput $parserOutput;

/**
* OutputPageParserOutput constructor.
*
* @param OutputPage $outputPage
* @param ParserOutput $parserOutput
* @param ParserOutput $parserOutput @deprecated unused since the inline-emission modal fix; will be removed in the next major release.
* @param BootstrapComponentsService $service
*/
public function __construct(
Expand All @@ -94,36 +82,11 @@ public function __construct(
* @return void
*/
public function process(): void {
$deferredText = $this->getContentForLaterInjection( $this->getParserOutput() );
if ( !empty( $deferredText ) ) {
$this->getOutputPage()->addHTML( $deferredText );
}

if ( $this->getBootstrapComponentsService()->vectorSkinInUse() ) {
$this->getOutputPage()->addModules( [ 'ext.bootstrapComponents.vector-fix' ] );
}
}

/**
* Returns the raw html that is to be inserted at the end of the page.
*
* @param ParserOutput $parserOutput
*
* @return string
*/
protected function getContentForLaterInjection( ParserOutput $parserOutput ): string {
$deferredContent = $parserOutput
->getExtensionData(BootstrapComponents::EXTENSION_DATA_DEFERRED_CONTENT_KEY );

if ( empty( $deferredContent ) || !is_array( $deferredContent ) ) {
return '';
}

// clearing extension data for unit and integration tests to work
$parserOutput->setExtensionData( BootstrapComponents::EXTENSION_DATA_DEFERRED_CONTENT_KEY, null );
return self::INJECTION_PREFIX . implode( array_values( $deferredContent ) ) . self::INJECTION_SUFFIX;
}

protected function getBootstrapComponentsService(): BootstrapComponentsService {
return $this->bootstrapComponentService;
}
Expand All @@ -136,6 +99,8 @@ protected function getOutputPage(): OutputPage {
}

/**
* @deprecated unused since the inline-emission modal fix; will be removed in the next major release.
*
* @return ParserOutput
*/
protected function getParserOutput(): ParserOutput {
Expand Down
14 changes: 8 additions & 6 deletions src/ModalBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ class ModalBuilder {

/**
* @var ParserOutputHelper $parserOutputHelper
*
* @deprecated unused since the inline-emission modal fix; will be removed in the next major release.
*/
private $parserOutputHelper;

Expand Down Expand Up @@ -146,7 +148,7 @@ public static function wrapTriggerElement( $element, $id ) {
* @param string $id
* @param string $trigger must be safe raw html (best run through {@see Parser::recursiveTagParse})
* @param string $content must be fully parsed html (use {@see Parser::recursiveTagParseFully})
* @param ParserOutputHelper $parserOutputHelper
* @param ParserOutputHelper $parserOutputHelper @deprecated unused since the inline-emission modal fix; will be removed in the next major release.
*
* @see ApplicationFactory::getNewModalBuilder
* @see Components\Modal::generateButton
Expand All @@ -163,14 +165,14 @@ public function __construct( $id, $trigger, $content, $parserOutputHelper ) {
/**
* Parses the modal.
*
* Emits the trigger followed by the modal container inline. The container is
* `position: fixed` and is addressed via `data-target="#id"`, so its DOM
* placement is not significant.
*
* @return string
*/
public function parse() {
$this->parserOutputHelper->injectLater(
$this->getId(),
$this->buildModal()
);
return $this->buildTrigger();
return $this->buildTrigger() . $this->buildModal();
}

/**
Expand Down
24 changes: 0 additions & 24 deletions src/ParserOutputHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,30 +138,6 @@ public function areImageModalsSuppressed() {
->getExtensionData( BootstrapComponents::EXTENSION_DATA_NO_IMAGE_MODAL );
}

/**
* Allows for html fragments for a given container id to be stored, so that it can be added to the page at a later time.
*
* @param string $id
* @param string $rawHtml
*
* @return ParserOutputHelper $this (fluid)
*/
public function injectLater( $id, $rawHtml ) {
if ( empty( $this->getParser()->getOutput() ) ) {
# fix issues with PageForms file upload (issue #20)
return $this;
}
if ( !empty( $rawHtml ) ) {
$deferredContent = $this->getParser()->getOutput()->getExtensionData( BootstrapComponents::EXTENSION_DATA_DEFERRED_CONTENT_KEY );
if ( empty( $deferredContent ) ) {
$deferredContent = [];
}
$deferredContent[$id] = $rawHtml;
$this->getParser()->getOutput()->setExtensionData( BootstrapComponents::EXTENSION_DATA_DEFERRED_CONTENT_KEY, $deferredContent );
}
return $this;
}

/**
* Formats a text as error text, so it can be added to the output.
*
Expand Down
12 changes: 1 addition & 11 deletions tests/phpunit/Unit/Components/ModalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,9 @@ public function testCanConstruct() {
*/
public function testCanRender( $input, $arguments, $expectedTriggerOutput, $expectedModalOutput ) {

$modalInjection = '';
$parserOutputHelper = $this->getMockBuilder( 'MediaWiki\\Extension\\BootstrapComponents\\ParserOutputHelper' )
->disableOriginalConstructor()
->getMock();
$parserOutputHelper->expects( $this->any() )
->method( 'injectLater' )
->will( $this->returnCallback( function( $id, $text ) use ( &$modalInjection ) {
$modalInjection .= $text;
} ) );
$parserOutputHelper->expects( $this->any() )
->method( 'renderErrorMessage' )
->will( $this->returnArgument( 0 ) );
Expand All @@ -74,11 +68,7 @@ public function testCanRender( $input, $arguments, $expectedTriggerOutput, $expe
/** @noinspection PhpParamsInspection */
$generatedOutput = $instance->parseComponent( $parserRequest );

$this->assertEquals( $expectedTriggerOutput, $generatedOutput );
$this->assertEquals(
$expectedModalOutput,
$modalInjection
);
$this->assertEquals( $expectedTriggerOutput . $expectedModalOutput, $generatedOutput );
}

/**
Expand Down
43 changes: 23 additions & 20 deletions tests/phpunit/Unit/Hooks/OutputPageParserOutputTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,40 +39,43 @@ public function testCanConstruct() {
);
}

public function testHookOutputPageParserOutput() {
$content = 'CONTENT';

public function testHookOutputPageParserOutputLoadsVectorFixUnderVector() {
$outputPage = $this->createMock( OutputPage::class );
$outputPage->expects( $this->once() )
->method( 'addHTML' )
->will( $this->returnCallback( function( $injection ) use ( &$content ) {
$content .= $injection;
} ) );
$outputPage->expects( $this->never() )->method( 'addHTML' );
$outputPage->expects( $this->once() )
->method( 'addModules' )
->with(
$this->equalTo( [ 'ext.bootstrapComponents.vector-fix' ] )
);

$observerParserOutput = $this->createMock( ParserOutput::class );
$observerParserOutput->expects( $this->exactly( 1 ) )
->method( 'getExtensionData' )
->with(
$this->stringContains( 'bsc_deferredContent' )
)
->willReturn( [ 'test' ] );

$bootstrapService = $this->createMock( BootstrapComponentsService::class );
$bootstrapService->expects( $this->once() )
->method( 'vectorSkinInUse' )
->willReturn( true );

$instance = new OutputPageParserOutput( $outputPage, $observerParserOutput, $bootstrapService );
$instance = new OutputPageParserOutput(
$outputPage,
$this->createMock( ParserOutput::class ),
$bootstrapService
);
$instance->process();
}

$this->assertEquals(
'CONTENT<!-- injected by Extension:BootstrapComponents -->test<!-- /injected by Extension:BootstrapComponents -->',
$content
public function testHookDoesNothingWhenNotVector() {
$outputPage = $this->createMock( OutputPage::class );
$outputPage->expects( $this->never() )->method( 'addHTML' );
$outputPage->expects( $this->never() )->method( 'addModules' );

$bootstrapService = $this->createMock( BootstrapComponentsService::class );
$bootstrapService->expects( $this->once() )
->method( 'vectorSkinInUse' )
->willReturn( false );

$instance = new OutputPageParserOutput(
$outputPage,
$this->createMock( ParserOutput::class ),
$bootstrapService
);
$instance->process();
}
}
10 changes: 2 additions & 8 deletions tests/phpunit/Unit/ImageModalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,7 @@ function( $component ) {
}
) );

$modalInjection = '';
$parserOutputHelper = $this->createMock( ParserOutputHelper::class );
$parserOutputHelper->expects( $this->any() )
->method( 'injectLater' )
->will( $this->returnCallback( function( $id, $text ) use ( &$modalInjection ) {
$modalInjection .= $text;
} ) );

$instance = $this->createImageModalWithMocks( null, $title, $file, $nestingController, null, $parserOutputHelper );
$time = false;
Expand All @@ -283,9 +277,9 @@ function( $component ) {
. '-- ' . ($resultOfParseCall ?: $res)
);
}
$this->assertEquals(
$this->assertStringContainsString(
$expectedModal,
$modalInjection,
$resultOfParseCall ?: $res,
'failed modal with test data:' . $this->generatePhpCodeForManualProviderDataOneCase( $fp, $hp )
);
}
Expand Down
12 changes: 1 addition & 11 deletions tests/phpunit/Unit/ModalBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,9 @@ public function testCanConstruct() {
*/
public function testCanParse( $id, $trigger, $content, $header, $footer, $outerClass, $outerStyle, $innerClass, $expectedTrigger, $expectedModal ) {

$modalInjection = '';
$parserOutputHelper = $this->getMockBuilder( 'MediaWiki\\Extension\\BootstrapComponents\\ParserOutputHelper' )
->disableOriginalConstructor()
->getMock();
$parserOutputHelper->expects( $this->any() )
->method( 'injectLater' )
->will( $this->returnCallback( function( $id, $text ) use ( &$modalInjection ) {
$modalInjection .= $text;
} ) );

/** @noinspection PhpParamsInspection */
$instance = new ModalBuilder( $id, $trigger, $content, $parserOutputHelper );
Expand All @@ -77,13 +71,9 @@ public function testCanParse( $id, $trigger, $content, $header, $footer, $outerC
$instance->setDialogClass( $innerClass );
}
$this->assertEquals(
$expectedTrigger,
$expectedTrigger . $expectedModal,
$instance->parse()
);
$this->assertEquals(
$expectedModal,
$modalInjection
);
}

/**
Expand Down
Loading