castillo-io / angular-css Goto Github PK
View Code? Open in Web Editor NEWCSS on-demand for AngularJS [Looking for New Maintainers]
Home Page: http://castillo-io.github.io/angular-css/#/
License: MIT License
CSS on-demand for AngularJS [Looking for New Maintainers]
Home Page: http://castillo-io.github.io/angular-css/#/
License: MIT License
The "weight" property is not evaluated ever...
Hi there,
I was reviewing this promising angular module and found a small algorithm issue in the $css.preload()
function.
Here's the original function code:
/**
* Preload: preloads css via http request
**/
$css.preload = function (stylesheets, callback) {
// If no stylesheets provided, then preload all
if (!stylesheets) {
stylesheets = [];
// Add all stylesheets from custom directives to array
if ($directives.length) Array.prototype.push.apply(stylesheets, $directives);
// Add all stylesheets from ngRoute to array
if ($injector.has('$route')) Array.prototype.push.apply(stylesheets, $css.getFromRoutes($injector.get('$route').routes));
// Add all stylesheets from UI Router to array
if ($injector.has('$state')) Array.prototype.push.apply(stylesheets, $css.getFromStates($injector.get('$state').get()));
}
stylesheets = filterBy(stylesheets, 'preload');
angular.forEach(stylesheets, function(stylesheet, index) {
// Preload via ajax request
$http.get(stylesheet.href)
.success(function (response) {
$log.debug('preload response: ' + response);
if (stylesheets.length === (index + 1) && angular.isFunction(callback))
callback(stylesheets);
})
.error(function (response) {
$log.error('Incorrect path for ' + stylesheet.href);
});
});
};
I can see that angular.forEach(stylesheets, ...
will make the program download each stylesheet by ajax, and for each stylesheet download success, we'll run the callback
function only when we downloaded the last stylesheet in the list.
For me, the problem is that we assumed that stylesheets will be loaded in sequential order.
However, due to the nature of ajax requests and the unpredictable response speed of servers, this cannot be guaranteed.
So I think this part of the algorithm should take advantage of promises to make sure that the callback function is called at the end when all stylesheets have been loaded successfully.
So here's my suggested code change:
// Assuming that $q is injected in the module's JS scope
var stylesheetLoadPromises = [];
angular.forEach(stylesheets, function(stylesheet) {
stylesheetLoadPromises.push(
// Preload via ajax request
$http.get(stylesheet.href)
.success(function (response) {
$log.debug('preload response: ' + response);
if (stylesheets.length === (index + 1) && angular.isFunction(callback))
callback(stylesheets);
})
.error(function (response) {
$log.error('Incorrect path for ' + stylesheet.href);
})
);
});
if (angular.isFunction(callback)) {
$q.all(stylesheetLoadPromises).then(function(){
callback(stylesheets);
});
}
Please let me know what you think.
Regards,
David
These can be automatically added to the $templateCache using a build tool like https://www.npmjs.com/package/grunt-angular-templates
Does angular-css work with the angular new router?
Hook add event to pre-compile phase
In order to avoid FOUC
ngAnnotate is a great tool that will automatically make your dependencies min-safe
I think this might be fixed by parsing the stylesheet just like in $css.add
Another possible solution: #5
In IE8 page is not loading if i add it
Anders: "Hey there Alex, first of all its a pretty damn cool plugin - just what I need for my project.. However once i set the css property in a directive, my link function is called with no arguments. So scope, and element are both undefined.
Is there a fix for this?"
I've tried this in my project, but unfortunately, it will throw "invalid arguments" error in IE9.
I do some analysis and want to confirm my guess:
I config the css like this:
$stateProvider.state('home', {
url: '/home',
template: require('./views/home.html'),
css: 'assets/home.css'
})
the error occurred when jquery try to set href for the link dom element. I guess it happens when the template is compiled.(below code is from $set method in angularjs)
this.$$element.attr(attrName, value);
at this moment, attrName is 'href', value is 'assets/home.css'. then I debug into jquery, then the error will throw at this line in jquery:
elem.setAttribute( name, value + "" );
then I found this: http://stackoverflow.com/questions/1184950/dynamically-loading-css-stylesheet-doesnt-work-on-ie
it seems this link explain why the error happen in IE9. I guess it's because in angular-css, the template is compile first and then append to head, but it seems IE9 doesn't support this.
But angular-css's doc says it support IE9, So I'm doubt my analysis and just want to confirm it. and figure out why I get the error here.
Hope get some help from your guys :), thanks in advance.
If I want to a service or constant available as a dependency on the directive, it fails. Looking at the demo, this works:
myApp.directive('magenta', function () {
return {
restrict: 'E',
replace: true,
templateUrl: 'directives/magenta/directive-magenta.html',
css: {
href: 'directives/magenta/directive-magenta.css',
/* Preload: this will trigger an HTTP request on app load.
* Once the stylesheet is added, it will be loaded from the browser cache */
preload: true
}
}
});
But this does not
myApp.directive('magenta', function ($log) {
$log.debug("in magenta directive");
return {
restrict: 'E',
replace: true,
templateUrl: 'directives/magenta/directive-magenta.html',
css: {
href: 'directives/magenta/directive-magenta.css',
/* Preload: this will trigger an HTTP request on app load.
* Once the stylesheet is added, it will be loaded from the browser cache */
preload: true
}
}
});
If I'm understanding the way this works, the directive factory is executed once in angular-cs.js to find the css definition and add appropriate event handlers.
var directive = angular.copy(originalDirectiveFactory)();
And when this fails, it is silently ignored (since many directives dont have css and might be written such that they might fail).:
However, this ignores the dependencies required by the factory. It looks like as long as the factory, itself, doesn't access the dependencies, or guards for undefined, and can return an object that has at least the the css def, it should work. In my case, I had a $log.debug that failed, because the $log is undefined, but was also using a constant to defined part of the path to the css and template.
Do you think it would it be feasible to use the $injector, so that the factory can execute properly as it would in normal use?
Hi,
Your module is pretty awesome, however i have a little problem, while loading my page for the first time, i have a tiny moment when the css is not yet applied to the html so i can see all the html element without css.
My application is very simple: it has only one module named Homepage that load the homepage of the site.
-> I inject the homepage.css in the stateProvider in the config/homepage.js which is the first file to be load of the module Homepage.
-> In terms of timing the site takes about 550ms to completely load.
-> The homepage.css is load at about 450ms and the homepage.html is load at 550ms. So the css is load about 100ms before the html however i always have this moment without css.
Do you have any ideas how to fix this?
Thanks
Given a directive with a template that has a select
with ngOptions
, the presence of a css
parameter seems to delay the link
state of a directive such that ngOptions
are parsed and set after a significant delay. This means that the ngModel
value set on a directive isn't respected since there aren't
any values in the dropdown to compare against.
I've reproduced the issue in this Plunker: http://plnkr.co/edit/mDelhZqXeqhkTt55u51M
Angular 1.3.17 and angular-css 1.0.7
Currently I am using a dynamic template URL using a function as given below in the Routes.
.when('/:page', {
templateUrl : function(url) {
return '/static/partials/' + url.page + '/template.html';
},
....
}
When I tried the same with CSS, it is unable to find "url"
css : function(url) {
return '/static/partials/' + url.page + '/styles.css';
}
Is there any chance that we can provide Dynamic CSS URL as mentioned above?
To make the codebase easier to read and work on, it would help to have each service/factory/provider separated into its own file and concatted at build.
Using Angular 1.5.0 and $routeProvider to inject the css like this:
.when('/profile/:memberId', { templateUrl: 'views/profile.html', controller: 'ProfileCtrl', css: { href: 'assets/css/profile.css', preload: true }, controllerAs: 'profile' })
Get an error that says: "Error: [orderBy:notarray] Expected array but received: 0"
Hi, is it possible to define nested states with ui-router and assign a stylesheet to a parent state that will be inherit for all child states?
Something like this:
Where profile.about and profile.friends states both will not reload the profile.css file since it was already loaded for the profile state?
what I found happen is that only the child state style file is loaded!
is that the intended behaviour, or there's something I'm missing?
here's a plunker with examples, thanks in advance.
when using the controller with the routes configurations the parent stylesheet gets loaded after the child stylesheet which ruin the overrides in the child state, this also happen when using only the controllers without the states configuration, also the link tags in the head gets inserted in the wrong order they should be reversed.
Simulate isolate css scope by prefixing the directive's name before each eligible selector.
just curious. thanks.
In order to avoid FOUC
I install angular-css using bower and I got angular-css 1.0.7. The problem is the module name is door3.css
rather then 'angularCSS'.
here is what I got.
/**
* AngularCSS - CSS on-demand for AngularJS
* @version v1.0.7
* @author DOOR3, Alex Castillo
* @link http://door3.github.io/angular-css
* @license MIT License, http://www.opensource.org/licenses/MIT
*/
'use strict';
(function (angular) {
/**
* AngularCSS Module
* Contains: config, constant, provider and run
**/
var angularCSS = angular.module('door3.css', []);
and here is new version in github
/**
* AngularCSS - CSS on-demand for AngularJS
* @version v1.0.8
* @author Alex Castillo
* @link http://castillo-io.github.io/angular-css
* @license MIT License, http://www.opensource.org/licenses/MIT
*/
'use strict';
(function (angular) {
/**
* AngularCSS Module
* Contains: config, constant, provider and run
**/
var angularCSS = angular.module('angularCSS', []);
should I use door3.css
or wait for 'angularCSS'
Hi,
I added this in my angularjs app, used in a state.
In the state, provided the css.
But it is loaded in all of the (unrelated) states, instead of just the requisite state.
Does this pulgin support folder destination? That is, on a parent state(Angular UI) set the href to folder and all the css files within the folder are added for child states of the parent state.
I'm noticing that the css file attached to a view is getting called every time I go to its corresponding view. Is there a way to only load the css file the first time a view is loaded?
This issue is causing a delay between the time it takes to load the view and render the css which is very noticeable.
Let's say I have 2 parts of a bigger website that typically look a lot different from the main website, ...like totally different and using totally different CSS assets (for historical reasons, etc.). When loading those 2 parts, I dont want them to "overwrite" neither any style from -a) the main site itself; & -b) nor each other.
Just to be sure, the way to deal with this is indeed with help from this cool plugin to specifically load the css needed WHEN I arrive on this $state (ui-router) and (also?) unload any "main" css files from the main websiite potentially colliding with the new css ...and when leaving to "reload" the "old" css from the main files and "unload" the css from $state I was on ? (And repeat same thing for the second 'special' part from my exampe)
Am I correct ? Thanks a lot.
which is obvious
but then how to allow user to force reload?
so maybe you could add additional property which could mark that such css is general one
and has to be available for all pages
something like
{
href: 'myGeneralCssFile.css',
global: true
}
this will of course overwrite persist property and should probably also overwrite preload as well
EDIT:
just to explain - it would be useful for example for other libs css files
ie:
font-awesome
is there a way to accomplish something like this in directive
...
css: '/path/to/{{scope.variable}}'
...
Hi,
Angular 1.5.0 has been released. Please release angular-css 1.0.8, as long as master contains the angular 1.5 compatibility fix.
I'm about to submit a feature enhancement, but I'm not quite sure how the testing is setup. I've tried this:
npm install
bower install
grunt test
Am I doing something wrong or is the project not setup for unit testing yet?
Is support for angular 1.5's component router on the roadmap? Do you think it would be difficult to add it?
We have a big AngularJS application and using angular-css extensively, since it gives a lot of freedom while designing directive templates.
When the application gets too big, FireFox and later also Internet Explorer begin to throw errors:
Error: too much recursion
Error: Out of stack space
Chrome is still happy with the app, until it grows even larger.
It seems that the problem lies in the call of $provide.decorator(...)
in the "AngularJS hack" (lines 567+).
Plunker of an abstracted structure of our app (which leads to the errors in FF and IE): http://plnkr.co/XGIJzZPcHhkXQ3HUoLgG
how in webpack use angular-css
Hi there,
I was wanting a way to include a certain CSS file (which is dynamic) on each and every state. I was thinking of doing this via an abstract state and having all other states use the abstract.
Does this support abstract states?
The css I need to include on every page would be available in a variable but I just can't insert it onto the page as it changes depending on certain this.
Is there support for this ?
Is it possible to return a string from a function to the css property in ui router? Because I would like to use the $stateParams to set the path to css file. Something like this:
.state('State', {
url: '/page/:id',
controller: 'Ctrl',
templateUrl: function($stateParams){
return $stateParams.id+'/views/index.html';
},
css: function($stateParams) {
console.log($stateParams);
return $stateParams.id+'/styles/main.css'
}
});
When the angular-css module is included in an app, the module's $logProvider.debugEnabled setting is overridden by the parent app's setting as it seems impossible to make the angular-css module have a distinct config phase. This makes for a significant amount of console noise.
Can the debugging be disabled in a way that leaves debugging enabled for the parent app? Perhaps remove the debug lines entirely as part of the build process, building to a dist folder?
Or am I seeing some weird behaviour that nobody else is seeing?
I'm using Angular 1.4.5
Hello,
When we reload the page on a child state (like /home/profile), the parent css (home.css) is not applied to the child.
Is there a way to persist the css on reload ?
Thanks !
Please update the bower~
Your module is amazing!
In order to avoid FOUC
when reload to page not get the css...
Love the plugin but when I went to use this in my deployed version none of the CSS is loading. This looks to be down to the fact that my server version uses $templateCache for all html files and as these aren't loaded over html they are not picking up the new styles. Is there any workaround for this?
Allow definition of breakpoints in $cssProvider.defaults
This will allow the user to reference a breakpoint as opposed to be using the same media queries over and over.
The API should look like this:
myApp.config(function($routeProvider, $cssProvider) {
angular.extend($cssProvider.defaults, {
breakpoints: {
mobile: '(max-width : 768px)',
desktop: '(min-width : 769px) and (max-width : 1219px)',
kiosk: '(min-width : 1220px)'
}
});
$routeProvider
.when('/black', {
title: 'Black',
templateUrl: 'pages/black/page-black.html',
css: [
{
href: 'pages/black/page-black.mobile.css',
breakpoint: 'mobile'
}, {
href: 'pages/black/page-black.desktop.css',
breakpoint: 'desktop'
}, {
href: 'pages/black/page-black.kiosk.css',
breakpoint: 'kiosk'
}
]
})
});
Create tests for:
Directives
Add
Remove
With sufficiently large stylesheets, there is a noticeable flicker when loading the sheet; after the HTML renders, but before the CSS is applied. Angular and uiRouter both have solutions for this issue, but angular-css
doesn't support either of them natively.
ngCloak
does wait until the HTML renders, but the stylesheet lags behind considerably; and I can't find a way to use angular-css
inside ui-router's resolve
. Support for either of these would be fantastic. Personally, I think the ngCloak
approach is more "Angular", but there needs to be a way to wait for the stylesheet before showing the page.
Thank you so much for an otherwise amazing project! This feels like one of those things that are so obvious it's weird they're not built into Angular as it is. Keep up the good work! ๐
Is there a way to specify the CSS to inject as a set of rules in text format? I mean, without having to reference a CSS file?
This can be done with debounced window resize events.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.