mirror of
https://github.com/gnosygnu/xowa.git
synced 2024-10-27 20:34:16 +00:00
Mw_parse: Add merge_attributes
This commit is contained in:
parent
78526c00c6
commit
32b4fafe10
@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package gplx.xowa.files; import gplx.*; import gplx.xowa.*;
|
||||
import org.junit.*;
|
||||
public class Xof_file_wkr__tst {
|
||||
private final Xof_file_wkr___fxt fxt = new Xof_file_wkr___fxt();
|
||||
private final Xof_file_wkr___fxt fxt = new Xof_file_wkr___fxt();
|
||||
@Test public void Ttl_standardize() {
|
||||
fxt.Test__ttl_standardize("Abc.png" , "Abc.png"); // basic
|
||||
fxt.Test__ttl_standardize("A b.png" , "A_b.png"); // spaces -> unders
|
||||
|
@ -19,6 +19,12 @@ package gplx.xowa.mws; import gplx.*; import gplx.xowa.*;
|
||||
import gplx.core.btries.*;
|
||||
import gplx.xowa.mws.htmls.*;
|
||||
import gplx.xowa.mws.linkers.*;
|
||||
/* TODO.XO
|
||||
* titleFormatter->gePrefixedTex
|
||||
* $html = HtmlArmor::getHtml($text);
|
||||
* Get_link_url
|
||||
* Get_link_classes
|
||||
*/
|
||||
public class Xomw_linker {
|
||||
private final Bry_bfr tmp = Bry_bfr_.New();
|
||||
private final Linker_rel_splitter splitter = new Linker_rel_splitter();
|
||||
|
@ -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");}
|
||||
}
|
||||
class Xomw_linker__normalize_subpage_link__fxt {
|
||||
private final Xomw_linker mgr = new Xomw_linker(new gplx.xowa.mws.linkers.Xomw_link_renderer());
|
||||
private final Xomw_linker mgr = new Xomw_linker(new gplx.xowa.mws.linkers.Xomw_link_renderer(new Xomw_sanitizer()));
|
||||
private final Xowe_wiki wiki;
|
||||
private final Xomw_linker__normalize_subpage_link normalize_subpage_link = new Xomw_linker__normalize_subpage_link();
|
||||
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");}
|
||||
}
|
||||
class Xomw_linker__split_trail__fxt {
|
||||
private final Xomw_linker linker = new Xomw_linker(new gplx.xowa.mws.linkers.Xomw_link_renderer());
|
||||
private final Xomw_linker linker = new Xomw_linker(new gplx.xowa.mws.linkers.Xomw_link_renderer(new Xomw_sanitizer()));
|
||||
private final Btrie_slim_mgr trie = Btrie_slim_mgr.cs();
|
||||
public Xomw_linker__split_trail__fxt() {
|
||||
String[] ary = new String[] {"a", "b", "c", "d", "e", "f"};
|
||||
|
@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package gplx.xowa.mws; import gplx.*; import gplx.xowa.*;
|
||||
import gplx.core.brys.*; import gplx.core.btries.*; import gplx.core.encoders.*; import gplx.core.primitives.*; import gplx.langs.htmls.entitys.*;
|
||||
import gplx.xowa.parsers.htmls.*;
|
||||
import gplx.xowa.mws.parsers.*; import gplx.langs.phps.utls.*;
|
||||
import gplx.langs.htmls.*; import gplx.xowa.mws.htmls.*; import gplx.xowa.mws.parsers.*; import gplx.langs.phps.utls.*;
|
||||
public class Xomw_sanitizer {
|
||||
private final Mwh_doc_wkr__atr_bldr atr_bldr = new Mwh_doc_wkr__atr_bldr();
|
||||
private final Mwh_atr_parser atr_parser = new Mwh_atr_parser();
|
||||
@ -91,6 +91,50 @@ public class Xomw_sanitizer {
|
||||
}
|
||||
}
|
||||
|
||||
// Merge two sets of HTML attributes. Conflicting items in the second set
|
||||
// will override those in the first, except for 'class' attributes which
|
||||
// will be combined (if they're both strings).
|
||||
// XO.MW: XO does src += trg; MW does rv = src + trg;
|
||||
public void Merge_attributes(Xomw_atr_mgr src, Xomw_atr_mgr trg) {
|
||||
int trg_len = trg.Len();
|
||||
for (int i = 0; i < trg_len; i++) {
|
||||
Xomw_atr_itm trg_atr = trg.Get_at(i);
|
||||
// merge trg and src
|
||||
byte[] atr_cls = Gfh_atr_.Bry__class;
|
||||
if (Bry_.Eq(trg_atr.Key_bry(), atr_cls)) {
|
||||
Xomw_atr_itm src_atr = src.Get_by_or_null(atr_cls);
|
||||
if (src_atr != null) {
|
||||
// NOTE: need byte[]-creation is unavoidable b/c src_atr and trg_atr are non-null
|
||||
Merge_atrs_combine(tmp_bfr, src_atr.Val(), Byte_ascii.Space);
|
||||
tmp_bfr.Add_byte_space();
|
||||
Merge_atrs_combine(tmp_bfr, trg_atr.Val(), Byte_ascii.Space);
|
||||
src_atr.Val_(tmp_bfr.To_bry_and_clear());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
src.Add_or_set(trg_atr);
|
||||
}
|
||||
}
|
||||
private void Merge_atrs_combine(Bry_bfr trg, byte[] src, byte sep) {
|
||||
int src_len = src.length;
|
||||
for (int i = 0; i < src_len; i++) {
|
||||
byte b = src[i];
|
||||
if (b == sep) {
|
||||
// gobble ws; EX: "a b"
|
||||
int space_bgn = i;
|
||||
int space_end = Bry_find_.Find_fwd_while(src, i, src_len, sep);
|
||||
i = space_end - 1; // -1 b/c i++ above
|
||||
|
||||
// ignore ws at BOS; EX: " a"
|
||||
if (space_bgn == 0)
|
||||
continue;
|
||||
// ignore ws at EOS; EX: "a "
|
||||
if (space_end == src_len)
|
||||
break;
|
||||
}
|
||||
trg.Add_byte(b);
|
||||
}
|
||||
}
|
||||
public byte[] Clean_url(byte[] url) {
|
||||
// Normalize any HTML entities in input. They will be
|
||||
// re-escaped by makeExternalLink().
|
||||
|
@ -16,7 +16,7 @@ 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; import gplx.*; import gplx.xowa.*;
|
||||
import org.junit.*; import gplx.core.tests.*; import gplx.core.btries.*;
|
||||
import org.junit.*; import gplx.core.tests.*; import gplx.core.btries.*; import gplx.xowa.mws.htmls.*;
|
||||
public class Xomw_sanitizer__tst {
|
||||
private final Xomw_sanitizer__fxt fxt = new Xomw_sanitizer__fxt();
|
||||
@Test public void Normalize__text() {fxt.Test__normalize_char_references("abc" , "abc");}
|
||||
@ -107,6 +107,22 @@ public class Xomw_sanitizer__tst {
|
||||
// ipv6_brack
|
||||
fxt.Test__clean_url("http://[0a.1b:12]:123/cd" , "http://[0a.1b:12]:123/cd");
|
||||
}
|
||||
@Test public void Merge_atrs() {
|
||||
Xomw_atr_mgr src_atrs = new Xomw_atr_mgr();
|
||||
Xomw_atr_mgr trg_atrs = new Xomw_atr_mgr();
|
||||
Xomw_atr_mgr expd_atrs = new Xomw_atr_mgr();
|
||||
String cls = "class";
|
||||
// basic: k1 + k2
|
||||
fxt.Test__merge_attributes(src_atrs.Clear().Add_many("k1", "v1"), trg_atrs.Clear().Add_many("k2", "v2"), expd_atrs.Clear().Add_many("k1", "v1", "k2", "v2"));
|
||||
// overwrite: k1 + k1
|
||||
fxt.Test__merge_attributes(src_atrs.Clear().Add_many("k1", "v1"), trg_atrs.Clear().Add_many("k1", "v1a"), expd_atrs.Clear().Add_many("k1", "v1a"));
|
||||
// cls: many
|
||||
fxt.Test__merge_attributes(src_atrs.Clear().Add_many(cls, "v1 v2"), trg_atrs.Clear().Add_many(cls, "v3 v4"), expd_atrs.Clear().Add_many(cls, "v1 v2 v3 v4"));
|
||||
// cls: src.empty
|
||||
fxt.Test__merge_attributes(src_atrs.Clear(), trg_atrs.Clear().Add_many(cls, "v1"), expd_atrs.Clear().Add_many(cls, "v1"));
|
||||
// cls: ws
|
||||
fxt.Test__merge_attributes(src_atrs.Clear().Add_many(cls, " v1 v2 "), trg_atrs.Clear().Add_many(cls, " v3 v4 "), expd_atrs.Clear().Add_many(cls, "v1 v2 v3 v4"));
|
||||
}
|
||||
}
|
||||
class Xomw_sanitizer__fxt {
|
||||
private final Xomw_sanitizer sanitizer = new Xomw_sanitizer();
|
||||
@ -145,4 +161,8 @@ class Xomw_sanitizer__fxt {
|
||||
byte[] src_bry = Bry_.new_u8(src_str);
|
||||
Gftest.Eq__str(expd, sanitizer.Clean_url(src_bry));
|
||||
}
|
||||
public void Test__merge_attributes(Xomw_atr_mgr src, Xomw_atr_mgr trg, Xomw_atr_mgr expd) {
|
||||
sanitizer.Merge_attributes(src, trg);
|
||||
Gftest.Eq__ary__lines(expd.To_str(tmp), src.To_str(tmp), "merge_atrs");
|
||||
}
|
||||
}
|
||||
|
@ -17,17 +17,14 @@ 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_atr_mgr {
|
||||
private final Ordered_hash hash = Ordered_hash_.New();
|
||||
public int Len() {return hash.Len();}
|
||||
public Xomw_atr_itm Get_at(int i) {return (Xomw_atr_itm)hash.Get_at(i);}
|
||||
public Xomw_atr_mgr Clear() {hash.Clear(); return this;}
|
||||
public void Add(byte[] key, byte[] val) {hash.Add(key, new Xomw_atr_itm(-1, key, val));}
|
||||
public void Add(Xomw_atr_itm itm) {hash.Add(itm.Key_bry(), itm);}
|
||||
public void Del(byte[] key) {hash.Del(key);}
|
||||
public void Set(byte[] key, byte[] val) {
|
||||
Xomw_atr_itm atr = Get_by_or_make(key);
|
||||
atr.Val_(val);
|
||||
}
|
||||
private final Ordered_hash hash = Ordered_hash_.New_bry();
|
||||
public int Len() {return hash.Len();}
|
||||
public Xomw_atr_itm Get_at(int i) {return (Xomw_atr_itm)hash.Get_at(i);}
|
||||
public Xomw_atr_itm Get_by_or_null(byte[] k) {return (Xomw_atr_itm)hash.Get_by(k);}
|
||||
public Xomw_atr_mgr Clear() {hash.Clear(); return this;}
|
||||
public void Del(byte[] key) {hash.Del(key);}
|
||||
public void Add(Xomw_atr_itm itm) {hash.Add(itm.Key_bry(), itm);}
|
||||
public void Add(byte[] key, byte[] val) {this.Add(new Xomw_atr_itm(-1, key, val));}
|
||||
public void Add_or_set(Xomw_atr_itm src) {
|
||||
Xomw_atr_itm trg = (Xomw_atr_itm)hash.Get_by(src.Key_bry());
|
||||
if (trg == null)
|
||||
@ -35,8 +32,9 @@ public class Xomw_atr_mgr {
|
||||
else
|
||||
trg.Val_(src.Val());
|
||||
}
|
||||
public Xomw_atr_itm Get_by_or_null(byte[] k) {
|
||||
return (Xomw_atr_itm)hash.Get_by(k);
|
||||
public void Set(byte[] key, byte[] val) {
|
||||
Xomw_atr_itm atr = Get_by_or_make(key);
|
||||
atr.Val_(val);
|
||||
}
|
||||
public Xomw_atr_itm Get_by_or_make(byte[] k) {
|
||||
Xomw_atr_itm rv = (Xomw_atr_itm)hash.Get_by(k);
|
||||
@ -50,11 +48,22 @@ public class Xomw_atr_mgr {
|
||||
Xomw_atr_itm atr = (Xomw_atr_itm)hash.Get_by(k);
|
||||
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);
|
||||
public Xomw_atr_mgr Add_many(String... kvs) {// TEST
|
||||
int len = kvs.length;
|
||||
for (int i = 0; i < len; i += 2) {
|
||||
byte[] key = Bry_.new_u8(kvs[i]);
|
||||
byte[] val = Bry_.new_u8(kvs[i + 1]);
|
||||
Add(key, val);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
public String To_str(Bry_bfr tmp) { // TEST
|
||||
int len = this.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Xomw_atr_itm itm = this.Get_at(i);
|
||||
tmp.Add(itm.Key_bry()).Add_byte_eq();
|
||||
tmp.Add(itm.Val()).Add_byte_nl();
|
||||
}
|
||||
return tmp.To_str_and_clear();
|
||||
}
|
||||
}
|
||||
|
@ -19,18 +19,20 @@ package gplx.xowa.mws.linkers; import gplx.*; import gplx.xowa.*; import gplx.xo
|
||||
import gplx.langs.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
|
||||
* P7: $html = HtmlArmor::getHtml($text);
|
||||
* P3: Get_link_url [alternate urls? EX: mw/wiki/index.php/title?]
|
||||
* P2: titleFormatter->getPrefixedText [depends on redlinks]
|
||||
* P1: Get_link_classes [depends on redlinks]
|
||||
*/
|
||||
public class Xomw_link_renderer {
|
||||
private boolean expand_urls = false;
|
||||
private final Xomw_html_utl html_utl = new Xomw_html_utl();
|
||||
private final Xomw_atr_mgr attribs = new Xomw_atr_mgr();
|
||||
|
||||
private final List_adp tmp_merge_deleted = List_adp_.New();
|
||||
private final Xomw_sanitizer sanitizer;
|
||||
public Xomw_link_renderer(Xomw_sanitizer sanitizer) {
|
||||
this.sanitizer = sanitizer;
|
||||
}
|
||||
// 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()) {
|
||||
@ -57,7 +59,7 @@ public class Xomw_link_renderer {
|
||||
attribs.Add(Gfh_atr_.Bry__title, prefixed_text);
|
||||
}
|
||||
|
||||
attribs.Merge(extra_atrs);
|
||||
Merge_attribs(attribs, extra_atrs);
|
||||
|
||||
if (text == null) {
|
||||
text = this.Get_link_text(target);
|
||||
@ -99,7 +101,7 @@ public class Xomw_link_renderer {
|
||||
attribs.Clear();
|
||||
attribs.Add(Gfh_atr_.Bry__href, url); // $attribs = ['href' => $url,] + $this->mergeAttribs($attribs, $extraAttribs);
|
||||
attribs.Add(Gfh_atr_.Bry__class, Bry_.new_a7("new"));
|
||||
attribs.Merge(extra_atrs);
|
||||
Merge_attribs(attribs, extra_atrs);
|
||||
|
||||
// $prefixedText = $this->titleFormatter->getPrefixedText($target);
|
||||
// if ($prefixedText !== '') {
|
||||
@ -157,22 +159,35 @@ public class Xomw_link_renderer {
|
||||
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;
|
||||
// }
|
||||
// XO.MW:SYNC:1.29; DATE:2017-02-01
|
||||
private void Merge_attribs(Xomw_atr_mgr src, Xomw_atr_mgr trg) {
|
||||
// XO.MW: ignore; src is always non-null and empty; if trg exists, it will be merged below
|
||||
// if (!$attribs) {return $defaults;}
|
||||
|
||||
// Merge the custom attribs with the default ones, and iterate
|
||||
// over that, deleting all "false" attributes.
|
||||
sanitizer.Merge_attributes(src, trg);
|
||||
|
||||
// XO.MW:MW removes "false" values; XO removes "null" values
|
||||
boolean deleted = false;
|
||||
int len = trg.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Xomw_atr_itm trg_atr = trg.Get_at(i);
|
||||
// A false value suppresses the attribute
|
||||
if (trg_atr.Val() == null) {
|
||||
tmp_merge_deleted.Add(trg_atr);
|
||||
deleted = true;
|
||||
}
|
||||
}
|
||||
if (deleted) {
|
||||
len = tmp_merge_deleted.Len();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Xomw_atr_itm atr = (Xomw_atr_itm)trg.Get_at(i);
|
||||
trg.Del(atr.Key_bry());
|
||||
}
|
||||
tmp_merge_deleted.Clear();
|
||||
}
|
||||
}
|
||||
public byte[] Get_link_classes(Xoa_ttl target) {
|
||||
// Make sure the target is in the cache
|
||||
// $id = $this->linkCache->addLinkObj($target);
|
||||
|
@ -26,7 +26,7 @@ public class Xomw_link_holders__tst {
|
||||
}
|
||||
}
|
||||
class Xomw_link_holders__fxt {
|
||||
private final Xomw_link_holders holders = new Xomw_link_holders(new Xomw_link_renderer(), Bry_bfr_.New());
|
||||
private final Xomw_link_holders holders = new Xomw_link_holders(new Xomw_link_renderer(new Xomw_sanitizer()), Bry_bfr_.New());
|
||||
private final Xomw_parser_bfr pbfr = new Xomw_parser_bfr();
|
||||
private final Xowe_wiki wiki;
|
||||
private boolean apos = true;
|
||||
|
@ -32,7 +32,7 @@ public class Xomw_parser {
|
||||
private final Xomw_heading_wkr heading_wkr = new Xomw_heading_wkr();
|
||||
private final Xomw_magiclinks_wkr magiclinks_wkr;
|
||||
private final Xomw_doubleunder_wkr doubleunder_wkr = new Xomw_doubleunder_wkr();
|
||||
private final Xomw_link_renderer link_renderer = new Xomw_link_renderer();
|
||||
private final Xomw_link_renderer link_renderer;
|
||||
private final Xomw_link_holders holders;
|
||||
private final Xomw_heading_cbk__html heading_wkr_cbk;
|
||||
private final Btrie_slim_mgr protocols_trie;
|
||||
@ -61,6 +61,7 @@ public class Xomw_parser {
|
||||
}
|
||||
}
|
||||
|
||||
this.link_renderer = new Xomw_link_renderer(sanitizer);
|
||||
this.linker = new Xomw_linker(link_renderer);
|
||||
this.protocols_trie = Xomw_parser.Protocols__dflt();
|
||||
this.holders = new Xomw_link_holders(link_renderer, tmp);
|
||||
|
@ -51,9 +51,9 @@ public class Xomw_parser__tst {
|
||||
, "</td></tr></table>"
|
||||
, "<p><i>italics</i>"
|
||||
, "<!--MWTOC-->"
|
||||
, "<a class=\"external text\" rel=\"nofollow\" href=\"https://a.org\">b</a>"
|
||||
, "<a rel=\"nofollow\" class=\"external text\" href=\"https://a.org\">b</a>"
|
||||
, "<a href=\"/wiki/A\" title=\"A\">abc</a>"
|
||||
, "<a class=\"external free\" rel=\"nofollow\" href=\"https://c.org\">https://c.org</a>"
|
||||
, "<a rel=\"nofollow\" class=\"external free\" href=\"https://c.org\">https://c.org</a>"
|
||||
, "a »b«  !important c"
|
||||
, "</p>"
|
||||
));
|
||||
|
@ -19,7 +19,7 @@ package gplx.xowa.mws.parsers.lnkes; import gplx.*; import gplx.xowa.*; import g
|
||||
import org.junit.*;
|
||||
public class Xomw_lnke_wkr__tst {
|
||||
private final Xomw_lnke_wkr__fxt fxt = new Xomw_lnke_wkr__fxt();
|
||||
@Test public void Basic() {fxt.Test__parse("[https://a.org b]" , "<a class='external text' rel='nofollow' href='https://a.org'>b</a>");}
|
||||
@Test public void Basic() {fxt.Test__parse("[https://a.org b]" , "<a rel='nofollow' class='external text' href='https://a.org'>b</a>");}
|
||||
@Test public void Invaild__protocol() {fxt.Test__parse("[httpz:a.org]" , "[httpz:a.org]");}
|
||||
@Test public void Invaild__protocol_slash() {fxt.Test__parse("[https:a.org]" , "[https:a.org]");}
|
||||
@Test public void Invaild__urlchars__0() {fxt.Test__parse("[https://]" , "[https://]");}
|
||||
@ -33,9 +33,9 @@ public class Xomw_lnke_wkr__tst {
|
||||
, "g"
|
||||
), String_.Concat_lines_nl_apos_skip_last
|
||||
( "a"
|
||||
, "<a class='external text' rel='nofollow' href='https://b.org'>c</a>"
|
||||
, "<a rel='nofollow' class='external text' href='https://b.org'>c</a>"
|
||||
, "d"
|
||||
, "<a class='external text' rel='nofollow' href='https://e.org'>f</a>"
|
||||
, "<a rel='nofollow' class='external text' href='https://e.org'>f</a>"
|
||||
, "g"
|
||||
));
|
||||
}
|
||||
|
@ -19,51 +19,51 @@ package gplx.xowa.mws.parsers.magiclinks; import gplx.*; import gplx.xowa.*; imp
|
||||
import org.junit.*;
|
||||
public class Xomw_magiclinks_wkr__tst {
|
||||
private final Xomw_magiclinks_wkr__fxt fxt = new Xomw_magiclinks_wkr__fxt();
|
||||
@Test public void Basic() {fxt.Test__parse("a https://b.org z", "a <a class='external free' rel='nofollow' href='https://b.org'>https://b.org</a> z");}
|
||||
@Test public void Basic() {fxt.Test__parse("a https://b.org z", "a <a rel='nofollow' class='external free' href='https://b.org'>https://b.org</a> z");}
|
||||
@Test public void Invalid() {fxt.Test__parse("a _https://b.org z", "a _https://b.org z");}
|
||||
@Test public void Tag__anch() {fxt.Test__parse("a <a title=\"https://b.org\">b</a> z", "a <a title=\"https://b.org\">b</a> z");}
|
||||
@Test public void Tag__misc() {fxt.Test__parse("a <div title=\"https://b.org\">b</div> z", "a <div title=\"https://b.org\">b</div> z");}
|
||||
@Test public void Interrupt() {
|
||||
// ent
|
||||
fxt.Test__parse("a https://b.org<z" , "a <a class='external free' rel='nofollow' href='https://b.org'>https://b.org</a><z");
|
||||
fxt.Test__parse("a https://b.org<z" , "a <a rel='nofollow' class='external free' href='https://b.org'>https://b.org</a><z");
|
||||
// hex
|
||||
fxt.Test__parse("a https://b.org<z" , "a <a class='external free' rel='nofollow' href='https://b.org'>https://b.org</a><z");
|
||||
fxt.Test__parse("a https://b.org<z" , "a <a rel='nofollow' class='external free' href='https://b.org'>https://b.org</a><z");
|
||||
// dec
|
||||
fxt.Test__parse("a https://b.org<z" , "a <a class='external free' rel='nofollow' href='https://b.org'>https://b.org</a><z");
|
||||
fxt.Test__parse("a https://b.org<z" , "a <a rel='nofollow' class='external free' href='https://b.org'>https://b.org</a><z");
|
||||
// num_post_proto rule
|
||||
fxt.Test__parse("a https://< z" , "a https://< z");
|
||||
}
|
||||
@Test public void Interrupt__hex_dec() {// implementation specific test for mixed hex / dec
|
||||
// dec-hex
|
||||
fxt.Test__parse("a https://b.orgc;z" , "a <a class='external free' rel='nofollow' href='https://b.org&#3c;z'>https://b.org&#3c;z</a>");
|
||||
fxt.Test__parse("a https://b.orgc;z" , "a <a rel='nofollow' class='external free' href='https://b.org&#3c;z'>https://b.org&#3c;z</a>");
|
||||
}
|
||||
@Test public void Separator() {
|
||||
// basic; ,;.:!?
|
||||
fxt.Test__parse("a https://b.org,;.:!? z" , "a <a class='external free' rel='nofollow' href='https://b.org'>https://b.org</a>,;.:!? z");
|
||||
fxt.Test__parse("a https://b.org,;.:!? z" , "a <a rel='nofollow' class='external free' href='https://b.org'>https://b.org</a>,;.:!? z");
|
||||
// ")" excluded
|
||||
fxt.Test__parse("a https://b.org).:!? z" , "a <a class='external free' rel='nofollow' href='https://b.org'>https://b.org</a>).:!? z");
|
||||
fxt.Test__parse("a https://b.org).:!? z" , "a <a rel='nofollow' class='external free' href='https://b.org'>https://b.org</a>).:!? z");
|
||||
// ")" included b/c "(" exists
|
||||
fxt.Test__parse("a https://b.org().:!? z" , "a <a class='external free' rel='nofollow' href='https://b.org()'>https://b.org()</a>.:!? z");
|
||||
fxt.Test__parse("a https://b.org().:!? z" , "a <a rel='nofollow' class='external free' href='https://b.org()'>https://b.org()</a>.:!? z");
|
||||
// ";" excluded
|
||||
fxt.Test__parse("a https://b.org;.:!? z" , "a <a class='external free' rel='nofollow' href='https://b.org'>https://b.org</a>;.:!? z");
|
||||
fxt.Test__parse("a https://b.org;.:!? z" , "a <a rel='nofollow' class='external free' href='https://b.org'>https://b.org</a>;.:!? z");
|
||||
// ";" included b/c of ent
|
||||
fxt.Test__parse("a https://b.org&abc;.:!? z" , "a <a class='external free' rel='nofollow' href='https://b.org&abc;'>https://b.org&abc;</a>.:!? z");
|
||||
fxt.Test__parse("a https://b.org&abc;.:!? z" , "a <a rel='nofollow' class='external free' href='https://b.org&abc;'>https://b.org&abc;</a>.:!? z");
|
||||
// ";" included b/c of hex; note that Clean_url changes "±" to "±"
|
||||
fxt.Test__parse("a https://b.org±.:!? z", "a <a class='external free' rel='nofollow' href='https://b.org±'>https://b.org±</a>.:!? z");
|
||||
fxt.Test__parse("a https://b.org±.:!? z", "a <a rel='nofollow' class='external free' href='https://b.org±'>https://b.org±</a>.:!? z");
|
||||
// ";" included b/c of dec; note that Clean_url changes "{" to "{"
|
||||
fxt.Test__parse("a https://b.org{.:!? z", "a <a class='external free' rel='nofollow' href='https://b.org{'>https://b.org{</a>.:!? z");
|
||||
fxt.Test__parse("a https://b.org{.:!? z", "a <a rel='nofollow' class='external free' href='https://b.org{'>https://b.org{</a>.:!? z");
|
||||
// ";" excluded b/c of invalid.ent
|
||||
fxt.Test__parse("a https://b.org&a1b;.:!? z" , "a <a class='external free' rel='nofollow' href='https://b.org&a1b'>https://b.org&a1b</a>;.:!? z");
|
||||
fxt.Test__parse("a https://b.org&a1b;.:!? z" , "a <a rel='nofollow' class='external free' href='https://b.org&a1b'>https://b.org&a1b</a>;.:!? z");
|
||||
// ";" excluded b/c of invalid.hex
|
||||
fxt.Test__parse("a https://b.org&#x;.:!? z" , "a <a class='external free' rel='nofollow' href='https://b.org&#x'>https://b.org&#x</a>;.:!? z");
|
||||
fxt.Test__parse("a https://b.org&#x;.:!? z" , "a <a rel='nofollow' class='external free' href='https://b.org&#x'>https://b.org&#x</a>;.:!? z");
|
||||
// ";" excluded b/c of invalid.dec
|
||||
fxt.Test__parse("a https://b.org&#a;.:!? z" , "a <a class='external free' rel='nofollow' href='https://b.org&#a'>https://b.org&#a</a>;.:!? z");
|
||||
fxt.Test__parse("a https://b.org&#a;.:!? z" , "a <a rel='nofollow' class='external free' href='https://b.org&#a'>https://b.org&#a</a>;.:!? z");
|
||||
// num_post_proto rule
|
||||
fxt.Test__parse("a https://.:!? z" , "a https://.:!? z");
|
||||
}
|
||||
@Test public void Clean_url() {
|
||||
// basic
|
||||
fxt.Test__parse("http://a᠆b.org/c᠆d" , "<a class='external free' rel='nofollow' href='http://ab.org/c᠆d'>http://ab.org/c᠆d</a>");
|
||||
fxt.Test__parse("http://a᠆b.org/c᠆d" , "<a rel='nofollow' class='external free' href='http://ab.org/c᠆d'>http://ab.org/c᠆d</a>");
|
||||
}
|
||||
}
|
||||
class Xomw_magiclinks_wkr__fxt {
|
||||
|
Loading…
Reference in New Issue
Block a user