I have a single page web application that utilizes DOJO (1.9.x). It normally loads the DOJO library from the Google CDN and my application functions as expected. But, some customers offer limited internet connection that excludes most of the internet for security (!?) reasons. So I have to host DOJO library locally on the server.
For this to work, I should point the URL to the local copy of dojo.js and relevant CSS files. As only the prefix of the URL changes, I am curious if there is a trick to achieve this by some external CSS file so that the URL in the HTML gets its prefix from this small CSS. By simply editing/changing this small CSS file, One site will load DOJO from the Google CDN and Another will load the locally hosted DOJO.
Is this possible with a static CSS file ?
This is not possible with CSS.
A few alternatives, in order of preference:
SAFEST - Distribute two versions of the page/app, with local and remote dojo.
If you have server-side rendering of any sort, configure that to update the dojo URL.
Always distribute the dojo loader with your application. Thereafter, load dojo modules from CDN or locally according to your config. This could get hairy.
More details on option 3:
dojoConfig.js
//var dojoRoot = ".."; // For LOCAL builds - relative to dojo.js
var dojoRoot = "//ajax.googleapis.com/ajax/libs/dojo/1.9.3"; // For CDN builds
var dojoConfig = {
packages: [
// Depending on your project structure, you may need to
// insert entries here for your local packages.
// Here, we override the location for dojo packages
{
name: "dojo",
location: dojoRoot + "/dojo"
},
{
name: "dojox",
location: dojoRoot + "/dojox"
},
{
name: "dijit",
location: dojoRoot + "/dijit"
}
]
};
HTML snippet to use it
<script src="dojoConfig.js"></script>
<script src="dojo/dojo.js"></script>
<script>
require(["dojo/_base/config", "dojo/json"], function(config, JSON) {
console.log(JSON.stringify(config.packages, null, "\t"));
});
</script>
Related
Before I start I should mention that I know about Hosting the Google JavaScript file locally is not recommended by Google. But since the Caching time is so low on these files I want to have it locally with much more cache time. I also automatically get the last version when the real file is changed.
I'm trying to fetch ga.js file by cron everyday like this and host it locally:
$ana = file_get_contents('https://www.google-analytics.com/analytics.js');
if ($ana!==false){
file_put_contents('ANA_LOCAL_PATH',$ana);
$tag = file_get_contents('https://www.googletagmanager.com/gtag/js');
if ($tag!==false){
$tag = str_replace('https://www.google-analytics.com/analytics.js','ANA_LOCAL_URL',$tag);
file_put_contents('GTAG_LOCAL_PATH',$tag);
}
}
I'm also getting analytics.js file and replacing Google URL with local analytics.js file.
But I want it to be future proof. Google using this URL:
https://www.googletagmanager.com/gtag/js?id=UA-xxxxxxxxx-x
I'm using this:
https://www.googletagmanager.com/gtag/js
I have more than 10 tag manager ID and I only get the JavaScript file one time without ID.
Another thing is that Google header file is starting with this:
// Copyright 2012 Google Inc. All rights reserved.
(function(){
var data = {
"resource": {
"version":"1",
"macros":[],
"tags":[],
"predicates":[],
"rules":[]
},
"runtime":[
[],[]
]
This file has multiple new lines (not only on header) which is not minified properly.
I found Google does not minified the script well. for example, case "url_no_fragment" has space after case. It can be case"url_no_fragment". You can find lots of switch case with white space in the file.
The Question
Is Downloading method has problem (now or future), just because I don't get it with Google tag manager ID?
Can I minify Google files with my own method and remove some flaws that I mentioned?
I know this part is not programming related and I think I'm getting NO for this. but just for the sake of minification. Am I allowed to remove that copyright comment to have the best minify file?
I am building an HTML5 phonegap application. This app exports data so that the user can backup and restore any time. I'm doing this exporting with the following javascript code:
var dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(this.data, null, "\t"));
var dlAnchorElem = document.createElement('a');
dlAnchorElem.setAttribute("href", dataStr);
dlAnchorElem.setAttribute("download", "data.json");
document.body.appendChild(dlAnchorElem);
dlAnchorElem.click();
This generates an anchor tag with an encoded file and clicks so it downloads. Works great on browser, but does nothing in a compiled Cordova application.
After doing some research, I found that the default solution would be to use a download plugin for Cordova, specifically this one: https://github.com/apache/cordova-plugin-file-transfer
I read the documentation, but it does not seem to take an encoded file as parameter, but an encoded URL for download. Also, it takes the save path on the phone, which I prefer would just default to the download folder.
My question is: What is the best way to achieve this, considering I'm dynamically generating the JSON backup file. Is there perhaps an AndroidManifest directive that allows for file downloads?
After some research and trying many different hacks, I came to the conclusion that it's currently not allowed natively with cordova or with the available plugins. My solution was to, instead of writing to the filesystem, use the web share api to let the user export the way he finds best (including file, if he chooses dropbox, onedrive or google drive).
MathJax enforces a directory structure based on its library design. Fonts bundled with the library are in a subdirectory alongside some Javascript configuration and other components.
I want to serve the fonts from a different location on disk but I'm not seeing any configuration values that allow me to do that. I've checked the documentation and while I'm seeing different ways to load the full library and pieces of configuration, I'm not seeing how to isolate the fonts.
How can I load fonts from a different location in MathJax?
Edit: This is a client-side solution; we're doing this in the browser. We're using the TeX-AMS_CHTML.js configuration, which uses the CommonHTML rendering strategy. In the configuration (which is minified) it looks like there's a MathJax.OutputJax.fontDir that could be edited?
You want to override the CommonHTML webfontDir. Try
<script type="text/x-mathjax-config">
MathJax.Hub.Register.StartupHook('CommonHTML Jax Ready", function () {
MathJax.OutputJax.CommonHTML.webfontDir = 'myURL/myDontDirectory';
});
</script>
where myURL/myFontDirectory is the full URL to the directory containing your fonts. You may need to set the access control for the fonts directory to allow cross-domain access if the URL domain is not the same as the domain of the page loading MathJax. See the MathJax documentation on shared installations for more details.
From v3 onwards, use the following:
<script type="text/javascript">
window.MathJax = {
startup: {
ready: () => {
MathJax.config.chtml.fontURL = "/your-path/es5/output/chtml/fonts/woff-v2";
MathJax.config.chtml.font.options.fontURL = "/your-path/es5/output/chtml/fonts/woff-v2";
MathJax.startup.defaultReady();
}
}
}
</script>
<script type="text/javascript" src="/your-path/es5/tex-mml-chtml.js"></script>
In a NodeJS application I would like to load configuration data (reports to be generated) from external files dynamically. I can load them statically by using require('path/config');
But I do have parts of the configuration that need to be refreshed on a regular schedule and, to make it all more complicated, these configuration files contain a function that must be executable.
One such report looks as follows:
const report = {
name : 'Report 3',
description : 'Very simple report.',
// Some properties
preprocessor : function() {
},
// Some more properties
};
module.exports = report;
When using require to re-load the report it is basically not reloaded. Even if I change something, it stays the same. (Reason: require() uses caching and rightfully it does.)
What is a good way (maybe an external library) to re-load external configuration files that contain executable functions?
I would use fs. If you have complete control over the configuration files (otherwise it's dangerous) you can use eval.
var fs = require('fs');
var file = fs.readFileSync(filename);
var module = {}
eval(file);
// You can access report in module.exports
If you don't want to block your application (usually recommended) you should use the async version and provide callbacks.
To circument caching problems, I now use the library require-without-cache. Seems to do the job.
I have a knockout/require app and am struggling with the caching of one particular file. Sadly it is the file that busts the cache for all other javascript files. The setup may be slightly odd:
Each view simply binds a knockout view model. It requires the require library and the main script for the particular area of the system:
<script data-main="scripts/user" src="~/Scripts/lib/require.js"></script>
The scripts/user.js file required above requires the common file (containing the require setup) and the main viewmodel script:
require(['./Common'], function (common) {
require(['userMain']);
})
The scripts/user/userMain.js file binds the viewmodel and requires anything needed at the view level (such as custom binding handlers).
define(function (require) {
require(['ko', 'userViewModel'], function (ko, userViewModel) {
var userVm = new userViewModel(false);
userVm.initialise();
// bound to the wrapper to stop jquery dialog bindings being applied twice
ko.applyBindings(userVm, document.getElementById('pageWrapper'));
});
});
Then we have common.js:
require.config({
baseUrl: './',
paths: {
'userMain': './Scripts/user/Main',
'userAjax': './Scripts/user/userAjax',
'userBasicDetails': './Scripts/user/userBasicDetails',
'userExchangesModel': './Scripts/user/userExchangesModel',
'userModel': './Scripts/user/userModel',
'userReportAccessModel': './Scripts/user/userReportAccessModel',
'usersModel': './Scripts/user/usersModel',
'userViewModel': './scripts/user/userViewModel',
... etc
,
urlArgs: "bust=" + (new Date()).getTime()
each script within the folder then requires anything it needs within its own model.
The script structure is then setup as so:
scripts\common.js
scripts\user.js
scripts\user\main.js
scripts\user\userAjax
scripts\user\etc...
This setup allows me to reference scripts from other folders without specifying where the file is anywhere other than in common.js. The downside is that all js files have a reference in common but I can live with that.
As an example there are 4 or 5 folders at the same level as 'user' ('scripts\report\', 'scripts\client' etc) and if I want to create
a user model from any of the scripts within those folders I can simply "define (['userModel'], function (userModel)" and common will tell require where to go and find that file. This system works well, allowing me to move files around at will and only change their path in one place.
The problem comes when I add new scripts or change paths in common.js. Whilst all others are bust every request due to the setup
in common the common file itself gets cached so I have to bust users' chrome caches before the new common.js file gets picked up. This is obviously a big issue at delivery time - pages fail as they cannot find the new script because it doesn't exist in the same folder and common has been cached.
Can anyone suggest a way of automatically busting common.js or moving the path config into a separate required file so that the urlArgs bust will do it for me?
Many thanks.
Before the script element that loads RequireJS, add the following code:
<script>
require = {
urlArgs: "bust=" + (new Date()).getTime()
};
</script>
RequireJS will pick this up as its initial configuration and any module it loads, through data-main or any other way, will be required with a bust parameter.
It is probably best to remove urlArgs from your subsequent call to require.config. It will override the earlier option so the value of the bust will change. Usually, modules are loaded once and only once by RequireJS so it should not happen that the same module is loaded by the same page with two different bust values. But there are scenarios I'm unsure about (for instance, using require.undef to undefine a module). Removing the later urlArgs would avoid bad surprises.