}
}
- // Could this page contain custom CSS or JavaScript, based on the title?
- $isCssOrJsPage = NS_MEDIAWIKI == $ns && preg_match( '!\.(css|js)$!u', $title->getText(), $m );
- if ( $isCssOrJsPage ) {
+ // Could this page contain code based on the title?
+ $isCodePage = NS_MEDIAWIKI == $ns && preg_match( '!\.(css|js|json)$!u', $title->getText(), $m );
+ if ( $isCodePage ) {
$ext = $m[1];
}
// Hook can force JS/CSS
- Hooks::run( 'TitleIsCssOrJsPage', array( $title, &$isCssOrJsPage ), '1.25' );
+ Hooks::run( 'TitleIsCssOrJsPage', array( $title, &$isCodePage ), '1.25' );
- // Is this a .css subpage of a user page?
- $isJsCssSubpage = NS_USER == $ns
- && !$isCssOrJsPage
- && preg_match( "/\\/.*\\.(js|css)$/", $title->getText(), $m );
- if ( $isJsCssSubpage ) {
+ // Is this a user subpage containing code?
+ $isCodeSubpage = NS_USER == $ns
+ && !$isCodePage
+ && preg_match( "/\\/.*\\.(js|css|json)$/", $title->getText(), $m );
+ if ( $isCodeSubpage ) {
$ext = $m[1];
}
// Is this wikitext, according to $wgNamespaceContentModels or the DefaultModelFor hook?
$isWikitext = is_null( $model ) || $model == CONTENT_MODEL_WIKITEXT;
- $isWikitext = $isWikitext && !$isCssOrJsPage && !$isJsCssSubpage;
+ $isWikitext = $isWikitext && !$isCodePage && !$isCodeSubpage;
// Hook can override $isWikitext
Hooks::run( 'TitleIsWikitextPage', array( $title, &$isWikitext ), '1.25' );
return CONTENT_MODEL_JAVASCRIPT;
case 'css':
return CONTENT_MODEL_CSS;
+ case 'json':
+ return CONTENT_MODEL_JSON;
default:
return is_null( $model ) ? CONTENT_MODEL_TEXT : $model;
}
public function createDifferenceEngine( IContextSource $context, $old = 0, $new = 0,
$rcid = 0, //FIXME: Deprecated, no longer used
$refreshCache = false, $unhide = false ) {
- $diffEngineClass = $this->getDiffEngineClass();
+ // hook: get difference engine
+ $differenceEngine = null;
+ if ( !Hooks::run( 'GetDifferenceEngine',
+ array( $context, $old, $new, $refreshCache, $unhide, &$differenceEngine )
+ ) ) {
+ return $differenceEngine;
+ }
+ $diffEngineClass = $this->getDiffEngineClass();
return new $diffEngineClass( $context, $old, $new, $rcid, $refreshCache, $unhide );
}
return false;
}
+ /**
+ * Return true if this content model supports direct editing, such as via EditPage.
+ *
+ * @return bool Default is false, and true for TextContent and it's derivatives.
+ */
+ public function supportsDirectEditing() {
+ return false;
+ }
+
+ /**
+ * Whether or not this content model supports direct editing via ApiEditPage
+ *
+ * @return bool Default is false, and true for TextContent and derivatives.
+ */
+ public function supportsDirectApiEditing() {
+ return $this->supportsDirectEditing();
+ }
+
/**
* Logs a deprecation warning, visible if $wgDevelopmentWarnings, but only if
* self::$enableDeprecationWarnings is set to true.
/**
* @group ContentHandler
- * @group Database
- *
- * @note Declare that we are using the database, because otherwise we'll fail in
- * the "databaseless" test run. This is because the LinkHolderArray used by the
- * parser needs database access.
*/
class ContentHandlerTest extends MediaWikiTestCase {
'wgContentHandlers' => array(
CONTENT_MODEL_WIKITEXT => 'WikitextContentHandler',
CONTENT_MODEL_JAVASCRIPT => 'JavaScriptContentHandler',
+ CONTENT_MODEL_JSON => 'JsonContentHandler',
CONTENT_MODEL_CSS => 'CssContentHandler',
CONTENT_MODEL_TEXT => 'TextContentHandler',
'testing' => 'DummyContentHandlerForTesting',
// Reset namespace cache
MWNamespace::getCanonicalNamespaces( true );
$wgContLang->resetNamespaces();
+ // And LinkCache
+ LinkCache::destroySingleton();
}
protected function tearDown() {
// Reset namespace cache
MWNamespace::getCanonicalNamespaces( true );
$wgContLang->resetNamespaces();
+ // And LinkCache
+ LinkCache::destroySingleton();
parent::tearDown();
}
return array(
array( 'Help:Foo', CONTENT_MODEL_WIKITEXT ),
array( 'Help:Foo.js', CONTENT_MODEL_WIKITEXT ),
+ array( 'Help:Foo.css', CONTENT_MODEL_WIKITEXT ),
+ array( 'Help:Foo.json', CONTENT_MODEL_WIKITEXT ),
array( 'Help:Foo/bar.js', CONTENT_MODEL_WIKITEXT ),
array( 'User:Foo', CONTENT_MODEL_WIKITEXT ),
array( 'User:Foo.js', CONTENT_MODEL_WIKITEXT ),
+ array( 'User:Foo.css', CONTENT_MODEL_WIKITEXT ),
+ array( 'User:Foo.json', CONTENT_MODEL_WIKITEXT ),
array( 'User:Foo/bar.js', CONTENT_MODEL_JAVASCRIPT ),
array( 'User:Foo/bar.css', CONTENT_MODEL_CSS ),
+ array( 'User:Foo/bar.json', CONTENT_MODEL_JSON ),
+ array( 'User:Foo/bar.json.nope', CONTENT_MODEL_WIKITEXT ),
array( 'User talk:Foo/bar.css', CONTENT_MODEL_WIKITEXT ),
array( 'User:Foo/bar.js.xxx', CONTENT_MODEL_WIKITEXT ),
array( 'User:Foo/bar.xxx', CONTENT_MODEL_WIKITEXT ),
array( 'MediaWiki:Foo.js', CONTENT_MODEL_JAVASCRIPT ),
- array( 'MediaWiki:Foo.css', CONTENT_MODEL_CSS ),
array( 'MediaWiki:Foo.JS', CONTENT_MODEL_WIKITEXT ),
- array( 'MediaWiki:Foo.CSS', CONTENT_MODEL_WIKITEXT ),
+ array( 'MediaWiki:Foo.css', CONTENT_MODEL_CSS ),
array( 'MediaWiki:Foo.css.xxx', CONTENT_MODEL_WIKITEXT ),
+ array( 'MediaWiki:Foo.CSS', CONTENT_MODEL_WIKITEXT ),
+ array( 'MediaWiki:Foo.json', CONTENT_MODEL_JSON ),
+ array( 'MediaWiki:Foo.JSON', CONTENT_MODEL_WIKITEXT ),
);
}
*/
public function testGetForTitle( $title, $expectedContentModel ) {
$title = Title::newFromText( $title );
+ LinkCache::singleton()->addBadLinkObj( $title );
$handler = ContentHandler::getForTitle( $title );
$this->assertEquals( $expectedContentModel, $handler->getModelID() );
}
public function testGetPageLanguage( $title, $expected ) {
if ( is_string( $title ) ) {
$title = Title::newFromText( $title );
+ LinkCache::singleton()->addBadLinkObj( $title );
}
$expected = wfGetLangObj( $expected );
$expectedModelId, $expectedNativeData, $shouldFail
) {
$title = Title::newFromText( $title );
-
+ LinkCache::singleton()->addBadLinkObj( $title );
try {
$content = ContentHandler::makeContent( $data, $title, $modelId, $format );
}
*/
+ public function testSupportsDirectEditing() {
+ $handler = new DummyContentHandlerForTesting( CONTENT_MODEL_JSON );
+ $this->assertFalse( $handler->supportsDirectEditing(), 'direct editing is not supported' );
+ }
+
/**
* @covers ContentHandler::runLegacyHooks
*/
return true;
}
}
-
-class DummyContentHandlerForTesting extends ContentHandler {
-
- public function __construct( $dataModel ) {
- parent::__construct( $dataModel, array( "testing" ) );
- }
-
- /**
- * @see ContentHandler::serializeContent
- *
- * @param Content $content
- * @param string $format
- *
- * @return string
- */
- public function serializeContent( Content $content, $format = null ) {
- return $content->serialize();
- }
-
- /**
- * @see ContentHandler::unserializeContent
- *
- * @param string $blob
- * @param string $format Unused.
- *
- * @return Content
- */
- public function unserializeContent( $blob, $format = null ) {
- $d = unserialize( $blob );
-
- return new DummyContentForTesting( $d );
- }
-
- /**
- * Creates an empty Content object of the type supported by this ContentHandler.
- *
- */
- public function makeEmptyContent() {
- return new DummyContentForTesting( '' );
- }
-}
-
-class DummyContentForTesting extends AbstractContent {
-
- public function __construct( $data ) {
- parent::__construct( "testing" );
-
- $this->data = $data;
- }
-
- public function serialize( $format = null ) {
- return serialize( $this->data );
- }
-
- /**
- * @return string A string representing the content in a way useful for
- * building a full text search index. If no useful representation exists,
- * this method returns an empty string.
- */
- public function getTextForSearchIndex() {
- return '';
- }
-
- /**
- * @return string|bool The wikitext to include when another page includes this content,
- * or false if the content is not includable in a wikitext page.
- */
- public function getWikitextForTransclusion() {
- return false;
- }
-
- /**
- * Returns a textual representation of the content suitable for use in edit
- * summaries and log messages.
- *
- * @param int $maxlength Maximum length of the summary text.
- * @return string The summary text.
- */
- public function getTextForSummary( $maxlength = 250 ) {
- return '';
- }
-
- /**
- * Returns native represenation of the data. Interpretation depends on the data model used,
- * as given by getDataModel().
- *
- * @return mixed The native representation of the content. Could be a string, a nested array
- * structure, an object, a binary blob... anything, really.
- */
- public function getNativeData() {
- return $this->data;
- }
-
- /**
- * returns the content's nominal size in bogo-bytes.
- *
- * @return int
- */
- public function getSize() {
- return strlen( $this->data );
- }
-
- /**
- * Return a copy of this Content object. The following must be true for the object returned
- * if $copy = $original->copy()
- *
- * * get_class($original) === get_class($copy)
- * * $original->getModel() === $copy->getModel()
- * * $original->equals( $copy )
- *
- * If and only if the Content object is imutable, the copy() method can and should
- * return $this. That is, $copy === $original may be true, but only for imutable content
- * objects.
- *
- * @return Content A copy of this object
- */
- public function copy() {
- return $this;
- }
-
- /**
- * Returns true if this content is countable as a "real" wiki page, provided
- * that it's also in a countable location (e.g. a current revision in the main namespace).
- *
- * @param bool $hasLinks If it is known whether this content contains links,
- * provide this information here, to avoid redundant parsing to find out.
- * @return bool
- */
- public function isCountable( $hasLinks = null ) {
- return false;
- }
-
- /**
- * @param Title $title
- * @param int $revId Unused.
- * @param null|ParserOptions $options
- * @param bool $generateHtml Whether to generate Html (default: true). If false, the result
- * of calling getText() on the ParserOutput object returned by this method is undefined.
- *
- * @return ParserOutput
- */
- public function getParserOutput( Title $title, $revId = null,
- ParserOptions $options = null, $generateHtml = true
- ) {
- return new ParserOutput( $this->getNativeData() );
- }
-
- /**
- * @see AbstractContent::fillParserOutput()
- *
- * @param Title $title Context title for parsing
- * @param int|null $revId Revision ID (for {{REVISIONID}})
- * @param ParserOptions $options Parser options
- * @param bool $generateHtml Whether or not to generate HTML
- * @param ParserOutput &$output The output object to fill (reference).
- */
- protected function fillParserOutput( Title $title, $revId,
- ParserOptions $options, $generateHtml, ParserOutput &$output ) {
- $output = new ParserOutput( $this->getNativeData() );
- }
-}