My site has some customers that work for organizations who are blocking font downloads in IE, so I need to create fallback options for FontAwesome. I am trying to use web font loader to detect if FontAwesome loaded correctly, but web font loader is always reporting that FontAwesome failed to load even though I can see that the FontAwesome icons loaded. I have tested IE 9/10/11.
You can view this in action at https://vnext.radresponder.net. You will see that in Firefox and Chrome, FontAwesome is correctly loaded and marked as active; however, in IE the font loads but then web font loader fires the failed to load callback and attaches the inactive class to the HTML tag. I have special CSS to load some fallback characters to replace the FontAwesome icons which are then loaded.
From the web font loader GitHub page, I don't see any incompatibilities listed with IE, so I assume this should work.
Here is my WebFont.load statement.
WebFont.load({
custom: {
families: ['FontAwesome'],
urls: ['/local/address/for/fontawesome.css'],
testStrings: {
'FontAwesome': '\uf00c\uf000'
}
},
loading: function () {
console.log("loading");
},
fontloading: function (fontFamily, fontDescription) {
console.log('fontloading: ' + fontFamily);
},
fontactive: function (fontFamily, fontDescription) {
console.log('fontActive: ' + fontFamily);
},
fontinactive: function (fontFamily, fontDescription) {
console.log('fontInActive: ' + fontFamily);
},
active: function () {
console.log("active: loaded all web fonts");
},
inactive: function () {
console.log("inactive: did not load all web fonts");
}
});
Edit - 2015/05/27 9:58 am
I changed the timeout from the default 3 seconds to 10 seconds, and the load is definitely taking all 10s and then timing out. I am not sure what that means. Why is it only timing out on IE?
Related
I created a little page with sveltekit and tailwind css. Now I want to use the sveltejsadapter-static to create a complete static html version. This works fine for all subpages like /imprint or /privacy but the the first page / doesn't load the stylesheet.
Here's my svelte.config.js
import adapter from '#sveltejs/adapter-static';
const config = {
kit: {
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: null,
precompress: false
}),
trailingSlash: 'always',
prerender: {
default: true
}
},
};
export default config;
By browsing to /imprint all styles look fine. The link to the stylesheet starts with /_app/…
When I load the base url, I can see the correct styles flashing for some milliseconds, but after that, all styles are gone. If I remove the / of the style and js links in the source code (_app/…), the page looks fine. But I can't find an option to create the first index file without the staring slash.
Also strange: When I click on the logo from /imprint (which links to /), the page looks fine, but never on first load.
Found the solution.
I defined the html tag in a component which is already defined in the app.html.
<svelte:head>
<html lang="de" />
</svelte:head>
I'm developing a new tab replacement extension for Google Chrome and I'd like to allow the user to customize the background, to do so I'm using the storage.sync API as suggested by this page.
The problem is that the style changes are applied asynchronously, so the default background (white) is briefly used during the page load resulting in unpleasing flashes.
Possible (unsatisfying) solutions are:
do not allow to change the background;
hard code a black background in the CSS (and move the problem to custom light backgrounds);
use a CSS transition (still super-ugly).
What could be an alternative approach?
Follows a minimal example.
manifest.json
{
"manifest_version": 2,
"name": "Dummy",
"version": "0.1.0",
"chrome_url_overrides": {
"newtab": "newtab.html"
},
"permissions": [
"storage"
]
}
newtab.html
<script src="/newtab.js"></script>
newtab.js
chrome.storage.sync.get({background: 'black'}, ({background}) => {
document.body.style.background = background;
});
I come up with a reasonable solution. Basically since the localStorage API is synchronous we can use it as a cache for storage.sync.
Something like this:
newtab.js
// use the value from cache
document.body.style.background = localStorage.getItem('background') || 'black';
// update the cache if the value changes from the outside (will be used the next time)
chrome.storage.sync.get({background: 'black'}, ({background}) => {
localStorage.setItem('background', background);
});
// this represents the user changing the option
function setBackground(background) {
// save to storage.sync
chrome.storage.sync.set({background}, () => {
// TODO handle error
// update the cache
localStorage.setItem('background', background);
});
}
This doesn't work 100% of the times but neither do the simple:
document.body.style.background = 'black';
So it's good enough.¹
¹ In the real extension I change the CSS variables directly and I obtain much better results than setting the element style.
This is basically the code I am using and lighthouse says my (almost empty!) css bundle is delaying my initial load.
So how do I put a link to critical.scss in the
<head><style>DONT_WANT_TO_WRITE_STUFF_INLINED</style>...</head>
Is there a better solution than https://www.npmjs.com/package/critical or writing everything inlined?
And how do I delay the load of the main styles.scss until the prerendered Universal content is loaded in the browser? The server-app's config in angular-cli.json does not contain styles or assets, so I don't understand why styles.scss is loaded initially
Regarding delaying the load of the main styles.scss, I rely on two things:
First of all, I build the application with the --extract-css=false flag. That ensures that the styles bundle will be a JavaScript file.
Second, I defer the loading of that file. To do so I rely on a small script that I called defer.styles.js and that runs at the end of the build process. That script simply looks for the script tag that loads the styles, and adds a defer to it.
const path = require('path');
const htmlPath = path.join(__dirname, 'dist', 'browser', 'index.html');
fs.readFile(htmlPath, 'utf8', (err, data) => {
if (err) {
console.log(err);
return;
}
const index = data.search(`src="styles.`);
if (index > -1) {
const output = [data.slice(0, index), 'defer ', data.slice(index)].join('');
console.log(output);
fs.writeFile(htmlPath, output, 'utf8', () => {
console.log('Styles succesfully deferred');
})
}
});
Regarding your other question - how to load the critical css -. I still didn't find a way of comfortably doing it.
I am new to chrome extension development. I am writing a chrome extension that will inject CSS into the page. I've been successful in doing this by specifying the css file in manifest.json.
I now want to apply different css (files) depending on a link or button selected on a popup triggered through a browser_action. So clicking link 1 will apply style-red.css and clicking link 2 will apply style-blue.css. A third "reset" button should reset css back to its original state (removing the custom style red or blue css files).
My manifest.json is as follows:
{
"name": "Redesign",
"version": "1.0",
"manifest_version": 2,
"content_scripts": [
{
"matches": ["*://*.my-site.com/*"],
"js": ["jquery-3.1.0.min.js", "script.js"]
}
],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": [
"tabs", "*://*.my-site.com/*"
]
}
My current approach is to have a listener in script.js listening for the button pressed in popup.html. Depending on the button pressed, the following script.js will add the corresponding CSS file into my-site.com using the jquery below:
$(document).ready(function() {
var path = chrome.extension.getURL('style-red.css');
$('head').append($('<link>')
.attr("rel","stylesheet")
.attr("type","text/css")
.attr("href", path));
});
I tried to use the above jquery in script.js (without the browser_action in the manifest.json) thinking script.js will get automatically loaded but the CSS does not get applied to my-site.com. What am I doing wrong or is there simpler Javascript without the need for a full jquery library to be added?
And even if the jquery works, how do I apply a different CSS file based on the choice in popup.html as well as reset the css back to its original styling upon user choice?
To insert css file in content scripts, you need to declare the css file as web_accessible_resources
To dynamically insert css files, see chrome.tabs.insertCSS, it can be called in extension context, such as popup page.
I'm working on a project where I'm trying to use some 5 custom fonts.
I use webfont.js library so that I can time my initialisation the way I want to.
However, I notice that I have an intermittent issue, whereby webfont.js will fail loading all 5 fonts 75% of the time. If I ignore the error (inactive handler) and just resume loading my site I can see all custom fonts fine.
This is annoying because webfont.js takes around 4 seconds to raise the inactive event and so the user just sees the blank page while this is happening.
How do I fix (or at least debug) this?
This is my setup (util.js):
var mutexFontsLoaded = $.Callbacks("memory once");
WebFontConfig = {
custom: {
families: ['Chennai-Regular', 'Chennai-Light', 'Chennai-Bold', 'Quicksand-Bold', 'Segoe-Print'],
urls: ['css/fonts.css']
},
loading: function () { console.log("Loading fonts.."); },
active: function () { mutexFontsLoaded.fire(); },
fontinactive: function (font, fvd) { console.log("Could'nt load " + font + " font"); },
inactive: function () { console.log("All fonts failed loading..\n\rTrying to load site anyway.."); mutexFontsLoaded.fire(); }
};
Followed by the Web Font Loader library - 1.5.1
Then in my main script:
$(document).ready(function () {
mutexFontsLoaded.add(function()
{
application.init();
});
});
Debugging the webfont.js library from google's CDN made me see the issue.
Webfont.js injects a <span> with a test string into the <body> DOM element. It then sets the custom font on this span and repeatedly calculates width of the <span> to test for any changes. If it captures a change then it assumes the custom font has loaded. If no change is detected within a timeout then it signals failure.
In my case <body> element was hidden with display: none; because I only wanted to show the page once I knew all the elements are downloaded. Because of this the injected <span> never changed its calculated width.
Finally fixed!