I am having trouble getting css/js to show up on a Webview.
Here is what I am doing:
initializing the webview and engine
WebView browser = new WebView();
WebEngine webEngine = browser.getEngine();
webEngine.setJavaScriptEnabled(true);
This is where I load html content:
htmlViewImgBtn.addEventHandler(MouseEvent.MOUSE_CLICKED,
new EventHandler<MouseEven
#Override
public void handle(MouseEvent event){
if (counter == 0){
contentContainer.getChildren().addAll(browser);
webEngine.loadContent(export.getHTML(note));
//browser.getEngine().load("http://stackoverflow.com/questions/34554583/cant-load-css-js-on-javafx-webview");
contentContainer.getChildren().remove(noteContent);
counter = 1;
}
else {
contentContainer.getChildren().remove(browser);
contentContainer.getChildren().addAll(noteContent);
counter = 0;
}
}
});
Note: The commented code works when loading a website onto the webview, no issues. But Still does not work for the content I am loading.
The content (HTML) that is loaded looks looks like this:
<link href="prism.css" rel="stylesheet" type="text/css" />
<script src="prism.js" type="text/javascript"></script>
<pre><code class="language-java">System.out.println("Hello");
</code></pre>
Also, the css and js files are in the same directory as the java file
I can confirm that the html works by loading it on a web browser, What am I missing?
Blockquote
I was able to get it working by modifying the html as such:
"<link href=\"" + getClass().getResource("./prism.css") + "\"" + " rel=\"stylesheet\"" + " type=\"text/css\"" + " />\n" +
"<script src=\"" + getClass().getResource("./prism.js") + "\"" + " type=\"text/javascript\"" + "></script>\n" +
(rest of html);
You can use ResourceLoader to load HTML, js and css which are located in the same directory as the Java class.
URL url = getClass().getResource("index.html");
webEngine.load(url.toExternalForm());
Related
I am having troubles loading all the scripts that I am inserting into the page context with <script> tags from a content_script script, because they are required to be executed in the correct loading order, as some depend on others. In an actual HTML file I guess there is a queue to load the files, but with inserting <script> tags it seems like if one script delays a little time, the next one starts loading and then is immediately executed notwithstanding it had to wait for its dependency library that is still loading.
Below is the network output with the error caused because of x-tag-core.min.js is loaded before primeui-all.min.js and eventPage.js which uses jquery-ui.min.js, is loaded before it:
// manifest.js
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"js/jquery-3.1.1.min.js",
"js/main.js"
]
}
]
// main.js
var s = document.createElement('script');
s.src = chrome.extension.getURL('js/jquery-3.1.1.min.js');
$(document.head).append(s);
s = document.createElement('script');
s.src = chrome.extension.getURL('js/jquery-ui.min.js');
$(document.head).append(s);
s = document.createElement('script');
s.src = chrome.extension.getURL('js/primeui-all.min.js');
$(document.head).append(s);
s = document.createElement('script');
s.src = chrome.extension.getURL('js/x-tag-core.min.js');
$(document.head).append(s);
s = document.createElement('script');
s.src = chrome.extension.getURL('js/primeelements.min.js');
$(document.head).append(s);
s = document.createElement('script');
s.src = chrome.extension.getURL('js/eventPage.js');
$(document.head).append(s);
Duplicating your problem in a snippet
The following snippet duplicates your problem by sequentially inserting <script> elements. I am using network resources, because there is no method of storing such scripts on Stack Overflow. Given that you only supplied version information for jQuery, I have had to guess at appropriate versions for the other libraries which you are using.
In order to stay close to the code which you are using in your Chrome extension, chrome.extension.getURL() is faked. In these snippets, that function returns a functional network URL for the libraries which you are using. Obviously, in your Chrome extension, you will want to continue to use the library files which you ave included with your extension.
In addition, the code for eventPage.js is faked by having some code that reports if jQuery exists, if $(document).puidialog is a function, and/or if xtag is defined. The errors you are seeing are that $([something]).puidialog was not a function and xtag was not defined. This fakeEventPageJS code accurately shows if the scripts have been properly loaded.
In this duplication of your problem, an error is also produced from the various libraries as the subsequent libraries can not find prior libraries.
var s = document.createElement('script');
s.src = chrome.extension.getURL('js/jquery-3.1.1.min.js');
document.head.appendChild(s);
s = document.createElement('script');
s.src = chrome.extension.getURL('js/jquery-ui.min.js');
document.head.appendChild(s);
s = document.createElement('script');
s.src = chrome.extension.getURL('js/primeui-all.min.js');
document.head.appendChild(s);
s = document.createElement('script');
s.src = chrome.extension.getURL('js/x-tag-core.min.js');
document.head.appendChild(s);
s = document.createElement('script');
s.src = chrome.extension.getURL('js/primeelements.min.js');
document.head.appendChild(s);
s = document.createElement('script');
//s.src = chrome.extension.getURL('js/eventPage.js');
//Fake js/eventPage.js with an actual script.
s.textContent = fakeEventPageJS;
document.head.appendChild(s);
<!-- The JavaScript code included in this HTML section is used to fake the chrome API
and part of faking the existence of a js/eventPage.js file by inserting code. -->
<!-- Using HTML <script> tags to test that loading it via these works prior to testing
using JavaScript inserts. If you want to verify that the code works when the
scripts are included in the original HTML, you can uncomment the <script>
tags here. -->
<!-- jquery-3.1.1.min.js -->
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script><!-- -->
<!-- jquery-ui.min.js -->
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<!-- <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script><!-- -->
<!-- primeui-all.min.js -->
<link rel="stylesheet" href="https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeui-all.min.css">
<!-- <script src="https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeui-all.min.js"></script><!-- -->
<!-- x-tag-core.min.js -->
<!-- <script src="https://cdn.rawgit.com/x-tag/core/master/dist/x-tag-core.min.js"></script>
<!-- primeelements.min.js -->
<!-- <script src="https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeelements.min.js"></script> <!-- -->
<script>
//Fake chrome.extension.getURL
var netScriptLoations = {
'js/jquery-3.1.1.min.js':'https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js',
'js/jquery-ui.min.js':'https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js',
'js/primeui-all.min.js':'https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeui-all.min.js',
'js/x-tag-core.min.js':'https://cdn.rawgit.com/x-tag/core/master/dist/x-tag-core.min.js',
'js/primeelements.min.js':'https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeelements.min.js'
}
if(typeof chrome !== 'object'){
var chrome = {};
}
if(typeof chrome.extension !== 'object'){
chrome.extension = {};
}
if(typeof chrome.extension.getURL !== 'function'){
chrome.extension.getURL = function(script){
//console.log(netScriptLoations[script]);
return netScriptLoations[script];
};
}
var fakeEventPageJS =
'var testResult = "Scripts did NOT load correctly. "'
+ ' + "$(document).puidialog is NOT a function.";'
+ 'var passedChecks=0;'
+ 'if(typeof $ === "function"){'
+ ' var puidialogNot = " NOT";'
+ ' if(typeof $(document).puidialog === "function") {'
+ ' puidialogNot = "";'
+ ' }'
+ ' console.log("$(document).puidialog is" + puidialogNot + " a function");'
+ '} else {'
+ ' console.log("No jQuery");'
+ '}'
+ 'var xtagNot = " NOT";'
+ 'if(typeof xtag !== "undefined") {'
+ ' xtagNot = "";'
+ '}'
+ 'console.log("xtag is" + xtagNot + " defined.");'
+ 'if(puidialogNot + xtagNot === "") {'
+ ' testResult = "Scripts loaded CORRECTLY. "'
+ '}'
+ 'console.log(testResult);';
</script>
Insert each <script> in the onload event handler of the prior script
It is clear that the inserted <script> elements are executed asynchronously. In order to force them to be executed synchronously, we need to insert the next script after the prior one has completed execution. This can be done by utilizing the load event for each script.
The following code loads each subsequent script in the load event handler of the prior script.
The function createScriptElement creates an individual <script> element. This function can be somewhat simplified in your code due to not needing to fake the eventPage.js script.
The function createScriptSequence creates a sequence of <script> elements which each inserts the next script in its onload listener. This uses script.addEventListerner('load',...) in order to be immune to the script being loaded changing the script.onload property/attribute.
var scriptsToInsert = [
'js/jquery-3.1.1.min.js',
'js/jquery-ui.min.js',
'js/primeui-all.min.js',
'js/x-tag-core.min.js',
'js/primeelements.min.js',
'js/eventPage.js'
]
function createScriptElement(script){
let scriptEl = document.createElement('script');
let scriptElSource = chrome.extension.getURL(script);
if(scriptElSource){
scriptEl.src = scriptElSource;
} else {
//Only need this `else` because we are faking having js/eventPage.js by using
// some code to indicate if $(document).puidialog is a function.
scriptEl.textContent = fakeEventPageJS;
}
return scriptEl;
}
function createScriptSequence(scriptArray){
var scriptEls = [];
//Create all the script elements
scriptArray.forEach((script,index)=>{
//console.log(script);
scriptEls.push(createScriptElement(script));
if(index>0){
//Add an onload listener for each script (except the last) which loads
// the next one in the sequence.
scriptEls[index - 1].addEventListener('load',function oneTime(){
//Probably don't need to remove this, but better to clean things up.
scriptEls[index - 1].removeEventListener('load',oneTime,false);
document.head.appendChild(scriptEls[index]);
},false);
}
});
//Return the first script in the sequence
return scriptEls[0];
}
document.head.appendChild(createScriptSequence(scriptsToInsert));
<!-- The JavaScript code included in this HTML section is used to fake the chrome API
and part of faking the existence of a js/eventPage.js file by inserting code. -->
<!-- jquery-ui.min.js -->
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<!-- primeui-all.min.js -->
<link rel="stylesheet" href="https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeui-all.min.css">
<script>
//Fake chrome.extension.getURL
var netScriptLoations = {
'js/jquery-3.1.1.min.js':'https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js',
'js/jquery-ui.min.js':'https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js',
'js/primeui-all.min.js':'https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeui-all.min.js',
'js/x-tag-core.min.js':'https://cdn.rawgit.com/x-tag/core/master/dist/x-tag-core.min.js',
'js/primeelements.min.js':'https://cdn.rawgit.com/primefaces/primeui-distribution/master/primeelements.min.js'
}
if(typeof chrome !== 'object'){
var chrome = {};
}
if(typeof chrome.extension !== 'object'){
chrome.extension = {};
}
if(typeof chrome.extension.getURL !== 'function'){
chrome.extension.getURL = function(script){
//console.log(netScriptLoations[script]);
return netScriptLoations[script];
};
}
var fakeEventPageJS =
'var testResult = "Scripts did NOT load correctly. "'
+ ' + "$(document).puidialog is NOT a function.";'
+ 'var passedChecks=0;'
+ 'if(typeof $ === "function"){'
+ ' var puidialogNot = " NOT";'
+ ' if(typeof $(document).puidialog === "function") {'
+ ' puidialogNot = "";'
+ ' }'
+ ' console.log("$(document).puidialog is" + puidialogNot + " a function");'
+ '} else {'
+ ' console.log("No jQuery");'
+ '}'
+ 'var xtagNot = " NOT";'
+ 'if(typeof xtag !== "undefined") {'
+ ' xtagNot = "";'
+ '}'
+ 'console.log("xtag is" + xtagNot + " defined.");'
+ 'if(puidialogNot + xtagNot === "") {'
+ ' testResult = "Scripts loaded CORRECTLY. "'
+ '}'
+ 'console.log(testResult);';
</script>
This is my script and it's being placed in the header internally on the html document:
<script type="text/javascript">
(function l(d){
var site = '6708', page = 'blahblah', s, er = d.createElement('script');
er.type = 'text/javascript';
er.async = true;
er.src = '//randomsite.com/?site=' + site + '&page=' + page; // **
s = d.getElementsByTagName('script')[0];
s.parentNode.insertBefore(er, s);
})(document);
</script>
and for some reason in Chrome when I check the console it shows up as
+ site + '&page='
instead of
+ site + '&page=' + page;
Edit
So the error disappeared after clearing up console and browser settings. But now a new error has shown up, and I'm not sure what this means
I'm at a loss as to why that is.
You should be getting Uncaught SyntaxError: Unexpected token * with the ** before site and after page. How have you embedded it in the html? this seemed to work fine for me:
<html>
<head>
</head>
<body>
<script type="text/javascript">
(function l(d){
var site = '6708', page = 'blahblah', s, er = d.createElement('script');
er.type = 'text/javascript';
er.async = true;
er.src = '//randomsite.com/?site=' + site + '&page=' + page;
s = d.getElementsByTagName('script')[0];
s.parentNode.insertBefore(er, s);
})(document);
</script>
</body>
</html>
Most likely you have an ad blocker installed in your browser. Disable it and try again. ;-)
I am trying to load a local js file from the assets folder in a web view.
It works perfectly under Android 4.4.4 and Android 5 but not under Android 4.3 and lower versions.
The css is displayed correctly but the js does not seem to be loaded.
This is my code:
private static final String HTML_CHARSET = "<meta charset='utf-8'>";
private static final String HTML_TITLE = "<title>Aufbau einer Tabelle</title>";
private static final String HTML_STYLESHEET = "<link href='matrix.css' type='text/css' rel='stylesheet'/>";
private static final String HTML_SCRIPT1 = "<script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js' type='text/javascript'></script>";
private static final String HTML_SCRIPT2 = "<script src='https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js' type='text/javascript'></script>";
private static final String HTML_SCRIPT3 = "<script src='matrix.js' type='text/javascript'></script>";
private static final String HTML_VIEWPORT = "<meta name='viewport' content='width=device-width, initial-scale=1.0'>";
private static final String HTML_STRING = "<!doctype html> <html> <head> " + HTML_CHARSET + HTML_TITLE + HTML_STYLESHEET + HTML_SCRIPT1 + HTML_SCRIPT2 + HTML_SCRIPT3 + HTML_VIEWPORT + "</head> <body> <table> %s%s </table> </body> </html>";
...
String htmlString = String.format(HTML_STRING, htmlTableHeader, tableBody);
WebSettings settings = matrixWebView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setDomStorageEnabled(true);
matrixWebView.loadDataWithBaseURL("file:///android_asset/", htmlString, "text/html", "UTF-8", null);
Anyone has an idea?
loadDataWithBaseURL doesn't need to be prefixed with "file://" or the path. It needs just the HTML content.
loadURL can be used to load a file contents.
I'm writing a little webpage that displays some Flickr photos and also includes microformats using oomph.js. I have bit of JS and when I run the code without <script type='text/javascript' src="oomph.js"></script> the code runs fine (all my photos are loaded. However, when I add in the above script tag, my photos don't load.
Here is my broke JS (doesn't show photos):
<script type='text/javascript' src="jquery-1.6.3.min.js"></script>
<script type='text/javascript' src="oomph.js"></script>
<script>
$(document).ready(function() {
var ajaxURL="http://api.flickr.com/services/feeds/groups_pool.gne?id=626753#N20&lang=en-us&format=json&jsoncallback=?";
$.getJSON(ajaxURL,function(data) {
$('h1').text(data.title);
$.each(data.items,function(i,photo) {
var photoHTML = '<span class="image">';
photoHTML += '<a href="' + photo.link + '">';
photoHTML += '<img src="' + photo.media.m.replace('_m','_s') + '"></a>';
$('#photos').append(photoHTML);
}); // end each
}); // end get JSON
}); // end ready
</script>
and here is the code that works (shows photos):
<script type='text/javascript' src="jquery-1.6.3.min.js"></script>
<script>
$(document).ready(function() {
var ajaxURL="http://api.flickr.com/services/feeds/groups_pool.gne?id=626753#N20&lang=en-us&format=json&jsoncallback=?";
$.getJSON(ajaxURL,function(data) {
$('h1').text(data.title);
$.each(data.items,function(i,photo) {
var photoHTML = '<span class="image">';
photoHTML += '<a href="' + photo.link + '">';
photoHTML += '<img src="' + photo.media.m.replace('_m','_s') + '"></a>';
$('#photos').append(photoHTML);
}); // end each
}); // end get JSON
}); // end ready
</script>
I've browsed the internet and have yet to find a solution. If anyone could shed some light on this issue I would greatly appreciate it :-).
I was able to fix the issue by including an older version of JQuery (version 1.3.2)
In my project I have the following script in order to open a page:
<script type="text/javascript">
function setPage(pName) {
var iPage = "'" + pName + "'";
document.getElementById('iFrame').src = window.location.href(iPage);
}
</script>
when I run the program it gives me the following problematic url:
Requested URL
http://localhost:7819/Pages/Account/'http:/localhost:7819/Pages/Support/Asp/Help01.aspx'
As we see the address contain the url of the current page plus the requested url.
More of it I'm loosing the second slash / in http:/ which I have it all the way inside the script.
How can I solve this issue?
I assume, you wanted something like this?
<script type="text/javascript">
function setPage(pName) {
document.getElementById('iFrame').src = pName;
}
</script>