* Get the appropriate HTML attributes to add to the "a" element of an ex-
* ternal link, as created by [wikisyntax].
*
- * @param string $title The (unescaped) title text for the link
- * @param string $unused Unused
* @param string $class The contents of the class attribute; if an empty
* string is passed, which is the default value, defaults to 'external'.
*/
- function getExternalLinkAttributes( $title, $unused = null, $class='' ) {
- return $this->getLinkAttributesInternal( $title, $class, 'external' );
+ function getExternalLinkAttributes( $class = 'external' ) {
+ return $this->getLinkAttributesInternal( '', $class );
}
/**
* @param string $class The contents of the class attribute; if an empty
* string is passed, which is the default value, defaults to 'external'.
*/
- function getInterwikiLinkAttributes( $title, $unused = null, $class='' ) {
+ function getInterwikiLinkAttributes( $title, $unused = null, $class = 'external' ) {
global $wgContLang;
# FIXME: We have a whole bunch of handling here that doesn't happen in
$title = $wgContLang->checkTitleEncoding( $title );
$title = preg_replace( '/[\\x00-\\x1f]/', ' ', $title );
- return $this->getLinkAttributesInternal( $title, $class, 'external' );
+ return $this->getLinkAttributesInternal( $title, $class );
}
/**
/**
* Common code for getLinkAttributesX functions
*/
- private function getLinkAttributesInternal( $title, $class, $classDefault = false ) {
+ private function getLinkAttributesInternal( $title, $class ) {
$title = htmlspecialchars( $title );
- if( $class === '' and $classDefault !== false ) {
- # FIXME: Parameter defaults the hard way! We should just have
- # $class = 'external' or whatever as the default in the externally-
- # exposed functions, not $class = ''.
- $class = $classDefault;
- }
$class = htmlspecialchars( $class );
$r = '';
- if( $class !== '' ) {
+ if ( $class != '' ) {
$r .= " class=\"$class\"";
}
- $r .= " title=\"$title\"";
+ if ( $title != '') {
+ $r .= " title=\"$title\"";
+ }
return $r;
}
* hook play with them, *then* expand it all at once.
*/
function makeExternalLink( $url, $text, $escape = true, $linktype = '', $attribs = array() ) {
- $attribsText = $this->getExternalLinkAttributes( $url, $text, 'external ' . $linktype );
+ $attribsText = $this->getExternalLinkAttributes( 'external ' . $linktype );
$url = htmlspecialchars( $url );
if( $escape ) {
$text = htmlspecialchars( $text );
# Render autocomments and make links:
$comment = $this->formatAutoComments( $comment, $title, $local );
- $comment = $this->formatLinksInComment( $comment );
+ $comment = $this->formatLinksInComment( $comment, $title, $local );
wfProfileOut( __METHOD__ );
return $comment;
* @param string $comment Text to format links in
* @return string
*/
- public function formatLinksInComment( $comment ) {
- return preg_replace_callback(
- '/\[\[:?(.*?)(\|(.*?))*\]\]([^[]*)/',
- array( $this, 'formatLinksInCommentCallback' ),
- $comment );
+ public function formatLinksInComment( $comment, $title = null, $local = false ) {
+ $this->commentContextTitle = $title;
+ $this->commentLocal = $local;
+ # Borrowed from Parser::replaceInternalLinks2
+ $parts = StringUtils::explode( '[[', ' ' . $comment );
+ $start = $parts->current();
+ $parts->next();
+ $line = $parts->current();
+ $html = substr( $start, 1 );
+ for ( ; $line !== false && $line !== null ; $parts->next(), $line = $parts->current() ) {
+ $linked = preg_replace_callback(
+ '/^:?(.*?)(\|(.*?))*\]\]([^[]*)/',
+ array( $this, 'formatLinksInCommentCallback' ),
+ $line, -1, $count );
+ if( !$count ) { // No valid link found, put the brackets back
+ $linked = '[[' . $linked;
+ }
+ $html .= $linked;
+ }
+ unset( $this->commentContextTitle );
+ unset( $this->commentLocal );
+ return $html;
}
protected function formatLinksInCommentCallback( $match ) {
$text = $match[1];
}
$submatch = array();
+ $thelink = null;
if( preg_match( '/^' . $medians . '(.*)$/i', $match[1], $submatch ) ) {
# Media link; trail not supported.
- $linkRegexp = '/\[\[(.*?)\]\]/';
+ $linkRegexp = '/^(.*?)\]\]/';
$title = Title::makeTitleSafe( NS_FILE, $submatch[1] );
$thelink = $this->makeMediaLinkObj( $title, $text );
} else {
} else {
$trail = "";
}
- $linkRegexp = '/\[\[(.*?)\]\]' . preg_quote( $trail, '/' ) . '/';
+ $linkRegexp = '/^(.*?)\]\]' . preg_quote( $trail, '/' ) . '/';
if (isset($match[1][0]) && $match[1][0] == ':')
$match[1] = substr($match[1], 1);
list( $inside, $trail ) = Linker::splitTrail( $trail );
- $thelink = $this->link(
- Title::newFromText( $match[1] ),
- $text . $inside
- ) . $trail;
+
+ $linkText = $text;
+ $linkTarget = Linker::normalizeSubpageLink( $this->commentContextTitle,
+ $match[1], $linkText );
+
+ $target = Title::newFromText( $linkTarget );
+ if( $target ) {
+ if( $target->getText() == '' && !$this->commentLocal && $this->commentContextTitle ) {
+ $newTarget = clone( $this->commentContextTitle );
+ $newTarget->setFragment( '#' . $target->getFragment() );
+ $target = $newTarget;
+ }
+ $thelink = $this->link(
+ $target,
+ $linkText . $inside
+ ) . $trail;
+ }
+ }
+ if( $thelink ) {
+ // If the link is still valid, go ahead and replace it in!
+ $comment = preg_replace( $linkRegexp, StringUtils::escapeRegexReplacement( $thelink ), $comment, 1 );
}
- $comment = preg_replace( $linkRegexp, StringUtils::escapeRegexReplacement( $thelink ), $comment, 1 );
return $comment;
}
+
+ static function normalizeSubpageLink( $contextTitle, $target, &$text ) {
+ # Valid link forms:
+ # Foobar -- normal
+ # :Foobar -- override special treatment of prefix (images, language links)
+ # /Foobar -- convert to CurrentPage/Foobar
+ # /Foobar/ -- convert to CurrentPage/Foobar, strip the initial / from text
+ # ../ -- convert to CurrentPage, from CurrentPage/CurrentSubPage
+ # ../Foobar -- convert to CurrentPage/Foobar, from CurrentPage/CurrentSubPage
+
+ wfProfileIn( __METHOD__ );
+ $ret = $target; # default return value is no change
+
+ # Some namespaces don't allow subpages,
+ # so only perform processing if subpages are allowed
+ if( $contextTitle && MWNamespace::hasSubpages( $contextTitle->getNamespace() ) ) {
+ $hash = strpos( $target, '#' );
+ if( $hash !== false ) {
+ $suffix = substr( $target, $hash );
+ $target = substr( $target, 0, $hash );
+ } else {
+ $suffix = '';
+ }
+ # bug 7425
+ $target = trim( $target );
+ # Look at the first character
+ if( $target != '' && $target{0} === '/' ) {
+ # / at end means we don't want the slash to be shown
+ $m = array();
+ $trailingSlashes = preg_match_all( '%(/+)$%', $target, $m );
+ if( $trailingSlashes ) {
+ $noslash = $target = substr( $target, 1, -strlen($m[0][0]) );
+ } else {
+ $noslash = substr( $target, 1 );
+ }
+
+ $ret = $contextTitle->getPrefixedText(). '/' . trim($noslash) . $suffix;
+ if( '' === $text ) {
+ $text = $target . $suffix;
+ } # this might be changed for ugliness reasons
+ } else {
+ # check for .. subpage backlinks
+ $dotdotcount = 0;
+ $nodotdot = $target;
+ while( strncmp( $nodotdot, "../", 3 ) == 0 ) {
+ ++$dotdotcount;
+ $nodotdot = substr( $nodotdot, 3 );
+ }
+ if($dotdotcount > 0) {
+ $exploded = explode( '/', $contextTitle->GetPrefixedText() );
+ if( count( $exploded ) > $dotdotcount ) { # not allowed to go below top level page
+ $ret = implode( '/', array_slice( $exploded, 0, -$dotdotcount ) );
+ # / at the end means don't show full path
+ if( substr( $nodotdot, -1, 1 ) === '/' ) {
+ $nodotdot = substr( $nodotdot, 0, -1 );
+ if( '' === $text ) {
+ $text = $nodotdot . $suffix;
+ }
+ }
+ $nodotdot = trim( $nodotdot );
+ if( $nodotdot != '' ) {
+ $ret .= '/' . $nodotdot;
+ }
+ $ret .= $suffix;
+ }
+ }
+ }
+ }
+
+ wfProfileOut( __METHOD__ );
+ return $ret;
+ }
/**
* Wrap a comment in standard punctuation and formatting if
foreach ( $tree as $section ) {
if ( $section['toclevel'] > $lastLevel )
$toc .= $this->tocIndent();
- else if ( $secton['toclevel'] < $lastLevel )
+ else if ( $section['toclevel'] < $lastLevel )
$toc .= $this->tocUnindent(
$lastLevel - $section['toclevel'] );
else
* @return string HTML headline
*/
public function makeHeadline( $level, $attribs, $anchor, $text, $link, $legacyAnchor = false ) {
- $ret = "<h$level id=\"$anchor\"$attribs"
+ $ret = "<h$level$attribs"
. $link
- . " <span class=\"mw-headline\">$text</span>"
+ . " <span class=\"mw-headline\" id=\"$anchor\">$text</span>"
. "</h$level>";
if ( $legacyAnchor !== false ) {
$ret = "<a id=\"$legacyAnchor\"></a>$ret";