Style Sheet getting added but not the style - javascript

I am trying to add some styling to my print page(unfortunately i am a beginner so far so bear with me if i am doing something dumb). Here is the style sheet
#font-face {
font-family: 'Cloister';
src: url('../fonts/fonts/CloisterBlack.ttf');
font-weight: normal;
font-style: normal;
}
.navbar {
display: none;
}
.main-navigation{
display: none;
}
.hidden-print {
display: none;
}
.breadcrumb {
display: none;
}
.page-header {
display: none;
}
.footer {
display: none;
}
.main-container {
/*margin: 0 ;
padding: 0 !important;*/
}
.main-content .container{
min-height: auto;
border: none;
background: #0000ff;
}
#page {
margin: 1cm;
}
h1.page-title {
font-family: 'Cloister';
font-size: 40pt!important;
text-align: center ;
}
and this is my print method.
$('#printButton').click( function () {
var divContents = $("#printPage").html();
//console.log(divContents);
var printWindow = window.open();
printWindow.document.write('<html>' +
'<head>' +
'<link rel="stylesheet" href="<?= base_url() ?>assets/css/print.css" type="text/css" media="print"/>'+
'<title>Student Report Card</title>');
printWindow.document.title = '';
printWindow.document.write('<h1 class="page-title"> BeaconHouse Potohar Campus</h1>');
printWindow.document.write('</head><body >');
printWindow.document.write(divContents);
printWindow.document.write('</body></html>');
printWindow.document.close();
printWindow.print();
});
Everything is seems to be working fine until i inspect my print page, there i can also see my style sheet getting added but when i go to the h1 tag, my style sheet doesn't appear and instead there is user agent stylesheet(added by browser as last resort when no style is present on stackoverflow).
Finally i am adding this image just to consolidate what i am trying to convey.

Two Three issues jump out:
In your style, you have font-family: 'Cloister'. Those quotes shouldn't be there, it should just be font-family: Cloister.
You're outputting your h1 within your head element. (The browser is then relocating it for you.) It should be after the start of body. I think you just have two of your document.write lines reversed.
As Darren Sweeney pointed out in a comment, you've identified the style sheet as being for print only (media="print"). When using dev tools, if you cancelled the print and inspected the window you opened without telling Chrome to show you the "print" media state, you're not going to see that style because it doesn't apply.
Here's how to tell Chrome to show you the "print" media state:
Open devtools (right-click the h1 and choose Inspect, for instance)
From the devtools menu box on the upper right-hand side...
...choose More Tools > Rendering Settings:
Tick the "Emulate media" checkbox and choose Print from the list:

Related

Can I use window.location.replace in an iframe?

We can use window.location.replace to avoid history, and to target on-page anchors without page reloads, but *not in iframes?
The problem is a CSP (content security policy) violation, which states script-src 'unsafe-inline' must be enabled. Except I don't have a CSP defined, and even if I define one and allow script-src 'unsafe-inline' it still gives the same violation error. Same result in ie11/chrome/ff.
iframe on the same domain (in the same directory).
Target the iframe in the console and use window.location.replace('/samepage.html#onpage_anchor') in console.
It works. It targets the on page anchor without reloading the page, and without history.
Put the same code inline on anchor links and it works.
Use the same code in external script, get the csp violation error. This works fine if not in an iframe.
I tried creating a CSP to allow the action, but not even the most permissive content security policies possible would allow it.
So I put together examples on plunker which allows multiple files so I could use proper hrefs which reference the parent/child pages.
Notes about the plunker examples:
The problem is not reproduced in these examples. The script works perfectly, even in the iframe. However, the same code does not work on my local server, or when I run it live on a VPS.
I suspect the CSP violation doesn't get triggered on plunker because plunker is presenting content to the browser via a kind of abstraction layer of some sort.
The first time you click the accordion links in the parent, it causes a refresh. This is because the way the page initially loads it doesn't reference index.html. Subsequent clicks work as expected without page reloads. Not an issue in the iframe because it does initially reference child.html
These are good examples to show the code without requiring alterations to make it work (as in the need to change the hrefs to make them work in stackoverflow snippets, mentioned below). It is also good as it shows the javascript working as it should. But it does not show the actually problem. You will still need to load it up in your editor and run it on a local server or live hosting environment to see the real problem.
Plunker examples: With script/without history. Without script/with history
Simple accordion with one entry. Sufficient to reproduce issue.
Clicking open/close will expand/collapse accordion, no JS required. The JS should do the exact same thing but without history. Works fine, but not in an iframe.
Code snippet notes:
You can run the snippet to get an idea about what I am describing, but it does not actually demonstrate the issue.
The snippet does not behave the way it would in a real browser, the javascript does not work.
The snippet shows the code, but it should be run in an iframe to see the issue. Run it outside an iframe to see the difference and how it should work.
Because of how the links work with the JS (replacing the whole url) they actually must be like this href="/thispage.html#ac1" rather than just href="#ac1" as they appear in the snippet (can't target the actual html page in the snippet). So if you try this in your editor (please do), then remember to change the links to this format this_document.html#anchor so they are still same page anchors, but the page.html is included in the link.
$(document).ready(function() {
// anchor links without history
$.acAnch = function(event) {
event.preventDefault();
var anchLnk = $(event.target);
var anchTrgt = anchLnk.attr('href');
window.location.replace(anchTrgt);
}
// listen for anchor clicks
$('.accordion').on('click', 'a', $.acAnch);
});
div#sample.example .accordion {
margin-left: 50px;
margin-top: 50px;
}
div#sample.example section {
box-sizing: border-box;
clear: both;
position: relative;
display: block;
width: 300px;
height: 32px;
padding: 0;
background-color: #fff;
box-shadow: inset 0 0 1px 1px #000;
overflow: hidden;
}
div#sample.example section:target {
height: auto;
}
div#sample.example a {
box-sizing: border-box;
display: block;
float: right;
width: 50%;
height: 32px;
margin: 0;
padding: 4px;
text-align: center;
font-size: 16px;
color: #000;
background-color: #fff;
box-shadow: inset 0 0 1px 1px #000;
}
div#sample.example p {
box-sizing: border-box;
clear: both;
display: block;
width: 100%;
padding: 16px;
margin: 16px 0 0;
text-align: center;
color: #000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="sample" class="example">
<article class="accordion">
<section id="ac1">
Close
Open
<div class="ac-content">
<p>The elephants talking in their sleep kept me up so late.</p>
</div>
</section>
</article>
</div>
$(document).ready(function() {
// anchor links without history
$.acAnch = function(event) {
event.preventDefault();
var anchLnk = $(event.target);
var anchTrgt = anchLnk.attr('href');
window.location.replace(anchTrgt);
}
// listen for anchor clicks
$('.accordion').on('click', 'a', $.acAnch);
});
This is very simple:
acAnch function takes the href attribute and drops it into window.location.replace().
Listen for clicks on anchors within the accordion to run the acAnch function.
So all the script does is run window.location.replace('/this_same_page.html#on_page_anchor')
If you put that in the console it works, no CSP violation. But running it from external script doesn't work.
Inline on the links works fine:
onclick="event.preventDefault();window.location.replace('/thispage.html#acc0');"
onclick="event.preventDefault();window.location.replace('/thispage.html#acc1');"
Putting that on the respective links works perfectly, but I really prefer not to use inline script like that. There must be a way to do this with an external script.
I tried running the javascript on parent instead of in the iframe (with modifications to select the links within the child of course). Same CSP error result.
Why am I doing this? Well the site is much more complex than the example. Anchors in iframes work fine but they add history. If you run the code above without the javascript, (or just run the snippet), open and close the accordion a few times, and use back button, it will go back through the open close states.
I wouldn't mind the history, but if it is in an iframe, when you leave the parent page and then come back to it, the history in the iframe is broken. Going back doesn't go back through the accordion states anymore, but instead just keeps reloading the iframe. Initially the anchors don't cause iframe reloads but just steps through accordion state history, which works fine, until you leave the page and come back. Then back no longer goes through the accordion states, but just goes through a pile of identical iframe reloads. It is very user unfriendly behavior.
I don't need to use location.replace if there is another method that will work. I have tried many other approaches though, and I've found that methods that can achieve the same result, generally result in the same error.
The goal is simply to activate the anchor links on page without reloading, and without history, inside an iframe.
The inline script works. Can we make it work in an external .js file?
This may be a non-issue, but you mentioned this is an issue on you local server, and I noticed your code relys on relative links.
If you are not setup correctly, you may be serving resource via the file:// protocol or somehow using a localhost, not recognized as a valid TLD, which would result in file:// protocol as default, or invalidate CSP
In any event, try using absolute URLs and see if that resolves the issue
yes you can use iframe with -window-location-replace
for reference, you can use this ref link Javascript location.replace and iframe
You can toggle an active class to the parent element like this using anchor click events.
// Code goes here
$(window).on('load', function() {
$('.accordion section').on('click', '.ac-open', function(e) {
e.preventDefault();
$(e.target).parent().addClass('active');
});
$('.accordion section').on('click', '.ac-close', function(e) {
e.preventDefault();
$(e.target).parent().removeClass('active');
});
});
/* Styles go here */
html,
body {
margin: 0;
padding: 0;
}
.flt-lft {
float: left;
margin: 16px;
}
h4 {
text-align: center;
margin: 0;
padding: 8px;
color: white;
background-color: green;
}
/* #sample.example .accordion {
margin-left: 50px;
margin-top: 50px;
} */
#sample.example section {
box-sizing: border-box;
clear: both;
position: relative;
display: block;
width: 300px;
height: 32px;
padding: 0;
background-color: #fff;
box-shadow: inset 0 0 1px 1px #000;
overflow: hidden;
}
#sample.example section.active {
height: auto;
}
#sample.example a {
box-sizing: border-box;
display: block;
float: right;
width: 50%;
height: 32px;
margin: 0;
padding: 4px;
text-align: center;
font-size: 16px;
color: #000;
background-color: #fff;
box-shadow: inset 0 0 1px 1px #000;
}
#sample.example p {
box-sizing: border-box;
clear: both;
display: block;
width: 100%;
padding: 16px;
margin: 16px 0 0;
text-align: center;
color: #000;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<div class="flt-lft">
<h4>parent</h4>
<div id="sample" class="example">
<article class="accordion">
<section id="ac1">
Close
Open
<div class="ac-content">
<p>The elephants talking in their sleep kept me up so late.</p>
</div>
</section>
</article>
</div>
</div>
<div class="flt-lft">
<h4>iframe</h4>
<iframe src="child.html"></iframe>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="script.js"></script>
</body>
</html>
yes you can , here is a live example from below link
https://codepen.io/pmk/pen/wOwoyW
HTML
<div class="">
<h3>Testing 4 methods of writing dynamic content to Iframe.</h3>
<p>#1 use <strong>document.write()</strong>,
#2 use <strong>URL.createObjectURL()</strong>,
#3 use <strong>encodeURI()</strong> and #4 <strong>iframe.srcdoc</strong></p>
<p>Using the recommended method <strong>URL.createObjectURL()</strong> leads to problems when trying to retrieve the <strong>windown.location</strong> object. (Same does the <strong>encodeURI()</strong> method)<p/>
<p>Only reliable method if you need window.location, seems to be the old obsolete <strong>document.write()</strong> method.</p>
<iframe id="iframe1"></iframe>
<iframe id="iframe2"></iframe>
<iframe id="iframe3"></iframe>
<iframe id="iframe4"></iframe>
</div>
CSS
#import url(https://fonts.googleapis.com /css?family=Fira+Sans:400,500italic);
html {
height: 100%;
background-color: rgba(34,32,36,1);
}
body {
text-align: center;
font: normal 100% 'Fira Sans', sans-serif;
color: #aaa;
}
iframe {
width: 40%;
height: 200px;
background: white;
}
JS
var template = [
'<!DOCTYPE HTML>',
'<html>',
'<head>',
'</head>',
'<body>',
'<script>',
'document.write("<pre>" + JSON.stringify(window.location, null, 4) +
"</pre>");',
'<\/script>',
'</body>',
'</html>'
].join('');
var iframe1El = document.querySelector('#iframe1');
var iframe1 = iframe1El.contentWindow || (
iframe1El.contentDocument.document || iframe1El.contentDocument);
var iframe2El = document.querySelector('#iframe2');
var iframe2 = iframe2El.contentWindow ||
( iframe2El.contentDocument.document || iframe2El.contentDocument);
var iframe3El = document.querySelector('#iframe3');
var iframe3 = iframe3El.contentWindow ||
( iframe3El.contentDocument.document ||
iframe3El.contentDocument);
var iframe4El = document.querySelector('#iframe4');
var iframe4 = iframe4El.contentWindow ||
( iframe4El.contentDocument.document || iframe4El.contentDocument);
iframe1.document.open();
iframe1.document.write(template);
iframe1.document.close();
var bData = new Blob([template], {type: 'text/html'});
iframe2El.onload = function() { window.URL.revokeObjectURL(bData); };
iframe2El.src = window.URL.createObjectURL(bData);
iframe3El.src = 'data:text/html;charset=utf-8,' +
encodeURI(template);
iframe4El.srcdoc = template;
Yes you can use it with iframe.
you can use CSS instead of html iframe tag
because iframe tag is removed in html

PrismJS no line breaks

Not sure if anyone has come across this. I'm using PrismJS syntax highlighter to highlight code. Application is written in Reactjs and what I'm trying to do is inside a WYSIWYG editor I'm wrapping user selected text with pre + code when user wants to insert code block. PrismJS seems to tokenize elements correctly as you would expect:
But as you can probably see from the image above, everything is put into a single line. Rather then nice code block:
I'm not sure what's wrong, using css from prismjs site:
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
#media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre) > code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre) > code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #dd4a68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
Here is outputted html:
EDIT:
If adding word-wrap: pre-wrap this is the outcome:
I had a similar issue when initializing the element manually. I stumbled upon this discussion, which had a fix that worked for me: https://github.com/PrismJS/prism/issues/1764
HTML - Load script with flag data-manual:
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/prism.min.js" data-manual></script>
JS - Add the following hook:
Prism.hooks.add("before-highlight", function (env) {
env.code = env.element.innerText;
});
Prism.highlightElement(code);
Working example:
https://codepen.io/Ukmasmu/pen/xxZLwxG?editors=1010
Try to update the CSS file with:
white-space: pre-wrap
https://github.com/PrismJS/prism/issues/1237
In case this is helpful for anyone else, I have a textarea that updates a code block as you type, and this worked for me:
<textarea onkeyup="this.onchange();" onchange="document.getElementById('query-highlighted').textContent = this.value; Prism.highlightAll();"></textarea>
<pre><code class="language-sql" id="query-highlighted"></code></pre>
Namely, I used .textContent = instead of .innerText = (the latter didn't preserve the line breaks as expected).
I was aided by Sever van Snugg's answer and the issue he linked.
1. Activate normalize whitespace plugin
I suggest you activate normalize whitespace plugin and set the break-lines property instead of manipulating prism.css file to using white-space: pre-wrap like this:
Prism.plugins.NormalizeWhitespace.setDefaults({
'remove-trailing': true,
'remove-indent': true,
'left-trim': true,
'right-trim': true,
'break-lines': 60, //max number of characters in each line before break
});
I'm using the above approach in my blog, and it works like a charm. You can adjust the break-lines value according to your preferences of course.
2. Insert a line break tag <br> to break a line at will
Now that you set the break-line property after a certain maximum number of characters, you probably want to break some lines at will for cleaner code. To do so you need to insert a <br> tag where you want to have a break line.
NOTE: if you're using an html parser to parse dynamic content with prism
If you're using a parser to parse you dynamically generated html code as a string (from a database for example) and prims is not parsing your <br> tags you'll have to use before-sanity-check prism hook like this:
Prism.hooks.add('before-sanity-check', function (env) {
env.element.innerHTML = env.element.innerHTML.replace(/<br>/g, '\n');
env.code = env.element.textContent;
});
before highlighting, what the above code does is replacing <br> tags with \n since prism can't parse <br> as a line break.
Similar to the answer by Sever van Snugg, I use the following solution where the forEach loop highlights all the code nodes according to the style rules of the Prism CSS stylesheet used (because I have several code tags on a single page). I locate these scripts in the bottom of my HTML body:
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.27.0/prism.min.js" data-manual></script>
<script>
Prism.hooks.add("before-highlight", function (env) {
env.code = env.element.innerText;
});
code = document.getElementsByTagName('code');
Array.from(code).forEach(el => { Prism.highlightElement(el) });
</script>
I tried to mixed Markdown and Prismjs the trick is to replace '\n' with '\r\n' to keep breaklines.
from bs4 import BeautifulSoup
...
code_tag = soup.new_tag('code class="lang-%s"' % lang)
code_tag.string = code.string.replace('\n','\r\n')
code.replaceWith(code_tag)

CSS selector and border issue

I would like to achieve the following with my code:
Issue (a) Change only Click Here to be surrounded by a box.
Issue (b) The border for the box in (a) should disappear and reappear.
Currently, I face the following issues with my code:
Issue (a)
For (a), my code does not just change Click Here to be surrounded by a box. It also changes Pinterest to be surrounded by a box. I believe the issue is with selecting the top level ul but I have not succeeded in doing so.
Relevant CSS code
.cover-buttons ul:first-of-type li:nth-last-child(5) a {
color: black;
border: 1px solid black;
padding: 14px 18px!important;
font-weight: 400;
line-height: 17px;
font-size: 12px;
display: inline-block;
transition: all .2s ease;
overflow: hidden;
border-radius: 2px;
box-sizing: border-box;
list-style-type: none;
font-family: 'Varela Round', 'Poppins', sans-serif;
}
Issue (b)
For (b), I can't seem to get the box border to blink.
Relevant Javascript code
$(function(){
var count = 0, $input = jQuery('.buttons.medium.button-outlined').not('.add-review, .bookmark, .show-dropdown, .sn-share'), interval = setInterval(function() {
if ($input.hasClass('blur')) {
$input.removeClass('blur').addClass('focus'); ++count;
} else {
$input.removeClass('focus').addClass('blur');
}
if (count === 3) { clearInterval(interval); }
}, 2000);
});
Relevant CSS code
.focus {
border: 1px solid white;
}
.blur {
border: 1px solid black;
}
The strange thing about issue (b) is that it seems to work when I change the background-color as shown here: https://jsfiddle.net/75nvLs4x/12/. However, when I try to modify the border thickness it does not work.
Full script including HTML is included here: https://jsfiddle.net/75nvLs4x/14/
Thank you for your help.
Issue A
Your selector is: .cover-buttons ul li:nth-last-child(5) a this will affect any ul inside .cover-buttons. As there are two uls that have li:nth-last-child(5), both have the li:nth-last-child applied.
You can fix this by saying only the ul that's directly inside .cover-buttons and only the li directly inside that ul
.cover-buttons > ul > li:nth-last-child(5) a
Issue B
Your border issue is due to specificity - the border in the .cover-buttons ul li:nth-last-child(5) a section is more specific than just .focus so is always used. You could add !important to the border inside .focus, but that's not best practice - instead, remove the border from the main block and it works fine.
Updated fiddle: https://jsfiddle.net/75nvLs4x/18/

JS print - CSS text color not showing

I'm making an invoice in HTML & CSS. The goal is that after filling in, the invoice gets printed. But for some reason it doesn't print the CSS color of text. All text is black.
All other CSS styling works, like font-family, font-size, font-weight ...
This is the original in HTML & CSS :
And this is what is printed :
The printing is done with js: window.print();
Does anyone know why CSS color isn't working?
EDIT:
the title is placed in a table with id 'factuur':
<td id="factuurTitel">Stukadoorwerken Vanhees Frank</td>
The title has this CSS:
#factuurTitel {
font-weight: bold;
font-size: 30px;
color: #194197;
text-align: center;
vertical-align: middle;
font-family: 'Carrois Gothic SC', Calibri, sans-serif;
}
I have this #media print :
#media print {
body * {
visibility: hidden;
}
#factuur, #factuur * {
visibility: visible;
}
#page {
margin: 0;
}
}
I've tried adding #factuurTitel { color: #194197; } to the #media print.
Usually JS Print only handles html content alone if you want to give stylings to print, Use separate media query print in your css file:
#media print
{
/* your css goes here */
}
#factuur, #factuur * {
-webkit-print-color-adjust: exact;
color-adjust: exact;
}
This works in webkit browsers and the latest firefox updates, otherwise there's no other known solution.
I had the same problem myself.

fontawesome icon display issue in mozila firefox with html2canvas

i am display font awesome css to display icon in my issue is that icon can display perfect but i am using html2cnvas js to convert that div to image. js can convert div to image perfect but my issue is when it convert to image font awesome icon cant display instead of icon it display rectangle sign. please help to find bug. my code is written below.
div which converting to image
HTML
<div id='parent_poster'>
<span class="boxfitted">
<i class="fa fa-apple change-color"></i>
</span>
</div>
CSS
#author{
margin-top: -85px;
margin-right: 10px;
text-align: left;
font-weight: 600;
overflow: hidden;
text-align: right;
float: right;
}
#watermark{
display: block;
position: static;
margin: -102px 0px 13px 0px;
font-size: 30px;
font-family: 'Monopol';
}
#watermark p{
opacity: 0.1;
}
JQuery
html2canvas javascript to convert image
$("#generate_quote").on('click', function() {
$(".watermark").show();
html2canvas($("#parent_poster"), {onrendered: function(canvas) {
$(".watermark").hide();
var myImage = canvas.toDataURL("image/jpeg");
window.open(myImage);
}});
});
Seems like an issue from an older html2canvas version. You can check the issue here (https://github.com/niklasvh/html2canvas/issues/314).
You can download the 5.0 version and try to run it again. or, if you don't want to change it, you can change the code in html2canvas of your version following this commit. https://github.com/kabushi/html2canvas/commit/0744de82b68a1922315f076e244a586445e5636b

Categories