I am currently using this library in my app: https://github.com/kexanie/MathView
which is used to convert text into maths, it uses TeX/MathJax.
This was working as expected:
MathView mv = new MathView(context, null);
mv.setEngine(MathView.Engine.MATHJAX);
mv.config("MathJax.Hub.Config({\n" +
"jax: [\"input/TeX\",\"output/HTML-CSS\"],\n" +
"displayAlign: \"left\"" +
"});"
);
mv.setText(context.getString(id));
where "id" pointed to a resource in strings.xml file.
Now, I changed it to be contained inside a file, and getting it from there.
MathView mv = new MathView(context, null);
mv.setEngine(MathView.Engine.MATHJAX);
mv.config("MathJax.Hub.Config({\n" +
"jax: [\"input/TeX\",\"output/HTML-CSS\"],\n" +
"displayAlign: \"left\"" +
"});"
);
String a= text;
mv.setText(a);
where text is received from the file, but is same as the earlier one in strings.xml, I logged that to verify.
But now the output is broken. It doesn't recognise the text correctly
"\frac{a}{b}" earlier used to be "a/b", now it is "fracab"
Is it a library issue?
I have used MathJax in angular4 project. It might help you out in your project as well.
use cdnjs link for mathjax library:
<script type="text/javascript" async
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?
config=TeX-MML-AM_CHTML"></script>
create mathjax directive:
import {Directive, ElementRef, Input, OnChanges} from'#angular/core';
declare var MathJax:any;
#Directive({
selector : '[mathText]',
})
export class MathTextDirective implements OnChanges {
constructor(public elementRef: ElementRef) {
this.hostEl = elementRef.nativeElement; //capture the HTML
element host
}
//Used to bind data: eg: <div [mathText]="raw string">
#Input('mathText') inputString:string;
// host element
private hostEl:HTMLElement;
//have MathJax parse the host element and render the math
render(){MathJax.Hub.Queue(['Typeset', MathJax.Hub, this.hostEl])}
// called when the inputString changes.
ngOnChanges(){
//make the input string into the innerText of the host element
this.hostEl.innerText = this.inputString;
this.render();
}
}
Register this directive in app.module.ts
and use this directive in html like:
<div [mathText]="\frac{a}{b}"></div>
Related
I have some difficulties when trying to pass data to my html file. My html file is located at project root inside assets folder. In short, i am displaying my html file inside a webView.
This is portion of my mainActivity.kt, which is used to populate my webView
mWebView = findViewById(R.id.activity_main_webview);
val webSettings = mWebView.settings
webSettings.javaScriptEnabled = true
mWebView.loadUrl("file:///android_asset/googlechart.html");
and here is portion of my googlechart.html, which is stored locally inside assets folder
var dataRow = [["mushroom", 1], ["fish", 3]]
var data = new google.visualization.DataTable();
data.addColumn('string', 'Topping');
data.addColumn('number', 'Slices');
data.addRows(dataRow);
I want to pass data from mainActivity.kt to my googlechart.html, per answer at Passing data from java class to Web View html, it didn't explain how to pass data to a html file which is stored inside project root. How can i achieve that ?
Any help or insight is appreciated.
Simple solution
use Query when loadUrl()
get document.location.href in script
deal with your data
decode string, split, etc
example
If data is json
android
val json = JsonObject().apply {
addProperty("age","28")
addProperty("name","john")
addProperty("contents","test")
}
val url = "file:///android_asset/test.html?$json"
binding.webView.loadUrl(url)
local .html
<!DOCTYPE html>
<html>
<body>
<H1>test</H1>
<oi id="list">
</oi>
<script type="text/javascript">
function makeList() {
const getOiTag = document.getElementById("list");
const decodeUrl = decodeURI(document.location.href);
const jsonStr = decodeUrl.split("?")[1];
const json = JSON.parse(jsonStr);
for(i in json){
const li = document.createElement("li")
li.textContent = i + " : " + json[i];
getOiTag.appendChild(li);
}
}
makeList()
</script>
</body>
</html>
I've seen multiple tutorials adding a GetBaseUrl separately for IOS and Android, but they don't answer my question. I was wondering if there is no other way to add custom CSS to a webview and only use 1 stylesheet (default.css). The reason why I want to do this is because my stylesheet is identical for both IOS and Android and contains little styling.
This is what I've tried:
I have a WebView:
<WebView.Source >
<HtmlWebViewSource Html="{Binding Data.Content}" />
</WebView.Source>
The Source of this WebView is a string that looks like this:
string contentString = #"<html>
<head>" +
"<link rel='stylesheet' href='default.css'"
"</head>" +
"<body style='text-align:left;background-color:white;font-size:16px;margin:0;'>" +
value +
"</body>" +
"</html>";
The default.css file mentioned above is in my Assets folder and has Build Action EmbeddedResource, located in the root directory of my project:
Can anyone help? Thanks in advance.
There are some ways to do this, one is to use HtmlWebViewSource, the html is like this:
htmlSource.Html = #"<html>
<head>
<link rel=""stylesheet"" href=""default.css"">
</head>
<body>
<h1>Xamarin.Forms</h1>
<p>The CSS and image are loaded from local files!</p>
<img src='XamarinLogo.png'/>
<p>next page</p>
</body>
</html>";
Another way is to use WebView.loadDataWithBaseURL, there is the same thread that you can take a look:
Rendering HTML in a WebView with custom CSS
The easiest way is to wrap your HTML with CSS (or replace link tags with its resulting content)
var html = AddHtmlAndCssTags("<div>my html</div>", ReadCss());
protected string ReadCss()
{
var resourceName = $"MyProj.Resources.Css.article.css";
var isExists = ResourceLoader.IsEmbeddedResourceExists(Assembly.GetAssembly(typeof(ResourceLoader)), resourceName);
if (isExists)
{
return ResourceLoader.GetEmbeddedResourceString(Assembly.GetAssembly(typeof(ResourceLoader)), resourceName);
}
return string.Empty;
}
protected string AddHtmlAndCssTags(string html, string css)
{
var cssTag = string.IsNullOrEmpty(css) ? string.Empty : $"<style>{css}</style>";
return $"<html><head>{cssTag}</head><body>{html}<body></html>";
}
I am trying to open an app. Its working fine when I give a static URL. But as I create a dynamic href tag in *ngFor I can see unsafe keyword is added before the URL and it's not working.
I am running on Angular 6. And getting the Id in a service. In ngFor I am looping the result and creating a link with Id to open the app. I create a pipe but it's still not working.
Safe Pipe
import { Pipe, PipeTransform } from '#angular/core';
import { DomSanitizer } from '#angular/platform-browser';
#Pipe({
name: 'safeurl'
})
export class SafeurlPipe implements PipeTransform {
constructor(private domSanitizer: DomSanitizer) {}
transform(value: any) {
return this.domSanitizer.bypassSecurityTrustUrl(value);
}
}
In the component I added the below line between ngFor tag
Join
You need to use your pipe within interpolation. With your way it's just a string (part of href). It means, angular does not recognize it as a pipe or part of your application. Also, you need to bind the value itself only and nothing else. In your case you can pass appName://joinTournament?id= as a parameter to the pipe.
Here is a working solution.
Add another parameter to your pipe as follows
transform(value: any, prefix = '') {
return this.domSanitizer.bypassSecurityTrustUrl(prefix + value);
}
And change
Join
to
<a [href]="t.tag | safeurl: 'appName://joinTournament?id='">Join</a>
Ionic printer plugin use Printer.print([html string], [printer options]) function to get print out using mobile app.
I need to create html template and update some values dynamically and use template as input for the print function.
Can anyone have any idea how to do this?
I am using ionic 2 and android platform.
It depends on what exactly want to print.
I would probably just create an HTML template inside your code and then replace the values before printing.
Example:
class Page {
template: string = `<h1>{title}</h1>
<p>This is a paragraph</p>
<p>{content}</p>`;
getHTML(title, content) {
let str = template;
str = str.replace('{title}', title);
str = str.replace('{content}', content);
return str;
}
printPage(title, content) {
let options = {};
this.p.print(getHTML(title, content), options).then(onSuccess, onError);
}
}
Question 1:
I'm trying to make an android application with python and WebView.
I wonder if I can get a python variable and send it to html and save them in a variable in javascript.
I tried this but does not work:
script.py
import android
import os, sys
ruta_del_proyecto = os.path.dirname(os.path.realpath(__file__))
droid = android.Android()
droid.webViewShow(ruta_del_proyecto + '/ui/prueba.html?ruta_del_proyecto=5')
print ruta_del_proyecto + '/ui/prueba.html?ruta_del_proyecto=5'
prueba.html
<html>
<!--urta cel: file:///sdcard/sl4a/scripts/test1/ -->
<head>
<title>prueba</title>
<script>
var droid = new Android();
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
vars[key] = value;
});
return vars;
}
var ruta_del_proyecto = getUrlVars()["ruta_del_proyecto"];
alert (ruta_del_proyecto);
</script>
</head>
<body>
</body>
</html>
Question 2:
When I make the script.py in to APK with "The Android Java IDE (AIDE)" , then install and open, WebView don't open
The python code are execute but WebView don't open
Any idea?
There is a simple hack you can do. Webkit WebView has the "load-finished" event that triigers after your page loads and after which you can execute your JavaScript function:
def on_load_finished(webview, frame):
browser.execute_script('your-js-function('+yourVariable+');')
browser = webkit.WebView()
browser.connect("load-finished", on_load_finished)
Remember, you can pass dictionaries as an argument by serializing them with json module and deserializing them in JS!