diff --git a/400_xowa/src/gplx/xowa/htmls/minifys/XoCssMin.java b/400_xowa/src/gplx/xowa/htmls/minifys/XoCssMin.java
index 5c78c6b17..d76478041 100644
--- a/400_xowa/src/gplx/xowa/htmls/minifys/XoCssMin.java
+++ b/400_xowa/src/gplx/xowa/htmls/minifys/XoCssMin.java
@@ -35,14 +35,12 @@ public class XoCssMin {
public static final int
MODE_NODEJS = 1
, MODE_YCSS_MIN = 2
- , MODE_XOWA = 4
- , MODE_ALL = MODE_NODEJS | MODE_YCSS_MIN | MODE_XOWA
+ , MODE_ALL = MODE_NODEJS | MODE_YCSS_MIN
;
public void DataCollectorMgr_(GfoDataCollectorMgr v) {this.dataCollectorMgr = v;} private GfoDataCollectorMgr dataCollectorMgr;
public String cssmin(String css, int linebreakpos) {return cssmin(css, linebreakpos, MODE_ALL);}
public String cssmin(String css, int linebreakpos, int mode) {
boolean isModeYcssMin = Bitmask_.Has_int(mode, MODE_YCSS_MIN);
- boolean isModeXowa = Bitmask_.Has_int(mode, MODE_XOWA);
int startIndex = 0,
endIndex = 0,
@@ -288,17 +286,6 @@ public class XoCssMin {
// Trim the final string (for any leading or trailing white spaces)
css = JsString_.replace(css, patterns, "^\\s+|\\s+$", "");
- if (isModeXowa) {
- // add the '.mw-parser-output ' selector
- css = JsString_.replace(css, patterns, "\\}([^@}].{2})", "}.mw-parser-output $1");
- css = JsString_.replace(css, patterns, "(@media[^\\{]*\\{)", "$1.mw-parser-output ");
- if (css.charAt(0) != '@')
- css = ".mw-parser-output " + css;
-
- // change some url(...) entries
- css = css.replace("//upload.wikimedia.org", "//www.xowa.org/xowa/fsys/bin/any/xowa/upload.wikimedia.org");
- }
-
return css;
}
private String _extractDataUrls(String css, List preservedTokens) {
diff --git a/400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde.java b/400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde.java
index d5cd1e0b1..7bb902036 100644
--- a/400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde.java
+++ b/400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde.java
@@ -27,7 +27,6 @@ import gplx.xowa.htmls.heads.Xoh_head_itm__css_dynamic;
import gplx.xowa.htmls.hxtns.blobs.Hxtn_blob_tbl;
import gplx.xowa.htmls.hxtns.pages.Hxtn_page_mgr;
import gplx.xowa.htmls.hxtns.wikis.Hxtn_wiki_itm;
-import gplx.xowa.htmls.minifys.XoCssMin;
import gplx.xowa.parsers.Xop_ctx;
import gplx.xowa.parsers.Xop_root_tkn;
import gplx.xowa.parsers.htmls.Mwh_atr_itm;
@@ -40,17 +39,17 @@ import gplx.xowa.xtns.Xox_xnde;
import gplx.xowa.xtns.Xox_xnde_;
public class Template_styles_nde implements Xox_xnde, Mwh_atr_itm_owner2 {
private byte[] css_ttl_bry;
- private byte[] wrapper;
private byte[] css_src;
private boolean css_ignore;
private int css_page_id;
private Xoa_ttl css_ttl;
- private static XoCssMin cssMin = new XoCssMin();
+ private String prepend = ".mw-parser-output";
+
public void Xatr__set(Xowe_wiki wiki, byte[] src, Mwh_atr_itm xatr, byte xatr_id) {
switch (xatr_id) {
case Xatr__src: css_ttl_bry = xatr.Val_as_bry(); break;
case Xatr__wrapper:
- wrapper = Bry_.Add(xatr.Val_as_bry(), Byte_ascii.Space); // add trailing space for html_head.format
+ prepend = prepend + " " + xatr.Val_as_str();
break;
}
}
@@ -104,7 +103,12 @@ public class Template_styles_nde implements Xox_xnde, Mwh_atr_itm_owner2 {
if (!css_ignore) {
Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b512();
try {
- html_head.Bld_many(tmp_bfr, css_page_id, wrapper, Bry_.new_u8(cssMin.cssmin(String_.new_u8(css_src), -1)) );
+ css_src = new XoCssTransformer(String_.new_u8(css_src))
+ .Minify()
+ .Prepend(prepend)
+ .Url("upload.wikimedia.org", "www.xowa.org/xowa/fsys/bin/any/xowa/upload.wikimedia.org")
+ .ToBry();
+ html_head.Bld_many(tmp_bfr, css_page_id, css_src);
Xoh_head_itm__css_dynamic css_dynamic = ctx.Page().Html_data().Head_mgr().Itm__css_dynamic();
css_dynamic.Enabled_y_();
css_dynamic.Add(tmp_bfr.To_bry_and_clear());
@@ -130,7 +134,7 @@ public class Template_styles_nde implements Xox_xnde, Mwh_atr_itm_owner2 {
.Add_str_byte("wrapper", Xatr__wrapper)
;
private static final Bry_fmt
- html_head = Bry_fmt.Auto("\n/*TemplateStyles:r~{id}*/\n~{wrapper}~{css}")
+ html_head = Bry_fmt.Auto("\n/*TemplateStyles:r~{id}*/\n~{css}")
, html_error = Bry_fmt.Auto("~{msg}")
;
}
diff --git a/400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde_tst.java b/400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde_tst.java
index ee37ffa34..a7dd42927 100644
--- a/400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde_tst.java
+++ b/400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde_tst.java
@@ -25,111 +25,127 @@ public class Template_styles_nde_tst {
@Before public void init() {
fxt.Reset();
}
- @Test public void Implicit_template() { // PURPOSE: default to template
- String css = fxt.Make__css_color("red");
- fxt.Init__page("Template:Test.css", css);
- fxt.Test__parse
+ @Test public void Implicit_template() { // PURPOSE: default to template
+ String css = fxt.Make_css_color("red");
+ fxt.Init_page("Template:Test.css", css);
+ fxt.Test_parse
( ""
, ""
- , fxt.Make__style(0, css)
+ , fxt.Make_style(0, css)
);
}
- @Test public void Force_main() { // PURPOSE: ":" forces main
- String css = fxt.Make__css_color("red");
- fxt.Init__page("Test.css", css);
- fxt.Test__parse
+ @Test public void Force_main() { // PURPOSE: ":" forces main
+ String css = fxt.Make_css_color("red");
+ fxt.Init_page("Test.css", css);
+ fxt.Test_parse
( ""
, ""
- , fxt.Make__style(0, css)
+ , fxt.Make_style(0, css)
);
}
- @Test public void Explicit() { // PURPOSE: explicit ns
- String css = fxt.Make__css_color("red");
- fxt.Init__page("Module:Test.css", css);
- fxt.Test__parse
+ @Test public void Explicit() { // PURPOSE: explicit ns
+ String css = fxt.Make_css_color("red");
+ fxt.Init_page("Module:Test.css", css);
+ fxt.Test_parse
( ""
, ""
- , fxt.Make__style(0, css)
+ , fxt.Make_style(0, css)
);
}
- @Test public void Multiple() { // PURPOSE: multiple calls to diff page should output diff styles; DATE:2018-12-30
- String css_red = fxt.Make__css_color("red");
- String css_blue = fxt.Make__css_color("blue");
- fxt.Init__page("Module:Test1.css", css_red);
- fxt.Init__page("Module:Test2.css", css_blue);
- fxt.Test__parse
+ @Test public void Multiple() { // PURPOSE: multiple calls to diff page should output diff styles; DATE:2018-12-30
+ String css_red = fxt.Make_css_color("red");
+ String css_blue = fxt.Make_css_color("blue");
+ fxt.Init_page("Module:Test1.css", css_red);
+ fxt.Init_page("Module:Test2.css", css_blue);
+ fxt.Test_parse
( String_.Concat_lines_nl
( ""
, ""
)
, ""
- , fxt.Make__style(0, css_red)
- + fxt.Make__style(1, css_blue)
+ , fxt.Make_style(0, css_red)
+ + fxt.Make_style(1, css_blue)
);
}
- @Test public void Dedupe() { // PURPOSE: multiple calls to same page should output link; DATE:2018-12-30
- String css = fxt.Make__css_color("red");
- fxt.Init__page("Module:Test.css", css);
- fxt.Test__parse
+ @Test public void Dedupe() { // PURPOSE: multiple calls to same page should output link; DATE:2018-12-30
+ String css = fxt.Make_css_color("red");
+ fxt.Init_page("Module:Test.css", css);
+ fxt.Test_parse
( String_.Concat_lines_nl
- ( ""
- , ""
+ ( ""
+ , ""
)
, ""
, String_.Concat_lines_nl
- ( fxt.Make__style(0, css))
+ ( fxt.Make_style(0, css))
);
}
- @Test public void Tag() { // PURPOSE: {{#tag}}
- String css = fxt.Make__css_color("red");
- fxt.Init__page("Module:A/Test.css", css);
- fxt.Test__parse
+ @Test public void Tag() { // PURPOSE: {{#tag}}
+ String css = fxt.Make_css_color("red");
+ fxt.Init_page("Module:A/Test.css", css);
+ fxt.Test_parse
( "{{#tag:templatestyles||src='Module:A/Test.css'}}"
, ""
- , fxt.Make__style(0, css)
+ , fxt.Make_style(0, css)
);
}
- @Test public void Fix_single_word_paragraph() { // PURPOSE:make sure block is closed, else single-word paragraphs; ISSUE#:616; DATE:2019-11-18
- String css = fxt.Make__css_color("red");
- fxt.Init__page("Template:Test.css", css);
+ @Test public void Fix_single_word_paragraph() { // PURPOSE:make sure block is closed, else single-word paragraphs; ISSUE#:616; DATE:2019-11-18
+ String css = fxt.Make_css_color("red");
+ fxt.Init_page("Template:Test.css", css);
fxt.Parser_fxt().Init_para_y_();
- fxt.Test__parse
+ fxt.Test_parse
( String_.Concat_lines_nl_skip_last("", "a")
, String_.Concat_lines_nl_skip_last("", "a", "
")
- , fxt.Make__style(0, css)
+ , fxt.Make_style(0, css)
);
fxt.Parser_fxt().Init_para_n_();
}
- @Test public void Error__invalid_title() {
- fxt.Test__parse
+ @Test public void Error__invalid_title() {
+ fxt.Test_parse
( ""
, "Invalid title for TemplateStyles src attribute."
, ""
);
}
- @Test public void Error__missing_page() {
- fxt.Test__parse
+ @Test public void Error__missing_page() {
+ fxt.Test_parse
( ""
, "Page Missing.css has no content."
, ""
);
}
- @Test public void Error__missing_src() {
- fxt.Test__parse
+ @Test public void Error__missing_src() {
+ fxt.Test_parse
( ""// PAGE:en.w:Switzerland; ISSUE#:416; DATE:2019-03-31
, "Invalid title for TemplateStyles src attribute."
, ""
);
}
- @Test public void Wrapper() {
- String css = fxt.Make__css_color("red");
- fxt.Init__page("Template:Test.css", css);
- fxt.Test__parse
+ @Test public void Wrapper() {
+ String css = fxt.Make_css_color("red");
+ fxt.Init_page("Template:Test.css", css);
+ fxt.Test_parse
( ""
, ""
- , fxt.Make__style(0, ".wrapper_class", css)
+ , fxt.Make_style(0, ".wrapper_class", css)
);
}
+ @Test public void Url() {
+ fxt.Init_page("Template:Test.css", fxt.Make_css_url("//upload.wikimedia.org/A.png"));
+ fxt.Test_parse
+ ( ""
+ , ""
+ , fxt.Make_style(0, fxt.Make_css_url("//www.xowa.org/xowa/fsys/bin/any/xowa/upload.wikimedia.org/A.png"))
+ );
+ }
+ @Test public void Minify() {
+ fxt.Init_page("Template:Test.css", fxt.Make_css_color("rgb (128,128,128)"));
+ fxt.Test_parse
+ ( ""
+ , ""
+ , fxt.Make_style(0, fxt.Make_css_color("#808080"))
+ );
+ }
}
class Template_styles_nde_fxt {
private final Xop_fxt parser_fxt = new Xop_fxt();
@@ -138,18 +154,21 @@ class Template_styles_nde_fxt {
parser_fxt.Reset();
parser_fxt.Wiki().Xtn_mgr().Init_by_wiki(parser_fxt.Wiki());
}
- public void Init__page(String page, String text) {
+ public void Init_page(String page, String text) {
parser_fxt.Init_page_create(page, text);
}
- public String Make__css_color(String color) {
+ public String Make_css_color(String color) {
return ".style0{color:" + color + "}";
}
- public String Make__style(int id, String css) {return Make__style(id, null, css);}
- public String Make__style(int id, String wrapper, String css) {
- wrapper = wrapper == null ? "" : wrapper + " ";
- return "\n/*TemplateStyles:r" + id + "*/\n" + wrapper + ".mw-parser-output " + css; // .mw-parser-output needs to be added to all TemplateStyles CSS, else TS ids called "portal" will affect sidebar; ISSUE#:426; PAGE:en.w:Poland DATE:2020-04-10
+ public String Make_css_url(String url) {
+ return ".style1{url(" + url + "}";
}
- public void Test__parse(String src, String expd_html, String expd_head) {
+ public String Make_style(int id, String css) {return Make_style(id, null, css);}
+ public String Make_style(int id, String wrapper, String css) {
+ wrapper = wrapper == null ? "" : wrapper + " ";
+ return "\n/*TemplateStyles:r" + id + "*/\n" + ".mw-parser-output " + wrapper + css; // .mw-parser-output needs to be added to all TemplateStyles CSS, else TS ids called "portal" will affect sidebar; ISSUE#:426; PAGE:en.w:Poland DATE:2020-04-10
+ }
+ public void Test_parse(String src, String expd_html, String expd_head) {
parser_fxt.Test__parse__tmpl_to_html(src, expd_html);
Gftest.Eq__ary__lines(expd_head, parser_fxt.Page().Html_data().Head_mgr().Itm__css_dynamic().Get_and_clear());
}
diff --git a/400_xowa/src/gplx/xowa/xtns/template_styles/XoCssTransformer.java b/400_xowa/src/gplx/xowa/xtns/template_styles/XoCssTransformer.java
new file mode 100644
index 000000000..952a07c99
--- /dev/null
+++ b/400_xowa/src/gplx/xowa/xtns/template_styles/XoCssTransformer.java
@@ -0,0 +1,37 @@
+package gplx.xowa.xtns.template_styles;
+
+import gplx.Bry_;
+import gplx.langs.javascripts.JsString_;
+import gplx.xowa.htmls.minifys.XoCssMin;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.regex.Pattern;
+
+public class XoCssTransformer {
+ private final static ConcurrentHashMap patterns = new ConcurrentHashMap<>();
+ private String css;
+ public XoCssTransformer(String css) {
+ this.css = css;
+ }
+
+ public XoCssTransformer Minify() {
+ XoCssMin minifier = new XoCssMin();
+ this.css = minifier.cssmin(css, -1);
+ return this;
+ }
+ public XoCssTransformer Prepend(String prepend) {
+ // prepend any classes to all declarations; primarily for '.mw-parser-output ' selector
+ css = JsString_.replace(css, patterns, "\\}([^@}].{2})", "} " + prepend + " $1");
+ css = JsString_.replace(css, patterns, "(@media[^\\{]*\\{)", "$1" + prepend + " ");
+ if (css.charAt(0) != '@')
+ css = prepend + " " + css;
+ return this;
+ }
+ public XoCssTransformer Url(String src, String trg) {
+ // change some url(...) entries
+ css = css.replace("//" + src, "//" + trg);
+ return this;
+ }
+ public byte[] ToBry() {return Bry_.new_u8(css);}
+ public String ToStr() {return css;}
+}
diff --git a/400_xowa/tst/gplx/xowa/xtns/template_styles/XoCssTransformerTest.java b/400_xowa/tst/gplx/xowa/xtns/template_styles/XoCssTransformerTest.java
new file mode 100644
index 000000000..63670fe8b
--- /dev/null
+++ b/400_xowa/tst/gplx/xowa/xtns/template_styles/XoCssTransformerTest.java
@@ -0,0 +1,43 @@
+package gplx.xowa.xtns.template_styles;
+
+import gplx.core.tests.Gftest;
+import org.junit.Test;
+
+public class XoCssTransformerTest {
+ private final XoCssTranformerTstr tstr = new XoCssTranformerTstr();
+
+ @Test
+ public void Minify() {
+ tstr.Test_Minify("basic" ,"rgb (128,128,128)", "#808080");
+ }
+
+ @Test
+ public void Prepend() {
+ tstr.Test_Prepend("cls.1.1" ,"x {}" , ".a" , ".a x {}");
+ tstr.Test_Prepend("cls.n.1" ,"x {}y {}", ".a" , ".a x {} .a y {}");
+ }
+
+ @Test
+ public void Url() {
+ tstr.Test_Url("match.y" , "url(//site/a.png)", "site", "prepend/site", "url(//prepend/site/a.png)");
+ tstr.Test_Url("match.y.any", "//site/abc" , "site", "prepend/site", "//prepend/site/abc"); // NOTE: matches any "//"
+ tstr.Test_Url("match.n" , "url(/-site/a.png)", "site", "prepend/site", "url(/-site/a.png)");
+ }
+}
+class XoCssTranformerTstr {
+ public void Test_Url(String note, String css, String src, String trg, String expd) {
+ XoCssTransformer transformer = new XoCssTransformer(css);
+ String actl = transformer.Url(src, trg).ToStr();
+ Gftest.Eq__str(expd, actl, note);
+ }
+ public void Test_Prepend(String note, String css, String prepend, String expd) {
+ XoCssTransformer transformer = new XoCssTransformer(css);
+ String actl = transformer.Prepend(prepend).ToStr();
+ Gftest.Eq__str(expd, actl, note);
+ }
+ public void Test_Minify(String note, String css, String expd) {
+ XoCssTransformer transformer = new XoCssTransformer(css);
+ String actl = transformer.Minify().ToStr();
+ Gftest.Eq__str(expd, actl, note);
+ }
+}