I've been playing with Polymer recently and finally I think I have my head around the shadow boundary, at least to the extent that I know where I need to include link tags to make my CSS work.
This is fine and dandy but I can't use Google fonts. If I use an #import inside my stylesheet, then as soon as that stylesheet is included in a Polymer custom element I get CORS issues:
XMLHttpRequest cannot load http://fonts.googleapis.com/css?family=Maven+Pro:400,700. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:64000' is therefore not allowed access
There's an XMLHttpRequest involved here, probably because of how Polymer fetches resources and custom elements in the first place, which I suppose is axing the header mentioned in the error message.
However, if I only use the link method
<link href='http://fonts.googleapis.com/css?family=Maven+Pro:400,700' rel='stylesheet' type='text/css'>
This doesn't cross the shadow boundary, and I still don't get my fonts.
Am I missing something obvious? How do I get Google fonts inside the shadow DOM? I tried downloading the zip file from Google Fonts itself but I only got TTF files.
What we typically do with fonts on the Polymer team is to create an HTML import that loads the font(s), and include that import as a dependency in your element's import. This puts the font definitions in the main document (so they can be used by any components) but also guarantees that the fonts will be available in your element's shadow dom.
Here's a quick example: http://jsbin.com/cefawali/1/edit
We do this with the RobotoDraft font. Here's the import: https://github.com/Polymer/font-roboto/blob/master/roboto.html
The other approach is to use no-shim and use #import:
<polymer-element>
<template>
<style no-shim>
#import url('http://fonts.googleapis.com/css?family=Maven+Pro:400,700');
</style>
...
Note There's currently a bug preventing this latter approach from working.
Related
Background
I want to stop using Latex for creating documentation and automatic reports for my applications and I would prefer to use html+css that I may later convert to pdf using wkhtml2pdf that allow for adding cover page, table of content, headers, footers, all in A4 separated pages.
wkhtml2pdf is light exe and supports for scripts/css for advanced document pre-processing / formatting. So, so far, so good, it all seems html+css is my best option to replace Latex ...
Issue
In order to ease maintenance and not to put all documentation content in a single file, I had initially thought to organize my local files like this:
doc/index.html
docs/includes/introduction.html
docs/includes/part1.html
docs/includes/part2.html
docs/resources/mystyle.css
docs/resources/jquery-3.1.1.min.js
And write main documentation index.html as follow:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="mystyle.css">
<script src="./resources/jquery-3.1.1.min.js"></script>
<script>
// When document is ready, feed divs with real content
$(document).ready(function()
{
$('#Introduction').load('./resources/introduction.html');
$('#Part1').load('./resources/part1.html');
$('#Part2').load('./resources/part2.html');
});
</script>
</head>
<body>
<div id="Introduction"></div>
<div id="Part1"></div>
<div id="Part2"></div>
</body>
</html>
Unfortunately doing this way, I receive a XMLHttpRequest error basically telling that it cannot load files because cross-origin is only supported for http, data, chrome, https etc... protocols (?? even though all my files are local and main.html was also launched from local file system --so all same origin-- ??).
I tried many workarounds (link rel=import, w3IncludeHTML, use iframe and try to read content) they all fall in cross-origin issue.
Question
Is there an easy/light solution to merge all local html fragments in local main.html file (i.e no external grep or extra tools, just basic html+javascript) ?
NB1: I know I can change flags in chrome browser to allow cross-origin but would like to avoid this. First, for security reason. Second, because I can't do the same when sending files to wkhtml2pdf converter. Third because is not easy to provide documentation as is and say "just click index.html to open documentation in web-browser".
NB2: Documentation fragments is very likely to be just <section>, <p>, <img>, <table> elements all merged in body of main.html managing for css-formatting and other stuff in a single place.
You can get local files in Firefox, using XMLHttpRequest.
It used to work with Chrome, but a "security" restriction has been introduced since 2010 for local files.
Maybe you can suggest to use Firefox to all your customers...
A workaround (for Chrome) could be to load ressources as <script>, and get the content in multiline strings.
In index.html:
<script src="ressource1.js"></script>
...
In ressource1.js:
var fragment1 = `
<section>
HTML content for part 1
</section>`
document.querySelector( '#target1' ).innerHTML = fragment1
Ressources are kept in separate files (in form of JavaScript) and injected in the main HTML document.
Maybe it would be worth to provide an Electron application along with your documentation files to browse it without web server.
Actually it's a node.js web server packed with a chromuim browser. It targets most platfoms and you just need your HTML/JS/CSS skills. By the way you could also integrate a PDF library inside.
Newest progression:
It seems that I can exclude firebase from possible causes. Because I tested only with polymer deployment and got a bad result too.
My project uses Google Polymer and is deployed to firebase hosting. It needs to import some polymer html file from outside the firebase hosting.
So I changed the code from the following "local" to "outside". However "outside" does not work at all, where "local" means my local computer for testing or the firebase hosting.
Could you point out what is wrong in my code?
my-app.html has one of following links.
//"local: OK"
<link rel="import" href="some.html">
//"outside: not OK"
<link rel="import" href="https://outside.com/some.html">
And my-app.html uses the element, id="some", as
<template><some></some></template>
And "some.html" contains just one dom-module with the following simple template. Let me omitt writting other parts because they are minimum too.
<template><h1>test</h1></template>
In order for this to work, resources on other origins must be CORS-enabled (cross origin resource sharing) as this article states. The W3C draft on HTML imports also mentions it.
The link tag also has a crossorigin attribute, which may help here. E.g. <link rel="import" href="https://outside.com/some.html" crossorgin="anonymous">.
I'm new to Polymer and one of the things I like is that I can declare global CSS styling and Javascript libraries in the elements.html file. However, in the demos I have seen elements.html has been reserved exclusively for importing Polymer templates.
Is it bad style to overload elements.html with CSS and JS imports?
No, there is nothing wrong about including JS and CSS files in the elements.html.
Think of elements.html as a non-ui web-component.
There is just one important thing to remember:
Polymer team has created a tool called Vulcanize which takes a file like elements.html which imports all the custom elements, to knit them together into a single file for reducing the number http requests the browser makes to gather the required resources. Adding JS and CSS files here will get this tool confused and generated rather odd results.
So this is exactly why you don't see official examples and tutorials include JS and CSS files in the elements.html.
More about Vulcanize:
https://github.com/Polymer/vulcanize
https://www.polymer-project.org/0.5/articles/concatenating-web-components.html
Hope my writing is clear.
I'm trying to get the content of css files of a website....
<link href="/files/includes/templates-css-main.css" rel="stylesheet" type="text/css" />
For example, it's the link of css ref of http://paceoil.ca/. When I tried to send a request for getting a css file to this url http://paceoil.ca/files/includes/templates-css-main.css, I got an unexpected result.
Any help? Thanks in advance.
On the particular website in question, the reason you're not seeing what you expected is because they've used an uncommon technique called #import to load several stylesheets into one. In general, your method is correct -- http://paceoil.ca/files/includes/templates-css-main.css is indeed a link to their stylesheet.
Inside that stylesheet, you'll see the following statements:
#import 'templates-css-reset.css';
#import 'templates-css-layout.css';
#import 'templates-css-type.css';
#import 'templates-css-nav.css';
#import 'modules-mod_superfishmenu-tmpl-css-superfish.css';
These lines simply load the contents of other .css files all together. The other CSS files can be found at:
http://paceoil.ca/files/includes/templates-css-reset.css
http://paceoil.ca/files/includes/templates-css-layout.css
http://paceoil.ca/files/includes/templates-css-type.css
http://paceoil.ca/files/includes/templates-css-nav.css
http://paceoil.ca/files/includes/modules-mod_superfishmenu-tmpl-css-superfish.css
It should also be noted that on some websites (most commonly on huge websites like facebook), CSS files are not necessarily statically generated. Some servers run "CSS-preprocessing" which allows them to embed code in CSS that is executed and translated before your browser ever sees it. In cases like this, it is impossible to view that code unless the owner shares it with you.
press F12, resources. then you should see the css file of a site
I used the #import at-rule, and it's located in the <head> of my HTML:
<style>
#import url('https://googledrive.com/host/0B4nfVqlTfnTzam45bnFnTXUyOEU');
</style>
This shows up in Firefox but not the latest version of Safari. Can anyone explain why? Is it because the file is in a Google Drive?
If it's just the actual CSS that's the problem, then I don't mind because it's only a test to see if the #import works, but is this method for importing style sheets good for most browsers?
While this should be a functioning method of linking styles to your website, it's not best practice. It basically tells the browser that you are providing an internal style sheet, then tells it to import an external style sheet to nest within this element. I wouldn't be surprised if this were to yield inconsistent results across different browsers. Try skipping the tags and including this instead:
<link rel="stylesheet" href="https://googledrive.com/host/0B4nfVqlTfnTzam45bnFnTXUyOEU/yourfilename.css">
Now, you should consider implementing this method either way, but notice I also changed the file path. Replace "yourfilename.css" with your style sheet's file name. Even if the directory linked contains only one style sheet, you must explicitly define that file in order for the browser find it.