Injecting remote iframe with Chrome extension - google-chrome-extension

For the life of me, I cannot get my Chrome extension to display an iframe with a remote URL.
I see the following message in the console -
Refused to frame 'https://www.example.com/' because it violates the following Content Security Policy directive: "child-src 'self'". Note that 'frame-src' was not explicitly set, so 'child-src' is used as a fallback.
I found a solution on here (Injecting iframe into page with restrictive Content Security Policy), which requires injecting a local iframe which then comatins another iframe that references the remote url. This is supposed to bypass the sontent security policy. But for some reason, it does not seem to work in my case. Am I missing something or has the chrome security policy changed?
Below are portions of my extension that pertain to this issue. Note - this code is not the prettiest as I've been hacking around trying to get this to work.
The way this works right now is background.js sends a message to inject.js. inject.js inserts the first iframe, referencing the local file infobar.html. This page is our main user interface, we want the remote html page displayed in an iframe as part of this page. Then infobar.js inserts an iframe referencing the local file frame.html. Finally, frame.html has an iframe hard coded to our remote url.
Based on the previous answer, only the first iframe should have been subject to the content security policy. However, that doesn't seem to be the case here, as the one referencing example.com is actually 3 iframes deep.
manifest.json
{
...
"content_security_policy": "script-src 'self'; object-src 'self'; frame-src https://www.example.com; child-src https://www.example.com",
"background": {
"scripts": [
"js/jquery/jquery.min.js",
"src/bg/background.min.js"
],
"persistent": true
},
...
"content_scripts": [
{
...
"css": [
...
"src/inject/inject.min.css"
],
"js": [
...
"src/inject/inject.min.js"
]
}
],
"externally_connectable": {
"matches": [
"*://localhost/*",
"*://*.example.com/*
]
},
"web_accessible_resources": [
"src/inject/inject.html",
"src/inject/infobar.html",
"src/inject/infobar.min.js",
"src/inject/frame.html"
],
"sandbox": {
"pages": [
"src/inject/infobar.html",
"src/inject/frame.html"
]
}
}
inject.js
var iframe = document.createElement("iframe");
iframe.scrolling = "no";
iframe.style.cssText = "display:none;";
...
$(iframe).load(function () {
var message = {
command: "render-frame",
context: data,
frameUrl: chrome.runtime.getURL("src/inject/frame.html")
};
iframe.contentWindow.postMessage(message, '*');
iframe.style.cssText = "border: 0px; overflow: visible; padding: 0px; right: auto; width: 100%; height: " + toolbarHeight + "px; top: 0px; left: 0px; z-index: 2147483647; box-shadow: rgba(0, 0, 0, 0.498039) 0px 3px 10px; position: fixed; display: none;";
});
...
iframe.src = chrome.runtime.getURL("src/inject/infobar.html");
...
document.documentElement.appendChild(iframe);
infobar.html
Simple HTML page. Nothing pertinent in there. References infobar.js.
infobar.js
window.addEventListener("message", function (event) {
var command = event.data.command;
switch (command) {
case "render-frame":
var frame = document.createElement("iframe");
frame.scrolling = "no";
frame.src = event.data.frameUrl;
document.getElementById("content").appendChild(frame);
...
break;
}
});
frame.html
<html>
<head>
<style>
html, body, iframe, h2 {
margin: 0;
border: 0;
padding: 0;
display: block;
width: 100vw;
height: 100vh;
background: white;
color: black;
}
</style>
</head>
<body>
<iframe src="https://www.example.com/page.html"></iframe>
</body>
</html>

The proper way is to use the chrome.webRequest API in your background script and intercept HTTP responses.
You can then override response headers to modify Content-Security-Policy header. You can also modify X-Frame-Options header (if required).
Documentation: chrome.webRequest

Related

Replacing Font Awesome in heading with local SVG

I'm using this snippet for adding a Font Awesome icon in front of H1 headings:
h1:before {
content: "\f192 ";
font-family: "FontAwesome";
color: blueviolet;
}
How to adapt it for using a locally served (on site's server) SVG icon instead?
(that is uploaded in WP Media Library and using SVG Support plugin)
If your icon needs to remain a separate file, you can set it as a background image.
h1:before {
display: inline-block;
background-image: url(resources/icon.svg)
}
Otherwise you can embed your icon as a data url.
h1:before {
display: inline-block;
background-image: url(data:image/svg+xml,...etc...)
}
Update
Working example:
h1:before {
content: " ";
display: inline-block;
width: 0.7em;
height: 0.7em;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 10'%3E%3Ccircle cx='5' cy='5' r='5'/%3E%3C/svg%3E");
background-size: contain;
background-repeat: no-repeat;
}
<h1>This is a title</h1>

Stripe Elements Icon Padding Issue

I'm using Stripe Elements on my site but running into some issues with the icon styling.
I've done some searching and found this link but they have closed the ticket saying the issue was fixed.
As you can see on my screenshot here the icon is flush to the edge and I'd like some padding to the left.
I've tried adding padding via my JS like so but it doesn't change anything.
var style = {
base: {
iconColor: "#fff",
padding: "5px 10px 5px 20px",
backgroundColor: "#a91537",
color: "#fff",
fontWeight: "400",
fontFamily: "Montserrat, sans-serif",
fontSize: "18px",
lineHeight: "80px",
fontSmoothing: "antialiased",
showIcon: false,
textIndent: "10px",
":-webkit-autofill": {
color: "#fff",
},
"::placeholder": {
color: "#fff",
},
},
invalid: {
color: "#fa775a",
iconColor: "#fa775a",
},
};
I've even tried adding it via CSS but because it's pulled in via an iframe my styling does nothing.
You need to be changing the style of the container you mount the Element to, not the Element itself. For example, if you were mounting your card element to #card-element you could add some basic styling like this:
<style>
#card-element {
padding: 12px;
}
</style>
<div id="card-element"></div>
You can read more about this here: https://stripe.com/docs/js/element/the_element_container?type=card

How to add fonts to chrome extension properly?

Fonts are not visible for my custom script chrome extension.
Folder structure:
assets
-fonts
content-app
manifest.json
manifest.json:
(...)
"content_scripts": [
{
"all_frames": false,
"js": ["/content-app/runtime.js", "/content-app/polyfills.js", "/content-app/styles.js", "/content-app/main.js"],
"matches": ["https://*/*"],
"match_about_blank": true,
"run_at": "document_idle"
}
],
"web_accessible_resources": [
"assets/fonts/icons.ttf",
"assets/fonts/icons.eot",
"assets/fonts/icons.svg",
"assets/fonts/icons.woff"
],
scss:
$icomoon-font-family: 'icons' !default;
$icon-equalizer: '\e912';
#font-face {
font-family: '#{$icomoon-font-family}';
src: url('chrome-extension://__MSG_##extension_id__/assets/fonts/#{$icomoon-font-family}.eot?64agaf');
src: url('chrome-extension://__MSG_##extension_id__/assets/fonts/#{$icomoon-font-family}.eot?64agaf#iefix') format('embedded-opentype'),
url('chrome-extension://__MSG_##extension_id__/assets/fonts/#{$icomoon-font-family}.ttf?64agaf') format('truetype'),
url('chrome-extension://__MSG_##extension_id__/assets/fonts/#{$icomoon-font-family}.woff') format('woff'),
url('chrome-extension://__MSG_##extension_id__/assets/fonts/#{$icomoon-font-family}.svg?64agaf##{$icomoon-font-family}') format('svg')
format('svg');
font-weight: normal;
font-style: normal;
font-display: block;
}
[class^='icon-'],
[class*=' icon-'] {
font-family: '#{$icomoon-font-family}' !important;
speak: never;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-equalizer {
&:before {
content: $icon-equalizer;
}
}
If I open chrome url with: chrome-extension://xxxxx/assets/fonts/icons.ttf, the file will be downloaded properly so it seems ok, but when I add some code to my content script like:
<span class="icon-equalizer"></span>
then nothing happens (I can see '' only). Any idea?
Because of many reasons I use shadow-root, and you can find the code from that element:
#shadow-root
<style>
#font-face{font-family:"icons";src:url("chrome-extension://__MSG_##extension_id__/assets/fonts/icons.eot?64agaf");src:url("chrome-extension://__MSG_##extension_id__/assets/fonts/icons.eot?64agaf#iefix") format("embedded-opentype"),url("chrome-extension://__MSG_##extension_id__/assets/fonts/icons.ttf?64agaf") format("truetype"),url("chrome-extension://__MSG_##extension_id__/assets/fonts/icons.woff") format("woff"),url("chrome-extension://__MSG_##extension_id__/assets/fonts/icons.svg?64agaf#icons") format("svg") format("svg");font-weight:normal;font-style:normal;font-display:block}[class^='icon-'],[class*=' icon-']{font-family:"icons" !important;speak:never;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-equalizer:before{content:""}
(...)
</style>

Font Awesome 4.7 to 5 broken?

Be forgiving, I am new to css let alone fontawesome :-)
I wanted to have a nice set of rating stars 0-5 and I managed it sort of using 4.7
https://jsfiddle.net/BoxRec/p3zgeLbt/36
content: "\f005\f006\f006\f006\f006";
However I needed half stars to complete the look and this required going to fontawesome 5
https://jsfiddle.net/BoxRec/p3zgeLbt/38
content: "\f005\f089\f006\f006\f006";
So I used the 5 library and now I now have the half star \f5c0 but the full star \f005 renders the same as the empty star \f006
https://jsfiddle.net/BoxRec/p3zgeLbt/46/
content: "\f005\f5c0\f006\f006\f006";
If you go to the cheatsheet, you can see that \f006 is gone in FontAwesome 5. I would (not a css guy) just use before and after tags to make the same effect. Regular vs solid is just changing the font weight.
note that I changed the font-family to 'Font Awesome\ 5 Free'
i.star {
font-family: 'Font Awesome\ 5 Free';
font-size: 16px;
color: #ffaa00;
font-style: normal;
}
i.s1::before {
content: "\f005";
font-weight: 900;
}
i.s1::after {
content: "\f005\f005\f005\f005";
font-weight: 200;
}
i.s1-5::before {
content: "\f005\f5c0";
font-weight: 900;
}
i.s1-5::after {
content: "\f005\f005\f005";
font-weight: 200;
}
Had to add this to the HTML:
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.12.0/css/all.css">

NodeJS with Puppeteer: how to set the margins of each pages (or scale all of them to fit the magins)?

I tried to just use below setting but turn out the header and footer positions will be changed. Please advise.
await page.pdf({
path: FILENAME,
format: 'A4',
margin: {
top: "0px",
right: "0px",
bottom: "0px",
left: "0px"
},
printBackground: true // required for photos otherwise blank
});
try preferCSSPageSize: true in page.pdf options.
This allows you to specify the margin's for page in the CSS and it will take priority.
**place CSS **
<style>
#page
{
size: A4 portrait;
margin:0;
}
</style>

Resources