javascript not working from network drive - javascript

I'm trying to run the below file. It runs perfectly fine when I run it on a local drive but if I place it on a network drive it no longer works. Any idea why this might be?
The below is code that I am trying to run. It is using pivottable from here: https://github.com/nicolaskruchten/pivottable.
<!DOCTYPE html>
<html>
<head>
<title> Demo</title>
<!-- external libs from cdnjs -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<!-- PivotTable.js libs from ../dist -->
<link rel="stylesheet" type="text/css" href="../dist/pivot.css">
<script type="text/javascript" src="../dist/pivot.js"></script>
<style>
body {font-family: Verdana;}
</style>
<!-- optional: mobile support with jqueryui-touch-punch -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js"></script>
</head>
<body>
<script type="text/javascript">
// This example shows custom aggregators using
$(function(){
var tpl = $.pivotUtilities.aggregatorTemplates;
$.getJSON("col.json", function(frontier) {
$("#output").pivotUI(frontier, {
rows: ["Manager"], cols: ["Sector"],
aggregators: {
"Number of Positions": function() { return tpl.count()() },
"Manager Weight": function() { return tpl.sum()(["Port"])},
"Benchmark XGCC Weight": function() { return tpl.sum()(["Bench"])},
}
});
});
});
</script>
<div id="output" style="margin: 30px;"></div>
</body>
</html>

File:/// urls will run in a different context than HTTP/HTTPS and other contexts (internal, public, private, unsafe). What limitations in question depend on the specific browser, the OS and the context itself.
If you must execute JavaScript within HTML, the safest and most assured way to run is to have it running via a web server.
Also worth noting, there are a few local/relative files. ../dist/pivot.js and ../dist/pivot.css are you sure you're saving those files, and they are in the correct relative path as well?

Related

Differences in script execution order using Chrome vs Firefox

Because I am new to programming and trying to learn several languages at once, I made a series of files in one folder in order to test how these different languages/technologies work together. In the folder I have two php files (including the main file I am testing; 'index.php'), a css file, a json file and two javascript files. The problem is that when I run it in the browser using a XAMPP apache server, the scripts that refer to the files 'script.js' and 'secondscript.js' on the 'index.php' file seem to be executing in the wrong order depending on the situation. I expected them to both be executed in the order in which they appeared on the file but if I use Chrome, 'secondscript.js' is always executed first even if I swap the order that they are written in the file and if I use Firefox, 'script.js' is always executed first. Here is the code:
index.php:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css"> <!-- ADD CSS -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- ADD JQUERY -->
<script> window.jQuery || document.write('<script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js"><\/script>')</script> <!-- ADD JQUERY BACKUP -->
<script src="secondscript.js"></script>
<!-- ADD JQUERY TEST -->
<script src="script.js"></script>
<!-- ADD JAVASCRIPT -->
</head>
<body>
<div id="ajaxdiv"></div>
<!-- ADD AJAX TEST -->
<?php include 'server.php'?>
<!-- ADD PHP -->
<noscript>Sorry, your browser does not support JavaScript!</noscript>
<!-- ADD BACKUP FOR JSLESS BROWSER -->
</body>
</html>
script.js:
document.write("<h1>Header</h1>")
Request = new XMLHttpRequest()
Request.open('GET', 'json.json')
Request.onload = function (){
Data = JSON.parse(Request.responseText)
p = document.createElement('p')
node = document.createTextNode(Data[1].Three)
p.appendChild(node)
document.getElementById("ajaxdiv").appendChild(p)
}
Request.send()
secondscript.js:
$(function() { alert('Alert') })
server.php:
<?php echo 'PHP TEST'?>
style.css:
body {background-color: pink}
h1 {color: red}
p {color: purple}
json.json:
[{"One": "A", "Two": "B"}, {"Three": "C", "Four": "D"}]
edit: by 'execute first' I mean it seems that way to me because the 'C' that appears via ajax appears before or after the alert message depending on the browser.

Referencing same js files from multiple locations using partial views

I am setting up an architecture for an MVC6 app, and I'm relying heavily on ViewComponents. My goal is to let each ViewComponent have its own javascript section, but from reading here rendersection does not work with ViewComponents so I've been trying to do it in another way.
In my _Layout.cshtml
I have this part in just before the closing of the body tag:
#{Html.RenderPartial("_LayoutScriptsPartial"); }
In _LayoutScriptsPartial
<environment names="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/app.js" asp-append-version="true"></script>
</environment>
<environment names="Staging,Production">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js">
</script>
<script src="~/js/app.min.js" asp-append-version="true"></script>
</environment>
Now in one of my components at /Views/Shared/Components/MyComponent/Default.cshtml I reference another partial view that has this content, it's for a carousel ViewComponent
#model MyProj.MyViewModel
#{Html.RenderPartial("_LayoutScriptsPartial"); }
#if (!string.IsNullOrEmpty(Model.ImageUrl))
{
<script type="text/javascript">
var cssClass= "#Model.cssClass";
var imageUrl = "#Model.ImageUrl";
webbCore.carouselSetBackgroundImage(cssClass, imageUrl);
</script>
}
Only reason I had to do this was to have all required js files available for my view component.
As you can see, I reference _LayoutScriptsPartial multiple times. When I debug using chromes f12 and watching the network section, I do not se the same javascript files being downloaded multiple times. Still I have a bad feeling about this solution. I have looked around and have not found any good solutions for working with js files and ViewComponents that I really liked. Something like this would suit my needs.
My question: how good is this solution, whats the pros and cons and are there any better ways to work with js files and ViewComponents?
There are 3 main cases for an ideal solution to your problem:
ViewComponent is added 0 times and the corresponding JavaScript library is added 0 times
ViewComponent is added 1 time, the corresponding JavaScript library is added 1 time and the dynamically created initialization JavaScript is created once and placed after the library.
ViewComponent is added many times, the corresponding JavaScript library is added 1 time and the dynamically created initialization JavaScript is created for each ViewComponent and are all placed after the library.
So in your example, jquery and app.js are your libraries while your dynamically created initialization JavaScript is the part that references #Model in your <script type="text/javascript"> tag. Let's say we added your component to a view 3 times (I'll replace #RenderBody() with the resulting html from a view that invokes your component 3 times):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] - MyProj.Web</title>
<environment names="Development,Staging,Production">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/lib/font-awesome/css/font-awesome.css" />
<link rel="stylesheet" href="~/css/site.css" />
<link rel="stylesheet" href="~/css/culture-flags.css" />
</environment>
</head>
<body>
<header>#Html.Partial("~/Views/Shared/_Header.cshtml")</header>
<main>
<nav></nav>
<article>
<div class="container body-content">
<!--#RenderBody()-->
<!--#await Component.InvokeAsync("MyComponent", new MyViewModel {cssClass="t1", ImageUrl="1.jpg"})-->
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/app.js" asp-append-version="true"></script>
<script type="text/javascript">
var cssClass= "t1";
var imageUrl = "1.jpg";
webbCore.carouselSetBackgroundImage(cssClass, imageUrl);
</script>
<!--#await Component.InvokeAsync("MyComponent", new MyViewModel {cssClass="t2", ImageUrl="2.jpg"}) -->
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/app.js" asp-append-version="true"></script>
<script type="text/javascript">
var cssClass= "t2";
var imageUrl = "2.jpg";
webbCore.carouselSetBackgroundImage(cssClass, imageUrl);
</script>
<!--#await Component.InvokeAsync("MyComponent", new MyViewModel {cssClass="t3", ImageUrl="3.jpg"}) -->
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/app.js" asp-append-version="true"></script>
<script type="text/javascript">
var cssClass= "t3";
var imageUrl = "t3.jpg";
webbCore.carouselSetBackgroundImage(cssClass, imageUrl);
</script>
</div>
</article>
<aside></aside>
</main>
<footer>#Html.Partial("~/Views/Shared/_Footer.cshtml")</footer>
<!-- These are the libraries that should only be loaded once -->
<environment names="Development,Staging,Production">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
</environment>
<!-- Ideally this is where the dynamically create scripts would go -->
#RenderSection("scripts", required: false)
</body>
</html>
As you can see, you would be loading the jquery library 4 times, once for your Layout and 3 times for your ViewComponents. Any good browser should only download the file once but will be loaded into memory multiple times and will just overwrite the the same global variables multiple times($ for example).
You might also be tempted to move the library to the top of the Layout and remove the references from the View Component but that is not a best practice either.
The main issue is that section doesn't work with ViewComponents and that appears to be by design. You should think of a ViewComponent as a fancy html helper. I haven't seen any great solutions to this problem but here are a couple of ideas.
Within the View, immediately after you call your component (Component.InvokeAsync("MyComponent")), add your javascript to #section scripts {...}
Create a library js that initializes this component and set data attributes from the element
$(".carousel").each(function() {
var css = $(this).data("carousel-css");
var image = $(this).data("carousel-image");
});
<input class="carousel" type=hidden data-carousel-css="#Model.cssClass" data-carousel-image="#Model.imageURL" />

Javascript executing incorrectly on Apache Cordova index.js/.html

So in an application I'm writing using Apache Cordova within Visual Studio, I am attempting to add functionality to the default index.html and index.js. However, my code within my index.js is executing very oddly - the debugger in VS shows that the $('#favorite-lot') is executed, but nothing within the .click(function()) method is. Is there any reason why this would be so?
Index.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="css/JQueryMobile/jquery.mobile-1.4.5.min.css" />
<link rel="stylesheet" type="text/css" href="css/index.css">
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="scripts/platformOverrides.js"></script>
<script src="scripts/JQueryMobile/jquery.mobile-1.4.5.js"></script>
<script type="text/javascript" src="scripts/index.js"></script>
</head>
<body>
<div role="main" class="ui-content">
<a id="favorite-lot" href=""><h5>Favorite Lot</h5></a>
</div>
</body>
</html>
Index.js
//This method is called on page load to set the favorite lot on the index page
//the document bit is called, but the if statement within it & ready aren't
//$(document).ready(function () {
$('#favorite-lot').click(function () {
var storage = window.localStorage;
var href = storage.getItem("favoriteLot");
//now redirect
window.location.replace(href);
});
//});
Note I have tried enclosing my function within a document.ready (see commented out code), however the results are the same.
EDIT: So I figured this issue out, and it was a fairly simple error: I wasn't including the jQuery code itself, just jQuery.mobile, and additionally, the jQuery has to load before jQuery.mobile for the .mobile stuff to work. Side note, I also didn't realize .mobile enables Ajax on most links/redirections, and had to disable that for some of my other code; maybe if you've found this post, you're suffering from the other problem as well

Firefox Addon Scripting Trusted Page Content

So I'm trying to use a chrome:// URI in my add-on and I want to use a page-worker on it using the scripting trusted content method, however it seems to not work when I hard code the URI in, the chrome://<package name>/<part>/<file>; however, it works when I use the self.data.url('filename'). I want to use the chrome:// URI is because I use a GUID instead of the email style as the add-on's ID and also I don't want to use the resource:// URI.
Content Script
addon.port.emit('hi');
HTML
<html>
<head>
<meta charset="UTF-8">
<title>Gaia Utils Settings</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="chrome://gaiascripts/content/dropdown.min.js"></script>
<script type="text/javascript" src="chrome://gaiascripts/content/settings.dev.js"></script>
<script type="text/javascript" src="chrome://gaiascripts/content/test.dev.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet" type="text/css">
<link href="css/settings.css" rel="stylesheet" type="text/css">
<link href="css/poststyle.css" rel="stylesheet" type="text/css">
</head>
<body>
<nav id="navbar_header" class="navbar navbar-blue navbar-static-top"></nav>
<div id="content_wrapper" class="container">
<div id="content_padding" class="container"></div>
</div>
<footer class="footer"></footer>
</body>
</html>
main.js
var PageWorker = require("sdk/page-worker");
PageWorker.Page({
contentURL: "chrome://gaiautils/content/settings.dev.html",
onMessage: function(message) {
console.log(message);
}
});
I know I can use a page-mod and attach the scripts to it with that, but I'd rather call the scripts from within the file and be able to communicate with the main add-on code. So is there a way so that I can have my cake and eat it too - using the hard coded chrome:// URI in conjunction with calling the scripts from within the HTML file while being able to have those scripts communicate back to the main.js file?
How can I have it so that I can use the addon.port.emit() in the content scripts that are called directly in the HTML file so that I don't have to use the self.data.url('htmlFile'), because I don't want to use the resource://pageckage-GUID-at-jetpack/path/to/file
The SDK only considers pages "trusted" if the URL you're loading is part of the add-on assets (data/). chrome:// URIs are not. Hence you'll need to use regular content scripts via the contentScriptFile: [...] option in your PageWorker definition.
<script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
Don't ever load remote scripts for security reasons (and performance reasons to a far lesser extent)! Ship a local copy of jQuery if you want to use it.

html/javascript sharing script lists... or doing CI with jasmine and selenium

I'm pretty new to js + html. I've set up some (extjs) js based acceptance tests using jasmine and am now looking at getting continuous integration setup for them.
Because they run in browser, there's going to be a bit of mucking about to get them running under CI. What I was thinking of doing was using selenium to run the tests (we've already got a working selenium setup so that should be easy) and using jasmine-reporters to get the results output to a file that CruiseControl.net can understand.
Jasmine is pretty straight-forward in the way it works and you end up writing a html page that looks like this:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Jasmine Spec Runner v2.0.0</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine-2.0.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="lib/jasmine-2.0.0/jasmine.css">
<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="lib/jasmine-2.0.0/boot.js"></script>
<script type="text/javascript">
//set this a bit higher to aid debugging
jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
</script>
<!-- include source files here... -->
<script type="text/javascript" src="Sample/src/Player.js"></script>
<script type="text/javascript" src="Sample/src/Song.js"></script>
<script type="text/javascript" src="/native/WeatherVane.js"></script>
<script type="text/javascript" src="/native/EventCreator.js"></script>
<script type="text/javascript" src="/ext/ext-all-dev.js"></script>
<script type="text/javascript" src="/api/api.js"></script>
<script type="text/javascript">
Ext.app.REMOTING_API.maxRetries = 0;
Ext.direct.Manager.addProvider(Ext.app.REMOTING_API);
</script>
<!-- include spec files here... -->
<script type="text/javascript" src="Sample/spec/SpecHelper.js"></script>
<script type="text/javascript" src="Sample/spec/PlayerSpec.js"></script>
<script type="text/javascript" src="Tests/EventCreation.js"></script>
<!-- note this needs to be last as it fires up the tests-->
<script type="text/javascript" src="TestApp.js"></script>
I've not actually got round to stripping out the sample tests yet!
Anyway the easiest way I could see of doing this would be to another page which uses a different TestApp (the last entry) which configures jasmine to use the nunitreporter from the jasmine-reporters library and just get selenium to run that page
Obviously I dont want to just copy + paste everything in there and modify just the last bit. This is going to be a list we're going to be adding to a lot and it's going to be a real pain if the CI and local testing aren't working basically the same way.
Basically what I'd like to do is effectively split it into two documents/sets of includes like this:
Document A - the shared setup
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Jasmine Spec Runner v2.0.0</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine-2.0.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="lib/jasmine-2.0.0/jasmine.css">
<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="lib/jasmine-2.0.0/boot.js"></script>
<script type="text/javascript">
//set this a bit higher to aid debugging
jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000;
</script>
<!-- include source files here... -->
<script type="text/javascript" src="Sample/src/Player.js"></script>
<script type="text/javascript" src="Sample/src/Song.js"></script>
<script type="text/javascript" src="/native/WeatherVane.js"></script>
<script type="text/javascript" src="/native/EventCreator.js"></script>
<script type="text/javascript" src="/ext/ext-all-dev.js"></script>
<script type="text/javascript" src="/api/api.js"></script>
<script type="text/javascript">
Ext.app.REMOTING_API.maxRetries = 0;
Ext.direct.Manager.addProvider(Ext.app.REMOTING_API);
</script>
<!-- include spec files here... -->
<script type="text/javascript" src="Sample/spec/SpecHelper.js"></script>
<script type="text/javascript" src="Sample/spec/PlayerSpec.js"></script>
<script type="text/javascript" src="Tests/EventCreation.js"></script>
Document B - the current browser output method:
SomeCommandToInclude(documentA);
<!-- note this needs to be last as it fires up the tests-->
<script type="text/javascript" src="TestApp.js"></script>
Document C - the CI/xml output method:
SomeCommandToInclude(documentA);
<!-- note this needs to be last as it fires up the tests-->
<script type="text/javascript" src="XmlOutputApp.js"></script>
I've felt myself wanting to do something very similar a few times with these html script lists. How do you do this? Is it even possible? I was looking at some stuff to do with document.write a while ago but it didn't seem to do quite do the right thing.
If it's not possible to include these script lists in each other, I'm open to other approaches for getting the CI going, although I have a pretty strong preference for doing it with selenium as I dont want to learn yet another library/technology and spend ages fiddling to get it working.
Here's what I did. I didn't figure out how to include html files but I got something working.
Basic approach
I passed in a parameter in the url which says whether we are in CI mode. The client side testing library parses the url to check if it should create xml output. Because this is run in-browser by selenium it can't be saved directly to file. Instead I wrote it into a string and then query this string from Selenium and from there write it out to disc.
Jasmine-reporters
Jasmine-reporters has been forked to cope with jasmine-2.0 which I am using note that the 2.0 branch is not the main branch. I'm not familiar with git and was thrown by it hiding the other branch from you in the history. There is a compatible version of jasmine-reporters there.
I used the NUnit reporter and to faciliate use with selenium I did a massive hack and replaced the write file method with the following:
self.writeFile = function(text) {
self.output(text, totalSpecsFailed > 0);
};
I also added this to the constructor:
self.output = options.output;
My calling/config code then does this if we are in CI mode:
var jasmineEnv = jasmine.getEnv();
jasmineEnv.addReporter(new jasmineReporters.NUnitXmlReporter(
{
output: function (xmlOutput, anyFailures) {
testConfig.xmlOutput = xmlOutput;
testConfig.anyFailures = anyFailures;
}
}));
Selenium
The selenium code looks like this (note this isn't raw selenium - it's going through an API I've wrapped around the basic stuff but you should be able to get the gist)
public void PokeTheTestPage()
{
try
{
NavigateTo(WebAppUrl + "Tests/Jasmine/SpecRunner.html?outputFile=true");
var error = Driver.GetStringWith("return weatherVane.testConfig.errorText;");
if (error != "")
ExitWithError(error);
var testOutput = LongWait.Until(d => d.GetStringWith("return weatherVane.testConfig.xmlOutput;"));
var failed = Driver.GetBoolWith("return weatherVane.testConfig.anyFailures;");
using (var file = File.OpenWrite(_outputFile))
using (var writer = new StreamWriter(file))
writer.Write(testOutput);
if (failed)
ExitWithError("tests failed");
}
catch (Exception e)
{
ExitWithError(e.ToString());
}
}
private void ExitWithError(string error)
{
Console.WriteLine("got Error:");
Console.WriteLine(error);
Driver.Close();
Environment.Exit(1);
}
}

Categories

Resources