Add external css file to dom AngleSharp - anglesharp

I have an external CSS file that isn't referenced inside of the html file. Is it possible to add this CSS file and apply the styling to the html via AngleSharp on the fly?
Another work around I've thought of is actually inserting the reference to the CSS in the html before parsing it into the DOM but I wanted to know if AngleSharp provided the initial question before I implemented the "workaround". Thanks so much!
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test Doc</title>
</head>
<body>
<div id="styleme">
Hello
</div>
</body>
</html>
Notice no css is linked.
And the external css file:
#styleme {
color:blue;
background-color: gray;
}

Yes. There are actually multiple ways.
I guess what you are looking for is:
var config = Configuration.Default.WithCss();
// note: ideally load your document from a URL directly if applicable
var document = await BrowsingContext.New(config)
.OpenAsync(res => res.Content(#"<!doctype html>
<html lang=en>
<head>
<meta charset='utf-8'>
<title>Test Doc</title>
</head>
<body>
<div id=styleme>
Hello
</div>
</body>
</html>"));
var style = document.CreateElement<IHtmlStyleElement>();
// note: if you have the CSS from a URL; choose IHtmlLinkElement instead
style.TextContent = #"#styleme { color:blue; background-color: gray; }";
document.Head.AppendChild(style);
// note: using LINQPad here; you may want to store the style somewhere
document.DefaultView.GetComputedStyle(document.QuerySelector("#styleme")).Dump();
Hope that helps!

Related

Microsoft/fast-element attribute change

Following the getting started with FAST element guide here, I don't understand why the value of the attribute is not changing whenever I use the element in.
Even when following the guide completely by basically copying and pasting the sample code, I can't make it work.
Based on the code and markup below, I would expect that the h3 element has the value of test and not default.
Anybody who has same issue, or know what I might be doing wrong?
Btw, I'm using esbuild to bundle, transpile and serve the files.
import { FASTElement, customElement, attr, html } from "#microsoft/fast-element";
const template = html`
<div class="header">
<h3>My name is: ${x => x.greeting}</h3>
</div>
<div class="name-tag-body">
<slot>Default slot</slot>
</div>
`;
#customElement({
name: 'name-tag',
template: template
})
export class NameTag extends FASTElement {
#attr greeting: string = "default";
greetingChanged() {
console.log("greeting changed:", this.greeting);
}
connectedCallback() {
super.connectedCallback();
console.log("connectedCallback");
}
} }
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<name-tag greeting="something"></name-tag>
</body>
</html>
The solution is to have the target property of the tsconfig.json file set to something other than ESNext. ES2016 works fine.

How to embed a file into a string using fx:String in MXML?

I'm trying to include a long string in an external file using the following syntax:
<fx:String id="myText" source="examples/text.txt" />
But it's generating an error:
1084: Syntax error: expecting identifier before rightparen.
Is there something I'm missing?
I've seen similar for embedding a text file using ActionScript but I would like to embed a string value using MXML.
I've found this example on Flex help docs:
<fx:String id="myStringProperty1" source="./file"/>
I can't see anything that I'm doing differently.
OK I found the cause. In my external file I have a few curly braces. The compiler is getting hung up on those.
Here is the contents of my external file:
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<style type="text/css" media="screen">
html, body {
height:100%;
}
</style>
</head>
</html>
The part where it has body { height:100% } it is interpreting it as data binding. Here is the generated ActionScript:
result[1] = new mx.binding.Binding(this,
function():String
{
var result:* = "<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\"> \n <head>\n <style type=\"text/css\" media=\"screen\"> \n html, body " + (
height:100%;
) + "\n </style>\n </head>\n</html>";
return (result == undefined ? null : String(result));
},
null,
"HTML"
);
As you can see it thinks I'm using data binding between the curly braces. Since I'm not, it's throwing an error because "height:100%" is out of context where it's being used.
I think I will have to try a different method to embed this text. It seems to be fine if I use this but I rather not:
<fx:String id="HTML">
<![CDATA[<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<style type="text/css" media="screen">
html, body {
height:100%;
}
</style>
</head>
</html>]]>
</fx:String>
UPDATE!!!
I WAS WRONG! It is possible. I have to escape at least the opening curly brace and then it works.
Contents of file that works:
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<style type="text/css" media="screen">
html, body \{
height:100%;
\}
</style>
</head>
</html>

Express + nodeJS never get my static file

I can't understand why express can't get my static file for display my css.
express.js :
app.use(express.static(__dirname + '/public'));
style.css
<style type="text/css">
body {
background-image: url("background.jpg");
} </style>
test.ejs :
<!DOCTYPE html>
<html> <body>
<h1> TEST </h1> </body> </html>
folder path :
/express.js
/public/style.css
/public/background.jpg
/views/test.ejs
test.ejs route :
.get('/myTest', function(req, res){
res.render('test.ejs', { data: req.session.info });
})
(info is an array of data for the current session)
test.ejs should be
<html>
<link rel="stylesheet" type="text/css" href="style.css">
<body>
<h1> TEST </h1 </body> </html>
hope this solves your problem
The problem is that you're using a relative path in your CSS from an absolute path other than /. So when you request /myTest, the browser is looking for /myTest/background.jpg which of course 404s because it really should be /background.jpg according to your filesystem layout.
One easy way to fix this is to make your CSS urls absolute:
body {
background-image: url("/background.jpg");
}
I was tired...unfortunatly It was the 1rst line of my css...
delete <style> </style balise

Unable to insert stylesheet/script into window.open

I have been fighting this issue for quite some time now, and have been (still) unable to print my div with its styling.
Currently, my script is:
$('#printMeButton').click(function () {
//alert("a");
var data = document.getElementById('thisPrintableTable').outerHTML;
var mywindow = window.open('', data);
mywindow.document.write('<html><head><title>Print Me!!!</title>');
// mywindow.document.write('<link rel="stylesheet" type="text/css" href="Site.css" media="screen">');
mywindow.document.write('</head><body>');
mywindow.document.write(data);
mywindow.document.write('</body></html>');
mywindow.document.close();
mywindow.focus();
mywindow.print();
mywindow.close();
return true;
});
which is nested within a $(document).ready function.
When I include the desired stylesheet (currently commented out), Nothing appears in the print preview.
I also have some script that has an effect on the appearance of the table, and, as such, I believe this may hold the key of having these included into the popup window.
How can i include this into the new popup?
Could someone please suggest a way of printing this as it stands?
Edit History
removed space at end of </head><body>
Changed var data to have outerHTML instead of innerHTML
Altered Question/details from better understanding of issue
Try to open a local html file using window.open with css linked within it. And set the content html to be printed to the local html file using js.
Here is the page to be printed:-
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="test.css" rel="stylesheet" type="text/css" />
<script src="jquery.js"></script>
</head>
<body>
<div id="print">
<div class="red">TODO write content</div>
</div>
<button id="print_btn">Print</button>
<script>
$('#print_btn').click(function(){
var newWindow = window.open('print.html','_blank');
$(newWindow).load(function(){
$(newWindow.document).find('body').html($('#print').html());
});
})
</script>
</body>
</html>
The css file test.css is linked here, and I'm opening print.html at the time of window.open, the test.css is also linked in the print.html
Now, in print.html I'll write:-
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link href="test.css" rel="stylesheet" type="text/css" />
</head>
<body>
</body>
</html>
Since you provide an empty string as a new window's URL (the first parameter of the open function), the page inside it most likely can't figure out where your stylesheet is (as it's address is "relative to nothing"). Try specifying an absolute URL to your stylesheet.
Also, there is media="screen" attribute that should be changed to media="print"
mywindow.document.write('<link rel="stylesheet" type="text/css" href="http://my.site/Site.css" media="print"')
The issue can be solved by introducing some delay time before executing mywindow.close(); method. Seems that some time is needed for CSS to be applied (loaded), like this:
$('#printMeButton').click(function () {
var content = document.getElementById(id).innerHTML;
var mywindow = window.open('', 'Print', 'height=600,width=800');
mywindow.document.write('<!DOCTYPE html><html dir="rtl"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Print</title>');
mywindow.document.write('<link rel="stylesheet" type="text/css" href="/static/css/styles.css" />');
mywindow.document.write('</head><body >');
mywindow.document.write(content);
mywindow.document.write('</body></html>');
mywindow.document.close();
mywindow.focus()
mywindow.print();
// this is needed for CSS to load before printing..
setTimeout(function () {
mywindow.close();
}, 250);
return true;
});
We can use this inline style.
var divToPrint = document.getElementById('DivIdToPrint');
var newWin=window.open('','Print-Window');
newWin.document.open();
newWin.document.write('<html>' +
'<style>' +
".btn-petty-cash-split{display: none}"+
".btn-petty-cash-split{display: none}"+
'</style>' +
'<body onload="window.print()">'+divToPrint.innerHTML+'</body></html>');
newWin.document.close();
setTimeout(function(){
newWin.close();
window.location.reload();
},10);

Using a data: encoded SVG as a CSS filter

Maybe someone can point an error in my test, but it seems that if I want to use a SVG filter in CSS encoding it as data: uri to avoid using an additional file, it fails if the data isn't encoded as base64.
I've tested with Firefox Aurora, other browsers don't seem to recognize the filter in neither case.
Test file:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style type="text/css">
#filter1 {
filter:url(data:image/svg+xml,<svg xmlns%3D"http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg"><filter id%3D"desaturate"><feColorMatrix type%3D"saturate" values%3D"0"%2F><%2Ffilter><%2Fsvg>#desaturate);
}
#filter2 {
filter:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxmaWx0ZXIgaWQ9ImRlc2F0dXJhdGUiPjxmZUNvbG9yTWF0cml4IHR5cGU9InNhdHVyYXRlIiB2YWx1ZXM9IjAiLz48L2ZpbHRlcj48L3N2Zz4%3D#desaturate);
}
</style>
</head>
<body>
<p style="color:red" id=filter1>Filter applied "as is"</p>
<p style="color:red" id=filter2>This one is encoded as base64</p>
</body>
</html>
Live demo at http://martinezdelizarrondo.com/bugs/svgfilter.html
the contents of the url() is the same in both cases:
<svg xmlns="http://www.w3.org/2000/svg"><filter id="desaturate"><feColorMatrix type="saturate" values="0"/></filter></svg>
Encoded with http://software.hixie.ch/utilities/cgi/data/data
As you can see, the first one remains red, but in the second case the svg filter is applied and the text becomes gray.
Have I forgot about something in the first case?
In this bug I don't find anything about the encoding, so I guess that it should be possible (and certainly using a simpler text encoding is much better instead of "encrypting" it with base64)
Thanks
After more trials and errors I've found that using escape on the data works and now we just have to wait for other browsers to implement support for it.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style type="text/css">
#filterBase64 {
filter:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxmaWx0ZXIgaWQ9ImRlc2F0dXJhdGUiPjxmZUNvbG9yTWF0cml4IHR5cGU9InNhdHVyYXRlIiB2YWx1ZXM9IjAiLz48L2ZpbHRlcj48L3N2Zz4%3D#desaturate);
}
#filterEscape {
filter:url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%3Cfilter%20id%3D%22desaturate%22%3E%3CfeColorMatrix%20type%3D%22saturate%22%20values%3D%220%22/%3E%3C/filter%3E%3C/svg%3E#desaturate);
}
</style>
</head>
<body>
<p style="color:red" id=filterBase64>This one is encoded as base64</p>
<p style="color:red" id=filterEscape>Filter encoded with "escape()"</p>
<p style="color:red" id=filterScript>This one is applied with javascript</p>
<script>
document.getElementById("filterScript").style.filter="url(data:image/svg+xml," + escape('<svg xmlns="http://www.w3.org/2000/svg"><filter id="desaturate"><feColorMatrix type="saturate" values="0"/></filter></svg>') + "#desaturate)";
</script>
</body>
</html>

Resources