Mw_parse: Add more implementation to link_renderer

pull/620/head
gnosygnu 8 years ago
parent 7bb09a8320
commit ca8017a876

@ -21,6 +21,10 @@ import gplx.langs.htmls.entitys.*;
import gplx.xowa.wikis.nss.*; import gplx.xowa.wikis.xwikis.*; import gplx.xowa.wikis.nss.*; import gplx.xowa.wikis.xwikis.*;
import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.miscs.*; import gplx.xowa.parsers.amps.*; import gplx.xowa.parsers.miscs.*;
import gplx.xowa.apps.utls.*; import gplx.langs.htmls.encoders.*; import gplx.xowa.langs.cases.*; import gplx.xowa.apps.utls.*; import gplx.langs.htmls.encoders.*; import gplx.xowa.langs.cases.*;
/* TODO.XO
Is_known
Create_fragment_target
*/
public class Xoa_ttl { // PAGE:en.w:http://en.wikipedia.org/wiki/Help:Link; REF.MW: Ttl.php|secureAndSplit; public class Xoa_ttl { // PAGE:en.w:http://en.wikipedia.org/wiki/Help:Link; REF.MW: Ttl.php|secureAndSplit;
private int wik_bgn = -1, ns_bgn = -1, page_bgn = 0, leaf_bgn = -1, anch_bgn = -1, root_bgn = -1; private int wik_bgn = -1, ns_bgn = -1, page_bgn = 0, leaf_bgn = -1, anch_bgn = -1, root_bgn = -1;
private byte[] tors_txt; private byte[] tors_txt;
@ -136,7 +140,7 @@ public class Xoa_ttl { // PAGE:en.w:http://en.wikipedia.org/wiki/Help:Link; REF.
public byte[] Get_prefixed_db_key() {return Full_db();} public byte[] Get_prefixed_db_key() {return Full_db();}
public boolean Has_fragment() {return anch_bgn != -1;} public boolean Has_fragment() {return anch_bgn != -1;}
public byte[] Get_fragment() {return Anch_txt();} public byte[] Get_fragment() {return Anch_txt();}
public byte[] Get_link_url(byte[] query, boolean query2, boolean proto) { public byte[] Get_link_url(gplx.xowa.mws.htmls.Xomw_qry_mgr qry_mgr, boolean query2, boolean proto) {
// if ( $this->isExternal() || $proto !== false ) { // if ( $this->isExternal() || $proto !== false ) {
// $ret = $this->getFullURL( $query, $query2, $proto ); // $ret = $this->getFullURL( $query, $query2, $proto );
// } // }
@ -190,6 +194,12 @@ public class Xoa_ttl { // PAGE:en.w:http://en.wikipedia.org/wiki/Help:Link; REF.
// } // }
return false; return false;
} }
public boolean Is_known() {
return true;
}
public Xoa_ttl Create_fragment_target() {
return this;
}
public boolean Is_external() {return this.wik_bgn != -1;} public boolean Is_external() {return this.wik_bgn != -1;}

@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.mws; import gplx.*; import gplx.xowa.*; package gplx.xowa.mws; import gplx.*; import gplx.xowa.*;
import gplx.core.btries.*; import gplx.core.btries.*;
import gplx.xowa.mws.htmls.*; import gplx.xowa.mws.htmls.*;
import gplx.xowa.mws.linkers.*;
public class Xomw_linker { public class Xomw_linker {
private final Bry_bfr tmp = Bry_bfr_.New(); private final Bry_bfr tmp = Bry_bfr_.New();
private final Linker_rel_splitter splitter = new Linker_rel_splitter(); private final Linker_rel_splitter splitter = new Linker_rel_splitter();
@ -27,95 +28,88 @@ public class Xomw_linker {
private final byte[][] split_trail_rv = new byte[2][]; private final byte[][] split_trail_rv = new byte[2][];
private Btrie_slim_mgr split_trail_trie; private Btrie_slim_mgr split_trail_trie;
private static final byte[] Atr__class = Bry_.new_a7("class"), Atr__rel = Bry_.new_a7("rel"), Atr__href = Bry_.new_a7("href"), Rel__nofollow = Bry_.new_a7("nofollow"); private static final byte[] Atr__class = Bry_.new_a7("class"), Atr__rel = Bry_.new_a7("rel"), Atr__href = Bry_.new_a7("href"), Rel__nofollow = Bry_.new_a7("nofollow");
private final Xomw_link_renderer link_renderer;
public Xomw_linker(Xomw_link_renderer link_renderer) {
this.link_renderer = link_renderer;
}
public void Init_by_wiki(Btrie_slim_mgr trie) { public void Init_by_wiki(Btrie_slim_mgr trie) {
this.split_trail_trie = trie; this.split_trail_trie = trie;
} }
// /** // This function returns an HTML link to the given target. It serves a few
// * This function returns an HTML link to the given target. It serves a few // purposes:
// * purposes: // 1) If $target is a Title, the correct URL to link to will be figured
// * 1) If $target is a Title, the correct URL to link to will be figured // out automatically.
// * out automatically. // 2) It automatically adds the usual classes for various types of link
// * 2) It automatically adds the usual classes for various types of link // targets: "new" for red links, "stub" for short articles, etc.
// * targets: "new" for red links, "stub" for short articles, etc. // 3) It escapes all attribute values safely so there's no risk of XSS.
// * 3) It escapes all attribute values safely so there's no risk of XSS. // 4) It provides a default tooltip if the target is a Title (the page
// * 4) It provides a default tooltip if the target is a Title (the page // name of the target).
// * name of the target). // link() replaces the old functions in the makeLink() family.
// * link() replaces the old functions in the makeLink() family. //
// * // @since 1.18 Method exists since 1.16 as non-static, made static in 1.18.
// * @since 1.18 Method exists since 1.16 as non-static, made static in 1.18. // @deprecated since 1.28, use MediaWiki\Linker\LinkRenderer instead
// * @deprecated since 1.28, use MediaWiki\Linker\LinkRenderer instead //
// * // @param Title $target Can currently only be a Title, but this may
// * @param Title $target Can currently only be a Title, but this may // change to support Images, literal URLs, etc.
// * change to support Images, literal URLs, etc. // @param String $html The HTML contents of the <a> element, i.e.,
// * @param String $html The HTML contents of the <a> element, i.e., // the link text. This is raw HTML and will not be escaped. If null,
// * 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
// * defaults to the prefixed text of the Title; or if the Title is just a // fragment, the contents of the fragment.
// * fragment, the contents of the fragment. // @param array $customAttribs A key => value array of extra HTML attributes,
// * @param array $customAttribs A key => value array of extra HTML attributes, // such as title and class. (href is ignored.) Classes will be
// * such as title and class. (href is ignored.) Classes will be // merged with the default classes, while other attributes will replace
// * merged with the default classes, while other attributes will replace // default attributes. All passed attribute values will be HTML-escaped.
// * default attributes. All passed attribute values will be HTML-escaped. // A false attribute value means to suppress that attribute.
// * A false attribute value means to suppress that attribute. // @param array $query The query String to append to the URL
// * @param array $query The query String to append to the URL // you're linking to, in key => value array form. Query keys and values
// * you're linking to, in key => value array form. Query keys and values // will be URL-encoded.
// * will be URL-encoded. // @param String|array $options String or array of strings:
// * @param String|array $options String or array of strings: // 'known': Page is known to exist, so don't check if it does.
// * '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.
// * 'broken': Page is known not to exist, so don't check if it does. // 'noclasses': Don't add any classes automatically (includes "new",
// * 'noclasses': Don't add any classes automatically (includes "new", // "stub", "mw-redirect", "extiw"). Only use the class attribute
// * "stub", "mw-redirect", "extiw"). Only use the class attribute // provided, if any, so you get a simple blue link with no funny i-
// * provided, if any, so you get a simple blue link with no funny i- // cons.
// * cons. // 'forcearticlepath': Use the article path always, even with a querystring.
// * 'forcearticlepath': Use the article path always, even with a querystring. // Has compatibility issues on some setups, so avoid wherever possible.
// * Has compatibility issues on some setups, so avoid wherever possible. // 'http': Force a full URL with http:// as the scheme.
// * 'http': Force a full URL with http:// as the scheme. // 'https': Force a full URL with https:// as the scheme.
// * 'https': Force a full URL with https:// as the scheme. // 'stubThreshold' => (int): Stub threshold to use when determining link classes.
// * 'stubThreshold' => (int): Stub threshold to use when determining link classes. // @return String HTML <a> attribute
// * @return String HTML <a> attribute public void Link(Bry_bfr bfr, Xoa_ttl target, byte[] html, Xomw_atr_mgr custom_attribs, Xomw_qry_mgr query, Xomw_opt_mgr options) {
// */ // XO.MW.UNSUPPORTED:MW has different renderers -- presumably for forcing "https:" and others; XO only has one
// public static function link( //if (options != null) {
// $target, $html = null, $customAttribs = [], $query = [], $options = [] // // Custom options, create new LinkRenderer
// ) { // if (!isset($options['stubThreshold'])) {
// if ( !$target instanceof Title ) { // $defaultLinkRenderer = $services->getLinkRenderer();
// wfWarn( __METHOD__ . ': Requires $target to be a Title Object.', 2 ); // $options['stubThreshold'] = $defaultLinkRenderer->getStubThreshold();
// return "<!-- ERROR -->$html"; // }
// } // $linkRenderer = $services->getLinkRendererFactory()->createFromLegacyOptions($options);
// //}
// if ( is_string( $query ) ) { //else {
// // some functions withing core using this still hand over query strings // $linkRenderer = $services->getLinkRenderer();
// wfDeprecated( __METHOD__ . ' with parameter $query as String (should be array)', '1.20' ); //}
// $query = wfCgiToArray( $query );
// } byte[] text = null;
// if (html != null) {
// $services = MediaWikiServices::getInstance(); // $text = new HtmlArmor($html);
// $options = (array)$options; }
// if ( $options ) { else {
// // Custom options, create new LinkRenderer text = html; // null
// if ( !isset( $options['stubThreshold'] ) ) { }
// $defaultLinkRenderer = $services->getLinkRenderer(); if (options.known) {
// $options['stubThreshold'] = $defaultLinkRenderer->getStubThreshold(); link_renderer.Make_known_link(bfr, target, text, custom_attribs, query);
// } }
// $linkRenderer = $services->getLinkRendererFactory() else if (options.broken) {
// ->createFromLegacyOptions( $options ); // return $linkRenderer->makeBrokenLink($target, $text, $customAttribs, $query);
// } else { }
// $linkRenderer = $services->getLinkRenderer(); else if (options.no_classes) {
// } link_renderer.Make_preloaded_link(bfr, target, text, Bry_.Empty, custom_attribs, query);
// }
// if ( $html !== null ) { else {
// $text = new HtmlArmor( $html ); // $linkRenderer->makeLink($target, $text, $customAttribs, $query);
// } else { }
// $text = $html; // null }
// }
// if ( in_array( 'known', $options, true ) ) {
// return $linkRenderer->makeKnownLink( $target, $text, $customAttribs, $query );
// } elseif ( in_array( 'broken', $options, true ) ) {
// return $linkRenderer->makeBrokenLink( $target, $text, $customAttribs, $query );
// } elseif ( in_array( 'noclasses', $options, true ) ) {
// return $linkRenderer->makePreloadedLink( $target, $text, '', $customAttribs, $query );
// } else {
// return $linkRenderer->makeLink( $target, $text, $customAttribs, $query );
// }
// }
public void Make_self_link_obj(Bry_bfr bfr, Xoa_ttl nt, byte[] html, byte[] query, byte[] trail, byte[] prefix) { public void Make_self_link_obj(Bry_bfr bfr, Xoa_ttl nt, byte[] html, byte[] query, byte[] trail, byte[] prefix) {
// MW.HOOK:SelfLinkBegin // MW.HOOK:SelfLinkBegin
if (html == Bry_.Empty) { if (html == Bry_.Empty) {
@ -130,12 +124,12 @@ public class Xomw_linker {
bfr.Add_str_a7("</strong>"); bfr.Add_str_a7("</strong>");
bfr.Add(trail); bfr.Add(trail);
} }
public void Make_external_link(Bry_bfr bfr, byte[] url, byte[] text, boolean escape, byte[] link_type, Xomwh_atr_mgr attribs, byte[] title) { public void Make_external_link(Bry_bfr bfr, byte[] url, byte[] text, boolean escape, byte[] link_type, Xomw_atr_mgr attribs, byte[] title) {
tmp.Add_str_a7("external"); tmp.Add_str_a7("external");
if (link_type != null) { if (link_type != null) {
tmp.Add_byte_space().Add(link_type); tmp.Add_byte_space().Add(link_type);
} }
Xomwh_atr_itm cls_itm = attribs.Get_by_or_make(Atr__class); Xomw_atr_itm cls_itm = attribs.Get_by_or_make(Atr__class);
if (cls_itm.Val() != null) { if (cls_itm.Val() != null) {
tmp.Add(cls_itm.Val()); tmp.Add(cls_itm.Val());
} }
@ -148,23 +142,23 @@ public class Xomw_linker {
title = wg_title; title = wg_title;
byte[] new_rel = Get_external_link_rel(url, title); byte[] new_rel = Get_external_link_rel(url, title);
Xomwh_atr_itm cur_rel_atr = attribs.Get_by_or_make(Atr__rel); Xomw_atr_itm cur_rel_atr = attribs.Get_by_or_make(Atr__rel);
if (cur_rel_atr.Val() == null) { if (cur_rel_atr.Val() == null) {
cur_rel_atr.Val_(new_rel); cur_rel_atr.Val_(new_rel);
} }
else { else {
// Merge the rel attributes. // Merge the rel attributes.
byte[] cur_rel = cur_rel_atr.Val(); byte[] cur_rel = cur_rel_atr.Val();
Bry_split_.Split(new_rel, 0, new_rel.length, Byte_ascii.Space, Bool_.N, splitter); // $newRels = explode( ' ', $newRel ); Bry_split_.Split(new_rel, 0, new_rel.length, Byte_ascii.Space, Bool_.N, splitter); // $newRels = explode(' ', $newRel);
Bry_split_.Split(cur_rel, 0, cur_rel.length, Byte_ascii.Space, Bool_.N, splitter); // $oldRels = explode( ' ', $attribs['rel'] ); Bry_split_.Split(cur_rel, 0, cur_rel.length, Byte_ascii.Space, Bool_.N, splitter); // $oldRels = explode(' ', $attribs['rel']);
cur_rel_atr.Val_(splitter.To_bry()); // $attribs['rel'] = implode( ' ', $combined ); cur_rel_atr.Val_(splitter.To_bry()); // $attribs['rel'] = implode(' ', $combined);
} }
//$link = ''; //$link = '';
//$success = Hooks::run( 'LinkerMakeExternalLink', //$success = Hooks::run('LinkerMakeExternalLink',
// [ &$url, &$text, &$link, &$attribs, $linktype ] ); // [ &$url, &$text, &$link, &$attribs, $linktype ]);
//if ( !$success ) { //if (!$success) {
// wfDebug( "Hook LinkerMakeExternalLink changed the output of link " // wfDebug("Hook LinkerMakeExternalLink changed the output of link "
// . "with url {$url} and text {$text} to {$link}\n", true ); // . "with url {$url} and text {$text} to {$link}\n", true);
// return $link; // return $link;
//} //}
attribs.Set(Atr__href, url); attribs.Set(Atr__href, url);
@ -174,9 +168,9 @@ public class Xomw_linker {
private byte[] Get_external_link_rel(byte[] url, byte[] title) { private byte[] Get_external_link_rel(byte[] url, byte[] title) {
// global $wgNoFollowLinks, $wgNoFollowNsExceptions, $wgNoFollowDomainExceptions; // global $wgNoFollowLinks, $wgNoFollowNsExceptions, $wgNoFollowDomainExceptions;
// $ns = $title ? $title->getNamespace() : false; // $ns = $title ? $title->getNamespace() : false;
// if ( $wgNoFollowLinks && !in_array( $ns, $wgNoFollowNsExceptions ) // if ($wgNoFollowLinks && !in_array($ns, $wgNoFollowNsExceptions)
// && !wfMatchesDomainList( $url, $wgNoFollowDomainExceptions ) // && !wfMatchesDomainList($url, $wgNoFollowDomainExceptions)
// ) { //) {
return Rel__nofollow; return Rel__nofollow;
// } // }
// return null; // return null;
@ -388,7 +382,7 @@ public class Xomw_linker {
// $paramName = 'no-link'; // $paramName = 'no-link';
// $value = true; // $value = true;
// $validated = true; // $validated = true;
// } elseif (preg_match("/^((?i)$prots)/", $value)) { // } else if (preg_match("/^((?i)$prots)/", $value)) {
// if (preg_match("/^((?i)$prots)$addr$chars*$/u", $value, $m)) { // if (preg_match("/^((?i)$prots)$addr$chars*$/u", $value, $m)) {
// $paramName = 'link-url'; // $paramName = 'link-url';
// $this->mOutput->addExternalLink($value); // $this->mOutput->addExternalLink($value);
@ -537,19 +531,8 @@ public class Xomw_linker {
// } // }
// return [ $this->mImageParams[$handlerClass], $this->mImageParamsMagicArray[$handlerClass] ]; // return [ $this->mImageParams[$handlerClass], $this->mImageParamsMagicArray[$handlerClass] ];
// } // }
// /** // // Make HTML for a thumbnail including image, border and caption
// * Make HTML for a thumbnail including image, border and caption // public static function makeThumbLinkObj(Title $title, $file, $label = '', $alt,
// * @param Title $title
// * @param File|boolean $file File Object or false if it doesn't exist
// * @param String $label
// * @param String $alt
// * @param String $align
// * @param array $params
// * @param boolean $framed
// * @param String $manualthumb
// * @return String
// */
// public static function makeThumbLinkObj( Title $title, $file, $label = '', $alt,
// $align = 'right', $params = [], $framed = false, $manualthumb = "" // $align = 'right', $params = [], $framed = false, $manualthumb = ""
// ) { // ) {
// $frameParams = [ // $frameParams = [
@ -557,227 +540,189 @@ public class Xomw_linker {
// 'caption' => $label, // 'caption' => $label,
// 'align' => $align // 'align' => $align
// ]; // ];
// if ( $framed ) { // if ($framed) {
// $frameParams['framed'] = true; // $frameParams['framed'] = true;
// } // }
// if ( $manualthumb ) { // if ($manualthumb) {
// $frameParams['manualthumb'] = $manualthumb; // $frameParams['manualthumb'] = $manualthumb;
// } // }
// return self::makeThumbLink2( $title, $file, $frameParams, $params ); // return self::makeThumbLink2($title, $file, $frameParams, $params);
// } // }
//
// /** // public static function makeThumbLink2(Title $title, $file, $frameParams = [],
// * @param Title $title
// * @param File $file
// * @param array $frameParams
// * @param array $handlerParams
// * @param boolean $time
// * @param String $query
// * @return String
// */
// public static function makeThumbLink2( Title $title, $file, $frameParams = [],
// $handlerParams = [], $time = false, $query = "" // $handlerParams = [], $time = false, $query = ""
// ) { // ) {
// $exists = $file && $file->exists(); // $exists = $file && $file->exists();
// //
// $page = isset( $handlerParams['page'] ) ? $handlerParams['page'] : false; // $page = isset($handlerParams['page']) ? $handlerParams['page'] : false;
// if ( !isset( $frameParams['align'] ) ) { // if (!isset($frameParams['align'])) {
// $frameParams['align'] = 'right'; // $frameParams['align'] = 'right';
// } // }
// if ( !isset( $frameParams['alt'] ) ) { // if (!isset($frameParams['alt'])) {
// $frameParams['alt'] = ''; // $frameParams['alt'] = '';
// } // }
// if ( !isset( $frameParams['title'] ) ) { // if (!isset($frameParams['title'])) {
// $frameParams['title'] = ''; // $frameParams['title'] = '';
// } // }
// if ( !isset( $frameParams['caption'] ) ) { // if (!isset($frameParams['caption'])) {
// $frameParams['caption'] = ''; // $frameParams['caption'] = '';
// } // }
// //
// if ( empty( $handlerParams['width'] ) ) { // if (empty($handlerParams['width'])) {
// // Reduce width for upright images when parameter 'upright' is used // // Reduce width for upright images when parameter 'upright' is used
// $handlerParams['width'] = isset( $frameParams['upright'] ) ? 130 : 180; // $handlerParams['width'] = isset($frameParams['upright']) ? 130 : 180;
// } // }
// $thumb = false; // $thumb = false;
// $noscale = false; // $noscale = false;
// $manualthumb = false; // $manualthumb = false;
// //
// if ( !$exists ) { // if (!$exists) {
// $outerWidth = $handlerParams['width'] + 2; // $outerWidth = $handlerParams['width'] + 2;
// } else { // } else {
// if ( isset( $frameParams['manualthumb'] ) ) { // if (isset($frameParams['manualthumb'])) {
// # Use manually specified thumbnail // // Use manually specified thumbnail
// $manual_title = Title::makeTitleSafe( NS_FILE, $frameParams['manualthumb'] ); // $manual_title = Title::makeTitleSafe(NS_FILE, $frameParams['manualthumb']);
// if ( $manual_title ) { // if ($manual_title) {
// $manual_img = wfFindFile( $manual_title ); // $manual_img = wfFindFile($manual_title);
// if ( $manual_img ) { // if ($manual_img) {
// $thumb = $manual_img->getUnscaledThumb( $handlerParams ); // $thumb = $manual_img->getUnscaledThumb($handlerParams);
// $manualthumb = true; // $manualthumb = true;
// } else { // } else {
// $exists = false; // $exists = false;
// } // }
// } // }
// } elseif ( isset( $frameParams['framed'] ) ) { // } else if (isset($frameParams['framed'])) {
// // Use image dimensions, don't scale // // Use image dimensions, don't scale
// $thumb = $file->getUnscaledThumb( $handlerParams ); // $thumb = $file->getUnscaledThumb($handlerParams);
// $noscale = true; // $noscale = true;
// } else { // } else {
// # Do not present an image bigger than the source, for bitmap-style images // // Do not present an image bigger than the source, for bitmap-style images
// # This is a hack to maintain compatibility with arbitrary pre-1.10 behavior // // This is a hack to maintain compatibility with arbitrary pre-1.10 behavior
// $srcWidth = $file->getWidth( $page ); // $srcWidth = $file->getWidth($page);
// if ( $srcWidth && !$file->mustRender() && $handlerParams['width'] > $srcWidth ) { // if ($srcWidth && !$file->mustRender() && $handlerParams['width'] > $srcWidth) {
// $handlerParams['width'] = $srcWidth; // $handlerParams['width'] = $srcWidth;
// } // }
// $thumb = $file->transform( $handlerParams ); // $thumb = $file->transform($handlerParams);
// } // }
// //
// if ( $thumb ) { // if ($thumb) {
// $outerWidth = $thumb->getWidth() + 2; // $outerWidth = $thumb->getWidth() + 2;
// } else { // } else {
// $outerWidth = $handlerParams['width'] + 2; // $outerWidth = $handlerParams['width'] + 2;
// } // }
// } // }
// //
// # ThumbnailImage::toHtml() already adds page= onto the end of DjVu URLs // // ThumbnailImage::toHtml() already adds page= onto the end of DjVu URLs
// # So we don't need to pass it here in $query. However, the URL for the // // So we don't need to pass it here in $query. However, the URL for the
// # zoom icon still needs it, so we make a unique query for it. See bug 14771 // // zoom icon still needs it, so we make a unique query for it. See bug 14771
// $url = $title->getLocalURL( $query ); // $url = $title->getLocalURL($query);
// if ( $page ) { // if ($page) {
// $url = wfAppendQuery( $url, [ 'page' => $page ] ); // $url = wfAppendQuery($url, [ 'page' => $page ]);
// } // }
// if ( $manualthumb // if ($manualthumb
// && !isset( $frameParams['link-title'] ) // && !isset($frameParams['link-title'])
// && !isset( $frameParams['link-url'] ) // && !isset($frameParams['link-url'])
// && !isset( $frameParams['no-link'] ) ) { // && !isset($frameParams['no-link'])) {
// $frameParams['link-url'] = $url; // $frameParams['link-url'] = $url;
// } // }
// //
// $s = "<div class=\"thumb t{$frameParams['align']}\">" // $s = "<div class=\"thumb t{$frameParams['align']}\">"
// . "<div class=\"thumbinner\" style=\"width:{$outerWidth}px;\">"; // . "<div class=\"thumbinner\" style=\"width:{$outerWidth}px;\">";
// //
// if ( !$exists ) { // if (!$exists) {
// $s .= self::makeBrokenImageLinkObj( $title, $frameParams['title'], '', '', '', $time == true ); // $s .= self::makeBrokenImageLinkObj($title, $frameParams['title'], '', '', '', $time == true);
// $zoomIcon = ''; // $zoomIcon = '';
// } elseif ( !$thumb ) { // } else if (!$thumb) {
// $s .= wfMessage( 'thumbnail_error', '' )->escaped(); // $s .= wfMessage('thumbnail_error', '')->escaped();
// $zoomIcon = ''; // $zoomIcon = '';
// } else { // } else {
// if ( !$noscale && !$manualthumb ) { // if (!$noscale && !$manualthumb) {
// self::processResponsiveImages( $file, $thumb, $handlerParams ); // self::processResponsiveImages($file, $thumb, $handlerParams);
// } // }
// $params = [ // $params = [
// 'alt' => $frameParams['alt'], // 'alt' => $frameParams['alt'],
// 'title' => $frameParams['title'], // 'title' => $frameParams['title'],
// 'img-class' => ( isset( $frameParams['class'] ) && $frameParams['class'] !== '' // 'img-class' => (isset($frameParams['class']) && $frameParams['class'] !== ''
// ? $frameParams['class'] . ' ' // ? $frameParams['class'] . ' '
// : '' ) . 'thumbimage' // : '') . 'thumbimage'
// ]; // ];
// $params = self::getImageLinkMTOParams( $frameParams, $query ) + $params; // $params = self::getImageLinkMTOParams($frameParams, $query) + $params;
// $s .= $thumb->toHtml( $params ); // $s .= $thumb->toHtml($params);
// if ( isset( $frameParams['framed'] ) ) { // if (isset($frameParams['framed'])) {
// $zoomIcon = ""; // $zoomIcon = "";
// } else { // } else {
// $zoomIcon = Html::rawElement( 'div', [ 'class' => 'magnify' ], // $zoomIcon = Html::rawElement('div', [ 'class' => 'magnify' ],
// Html::rawElement( 'a', [ // Html::rawElement('a', [
// 'href' => $url, // 'href' => $url,
// 'class' => '@gplx.Internal protected', // 'class' => '@gplx.Internal protected',
// 'title' => wfMessage( 'thumbnail-more' )->text() ], // 'title' => wfMessage('thumbnail-more')->text() ],
// "" ) ); // ""));
// } // }
// } // }
// $s .= ' <div class="thumbcaption">' . $zoomIcon . $frameParams['caption'] . "</div></div></div>"; // $s .= ' <div class="thumbcaption">' . $zoomIcon . $frameParams['caption'] . "</div></div></div>";
// return str_replace( "\n", ' ', $s ); // return str_replace("\n", ' ', $s);
// } // }
// /** // // Make a "broken" link to an image
// * Make a "broken" link to an image // public static function makeBrokenImageLinkObj($title, $label = '',
// *
// * @since 1.16.3
// * @param Title $title
// * @param String $label Link label (plain text)
// * @param String $query Query String
// * @param String $unused1 Unused parameter kept for b/c
// * @param String $unused2 Unused parameter kept for b/c
// * @param boolean $time A file of a certain timestamp was requested
// * @return String
// */
// public static function makeBrokenImageLinkObj( $title, $label = '',
// $query = '', $unused1 = '', $unused2 = '', $time = false // $query = '', $unused1 = '', $unused2 = '', $time = false
// ) { // ) {
// if ( !$title instanceof Title ) { // if (!$title instanceof Title) {
// wfWarn( __METHOD__ . ': Requires $title to be a Title Object.' ); // wfWarn(__METHOD__ . ': Requires $title to be a Title Object.');
// return "<!-- ERROR -->" . htmlspecialchars( $label ); // return "<!-- ERROR -->" . htmlspecialchars($label);
// } // }
// //
// global $wgEnableUploads, $wgUploadMissingFileUrl, $wgUploadNavigationUrl; // global $wgEnableUploads, $wgUploadMissingFileUrl, $wgUploadNavigationUrl;
// if ( $label == '' ) { // if ($label == '') {
// $label = $title->getPrefixedText(); // $label = $title->getPrefixedText();
// } // }
// $encLabel = htmlspecialchars( $label ); // $encLabel = htmlspecialchars($label);
// $currentExists = $time ? ( wfFindFile( $title ) != false ) : false; // $currentExists = $time ? (wfFindFile($title) != false) : false;
// //
// if ( ( $wgUploadMissingFileUrl || $wgUploadNavigationUrl || $wgEnableUploads ) // if (($wgUploadMissingFileUrl || $wgUploadNavigationUrl || $wgEnableUploads)
// && !$currentExists // && !$currentExists
// ) { // ) {
// $redir = RepoGroup::singleton()->getLocalRepo()->checkRedirect( $title ); // $redir = RepoGroup::singleton()->getLocalRepo()->checkRedirect($title);
// //
// if ( $redir ) { // if ($redir) {
// // We already know it's a redirect, so mark it // // We already know it's a redirect, so mark it
// // accordingly // // accordingly
// return self::link( // return self::link(
// $title, // $title,
// $encLabel, // $encLabel,
// [ 'class' => 'mw-redirect' ], // [ 'class' => 'mw-redirect' ],
// wfCgiToArray( $query ), // wfCgiToArray($query),
// [ 'known', 'noclasses' ] // [ 'known', 'noclasses' ]
// ); // );
// } // }
// //
// $href = self::getUploadUrl( $title, $query ); // $href = self::getUploadUrl($title, $query);
// //
// return '<a href="' . htmlspecialchars( $href ) . '" class="new" title="' . // return '<a href="' . htmlspecialchars($href) . '" class="new" title="' .
// htmlspecialchars( $title->getPrefixedText(), ENT_QUOTES ) . '">' . // htmlspecialchars($title->getPrefixedText(), ENT_QUOTES) . '">' .
// $encLabel . '</a>'; // $encLabel . '</a>';
// } // }
// //
// return self::link( $title, $encLabel, [], wfCgiToArray( $query ), [ 'known', 'noclasses' ] ); // return self::link($title, $encLabel, [], wfCgiToArray($query), [ 'known', 'noclasses' ]);
// } // }
// /** // // Create a direct link to a given uploaded file.
// * Create a direct link to a given uploaded file. // public static function makeMediaLinkObj($title, $html = '', $time = false) {
// * // $img = wfFindFile($title, [ 'time' => $time ]);
// * @since 1.16.3 // return self::makeMediaLinkFile($title, $img, $html);
// * @param Title $title
// * @param String $html Pre-sanitized HTML
// * @param String $time MW timestamp of file creation time
// * @return String HTML
// */
// public static function makeMediaLinkObj( $title, $html = '', $time = false ) {
// $img = wfFindFile( $title, [ 'time' => $time ] );
// return self::makeMediaLinkFile( $title, $img, $html );
// } // }
// //
// /** // // Create a direct link to a given uploaded file.
// * Create a direct link to a given uploaded file. // // This will make a broken link if $file is false.
// * This will make a broken link if $file is false. // public static function makeMediaLinkFile(Title $title, $file, $html = '') {
// * // if ($file && $file->exists()) {
// * @since 1.16.3
// * @param Title $title
// * @param File|boolean $file File Object or false
// * @param String $html Pre-sanitized HTML
// * @return String HTML
// *
// * @todo Handle invalid or missing images better.
// */
// public static function makeMediaLinkFile( Title $title, $file, $html = '' ) {
// if ( $file && $file->exists() ) {
// $url = $file->getUrl(); // $url = $file->getUrl();
// $class = '@gplx.Internal protected'; // $class = '@gplx.Internal protected';
// } else { // } else {
// $url = self::getUploadUrl( $title ); // $url = self::getUploadUrl($title);
// $class = 'new'; // $class = 'new';
// } // }
// //
// $alt = $title->getText(); // $alt = $title->getText();
// if ( $html == '' ) { // if ($html == '') {
// $html = $alt; // $html = $alt;
// } // }
// //
@ -788,21 +733,34 @@ public class Xomw_linker {
// 'title' => $alt // 'title' => $alt
// ]; // ];
// //
// if ( !Hooks::run( 'LinkerMakeMediaLinkFile', // if (!Hooks::run('LinkerMakeMediaLinkFile',
// [ $title, $file, &$html, &$attribs, &$ret ] ) ) { // [ $title, $file, &$html, &$attribs, &$ret ])) {
// wfDebug( "Hook LinkerMakeMediaLinkFile changed the output of link " // wfDebug("Hook LinkerMakeMediaLinkFile changed the output of link "
// . "with url {$url} and text {$html} to {$ret}\n", true ); // . "with url {$url} and text {$html} to {$ret}\n", true);
// return $ret; // return $ret;
// } // }
// //
// return Html::rawElement( 'a', $attribs, $html ); // return Html::rawElement('a', $attribs, $html);
// } // }
public static Xoa_ttl Normalise_special_page(Xoa_ttl target) {
// if (target.Ns().Id_is_special() && !target.Is_external()) {
// list($name, $subpage) = SpecialPageFactory::resolveAlias($target->getDBkey());
// if (!$name) {
// return $target;
// }
// $ret = SpecialPage::getTitleValueFor($name, $subpage, $target->getFragment());
// return $ret;
// }
// else {
return target;
// }
}
private static final byte[] Bry__dot2 = Bry_.new_a7("../"); private static final byte[] Bry__dot2 = Bry_.new_a7("../");
} }
class Linker_rel_splitter implements gplx.core.brys.Bry_split_wkr { class Linker_rel_splitter implements gplx.core.brys.Bry_split_wkr {
private final Hash_adp_bry hash = Hash_adp_bry.cs(); private final Hash_adp_bry hash = Hash_adp_bry.cs();
private final Bry_bfr bfr = Bry_bfr_.New(); private final Bry_bfr bfr = Bry_bfr_.New();
public int Split(byte[] src, int itm_bgn, int itm_end) { // $combined = array_unique( array_merge( $newRels, $oldRels ) ); public int Split(byte[] src, int itm_bgn, int itm_end) { // $combined = array_unique(array_merge($newRels, $oldRels));
byte[] val = (byte[])hash.Get_by_mid(src, itm_bgn, itm_end); byte[] val = (byte[])hash.Get_by_mid(src, itm_bgn, itm_end);
if (val == null) { if (val == null) {
val = Bry_.Mid(src, itm_bgn, itm_end); val = Bry_.Mid(src, itm_bgn, itm_end);

@ -28,7 +28,7 @@ public class Xomw_linker__normalize_subpage_link__tst {
@Test public void Dot2__trailing() {fxt.Test__normalize_subpage_link("A/B/C" , "../../Z/" , "" , "A/Z" , "Z");} @Test public void Dot2__trailing() {fxt.Test__normalize_subpage_link("A/B/C" , "../../Z/" , "" , "A/Z" , "Z");}
} }
class Xomw_linker__normalize_subpage_link__fxt { class Xomw_linker__normalize_subpage_link__fxt {
private final Xomw_linker mgr = new Xomw_linker(); private final Xomw_linker mgr = new Xomw_linker(new gplx.xowa.mws.linkers.Xomw_link_renderer());
private final Xowe_wiki wiki; private final Xowe_wiki wiki;
private final Xomw_linker__normalize_subpage_link normalize_subpage_link = new Xomw_linker__normalize_subpage_link(); private final Xomw_linker__normalize_subpage_link normalize_subpage_link = new Xomw_linker__normalize_subpage_link();
public Xomw_linker__normalize_subpage_link__fxt() { public Xomw_linker__normalize_subpage_link__fxt() {

@ -23,7 +23,7 @@ public class Xomw_linker__split_trail__tst {
@Test public void None() {fxt.Test__split_trail(" abc" , null , " abc");} @Test public void None() {fxt.Test__split_trail(" abc" , null , " abc");}
} }
class Xomw_linker__split_trail__fxt { class Xomw_linker__split_trail__fxt {
private final Xomw_linker linker = new Xomw_linker(); private final Xomw_linker linker = new Xomw_linker(new gplx.xowa.mws.linkers.Xomw_link_renderer());
private final Btrie_slim_mgr trie = Btrie_slim_mgr.cs(); private final Btrie_slim_mgr trie = Btrie_slim_mgr.cs();
public Xomw_linker__split_trail__fxt() { public Xomw_linker__split_trail__fxt() {
String[] ary = new String[] {"a", "b", "c", "d", "e", "f"}; String[] ary = new String[] {"a", "b", "c", "d", "e", "f"};

@ -16,8 +16,8 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package gplx.xowa.mws.htmls; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; package gplx.xowa.mws.htmls; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
public class Xomwh_atr_itm { public class Xomw_atr_itm {
public Xomwh_atr_itm(int key_int, byte[] key, byte[] val) { public Xomw_atr_itm(int key_int, byte[] key, byte[] val) {
this.key_int = key_int; this.key_int = key_int;
this.key_bry = key; this.key_bry = key;
this.val = val; this.val = val;

@ -16,38 +16,45 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package gplx.xowa.mws.htmls; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; package gplx.xowa.mws.htmls; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
public class Xomwh_atr_mgr { public class Xomw_atr_mgr {
private final Ordered_hash hash = Ordered_hash_.New(); private final Ordered_hash hash = Ordered_hash_.New();
public int Len() {return hash.Len();} public int Len() {return hash.Len();}
public Xomwh_atr_itm Get_at(int i) {return (Xomwh_atr_itm)hash.Get_at(i);} public Xomw_atr_itm Get_at(int i) {return (Xomw_atr_itm)hash.Get_at(i);}
public Xomwh_atr_mgr Clear() {hash.Clear(); return this;} public Xomw_atr_mgr Clear() {hash.Clear(); return this;}
public void Add(byte[] key, byte[] val) {hash.Add(key, new Xomwh_atr_itm(-1, key, val));} public void Add(byte[] key, byte[] val) {hash.Add(key, new Xomw_atr_itm(-1, key, val));}
public void Add(Xomwh_atr_itm itm) {hash.Add(itm.Key_bry(), itm);} public void Add(Xomw_atr_itm itm) {hash.Add(itm.Key_bry(), itm);}
public void Del(byte[] key) {hash.Del(key);} public void Del(byte[] key) {hash.Del(key);}
public void Set(byte[] key, byte[] val) { public void Set(byte[] key, byte[] val) {
Xomwh_atr_itm atr = Get_by_or_make(key); Xomw_atr_itm atr = Get_by_or_make(key);
atr.Val_(val); atr.Val_(val);
} }
public void Add_or_set(Xomwh_atr_itm src) { public void Add_or_set(Xomw_atr_itm src) {
Xomwh_atr_itm trg = (Xomwh_atr_itm)hash.Get_by(src.Key_bry()); Xomw_atr_itm trg = (Xomw_atr_itm)hash.Get_by(src.Key_bry());
if (trg == null) if (trg == null)
this.Add(src); this.Add(src);
else else
trg.Val_(src.Val()); trg.Val_(src.Val());
} }
public Xomwh_atr_itm Get_by_or_null(byte[] k) { public Xomw_atr_itm Get_by_or_null(byte[] k) {
return (Xomwh_atr_itm)hash.Get_by(k); return (Xomw_atr_itm)hash.Get_by(k);
} }
public Xomwh_atr_itm Get_by_or_make(byte[] k) { public Xomw_atr_itm Get_by_or_make(byte[] k) {
Xomwh_atr_itm rv = (Xomwh_atr_itm)hash.Get_by(k); Xomw_atr_itm rv = (Xomw_atr_itm)hash.Get_by(k);
if (rv == null) { if (rv == null) {
rv = new Xomwh_atr_itm(-1, k, null); rv = new Xomw_atr_itm(-1, k, null);
Add(rv); Add(rv);
} }
return rv; return rv;
} }
public byte[] Get_val_or_null(byte[] k) { public byte[] Get_val_or_null(byte[] k) {
Xomwh_atr_itm atr = (Xomwh_atr_itm)hash.Get_by(k); Xomw_atr_itm atr = (Xomw_atr_itm)hash.Get_by(k);
return atr == null ? null : atr.Val(); return atr == null ? null : atr.Val();
} }
public void Merge(Xomw_atr_mgr src) {
int src_len = src.Len();
for (int i = 0; i < src_len; i++) {
Xomw_atr_itm src_atr = src.Get_at(i);
this.Add(src_atr);
}
}
} }

@ -21,7 +21,7 @@ import gplx.langs.phps.utls.*;
public class Xomw_html_utl { public class Xomw_html_utl {
private final Bry_bfr tmp = Bry_bfr_.New(); private final Bry_bfr tmp = Bry_bfr_.New();
private final Btrie_rv trv = new Btrie_rv(); private final Btrie_rv trv = new Btrie_rv();
public void Raw_element(Bry_bfr bfr, byte[] element, Xomwh_atr_mgr attribs, byte[] contents) { public void Raw_element(Bry_bfr bfr, byte[] element, Xomw_atr_mgr attribs, byte[] contents) {
Bry_.Lcase__all(element); // XO:lcase element Bry_.Lcase__all(element); // XO:lcase element
Open_element__lcased(bfr, element, attribs); Open_element__lcased(bfr, element, attribs);
@ -33,7 +33,7 @@ public class Xomw_html_utl {
Close_element__lcased(bfr, element); Close_element__lcased(bfr, element);
} }
} }
private void Open_element__lcased(Bry_bfr bfr, byte[] element, Xomwh_atr_mgr attribs) { private void Open_element__lcased(Bry_bfr bfr, byte[] element, Xomw_atr_mgr attribs) {
// This is not required in HTML5, but let's do it anyway, for // This is not required in HTML5, but let's do it anyway, for
// consistency and better compression. // consistency and better compression.
// $element = strtolower($element); // XO:handled by callers // $element = strtolower($element); // XO:handled by callers
@ -58,10 +58,10 @@ public class Xomw_html_utl {
Expand_attributes(bfr, attribs); // TODO.XO:self::dropDefaults($element, $attribs) Expand_attributes(bfr, attribs); // TODO.XO:self::dropDefaults($element, $attribs)
bfr.Add_byte(Byte_ascii.Angle_end); bfr.Add_byte(Byte_ascii.Angle_end);
} }
public void Expand_attributes(Bry_bfr bfr, Xomwh_atr_mgr atrs) { public void Expand_attributes(Bry_bfr bfr, Xomw_atr_mgr atrs) {
int len = atrs.Len(); int len = atrs.Len();
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
Xomwh_atr_itm atr = (Xomwh_atr_itm)atrs.Get_at(i); Xomw_atr_itm atr = (Xomw_atr_itm)atrs.Get_at(i);
byte[] key = atr.Key_bry(); byte[] key = atr.Key_bry();
byte[] val = atr.Val(); byte[] val = atr.Val();

@ -25,12 +25,12 @@ class Xomw_html_utl__expand_attributes__fxt {
private final Xomw_html_utl utl = new Xomw_html_utl(); private final Xomw_html_utl utl = new Xomw_html_utl();
private final Bry_bfr bfr = Bry_bfr_.New(); private final Bry_bfr bfr = Bry_bfr_.New();
public void Test__expand_attributes(String expd, String... kvs) { public void Test__expand_attributes(String expd, String... kvs) {
Xomwh_atr_mgr atrs = new Xomwh_atr_mgr(); Xomw_atr_mgr atrs = new Xomw_atr_mgr();
int kvs_len = kvs.length; int kvs_len = kvs.length;
for (int i = 0; i < kvs_len; i += 2) { for (int i = 0; i < kvs_len; i += 2) {
byte[] key = Bry_.new_a7(kvs[i]); byte[] key = Bry_.new_a7(kvs[i]);
byte[] val = Bry_.new_a7(kvs[i + 1]); byte[] val = Bry_.new_a7(kvs[i + 1]);
Xomwh_atr_itm itm = new Xomwh_atr_itm(-1, key, val); Xomw_atr_itm itm = new Xomw_atr_itm(-1, key, val);
atrs.Add(itm); atrs.Add(itm);
} }
utl.Expand_attributes(bfr, atrs); utl.Expand_attributes(bfr, atrs);

@ -0,0 +1,23 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.mws.htmls; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
public class Xomw_opt_mgr {
public boolean known;
public boolean broken;
public boolean no_classes;
}

@ -0,0 +1,27 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.mws.htmls; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
public class Xomw_qry_mgr {
public byte[] action;
public int redlink;
public Xomw_qry_mgr Clear() {
action = null;
redlink = -1;
return this;
}
}

@ -18,31 +18,46 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.mws.linkers; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*; package gplx.xowa.mws.linkers; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
import gplx.langs.htmls.*; import gplx.langs.htmls.*;
import gplx.xowa.mws.htmls.*; import gplx.xowa.mws.htmls.*;
/* TODO.XO
* titleFormatter->gePrefixedTex
* $html = HtmlArmor::getHtml($text);
* Get_link_url
* Normalise_special_page
* Merge_attribs
* Get_link_classes
*/
public class Xomw_link_renderer { public class Xomw_link_renderer {
private boolean expand_urls = false; private boolean expand_urls = false;
private final Xomw_html_utl html_utl = new Xomw_html_utl(); private final Xomw_html_utl html_utl = new Xomw_html_utl();
private final Xomwh_atr_mgr attribs = new Xomwh_atr_mgr(); private final Xomw_atr_mgr attribs = new Xomw_atr_mgr();
// XO.MW:SYNC:1.29; DATE:2017-01-31
public void Make_link(Bry_bfr bfr, Xoa_ttl target, byte[] text, byte[] classes, Xomw_atr_mgr extra_atrs, Xomw_qry_mgr query) {
if (target.Is_known()) {
this.Make_known_link(bfr, target, text, extra_atrs, query);
} else {
this.Make_broken_link(bfr, target, text, extra_atrs, query);
}
}
// If you have already looked up the proper CSS classes using LinkRenderer::getLinkClasses() // If you have already looked up the proper CSS classes using LinkRenderer::getLinkClasses()
// or some other method, use this to avoid looking it up again. // or some other method, use this to avoid looking it up again.
public void Make_preloaded_link(Bry_bfr bfr, Xoa_ttl target, byte[] text, byte[] classes, Xomwh_atr_mgr extra_atrs, byte[] query) { // XO.MW:SYNC:1.29; DATE:2017-01-31
// IGNORE: $this->runBeginHook --> 'HtmlPageLinkRendererBegin', 'LinkBegin' public void Make_preloaded_link(Bry_bfr bfr, Xoa_ttl target, byte[] text, byte[] classes, Xomw_atr_mgr extra_atrs, Xomw_qry_mgr query) {
// XO.MW.HOOK: $this->runBeginHook --> 'HtmlPageLinkRendererBegin', 'LinkBegin'
// $target = $this->normalizeTarget( $target ); // normalizeSpecialPage target = Normalize_target(target);
byte[] url = Get_link_url(target, query); byte[] url = Get_link_url(target, query);
attribs.Clear(); attribs.Clear();
attribs.Add(Gfh_atr_.Bry__href, url); // NOTE: add url 1st; MW does attribs["url", url] + attribs + extra_attribs attribs.Add(Gfh_atr_.Bry__href, url); // XO.MW: add url 1st; MW does attribs["url", url] + attribs + extra_attribs
if (classes.length > 0) // XO:do not bother adding if empty if (classes.length > 0) // XO.MW:do not bother adding if empty
attribs.Add(Gfh_atr_.Bry__class, classes); attribs.Add(Gfh_atr_.Bry__class, classes);
byte[] prefixed_text = target.Get_prefixed_text(); byte[] prefixed_text = target.Get_prefixed_text();
if (prefixed_text != Bry_.Empty) { if (prefixed_text != Bry_.Empty) {
attribs.Add(Gfh_atr_.Bry__title, prefixed_text); attribs.Add(Gfh_atr_.Bry__title, prefixed_text);
} }
int extra_atrs_len = extra_atrs.Len(); attribs.Merge(extra_atrs);
for (int i = 0; i < extra_atrs_len; i++) {
attribs.Add_or_set(extra_atrs.Get_at(i));
}
if (text == null) { if (text == null) {
text = this.Get_link_text(target); text = this.Get_link_text(target);
@ -50,32 +65,68 @@ public class Xomw_link_renderer {
Build_a_element(bfr, target,text, attribs, true); Build_a_element(bfr, target,text, attribs, true);
} }
private void Build_a_element(Bry_bfr bfr, Xoa_ttl target, byte[] text, Xomwh_atr_mgr attribs, boolean is_known) {
// IGNORE: if ( !Hooks::run( 'HtmlPageLinkRendererEnd',
byte[] html = text; // XO.MW:SYNC:1.29; DATE:2017-01-31
// $html = HtmlArmor::getHtml( $text ); public void Make_known_link(Bry_bfr bfr, Xoa_ttl target, byte[] text, Xomw_atr_mgr extra_atrs, Xomw_qry_mgr query) {
byte[] classes = Bry_.Empty;
if (target.Is_external()) {
classes = Bry__classes__extiw;
}
byte[] colour = Get_link_classes(target);
if (colour != Bry_.Empty) {
classes = Bry_.Add(classes, Byte_ascii.Space_bry, colour);
}
Make_preloaded_link(bfr, target, text, classes, extra_atrs, query);
}
// XO.MW:SYNC:1.29; DATE:2017-01-31
public void Make_broken_link(Bry_bfr bfr, Xoa_ttl target, byte[] text, Xomw_atr_mgr extra_atrs, Xomw_qry_mgr query) {
// XO.MW.HOOK: Run legacy hook
// IGNORE: if ( Hooks::isRegistered( 'LinkEnd' ) ) { // We don't want to include fragments for broken links, because they
// generally make no sense.
if (target.Has_fragment()) {
target = target.Create_fragment_target();
}
target = Normalize_target(target);
html_utl.Raw_element(bfr, Gfh_tag_.Bry__a, attribs, html); if (query.action == null && target.Ns().Id() != gplx.xowa.wikis.nss.Xow_ns_.Tid__special) {
query.action = Bry_.new_a7("edit");
query.redlink = 1;
} }
private byte[] Get_link_url(Xoa_ttl target, byte[] query) {
// TODO: Use a LinkTargetResolver service instead of Title
// if ( $this->forceArticlePath ) {
// $realQuery = $query;
// $query = [];
// }
// else {
// $realQuery = [];
// }
byte[] url = target.Get_link_url(query, false, expand_urls);
// if ( $this->forceArticlePath && $realQuery ) { byte[] url = Get_link_url(target, query);
// $url = wfAppendQuery( $url, $realQuery ); attribs.Clear();
// } attribs.Add(Gfh_atr_.Bry__href, url); // $attribs = ['href' => $url,] + $this->mergeAttribs($attribs, $extraAttribs);
return url; attribs.Add(Gfh_atr_.Bry__class, Bry_.new_a7("new"));
attribs.Merge(extra_atrs);
// $prefixedText = $this->titleFormatter->getPrefixedText($target);
// if ($prefixedText !== '') {
// // This ends up in parser cache!
// $attribs['title'] = wfMessage('red-link-title', $prefixedText)
// ->inContentLanguage()
// ->text();
// }
if (text == null) {
text = Get_link_text(target);
}
Build_a_element(bfr, target, text, attribs, false);
} }
// XO.MW:SYNC:1.29; DATE:2017-01-31
private void Build_a_element(Bry_bfr bfr, Xoa_ttl target, byte[] text, Xomw_atr_mgr attribs, boolean is_known) {
// XO.MW.HOOK:HtmlPageLinkRendererEnd
byte[] html = text;
// $html = HtmlArmor::getHtml($text);
// XO.MW.HOOK:LinkEnd
html_utl.Raw_element(bfr, Gfh_tag_.Bry__a, attribs, html);
}
// XO.MW:SYNC:1.29; DATE:2017-01-31
private byte[] Get_link_text(Xoa_ttl target) { private byte[] Get_link_text(Xoa_ttl target) {
byte[] prefixed_text = target.Get_prefixed_text(); byte[] prefixed_text = target.Get_prefixed_text();
// If the target is just a fragment, with no title, we return the fragment // If the target is just a fragment, with no title, we return the fragment
@ -85,48 +136,57 @@ public class Xomw_link_renderer {
} }
return prefixed_text; return prefixed_text;
} }
// private function normalizeTarget( LinkTarget $target ) { private byte[] Get_link_url(Xoa_ttl target, Xomw_qry_mgr query) {
// return Linker::normaliseSpecialPage( $target ); // TODO: Use a LinkTargetResolver service instead of Title
// }
// public static function normaliseSpecialPage( LinkTarget $target ) { // if ($this->forceArticlePath) {
// if ( $target->getNamespace() == NS_SPECIAL && !$target->isExternal() ) { // $realQuery = $query;
// list( $name, $subpage ) = SpecialPageFactory::resolveAlias( $target->getDBkey() ); // $query = [];
// if ( !$name ) {
// return $target;
// } // }
// $ret = SpecialPage::getTitleValueFor( $name, $subpage, $target->getFragment() ); // else {
// return $ret; // $realQuery = [];
// } else {
// return $target;
// } // }
byte[] url = target.Get_link_url(query, false, expand_urls);
// if ($this->forceArticlePath && $realQuery) {
// $url = wfAppendQuery($url, $realQuery);
// } // }
private static final byte[] Bry__classes__extiw = Bry_.new_a7("extiw"); return url;
public void Make_known_link(Bry_bfr bfr, Xoa_ttl target, byte[] text, Xomwh_atr_mgr extra_atrs, byte[] query) {
byte[] classes = Bry_.Empty;
if (target.Is_external()) {
classes = Bry__classes__extiw;
}
byte[] colour = Get_link_classes(target);
if (colour != Bry_.Empty) {
classes = Bry_.Add(classes, Byte_ascii.Space_bry, colour);
} }
// XO.MW:SYNC:1.29; DATE:2017-01-31
Make_preloaded_link(bfr, target, text, classes, extra_atrs, query); private Xoa_ttl Normalize_target(Xoa_ttl target) {
return Xomw_linker.Normalise_special_page(target);
} }
// private function mergeAttribs( $defaults, $attribs ) {
// if ( !$attribs ) {
// return $defaults;
// }
// // Merge the custom attribs with the default ones, and iterate
// // over that, deleting all "false" attributes.
// $ret = [];
// $merged = Sanitizer::mergeAttributes( $defaults, $attribs );
// foreach ( $merged as $key => $val ) {
// # A false value suppresses the attribute
// if ( $val !== false ) {
// $ret[$key] = $val;
// }
// }
// return $ret;
// }
public byte[] Get_link_classes(Xoa_ttl target) { public byte[] Get_link_classes(Xoa_ttl target) {
// Make sure the target is in the cache // Make sure the target is in the cache
// $id = $this->linkCache->addLinkObj( $target ); // $id = $this->linkCache->addLinkObj($target);
// if ( $id == 0 ) { // if ($id == 0) {
// // Doesn't exist // // Doesn't exist
// return ''; // return '';
// } // }
// if ( $this->linkCache->getGoodLinkFieldObj( $target, 'redirect' ) ) { // if ($this->linkCache->getGoodLinkFieldObj($target, 'redirect')) {
// Page is a redirect // Page is a redirect
// return 'mw-redirect'; // return 'mw-redirect';
// } // }
// elseif ( $this->stubThreshold > 0 && MWNamespace::isContent( $target->getNamespace() ) // elseif ($this->stubThreshold > 0 && MWNamespace::isContent($target->getNamespace())
// && $this->linkCache->getGoodLinkFieldObj( $target, 'length' ) < $this->stubThreshold // && $this->linkCache->getGoodLinkFieldObj($target, 'length') < $this->stubThreshold
// ) { // ) {
// Page is a stub // Page is a stub
// return 'stub'; // return 'stub';
@ -134,4 +194,5 @@ public class Xomw_link_renderer {
return Bry_.Empty; return Bry_.Empty;
} }
private static final byte[] Bry__classes__extiw = Bry_.new_a7("extiw");
} }

@ -0,0 +1,35 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.mws.linkers; import gplx.*; import gplx.xowa.*; import gplx.xowa.mws.*;
// import org.junit.*;
// public class Xomw_link_renderer__tst {
// private final Xomw_link_renderer__fxt fxt = new Xomw_link_renderer__fxt();
/*
Make_broken_link
target.Has_fragment()
*/
// }
// class Xomw_link_renderer__fxt {
// private final Xomw_link_renderer wkr = new Xomw_link_renderer(new Xomw_parser());
// public void Test__parse(String src_str, String expd) {
// byte[] src_bry = Bry_.new_u8(src_str);
// wkr.Replace_external_links(new Xomw_parser_ctx(), pbfr.Init(src_bry));
// if (apos) expd = gplx.langs.htmls.Gfh_utl.Replace_apos(expd);
// Tfds.Eq_str_lines(expd, pbfr.Rslt().To_str_and_clear(), src_str);
// }
// }

@ -25,7 +25,8 @@ public class Xomw_link_holders {
private final Bry_bfr tmp; private final Bry_bfr tmp;
private int link_id = 0; // MOVED:Parser.php private int link_id = 0; // MOVED:Parser.php
private final Xomw_link_holder_list internals = new Xomw_link_holder_list(); private final Xomw_link_holder_list internals = new Xomw_link_holder_list();
private final Xomwh_atr_mgr extra_atrs = new Xomwh_atr_mgr(); private final Xomw_atr_mgr extra_atrs = new Xomw_atr_mgr();
private final Xomw_qry_mgr query = new Xomw_qry_mgr();
public Xomw_link_holders(Xomw_link_renderer link_renderer, Bry_bfr tmp) { public Xomw_link_holders(Xomw_link_renderer link_renderer, Bry_bfr tmp) {
this.link_renderer = link_renderer; this.link_renderer = link_renderer;
this.tmp = tmp; this.tmp = tmp;
@ -136,7 +137,7 @@ public class Xomw_link_holders {
// } // }
bfr.Add_mid(src, prv, link_bgn); bfr.Add_mid(src, prv, link_bgn);
link_renderer.Make_preloaded_link(bfr, item.Title(), item.Text(), Bry_.Empty, extra_atrs, Bry_.Empty); link_renderer.Make_preloaded_link(bfr, item.Title(), item.Text(), Bry_.Empty, extra_atrs, query.Clear());
cur = key_end + Gfh_tag_.Comm_end_len; cur = key_end + Gfh_tag_.Comm_end_len;
prv = cur; prv = cur;
} }

@ -45,7 +45,7 @@ public class Xomw_parser {
// private final Xomw_prepro_wkr prepro_wkr = new Xomw_prepro_wkr(); // private final Xomw_prepro_wkr prepro_wkr = new Xomw_prepro_wkr();
public Xomw_strip_state Strip_state() {return strip_state;} private final Xomw_strip_state strip_state = new Xomw_strip_state(); public Xomw_strip_state Strip_state() {return strip_state;} private final Xomw_strip_state strip_state = new Xomw_strip_state();
public Xomw_sanitizer Sanitizer() {return sanitizer;} private final Xomw_sanitizer sanitizer = new Xomw_sanitizer(); public Xomw_sanitizer Sanitizer() {return sanitizer;} private final Xomw_sanitizer sanitizer = new Xomw_sanitizer();
public Xomw_linker Linker() {return linker;} private final Xomw_linker linker = new Xomw_linker(); public Xomw_linker Linker() {return linker;} private final Xomw_linker linker;
public Bry_bfr Tmp() {return tmp;} private final Bry_bfr tmp = Bry_bfr_.New(); public Bry_bfr Tmp() {return tmp;} private final Bry_bfr tmp = Bry_bfr_.New();
public Xomw_quote_wkr Quote_wkr() {return quote_wkr;} private final Xomw_quote_wkr quote_wkr; public Xomw_quote_wkr Quote_wkr() {return quote_wkr;} private final Xomw_quote_wkr quote_wkr;
public Xomw_lnki_wkr Lnki_wkr() {return lnki_wkr;} private final Xomw_lnki_wkr lnki_wkr; public Xomw_lnki_wkr Lnki_wkr() {return lnki_wkr;} private final Xomw_lnki_wkr lnki_wkr;
@ -61,6 +61,7 @@ public class Xomw_parser {
} }
} }
this.linker = new Xomw_linker(link_renderer);
this.protocols_trie = Xomw_parser.Protocols__dflt(); this.protocols_trie = Xomw_parser.Protocols__dflt();
this.holders = new Xomw_link_holders(link_renderer, tmp); this.holders = new Xomw_link_holders(link_renderer, tmp);
this.table_wkr = new Xomw_table_wkr(this); this.table_wkr = new Xomw_table_wkr(this);
@ -266,7 +267,7 @@ public class Xomw_parser {
strip_state.Add_general(marker, text); strip_state.Add_general(marker, text);
return marker; return marker;
} }
public Xomwh_atr_mgr Get_external_link_attribs(Xomwh_atr_mgr atrs) { public Xomw_atr_mgr Get_external_link_attribs(Xomw_atr_mgr atrs) {
atrs.Clear(); atrs.Clear();
byte[] rel = Get_external_link_rel; byte[] rel = Get_external_link_rel;

@ -26,7 +26,7 @@ public class Xomw_lnke_wkr {// THREAD.UNSAFE: caching for repeated calls
private int autonumber; private int autonumber;
private final Xomw_parser parser; private final Xomw_parser parser;
private final Xomw_linker linker; private final Xomw_linker linker;
private final Xomwh_atr_mgr attribs = new Xomwh_atr_mgr(); private final Xomw_atr_mgr attribs = new Xomw_atr_mgr();
private Xomw_regex_url regex_url; private Xomw_regex_url regex_url;
private Xomw_regex_space regex_space; private Xomw_regex_space regex_space;
public Xomw_lnke_wkr(Xomw_parser parser) { public Xomw_lnke_wkr(Xomw_parser parser) {

@ -35,7 +35,8 @@ public class Xomw_lnki_wkr {// THREAD.UNSAFE: caching for repeated calls
private final Xomw_linker__normalize_subpage_link normalize_subpage_link = new Xomw_linker__normalize_subpage_link(); private final Xomw_linker__normalize_subpage_link normalize_subpage_link = new Xomw_linker__normalize_subpage_link();
private final Bry_bfr tmp; private final Bry_bfr tmp;
private final Xomw_parser parser; private final Xomw_parser parser;
private final Xomwh_atr_mgr extra_atrs = new Xomwh_atr_mgr(); private final Xomw_atr_mgr extra_atrs = new Xomw_atr_mgr();
private final Xomw_qry_mgr query = new Xomw_qry_mgr();
public Xomw_lnki_wkr(Xomw_parser parser, Xomw_link_holders holders, Xomw_link_renderer link_renderer, Btrie_slim_mgr protocols_trie) { public Xomw_lnki_wkr(Xomw_parser parser, Xomw_link_holders holders, Xomw_link_renderer link_renderer, Btrie_slim_mgr protocols_trie) {
this.parser = parser; this.parser = parser;
this.holders = holders; this.holders = holders;
@ -436,7 +437,7 @@ public class Xomw_lnki_wkr {// THREAD.UNSAFE: caching for repeated calls
tmp.Add_bry_escape_html(inside); tmp.Add_bry_escape_html(inside);
text = tmp.To_bry_and_clear(); text = tmp.To_bry_and_clear();
link_renderer.Make_known_link(bfr, nt, text, extra_atrs, Bry_.Empty); link_renderer.Make_known_link(bfr, nt, text, extra_atrs, query);
byte[] link = bfr.To_bry_and_clear(); byte[] link = bfr.To_bry_and_clear();
parser.Armor_links(bfr, link, 0, link.length); parser.Armor_links(bfr, link, 0, link.length);
bfr.Add(trail); bfr.Add(trail);

@ -19,7 +19,6 @@ package gplx.xowa.mws.parsers.magiclinks; import gplx.*; import gplx.xowa.*; imp
import gplx.core.primitives.*; import gplx.core.btries.*; import gplx.core.net.*; import gplx.core.primitives.*; import gplx.core.btries.*; import gplx.core.net.*;
import gplx.langs.phps.utls.*; import gplx.xowa.mws.htmls.*; import gplx.langs.phps.utls.*; import gplx.xowa.mws.htmls.*;
import gplx.langs.regxs.*; import gplx.langs.regxs.*;
// TODO.XO: getExternalLinkAttribs($url)
// TODO.XO: this->getConverterLanguage()->markNoConversion($url, true), // TODO.XO: this->getConverterLanguage()->markNoConversion($url, true),
public class Xomw_magiclinks_wkr { public class Xomw_magiclinks_wkr {
private final Btrie_slim_mgr regex_trie = Btrie_slim_mgr.ci_a7(); // NOTE: must be ci to handle protocols; EX: "https:" and "HTTPS:" private final Btrie_slim_mgr regex_trie = Btrie_slim_mgr.ci_a7(); // NOTE: must be ci to handle protocols; EX: "https:" and "HTTPS:"
@ -32,7 +31,7 @@ public class Xomw_magiclinks_wkr {
private final Xomw_regex_url regex_url; private final Xomw_regex_url regex_url;
private final Xomw_sanitizer sanitizer; private final Xomw_sanitizer sanitizer;
private final Xomw_linker linker; private final Xomw_linker linker;
private final Xomwh_atr_mgr atrs = new Xomwh_atr_mgr(); private final Xomw_atr_mgr atrs = new Xomw_atr_mgr();
private byte[] page_title; private byte[] page_title;
private static final byte Regex__anch = 1, Regex__elem = 2, Regex__free = 3; private static final byte Regex__anch = 1, Regex__elem = 2, Regex__free = 3;

Loading…
Cancel
Save