if ( $t->isRedirect() ) {
# Page is a redirect
$colour = 'mw-redirect';
- } elseif ( $threshold > 0 && $t->getLength() < $threshold && MWNamespace::isContent( $t->getNamespace() ) ) {
+ } elseif ( $threshold > 0 &&
+ $t->exists() && $t->getLength() < $threshold &&
+ MWNamespace::isContent( $t->getNamespace() ) ) {
# Page is a stub
$colour = 'stub';
}
* the link text. This is raw HTML and will not be escaped. If null,
* defaults to the prefixed text of the Title; or if the Title is just a
* fragment, the contents of the fragment.
- * @param $query array The query string to append to the URL
- * you're linking to, in key => value array form. Query keys and values
- * will be URL-encoded.
* @param $customAttribs array A key => value array of extra HTML attri-
* butes, such as title and class. (href is ignored.) Classes will be
* merged with the default classes, while other attributes will replace
* default attributes. All passed attribute values will be HTML-escaped.
* A false attribute value means to suppress that attribute.
+ * @param $query array The query string to append to the URL
+ * you're linking to, in key => value array form. Query keys and values
+ * will be URL-encoded.
* @param $options mixed String or array of strings:
* 'known': Page is known to exist, so don't check if it does.
* 'broken': Page is known not to exist, so don't check if it does.
}
if( !$target instanceof Title ) {
- throw new MWException( 'Linker::link passed invalid target' );
+ return "<!-- ERROR -->$text";
}
$options = (array)$options;
} elseif( $target->isContentPage() ) {
# Check for stub.
$threshold = $wgUser->getOption( 'stubthreshold' );
- if( $threshold > 0 and $target->getLength() < $threshold ) {
+ if( $threshold > 0 and $target->exists() and $target->getLength() < $threshold ) {
$classes[] = 'stub';
}
}
}
private function linkText( $target ) {
+ # We might be passed a non-Title by make*LinkObj(). Fail gracefully.
+ if( !$target instanceof Title ) {
+ return '';
+ }
+
# If the target is just a fragment, with no title, we return the frag-
# ment text. Otherwise, we return the title text itself.
if( $target->getPrefixedText() === '' and $target->getFragment() !== '' ) {
* the end of the link.
* @param $prefix String: optional prefix. As trail, only before instead of after.
*/
- function makeLinkObj( Title $nt, $text= '', $query = '', $trail = '', $prefix = '' ) {
+ function makeLinkObj( $nt, $text= '', $query = '', $trail = '', $prefix = '' ) {
global $wgUser;
wfProfileIn( __METHOD__ );
* @param $style String: style to apply - if empty, use getInternalLinkAttributesObj instead
* @return the a-element
*/
- function makeKnownLinkObj( Title $title, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '', $style = '' ) {
+ function makeKnownLinkObj( $title, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '', $style = '' ) {
wfProfileIn( __METHOD__ );
if ( $text == '' ) {
* be included in the link text. Other characters will be appended after
* the end of the link.
*/
- function makeBrokenLinkObj( Title $title, $text = '', $query = '', $trail = '', $prefix = '' ) {
+ function makeBrokenLinkObj( $title, $text = '', $query = '', $trail = '', $prefix = '' ) {
wfProfileIn( __METHOD__ );
list( $inside, $trail ) = Linker::splitTrail( $trail );
# Sanitize text a bit:
$comment = str_replace( "\n", " ", $comment );
- $comment = htmlspecialchars( $comment );
+ # Allow HTML entities (for bug 13815)
+ $comment = Sanitizer::escapeHtmlAllowEntities( $comment );
# Render autocomments and make links:
$comment = $this->formatAutoComments( $comment, $title, $local );
* @todo Document the $local parameter.
*/
private function formatAutocomments( $comment, $title = null, $local = false ) {
- $match = array();
- while (preg_match('!(.*)/\*\s*(.*?)\s*\*/(.*)!', $comment,$match)) {
- $pre=$match[1];
- $auto=$match[2];
- $post=$match[3];
- $link='';
- if( $title ) {
- $section = $auto;
-
- # Generate a valid anchor name from the section title.
- # Hackish, but should generally work - we strip wiki
- # syntax, including the magic [[: that is used to
- # "link rather than show" in case of images and
- # interlanguage links.
- $section = str_replace( '[[:', '', $section );
- $section = str_replace( '[[', '', $section );
- $section = str_replace( ']]', '', $section );
- if ( $local ) {
- $sectionTitle = Title::newFromText( '#' . $section );
- } else {
- $sectionTitle = clone( $title );
- $sectionTitle->mFragment = $section;
- }
+ // Bah!
+ $this->autocommentTitle = $title;
+ $this->autocommentLocal = $local;
+ $comment = preg_replace_callback(
+ '!(.*)/\*\s*(.*?)\s*\*/(.*)!',
+ array( $this, 'formatAutocommentsCallback' ),
+ $comment );
+ unset( $this->autocommentTitle );
+ unset( $this->autocommentLocal );
+ return $comment;
+ }
+
+ private function formatAutocommentsCallback( $match ) {
+ $title = $this->autocommentTitle;
+ $local = $this->autocommentLocal;
+
+ $pre=$match[1];
+ $auto=$match[2];
+ $post=$match[3];
+ $link='';
+ if( $title ) {
+ $section = $auto;
+
+ # Generate a valid anchor name from the section title.
+ # Hackish, but should generally work - we strip wiki
+ # syntax, including the magic [[: that is used to
+ # "link rather than show" in case of images and
+ # interlanguage links.
+ $section = str_replace( '[[:', '', $section );
+ $section = str_replace( '[[', '', $section );
+ $section = str_replace( ']]', '', $section );
+ if ( $local ) {
+ $sectionTitle = Title::newFromText( '#' . $section );
+ } else {
+ $sectionTitle = Title::makeTitleSafe( $title->getNamespace(),
+ $title->getDBkey(), $section );
+ }
+ if ( $sectionTitle ) {
$link = $this->link( $sectionTitle,
wfMsgForContent( 'sectionlink' ), array(), array(),
'noclasses' );
+ } else {
+ $link = '';
}
- $auto = $link . $auto;
- if( $pre ) {
- # written summary $presep autocomment (summary /* section */)
- $auto = wfMsgExt( 'autocomment-prefix', array( 'escapenoentities', 'content' ) ) . $auto;
- }
- if( $post ) {
- # autocomment $postsep written summary (/* section */ summary)
- $auto .= wfMsgExt( 'colon-separator', array( 'escapenoentities', 'content' ) );
- }
- $auto = '<span class="autocomment">' . $auto . '</span>';
- $comment = $pre . $auto . $post;
}
-
+ $auto = "$link$auto";
+ if( $pre ) {
+ # written summary $presep autocomment (summary /* section */)
+ $auto = wfMsgExt( 'autocomment-prefix', array( 'escapenoentities', 'content' ) ) . $auto;
+ }
+ if( $post ) {
+ # autocomment $postsep written summary (/* section */ summary)
+ $auto .= wfMsgExt( 'colon-separator', array( 'escapenoentities', 'content' ) );
+ }
+ $auto = '<span class="autocomment">' . $auto . '</span>';
+ $comment = $pre . $auto . $post;
return $comment;
}
if( !is_null( $tooltip ) ) {
$attribs['title'] = wfMsg( 'editsectionhint', $tooltip );
}
- $url = $this->link( $nt, wfMsg('editsection'),
+ $link = $this->link( $nt, wfMsg('editsection'),
$attribs,
array( 'action' => 'edit', 'section' => $section ),
array( 'noclasses', 'known' )
$attribs = " title=\"$attribs\"";
}
$result = null;
- wfRunHooks( 'EditSectionLink', array( &$this, $nt, $section, $attribs, $url, &$result ) );
+ wfRunHooks( 'EditSectionLink', array( &$this, $nt, $section, $attribs, $link, &$result ) );
if( !is_null( $result ) ) {
# For reverse compatibility, add the brackets *after* the hook is
# run, and even add them to hook-provided text. (This is the main
# reason that the EditSectionLink hook is deprecated in favor of
# DoEditSectionLink: it can't change the brackets or the span.)
- $result = wfMsgHtml( 'editsection-brackets', $url );
+ $result = wfMsgHtml( 'editsection-brackets', $result );
return "<span class=\"editsection\">$result</span>";
}
# Add the brackets and the span, and *then* run the nice new hook, with
# clean and non-redundant arguments.
- $result = wfMsgHtml( 'editsection-brackets', $url );
+ $result = wfMsgHtml( 'editsection-brackets', $link );
$result = "<span class=\"editsection\">$result</span>";
wfRunHooks( 'DoEditSectionLink', array( $this, $nt, $section, $tooltip, &$result ) );
}
$query['token'] = $wgUser->editToken( array( $title->getPrefixedText(),
$rev->getUserText() ) );
- return $this->link( $title, wfMsgHtml( 'rollbacklink' ), array(),
+ return $this->link( $title, wfMsgHtml( 'rollbacklink' ),
+ array( 'title' => wfMsg( 'tooltip-rollback' ) ),
$query, array( 'known', 'noclasses' ) );
}
* @return string title and accesskey attributes, ready to drop in an
* element (e.g., ' title="This does something [x]" accesskey="x"').
*/
- public function tooltipAndAccesskey($name) {
- $fname="Linker::tooltipAndAccesskey";
- wfProfileIn($fname);
- $out = '';
+ public function tooltipAndAccesskey( $name ) {
+ wfProfileIn( __METHOD__ );
+ $attribs = array();
- $tooltip = wfMsg('tooltip-'.$name);
- if (!wfEmptyMsg('tooltip-'.$name, $tooltip) && $tooltip != '-') {
+ $tooltip = wfMsg( "tooltip-$name" );
+ if( !wfEmptyMsg( "tooltip-$name", $tooltip ) && $tooltip != '-' ) {
// Compatibility: formerly some tooltips had [alt-.] hardcoded
$tooltip = preg_replace( "/ ?\[alt-.\]$/", '', $tooltip );
- $out .= ' title="'.htmlspecialchars($tooltip);
+ $attribs['title'] = $tooltip;
}
- $accesskey = wfMsg('accesskey-'.$name);
- if ($accesskey && $accesskey != '-' && !wfEmptyMsg('accesskey-'.$name, $accesskey)) {
- if ($out) $out .= " [$accesskey]\" accesskey=\"$accesskey\"";
- else $out .= " title=\"[$accesskey]\" accesskey=\"$accesskey\"";
- } elseif ($out) {
- $out .= '"';
+
+ $accesskey = wfMsg( "accesskey-$name" );
+ if( $accesskey && $accesskey != '-' &&
+ !wfEmptyMsg( "accesskey-$name", $accesskey ) ) {
+ if( isset( $attribs['title'] ) ) {
+ $attribs['title'] .= " [$accesskey]";
+ }
+ $attribs['accesskey'] = $accesskey;
}
- wfProfileOut($fname);
- return $out;
+
+ $ret = Xml::expandAttributes( $attribs );
+ wfProfileOut( __METHOD__ );
+ return $ret;
}
/**
* isn't always, because sometimes the accesskey needs to go on a different
* element than the id, for reverse-compatibility, etc.)
*
- * @param string $name Id of the element, minus prefixes.
+ * @param string $name Id of the element, minus prefixes.
+ * @param mixed $options null or the string 'withaccess' to add an access-
+ * key hint
* @return string title attribute, ready to drop in an element
* (e.g., ' title="This does something"').
*/
- public function tooltip($name) {
- $out = '';
+ public function tooltip( $name, $options = null ) {
+ wfProfileIn( __METHOD__ );
- $tooltip = wfMsg('tooltip-'.$name);
- if (!wfEmptyMsg('tooltip-'.$name, $tooltip) && $tooltip != '-') {
- $out = ' title="'.htmlspecialchars($tooltip).'"';
+ $attribs = array();
+
+ $tooltip = wfMsg( "tooltip-$name" );
+ if( !wfEmptyMsg( "tooltip-$name", $tooltip ) && $tooltip != '-' ) {
+ $attribs['title'] = $tooltip;
}
- return $out;
+ if( isset( $attribs['title'] ) && $options == 'withaccess' ) {
+ $accesskey = wfMsg( "accesskey-$name" );
+ if( $accesskey && $accesskey != '-' &&
+ !wfEmptyMsg( "accesskey-$name", $accesskey ) ) {
+ $attribs['title'] .= " [$accesskey]";
+ }
+ }
+
+ $ret = Xml::expandAttributes( $attribs );
+ wfProfileOut( __METHOD__ );
+ return $ret;
}
}