Jquery to merge all referenced pages into root page? - javascript

This sounds a little obscure, but...
Is there a technique in Jquery (or just straight javascript) to step thru all the external CSS and JS file references in an HTML file and replace the references with the contents of the files.
So instead of:
<link rel='stylesheet' id='style-css' href='http://domain.com/style.css' type='text/css' media='all' />
<script type='text/javascript' src='http://domain.com/js/domain.js'></script>
..it takes all the stuff from those files and sticks it into the rendering html to make one big html doc...?
<head>
...
<style type="text/css">
hr {color:sienna}
p {margin-left:20px}
body {background-image:url("images/back40.gif")}
.etc {color:red}
.etc {color:red}
.etc {color:red}
</style>
<script type="text/javascript">
function message()
{
alert("This is an alert");
}
etc
etc
</script>
</head>
<body>
...
</body>

Add this script..
$("script").each(function() {
var script = $(this);
script.load(script.attr("src"));
script.removeAttr("src");
});
$("link[rel='stylesheet']").each(function() {
var link = $(this);
link.after("<style type='text/css'></style>").next().load(link.attr("href"));
link.remove();
});
..and you can test it with..
alert($("head").html());
..when it's all done.
(And I don't see any reason in doing this ;)

The only place I can imagine that makes sense is if you run Javascript on the server, using Rhino or similar.
You can do as Sverre suggests and load the files yourself from the browser instead of letting the browser do it, but I can't see any scenario where that would be useful - you have the same number of background requests and end up with the same result, so the only thing you gain is extra work for yourself and probably some extra delay in rendering the page. Or do I misunderstand your goal?
On the server, on the other hand, it can make sense, as the browser can save a load of requests by getting all the external resources in the same document. Is this what you want to achieve?

Related

Load css file before js

I had a internal style followed by a external style. I noticed the page was blank till the external css didn't load. So i changed it to the below code. Now the external css request is made after the js.
Why for both above and how do i make css request before js. Are there any advantages to it(css before js in below code).
<body>
<style>
body {
background: #333;
}
</style>
<script>
var headHTML = document.getElementsByTagName('head')[0].innerHTML;
headHTML += '<link type="text/css" rel="stylesheet" href="build/main.css">';
document.getElementsByTagName('head')[0].innerHTML = headHTML;
</script>
<!-- The polyfills js is generated during the build process -->
<script src="build/polyfills.js"></script>
Use setTimeout in a function which is called when the body loads.
<body onload="loadPage()">
JS
function loadPage() {
//code to load css
setTimeout(function() {
//code to load js
}, 1);
}
I think that would work. Hope it helps.
This happends because a page is rendered from top to bottom. So I suppose that browser renders you inline styles and goes executing inlines script which uppends link to a style. Then it goes further and executes external script. And after that it loads your newly appended stylesheet.
So, I'd be too naive to ask but why don't you just put your stylesheet link into the head?
Of course you should just put your css files like normal people do :). but if you really want to make it happen, it's gonna get as ugly as this code gets:
<script>
var head = document.getElementsByTagName('head')[0],
link = document.createElement('link');
link.setAttribute('rel', 'stylesheet');
link.setAttribute('href', 'style.css');
var sheet = "sheet", cssRules = "cssRules";
if (!('sheet' in link)) {
sheet = "styleSheet";
cssRules = "rules";
}
var waitForCSS = setInterval(function() {
if (link[sheet]) {
// now you can load your javascript files here like I did with CSS
// or just use any js code you want.
clearInterval(waitForCSS);
}
}, 10);
head.appendChild(link);
</script>
The way to do this is
<head>
<link type="text/css" rel="stylesheet" href="build/main.css">
<style>
body {
background: #333;
}
</style>
</head>
<body>
<!--
Rest of your code in body
//-->
<!--Body is going to end after the below //-->
<script>
window.addEventListener("DOMContentLoaded",function(){
var sc=document.createElement('script');
sc.src="build/polyfills.js";
document.head.appendChild(sc);
});
</script>
</body>
A webpage is parsed from top to bottom.
So, try put the style in your head tag and place the scripts in just before end of body tag
In the script,
add an eventlistener to window when the Dom content Loaded, make a script tag, append src and append it to Head.
It's important to load the style before anything because it's the visual of your page. It's the first thing the user see.
You change css too along with DOM using javascript. So it is preferred to load css first.
Adding a preload mostly did the trick
<link rel="preload" href="build/main.css" as="style">
The browser now made the request for css. Then it makes a call for js. Then it adds CSS tag to the head. Finally, tries to remakes the call to get CSS but since the call is in progress or done it just loads it. There is an issue of FOUC though if CSS takes times.

Html code to Png image

I made a web application which allow the user to create an image dynamically in JavaScript.
It use jQuery to allow the user to place div, resize them and drag them into a <div> Container.
When the user finished to place all div, he can press the "Generate" button which send the <div> Container outerHTML code into a local database.
Then the user can use another script, in php, and past in parameter the id in the database of which render he want to display, then the php script create a page using the code in the database.
My problem is now I want to take the code of this generated html page, then convert it into a png image.
I looked at some other posts and found something interesting : Phantom.js
But what I tried doesn't seem to work. Here is my code :
<html>
<head>
<title>Test</title>
<LINK rel='stylesheet' type='text/css' href='style.css'>
<script type='text/javascript' src='jquery/jquery.js'></script>
<script type='text/javascript' src='jquery-ui/jquery-ui.js'></script>
</head>
<body>
<script>
var page = require('webpage').create();
page.open('http://10.237.35.10/maxime/affichage.php?afficheur=0', function() {
page.render('affichageTest.png');
phantom.exit();
});
</script>
</body>
</html>
So we have the database with the div outerHTML code contained at the id '0'.
"affichage.php" take in parameter a variable "afficheur" then it ask the database to get the code from this variable. For example, afficheur=0 will return the div code contained in the database at the id=0.
When I go to "http://10.237.35.10/maxime/affichage.php?afficheur=0" I have a html page with the render I want. But when I try to run the script I'd posted higher, I haven't any "affichageTest.png" rendered in my folder.
What do I have to do? Do I have to import anything else to run Phantom.js? Or maybe I need to add something to my code?
PhantomJS is a binary not a javascript librarie (it is actually a headless webkit), I can not test it here atm, but here the main idea :
First download the PhantomJS binary, upload it somewhere and make it executable (chmod +x).
Create a file named test.js with this code below :
var page = require('webpage').create();
page.open('http://10.237.35.10/maxime/affichage.php?afficheur=0', function() {
page.render('affichageTest.png');
phantom.exit();
});
Create a file named display.php with this code below :
<?php
$file_path = exec('/path/to/phantomjs test.js');
?>
<html>
<head>
<title>Test</title>
<LINK rel='stylesheet' type='text/css' href='style.css'>
<script type='text/javascript' src='jquery/jquery.js'></script>
<script type='text/javascript' src='jquery-ui/jquery-ui.js'></script>
</head>
<body>
<img src="<?php $file_path ?>" alt="test">
</body>
</html>
Visit the display.php page to see the screen capture
If you need a full script solution, as you have said in comments, your only hope is Image Magic php extension. This in conjunction with HTML2PDF can be used to device html to image conversion for non-complex markup.
The trick is to create a pdf out of html first:
$html2pdf = new HTML2PDF('P', 'A4');
$html2pdf->writeHTML($html_content);
$file = $html2pdf->Output('temp.pdf','F');
Now you can get this pdf file and convert it image using Image Magic
$im = new imagick('temp.pdf');
$im->setImageFormat( "jpg" );
$img_name = time().'.jpg';
$im->setSize(800,600);
$im->writeImage($img_name);
$im->clear();
$im->destroy();
Installation of Image Magic extensions and support libraries could be painstaking. Please read the installation notes carefully.
The complexity of the html markup which could be converted is limited. You can do a fairly good job. But you can't call it a day if you need to convert ANY html.

Best way to access external JavaScript file and place contents in div?

So, lets say you have a page that wants to load from a javascript file and it includes
temp.html file
<script src="example.js"></script>
<p class="one"></p>
Now in the example.js file you have a function that is
function getInfo() {
var place = "foo"
$(".one").html(place);
}
//Edit currently I call the function inside the JS file
getInfo();
My question is how would you connect the two files so that the external javascript file knows that it is pointed to the paragraph with the class one?
Normally when this is in a single page, you would call the function and the info will be set.
I have seen a getScript method and a load method for Jquery. Would that be applicable here?
Any ideas on how to approach this? If you provide some code that will be super helpful.
Thanks in advance.
Looks like you want to execute getInfo() as soon as it's defined (i.e.: example.js is loaded).
You can try this approach:
<script src="example.js" onload="getInfo();"></script>
In your example.js, change getInfo() to something like this:
function getInfo() {
$(document).ready(function() {
var place = "foo"
$(".one").html(place);
});
}
Your language is confusing, but you could use jQuery's $(document).ready function which would suffice. Generally speaking, an externally loaded file should execute where the tag is in the script.
A hack could be to place a tag before the end of your document body, give it an id, and then use $('#id').ready() there. In general though, you could just try coding the transclusion concept (I'm guessing you're used to this) from scratch using intervals and timeouts.
<div id="rdy">
</div>
</body>
Then in your file:
$('#rdy').ready(getInfo);
Just my added opinion, you should consider that Google is up to some not-so-nice things these days, they are long-gone from the "do no evil" mantra.
If we assume you have a JavaScript file that contains this content:
function getInfo() {
var place = "foo"
$(".one").html(place);
}
then your markup will look something like this:
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="example.js"></script>
<script>
$(function(){
getInfo();
});
</script>
</head>
<body>
<p class="one"></p>
</body>
</html>
$(function(){ ... }); is just the simplified version of $(document).ready(function(){ ... });. They both more or less handle the onload event, which fires when page has finished loading.

Javascript include technique with dynamic SRC="url"

Is it possible (and a good idea) to pass dynamic data to a JavaScript include file via a hash url?
Such as:
<head> <script src="scripts.js#x=123&y=456"></script> </head>
I am looking for an alternative to inline js in dynamically built pages:
<head>
<script src="scripts.js#x=123&y=456"></script>
<script>
$( document ).ready(function() {
pageInit(123, 456)
});
</script>
</head>
Is it a good idea to avoid inline js? How can you pass dynamic data without ajax which creates a needless roundtrip network request?
Note: The hash bang url is a special because the browsers ignore the hash portion of the url when checking the cache. At least for html files.
So all of these will reuse the index.html file it is in the cache:
index.html
index.html#x=123
index.html#x=345345
index.html#x=2342&y=35435
This same principle should hold true for javascript files. What I hope to achieve is to reuse the cache version of script.js from page to page.
Going to index.php, include this:
<head> <script src="scripts.js#x=123&y=456"></script> </head>
Then going to fun.php include this
<head> <script src="scripts.js#x=898756465&y=5678665468456"></script> </head>
Then going to see.php include this
<head> <script src="scripts.js#session=887987979&csrf_token=87965468796"></script> </head>
From page view to page view, pass whatever info the page needs via the hash bang while at the same time reuse scirpt.js from cache.
So, is it possible to read the hash bang info from within the scirpts.js?
If the HTML file you are creating is dynamic, then just create inline JavaScript. Writing an include will just create an extra request from the browser, which you can avoid in the first place.
Edit:
just include a JavaScript file that reads the URL, you don't need to pass any variables (but of course, you also could):
$(document).ready(function() {
// pseudo code
hashbang = location.href.substr(location.href.indexOf('#') + 1);
if (hashbang.x && hashbang.y) {
pageInit(hashbang.x, hashbang.y);
} else if (hashbang.csrf_token) {
// do something else
}
});

How to detect whether a plugin or script has already been loaded without using eval() or requireJS?

I'm working on a plugin that allows to inject 3rd party code into a page (either as iframe or directly into the DOM).
My problem is "direct injections", because I need to make sure, I don't add any <scripts> additional times, if they are needed in my main page and in a page I'm loading and injecting.
For example (and I can't use requireJS), my page.html looks like this:
<html>
<head>
<script type="text/js" src="jquery.js"></script> // exports window.$
<script type="text/js" src="foo.js"></script> // exports window.foo
</head>
<body>
<!-- things that make foo load anotherPage.html and append its content here -->
</body>
</html>
with anotherPage.html
<html>
<head>
<script type="text/js" src="foo.js"></script> // exports window.foo
</head>
<body>
<!-- stuff that also runs on FOO -->
</body>
</html>
Page loading is done via Ajax and when I'm processing the data returned by my request for anotherPage.html I end up with a list of all elements after doing this:
cleanedString = ajaxResponseData
.replace(priv.removeJSComments, "")
.replace(priv.removeHTMLComments,"")
.replace(priv.removeLineBreaks, "")
.replace(priv.removeWhiteSpace, " ")
.replace(priv.removeWhiteSpaceBetweenElements, "><");
// this will return a list with head and body elements
// e.g. [meta, title, link, p, div, script.foo]
content = $.parseHTML(cleanedString, true);
// insert into DOM
someTarget.append(content);
This is where I'm stuck trying to detect whether a script I'm about to append to the document is already there.
I cannot go by the src, because the filename may differ and a script may be hosted on a different domain (with Access-Control-Allow-Origin correctly set). I also don't know, what and if the script I'm about to append returns a global I already have defined and I can't/don't want to use eval() to find out.
Question:
Is there any way to identify whether a plugin or script that may return a global is already "on" a page, when I only have the "non-appended" <script> element available?
Thanks!
here is an example of my self-enclosed module pattern, i call it a "Sentinel":
(function wait(){
if(!self.$){
if(!wait.waitingJQ){
wait.waitingJQ=true;
addScriptTag(JQUERY_URL);
}
return setTimeout(wait, 44);
}
doStuffThatNeedsJquery();
}());
The sentinel pattern work from anywhere (internal or external), doesn't care about script loading order, and works with ANY script loading library. you can list additional depends below the jQuery fork in the same manner, just put your greedy code at the bottom of the sentinel wrapper function.

Categories