I've got a full bore copy of jQuery UI in the app, so it doesn't matter if I'm loading from the CDN or locally, all I know is it's loaded. (because if we load from the CDN our only option is to monkeypatch the live version, yes?)
I see from: https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.progressbar.js that this.min is unfortunately not a settable option (this.options.max in contrast). I need this.min to be -1 in my case (and yes, application wide, we have discussed this internally on the team and we understand the reason for the jQuery decision, we just need it to be otherwise), so my only options seem to be to monkeypatch the prototype or maintain my own plugin. I also see that they are using the "widget" architecture now, for loading the jQuery UI objects.
In this particular application, my scripts are roughly loaded like so:
/javascripts/lib/jquery.min.js
/javascripts/lib/jquery-ui.min.js
...
/javascripts/company.utils.js
/javascripts/company.helpers.js
...
page level includes of javascript libraries
...
page level javascript
So I'm thinking of going into company.utils.js and define a monkeypatch like so:
$.ui.progressbar.prototype.min = -1;
However, I'm curious if this is the right way to monkeypatch this object. Pretty sure it is, but thought I would ask the wider StackOverflow community, and offer something googlable for future searchers.
Yes, that's correct. Alternatively, if you're using jQuery UI 1.9, you can use the widget factory to define your extension:
$.widget( "ui.progressbar", $.ui.progressbar, {
min: -1
});
Though it is slightly more verbose.
Related
Short version:
I'm updating some old libs to try to get them in AMD/requirejs format for management, but some of them have dependencies on old code.
Main Question:
I'm primarily confused as to what to list in the:
define(['what','goes','here'],function('what','needs','to','be','here'){})
and what goes in the shim dependencies list when dealing with combinations of AMD and non-AMD tools, and things like jquery-ui and jquery plugins.
ADDITIONAL INFO
The problem:
One of the older libraries depends on .draggable() from (and older version of) jquery-ui, some old version of a jquery plugin called 'onScreen', a spinner modal called spin.js -- all of which are not AMD friendly. (I also implemented an update to an AMD friendly new version of dropzone)
Two of the older libraries also use a modal library called vex which requires a dependency of vex.dialog. The existing site has an old version that is uglified.
I'm trying not to completely revamp this code as the longer term goal would be to remove those dependencies entirely, but I may not have to the time now to figure out what they are doing.
I've tried every combination of define(['list','of','stuff']) I can think of, but some of the libraries like spin (class Spinner), vex/vex.dialog and onScreen still don't always load properly. (sometimes I get one, but then lose another)
Can I define a shim AND include a list of AMD modules in the define? And if so, do I include the AMD list of dependencies in the shim in require.config? What goes where and why?
My libraries:
ImageSelector (requires AwsHelper, Utilities and ImageLayout below)
-- uses jquery (AMD), dropzone (AMD) and an old jquery plugin called jquery.onscreen.js (non-AMD)
-- depends on vex and vex.dialog (non-AMD)
-- uses .draggable() from old jquery-ui (non-AMD)
-- calls a global function 'loadSpinner' which uses spin.js (non-AMD -- see Utilities below)
ImageLayout (requires AwsHelper and Utilities - has attached instance of ImageSelector as a property .selector for methods that work in conjunction with the selector)
-- uses jquery (AMD)
-- also utilizes vex/vex.dialog (non-AMD)
Utilities
-- I'm trying to move the loadSpinner() function that requires spin.js (class Spinner, non-AMD) into this
-- I've managed thus far to avoid dependencies on things like jquery in this by refactoring code
Long version:
I'm trying to update some website code to use require.js for dependency management and to make the code more portable. But I'm running into a number of dependencies on old code that don't appear to be AMD-ready. Where possible, I'm trying to replace these with updated code and/or replace their functionality entirely, but in a number of cases, the code is minified and it's difficult to get a quick handle on what it's doing.
Rather than getting mired in minutia of trying to figure out and either replace or update these things, I read about how 'shim' can be used in some cases to handle these types of non-AMD code, but I'm still unclear on how to configure them.
Here's what I have... I have three libraries I have updated and one new one I created. One called 'ImageSelector' builds a web-gui to allow uploading files with dropzone. (My reason for updating it is that I converted it from using a local filesystem to using Amazon AWS S3 storage.) A second one called 'ImageLayout' handles the business logic of creating a product layout of photos selected by the user. (ImageSelector is split into two frames, a left one for uploading and sorting user files into folders, a right one for building the layout. Thus ImageSelector is dependent on ImageLayout)
The third library is one I created just with a number of repeatedly use 'utility' functions used across the website. There is an existing structured-code version of this in global scope with just a list of functions like roundPrecision(), sanitizeFilename(), escapeRegex(), baseName(), etc. I was going to build this with static methods, but then realized I can customize it if I spawn instances of it instead (e.g. I can change the characters 'sanitized' for different applications with global instance parameters)
The new one is the AwsHelper which is not a problem as it's entirely new code and handles all the interaction with Amazon AWS and S3. It was created in a define() AMD format while the others I have converted to define()/export format.
Anyway, some functions of the ImageLayout can be used independently by the order system, but for the most part, it's used as a dependency of the ImageSelector. AwsHelper is used mostly by ImageSelector but there are two functions in ImageLayout that utilize it. All of the above use the Utilities library.
My guess is something like this in the config (using ImageSelector as an example, but I'm wondering if "jquery" an "dropzone" need to be in there or the function define or both?)
shim: {
"ImageSelector": {
deps: ["jquery","dropzone","vex","vex.dialog","jquery-ui","jquery.onscreen"]
}
}
Additional require.js semantic questions:
(I'll post these separately if needed, but they may be short-answer and related)
Is there anything anywhere that shows how require.js searches for files? e.g. I understand about r.js for uglifying, but in some cases I can't track down the original code for these things. Can filenames include .min.js on the end or version numbers and will require.js still find them or should I rename and/or symlink files? e.g. jquery.js vs jquery-1.7.min.js for example.
The spin.js referenced above actually includes a class definition called 'Spinner'. How do I represent that in the config/shim?
Well, I posted that based on my experimenting the last 3 days riddled with failures, expecting more trouble. But apparently, shim was straightforward and having the required libs in more than one place (shim definitions and define([])) wasn't a problem.
I took a blind guess going through the examples on the require.js and came up with this configuration and amazingly it worked first try! (which makes me nervous as this is the first time I've gotten this code to work with no errors since trying to import it to require.js)
Here's what I came up with:
requirejs.config({
"baseUrl": "/js/lib",
"paths": {
"ImageSelector" : "../awsS3/ImageSelector",
"ImageLayout" : "../awsS3/ImageLayout",
"AwsHelper" : "../awsS3/AwsHelper",
"Utilities" : "../awsS3/Utilities"
},
"shim": {
"jquery.onscreen": {
"deps": ['jquery'],
"exports": 'jQuery.fn.onScreen'
},
"jquery-ui" : ['jquery'],
"vex.dialog" : ['jquery','vex'],
"vex" : ['jquery'],
"spin" : {
"exports": "Spinner"
},
"aws-sdk" : {
"exports" : "AWS"
},
"Utilities": ["spin"],
"AwsHelper": ["jquery","aws-sdk"],
"ImageSelector": {
"deps" : ["jquery","dropzone","vex","vex.dialog","jquery-ui","jquery.onscreen","ImageLayout","AwsHelper","Utilities"]
},
"ImageLayout": {
"deps" : ["jquery","vex","vex.dialog","Utilities"]
}
}
});
I also noted that some of the version naming was handled in the paths, thus I just named my libs in the paths and got rid of my "app/" directory reference altogether.
rails 3.2
I am new to slim, and I have to work with an application that's using it. Reading through some documentation, I see that using something like:
.class
which translates to:
<div class="class"></div>
In the code I inherited, in the .html.slim file, I have:
.form-section.customer_info
When I look through the stylesheets folder, I cannot find customer_info, but I can find form-section.
Shouldn't I be able to find customer_info in one of the stylesheets?
The answer is maybe you can find it in a stylesheet. But there are other cases, where you may not:
Sometimes a class is used as a target for a JavaScript snippet; if you find it mentioned in the javascript for the app, then you likely want to keep it because an interaction may depend on it (read the JS code to determine this).
Sometimes, the class has been removed from the stylesheet and not removed from the code; in this case you may remove it.
However, sometimes a class is added to mark the section of HTML as semantically significant so that styling can be applied to it at a future time; in that case, you may choose to keep it.
For instance, for better or ill, when I am writing code, I will name sections using classes, as .user-list or .part-table to indicate that, as the coder, I know the HTML code is going to contain users or parts. By doing this consistently I can mark out portions of the front end for later consistent styling by usage; that is, all the part tables can be styled the same way, all the user lists can be styled the same way, etc. Again, this is a convention I have seen used and that I practice. Nonetheless, these represent a few reasons why a class may be present in the HTML, but not referenced elsewhere.
I have situation where I generate stylesheets based on information in the database. This means I have a views/users/show.css.erb which contains code like:
a {
color: <%= #user.favorite_color %>;
}
Fair enough, works perfectly with a respond_to { |f| f.css } in my controller. However now I would like to use some of SASS's sassy functions like lighten, darken etc. in my CSS, so I would like to have SASS parse my view. However I cannot figure out how to register SASS as a template handler in my views without too much ugly hacks. I just don't get how it works. Has anyone ever tried this?
I have tried including SASS's Functions module but to no avail.
I was planning of doing the same for dynamic user themes some time ago. Back then, I found a mailing list answer to a similar question to yours, by Nathan Weizenbaum (author of SASS) which got me back on the straight and narrow:
On Mar 18, 11:46 am, Nathan Weizenbaum wrote:
There's a reason Sass doesn't allow dynamic access to Rails code - see
the Sass section ofhttp://haml.hamptoncatlin.com/docs/rdoc/files/FAQ.htmlfor
a brief discussion. Sass is also fairly slow, since it's only compiled once,
so this is probably far too slow for a production environment.
The link is not working anymore, but the SASS FAQ has only one section called Can I use a variable from my controller in my Sass file? which answer the dynamic question:
If you really, really need to compile Sass on each request, first make sure you have adequate caching set up. Then you can use Sass::Engine to render the code, using the :custom option to pass in data that can be accessed from your Sass functions.
So in general, SASS is not designed for dynamic css generation on each request. Rather it is intended to be used as a pre compilation solution to generate static css files.
Intro:
I'm trying out LESS in an asp.net mvc environment.
I use dotless for server side processing (and I wouldn't want to use client side processing especially afer publishing the complete project).
I have to apply a design where there are different color schemes depending on different things (e.g. time of the day).
Less felt very powerful in this case as designing a parameterized css and only changing like 10 variables at the beginning of the file for every theme was really uplifting.
Problem:
But I would need to somehow change the color themes from an outside parameter.
Ideas:
First I thought that an URL parameter like style.less?theme=fuschia would be good, but I found no way to parse something like this.
Then I thought that making a very short blue.less, green.less, orange.less consisting only declared color variables, and including the main.less in every one of them would be a solid solution.
I had no chance to try out the second solution, but I thought this would be a good time to ask for advice on the most robust way of doing this.
The problem again is: I want to control some things in my less file from the outside.
Yes you can (because I implemented that feature for exactly that reason).
Dotless supports parameters from the outside via the querystring parameter.
<link rel="stylesheet" href="style.less?foo=bar" />
Will let you use the following less:
#foo = bar;
The parameter injection code is very simple. it just prepends the variable declarations to your normal less file, so anything that comes as a querystring parameter will follow the above syntax.
The code in question is very simple: https://github.com/dotless/dotless/blob/master/src/dotless.Core/Engine/ParameterDecorator.cs
AFAIK, you cannot pass parameters for dotnetless to use to do the compile.
As a suggestion, why not just call different less files? This would be fairly easy to do by using a Viewbag property.
To make the different less ones, You first create a less file with each set of colors in them. Then you import your base css file. dotnetless will merge the color definations in the parent file with the usages in the base file. So you have something like -
#baseGray: #ddd;
#baseGrayDark: darken(#baseGray, 15%);
#baseGrayLight: lighten(#baseGray, 10%);
#import "baseCss.less";
I just tested this on and MVC3 project and it works.
I'm working on my first very complex JQuery based application.
A single web page can contain hundreds of JQuery related code for example to JQueryUI dialogs.
Now I want to organize code in separated files.
For example I'm moving all initialization dialogs code $("#dialog-xxx").dialog({...}) in separated files and due to reuse I wrap them on single function call like
dialogs.js
function initDialog_1() {
$("#dialog-1").dialog({});
}
function initDialog_2() {
$("#dialog-2").dialog({});
}
This simplifies function code and make caller page clear
$(function() {
// do some init stuff
initDialog_1();
initTooltip_2();
});
Is this the correct pattern?
Are you using more efficient techniques?
I know that splitting code in many js files introduces an ugly band-bandwidth usage so.
Does exist some good practice or tool to 'join' files for production environments?
I imagine some tool that does more work than simply minimize and/or compress JS code.
Some suggestions I might add:
keep all your variables in a globally available, multi-structured object, something like: MyVars = { dialogs: {}, tooltips: {} } and then use that across all your scripts
use call or apply methods for dynamically calling custom function names,if you perhaps want to keep the above object lightweight
For tidying things up, you could read this: http://betterexplained.com/articles/speed-up-your-javascript-load-time
This sounds fairly okay too me. Just two notes:
Use descriptive method names. "initDialog_1" doesn't tell you anything about the dialog it initializes.
While keeping JS code split into several files eases development it harms the felt performance of your interface. You could merge all files into one during build/deployment/runtime of your app. How to do it best heavily depends on your environment though.
I'm working on something fairly complex in JS right now, and have been wondering the same thing. I looked at various "module" implementations but while they look "cool" they don't seem to offer much value.
My plan at this point is to continue referencing lots of script files from my .html page (the plan is to only have one .html page, or very few).
Then when I'm building the release version, I'll write a very simple tool to fit into my build process, which will discover all the scripts I reference from the .html pages and concatenate them into one file, and replace the multiple <script> elements with a single one, so that only one request is necessary in the "release" version.
This will allow the compression to work across all the script text instead of on each separate file (like doing tar followed by gzip) and should make a difference to the script download time (though I should stress I haven't actually implemented it yet).
You usually want to keep all of your javascript inside one file. Less HTTP requests is usually better. If you take a look at the jQuery source, you'll notice that every function and property is right there in the jQuery global object:
jQuery.fn = jQuery.prototype = {
init: function(){ ... },
animate: function() { ... },
each: function() { ... },
// etc
}
However, the pattern you seem to be interested seems similar to the "module" pattern. The YUI framework uses this pattern, and allows developers to "require" different components of the library from the core module via HTTP request. You can read more about YUI here:
http://developer.yahoo.com/yui/3/yui/