Rails - rack::offline not permanently caching vendor javascript - ruby-on-rails

I'm building a Rails app that needs to be able to load a particular view/action while a user is offline, using the rack::offline gem... some of the functionality of the page in question is dependent on jQuery, and I added jQuery 2.2.4 to the vendor javascript folder. jQuery 2.2.4 is required in the application.js file, but the problem that I am having is that jQuery doesn't seem to be getting added to the cache, and the jQuery functionality is lost if the user refreshes the browser while offline.
I was able to temporarily resolve this issue by literally pasting the entire jQuery script into the view in question, but that is definitely not a practical solution.
How can I make sure the jQuery file in my vendor scripts is cached along with the HTML for he view in question?
The html element for the view includes the manifest attribute...
<html manifest="/application.manifest">
and from routes.rb
get '/application.manifest' => Rails::Offline
from my application.js file
//= require jquery-2.2.4.js
//= require turbolinks
//= require_tree .
And, to be comprehensive, here's the manifest...
CACHE MANIFEST
# 70f990270c71e8065f366ef4b2d73c870e89f37e4dbef32b57e0135c84b90001
404.html
422.html
500.html
NETWORK:
*
The first time I visit the page while offline (after caching), no problem, it pulls up the working cached version. However, as I mentioned, if I refresh the page, it loses the jQuery functionality ($ is undefined, etc.), although the HTML remains unchanged.

Pleased to say that I was able to figure this out...
You'll notice in my original post, there was no jQuery being included in the manifest - this is a problem! First thing, I needed to make sure that jQuery was tucked into my public folder - I added it to public/javascripts/jquery-2.2.4.js.
Now my manifest looks like this:
CACHE MANIFEST
# 70f990270c71e8065f366ef4b2d73c870e89f37e4dbef32b57e0135c84b90001
404.html
422.html
500.html
javascripts/jquery-2.2.4.js
NETWORK:
*
Lovely!
Now, despite the fact that I had put jQuery into the public folder, it wasn't automatically loading when I navigated to the view that was being cached (I'd love it if someone could help me figure out why that is happening, but it's not the end of the world). So, I added <script> src="/javascripts/jquery-2.2.4.js"></script> to the head of the layout file associated with the view, and boom, there ya go.
Now jQuery is being cached appropriately, my app runs offline.

Related

Configure asset-pipeline to not include resources multiple times (grails 2)?

We're in the process of upgrading from grails 2.5 to 3, as a starting point, we're migrating resources to asset-pipeline. I've read through the docs superficially, but in testing ran into a scenario that's causing problems... resources are getting included multiple times on the page.
The problem is best illustrated by exampe. Create testing.js file in assets/javascripts:
$(document).ready( function() {
alert("test alert");
});
In application.js (included in main.gsp layout) add //= require testing. On any page in application add <asset:javascript src='testing'/>. Launch the page and the alert shows twice.
Is there a way to configure asset-pipeline so as not to do this?
I assume I'm missing something, because this seems like a big problem with transitive dependencies from plugins (e.g., everything depends on jquery).
Adding grails.assets.bundle=true to Config.groovy doesn't seem to help.
Edit: Adding clarification with jquery example
Our application's application.js contains, among many other things: //= require jquery-version.js
Plugins we use provide GSPs that also include jquery-version.js (either in their own asset tag or transitively through included js files) because those pages require jquery to be on the page. Perhaps I have some fundamental misunderstanding, but this seems correct... the plugin GSPs should require their dependencies.
Now, on this page, jquery.js is included multiple times. This seems like a step back from Resources which would resolve multiple inclusions through transitive modules.

Turning on turbolink

After I've precompiled assets and uploaded them to CDN I decided to turn on turbolinks. They were kind of turned on before when I were precompiling assets, that is I had gem turbolinks in Gemfile and require turbolinks in application.js but in application.html I had data-no-turbolink instead of data-turbolinks-track" => true.
Now I change it to data-no-turbolink to data-turbolinks-track" => true and expect them to work in production on the my local machine but it seems they aren't. Visually it seems they aren't working and "initiator" in the browser isn't turbolinks.
I don't want to recompile the assets if it's not really needed because reuploading them to CDN takes a lot of time.
So do I have to recompile them? Or perhaps I just don't notice that they are really working already?
data-turbolinks-track is only for asset tracking (to make sure the loaded assets file is the latest). It does not affect whether Turbolinks is used for a particular link.
If turbolinks is installed, any internal link without data-no-turbolink will be loaded using Turbolinks UJS.
The following code will fire an alert if Turbolinks is running.
$(document).on('page:load', function(){ alert("Turbolinks is active"); });
Not easy with the sparse information you provide. But here are some notes worth considering:
About Turbolinks:
With Turbolinks pages will change without a full reload, so you can't
rely on DOMContentLoaded or jQuery.ready() to trigger your code.
Instead Turbolinks fires events on document to provide hooks into the
lifecycle of the page.
You probably use jQuery? Read above link to understand. A good solution is this one: jQuery.turbolinks
...
But if you have a large codebase with lots of $(el).bind(...)
Turbolinks will surprise you. Most part of your JavaScripts will stop
working in usual way. It's because the nodes on which you bind events
no longer exist.
...

Galleria slideshow works on local server, not on live server

I'm trying to get a Galleria slideshow up and running in my rails app. It works fine with the local server (on both Chrome and Firefox) but does not work on the live server (on either Chrome or Firefox). In Chrome, the slideshow flashes briefly (maybe .25 seconds?) upon loading before going away. In Firefox, it just never shows up at all.
When I look at what is happening with inspect element on Chrome, under the network tab, it says that galleria.classic.css was canceled due to a 404 error.
I have the following code in my app: (note, originally, I had other code on the page, but I pulled the slideshow to an admin-only page so I could examine it live without messing up the client-facing stuff so that's all that's on the page. It didn't work either on the client-facing page or the admin page.
In the view:
<head><link rel="stylesheet" type="text/css" href="assets/libs/galleria/themes/classic/galleria.classic.css"></head>
<body>
<div id="slideshow">
<div id="galleria">
<%= image_tag("pic1_url")%>
<%= image_tag("pic2_url")%>
<%= image_tag("pic3_url")%>
</div>
<script>
$('#galleria').galleria();
</script>
</div>
</body>
In my application.css stylesheet, I have:
*= require_self
*= require galleria/themes/classic/galleria.classic
*= require_tree .
*/
In my application.js file, I have:
//= require jquery
//= require jquery_ujs
//= require jquery_nested_form
//= require galleria/galleria-1.2.9.min
//= require galleria/themes/classic/galleria.classic
//= require_tree .
Fixes I've tried:
Double check my pathways (per this answer: Galleria works locally in all browsers but only IE8 & Chrome when hosted). They are all forward slashes not backwards slashes.
In galleria.classic.js, changed css: galleria.classic.css to css: false (per this answer:Galleria not showing up on Heroku in Rails app)
I have my Galleria in the rails asset pipeline in vendor/assets/libs/galleria (per this answer: Where to put Galleria (jQuery image gallery framework) in Rails 3.1 Asset Pipeline?)
I added type="text/css" to the link to the stylesheet in the head, (per the second answer here: Galleria not loading on initial page visit)
How can I get Galleria to work?
When you deploy your file to production it compile and collect all your assets in one folder called assets, so specified paths doesn't work, because there is no galleria/themes/classic/ path on Heroku server or other server, which you're using.
So, you need to specify path in HTML file like this href="assets/galleria.classic.css" if it is necessary.
But in fact your
*= require galleria/themes/classic/galleria.classic
and
//= require galleria/galleria-1.2.9.min
//= require galleria/themes/classic/galleria.classic
has already done it, and all the necessary code must be in your compiled .css and .js files. So, you can just remove <link rel...> part from your code.
P.S. I'm trying to avoid subfolders in css, javascripts and images folders, because it can often cause such problems like yours, and also it's make app structure more clear. But to do so, you need to check plugin files, if they have any specified paths to each other, and remove any /folder/subfolder/ part of them, left only filenames.

ruby on rails jquery.js and application.js both fire a request per ajax button

Firefox is firing off two requests when I click on the following button (and all other ajax forms on the page):
<%= form_tag(action_object_path, :remote => true) do -%>
<div><%= submit_tag "run process" %></div>
<% end -%>
I do not want this behavior. I pulled up firebug and can see that there are two requests made:
POST http://localhost:3000/object/1/action jquery.js?body=1 (line 8527)
POST http://localhost:3000/object/1/action application.js?body=1 (line 8527)
How do I fix this to only fire one request when I click my button?
One thing I remember that may help diagnose this problem. I know they are both javascript assets and can vaguely remember modifying something with my assets immediately after I started building my app because rails server barked at me and told me to precompile (I at least think it was precompile) my assets. I don't remember what I did and so dont' know how to reverse it.
I also read somewhere that firefox's cache may cause it to fire two requests, so I have tried clearing my cache and that does not work.
Thanks
To explain the problem a bit more clearly than the comments indicate:
The jquery-ujs javascript library adds event bindings to change events for elements that would normally generate standard HTTP requests (and are flagged as :remote) into AJAX requests. In Rails you would typically have the jquery-rails gem installed and then have the jquery_ujs.js file render in one of several ways:
add a require jquery_ujs line in your application.js manifest
add a javascript_include_tag :jquery_ujs line to your application layout file
copy the jquery_ujs file to your assets and rely on some line in the application.js manifest to pull it in (e.g. require_tree .)
Choosing more than one of these methods will cause the library to be linked twice - and will result in the symptoms described.

jquery mobile does not work in production rails 3.2 app

I have a Rails 3.2.9 app using jquery mobile.
I use the jquery_mobile_rails gem to embed jqm and the mobylette gem to detect when requests come from a mobile device.
All works ok in development environment (Webrick)
The production env is based on apache/passenger.
when I run rake assets:precompile all seems to go well,
and if I look at assets/manifest.yml I can see that all seems ok.
When I invoke the welcome page the login form is sent to the browser,
but while in development env the page has all the jqm formats,
in production the html is not "injected" with the needed JQM code,
so for example the tag is simply
<body>
instead of
<body class="ui-mobile-viewport ui-overlay-c">
So it seems that after loading the page, the javascript that should run and "enrich" the html with JQM specific code is not triggered.
Any hint about why this is happening?
EDIT
assets
javascripts
application.js
mobile
application.js
views
layouts
application.html.erb
application.mobile.erb
manifest files are:
javascripts/application.js
//= require jquery
//= require jquery_ujs
//= require_directory .
javascripts/mobile/application.js
//= require jquery.mobile
//= require_directory .
In case you would like to include a bunch of files from a particular directory (or a library ) ,you can use index manifest file (look for 2.1.2). It is really simple:
in your directory (app/assets/javascripts/mobile) create a file index.js with content :
//= require_self
//= require other_files_you_want
(and optionaly):
//= require_tree .
then in your application.js manifest file you can require the library with the name of the directory , in which you have created the index.js file :
//= require mobile
I would suggest, when you pass these steps, to remove the file app/assets/javascripts/mobile/application.js. It is not a good style in one app to have more than one file with the name application.js.
EDIT (after taking a look at the application.css):
I would suggest a couple of corrections in your manifest file application.css:
move the css code in a new file (for example app/assets/stylesheets/custom.css.scss)
if there are others css libs that you use , include them like normal (*= require your_css) in your application.css.
The problem was due to an incompatibility between the last versions of jquery and jquery mobile.
jquery mobile 1.2.0 released Oct 2 2012 has problems with last jquery version 1.9.x.
Specifically, jquery 1.9 removed the $.browser method, which is used in jquery mobile 1.2.0.
So when jqwery mobile tries to initialize objects on the page it dies with the error
TypeError: 'undefined' is not an object (evaluating 'e.browser.msie')
I solved the problem by forcing the use of jquery 1.8.3; in Gemfile
gem 'jquery-rails', '~> 2.1.4'
which includes jquery 1.8.3 in the assets pipeline.
Without web inspector on the BB Z10 (or remote debug function on android 4 devices) I would have never been able to detect such javascript problem on the mobile platform.
As a final tought, BlackBerry Z10 Web Inspector works via Wi-Fi, while Android devices need an USB connection to have remote debug work.

Resources