How can I avoid CORS policies to load a website inside the sidebar on my Firefox extension? - firefox

I'm making a Firefox extension to open sites on a sidebar. It mostly works except for some sites like mastodon.social and github, I keep bumping into the Cross-Origin Resource Sharing (CORS) policies, which restricts other websites from displaying their content in iframes for security reasons.
How can I avoid that? Just to clarify, I'm not trying to circumvent it, I just want the site to open on my sidebar normally. Other extensions like Webpage Sidebar Viewer show the sites without any issue at all. This is my first extension, so I'm struggling to find the issue.
Here is my code:
MANIFEST.JSON
{
"manifest_version": 2,
"name": "Website Viewer",
"version": "1.0",
"description": "A website viewer with a bookmark feature",
"icons": {
"48": "icons/icon48.png"
},
"sidebar_action": {
"default_title": "Website Viewer",
"default_panel": "panel.html",
"default_icon": {
"48": "icons/icon48.png"
}
},
"permissions": [
"activeTab",
"storage",
"<all_urls>"
]
}
PANEL.HTML
<!DOCTYPE html>
<html>
<head>
<title>Website Viewer</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="sites"><button id="bookmark">+</button></div>
<script src="panel.js"></script>
</body>
</html>
STYLE.CSS
body {
margin: 0;
padding: 0;
height: 100vh;
display: flex;
flex-direction: column;
}
iframe {
width: 100%;
height: 100%;
border: none;
}
#bookmark {
display: block;
border: 1px;
border-radius:5px;
border-color: gray;
}
#sites {
display: flex;
flex-wrap: wrap;
margin: 10px;
overflow-y: auto;
height: auto;
width: 100%;
}
button {
cursor: pointer;
margin: 5px;
padding: 0;
width: 16px;
height: 16px;
border: none;
background-color: transparent;
background-repeat: no-repeat;
background-size: contain;
background-position: center center;
}
PANEL.JS
let iframe = null;
function showWebsite(url) {
// If the iframe has not been created yet, create it and add it to the page
if (!iframe) {
iframe = document.createElement('iframe');
iframe.setAttribute('id', 'website-iframe');
document.body.appendChild(iframe);
}
// Set the src attribute of the iframe to the URL of the website to display
iframe.src = url;
// Listen for the iframe's load event and set its sandbox attribute to allow scripts and forms
iframe.addEventListener('load', () => {
iframe.setAttribute('sandbox', 'allow-scripts allow-forms');
});
}
function addBookmark() {
browser.tabs.query({currentWindow: true, active: true}).then((tabs) => {
var site = tabs[0].url;
// If the site is not already in the list of bookmarks, add it
if (!document.getElementById(site)) {
var item = document.createElement('button');
item.setAttribute('id', site);
item.style.backgroundImage = `url("https://s2.googleusercontent.com/s2/favicons?domain=${site}")`;
item.addEventListener('click', () => {
showWebsite(site);
});
document.getElementById('sites').appendChild(item);
browser.storage.local.set({
[site]: true
});
}
});
}
function initialize() {
browser.storage.local.get().then((items) => {
Object.keys(items).forEach((key) => {
var item = document.createElement('div');
item.setAttribute('id', key);
item.textContent = key;
item.addEventListener('click', () => {
showWebsite(key);
});
document.getElementById('sites').appendChild(item);
});
});
}
document.addEventListener('DOMContentLoaded', initialize);
document.getElementById('bookmark').addEventListener('click', addBookmark);
My extension should open any website on the sidebar. Instead, I got an error saying that security measures that avoid loading the site altogether.

Related

botframework v4 customize title and minimizable webchat

I´m rendering my chat using this:
<!DOCTYPE html>
<html>
<head>
<style>
html, body {
height: 100%;
}
body {
margin: 0;
}
.main {
margin: 18px;
border-radius: 4px;
}
div[role="form"] {
background-color: black;
}
div[role="log"] {
background: gainsboro;
}
div[role="status"] {
background: darkgray;
}
#webchat {
position: fixed;
height: calc(100% - 135px);
z-index: 9999;
width: 400px;
top: 132px;
overflow: hidden;
border-color: red;
border-style: dotted;
visibility:visible;
}
</style>
</head>
<body>
<div>
<div id="heading">
<div id="heading">
<h1><img src="mylogo.png"> mychat</h1>
</div>
</div>
<div id="webchat" role="main"></div>
</div>
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
<script>
openchat();
function openchat() {
const styleOptions = {
userID: 'YOUR_USER_ID',
username: 'Web Chat User',
botAvatarInitials: '',
userAvatarInitials: 'You',
bubbleBackground: 'rgba(0, 255, 50, .4)',
bubbleFromUserBackground: 'rgba(125, 125, 125, .3)',
botAvatarImage: 'mylogo.png'
};
window.WebChat.renderWebChat(
{
directLine: window.WebChat.createDirectLine({
token: '*'
}),
styleOptions
},
document.getElementById('webchat')
);
}
</script>
</body>
</html>
It works fine, but now I need to publish this chat in the webpage of the company, as a popup or something like that, so using the previous script is OK but I have not options to add a title to the popup and also I need to add a minimize button. How I can set title and minimize button to my webchat inside a main page?
Tx,
I think your best bet going forward is to use the samples provided by the webchat team.
The minimizable webchat sample is a good example.

Firefox render bug with fixed background images and a filter applied

So I was experimenting with css filter, the experiment worked quite well but not in Firefox.
I wanted to apply a filter onto a segment of the background image. The idea was to fix the background image of the wrapper and the inner elements to create the illusion that the filter is applying only to a certain area and can be moved, here with scrolling.
This is what I tried:
html,
body {
width: 100%;
height: 100%;
}
body {
margin: 0px;
height: 200%;
display: flex;
justify-content: space-around;
align-items: center;
flex-direction: column
}
body,
div {
background-image: url("https://i.imgur.com/wu7EkAX.jpg");
background-attachment: fixed;
}
div {
filter: saturate(0%);
width: 50%;
height: 40%;
}
<div></div>
<div></div>
This works quite well with Chrome (and I think also in other browsers) but not with Firefox. It seems like it is a result of some optimization which misbehaves.
If you scroll with your mousewheele and then click, it refreshes, otherwise it stays in this state (at least if you run it standalone).
The "solution" is quite simple, you force Firefox to re render, there are whole posts about this topic but here are two of my approaches:
With a css animation
#keyframes renderFix {
from {
outline-color: red;
}
to {
outline-color: blue;
}
}
html {
outline: 1px solid red;
animation: 1s infinite alternate renderFix;
}
With some JavaScript
{
let html, s = false,
cycle = function () {
html.style.outlineColor = s ? "red" : "blue"
s = !s;
window.requestAnimationFrame(cycle)
}
window.requestAnimationFrame(function () {
html = document.body.parentElement
html.style.outlineStyle = "solid";
html.style.outlineWidth = "1px";
cycle()
})
}
The JavaScript fix applied:
{
let html, s = false,
cycle = function () {
html.style.outlineColor = s ? "red" : "blue"
s = !s;
window.requestAnimationFrame(cycle)
}
window.requestAnimationFrame(function () {
html = document.body.parentElement
html.style.outlineStyle = "solid";
html.style.outlineWidth = "1px";
cycle()
})
}
html,
body {
width: 100%;
height: 100%;
}
body {
margin: 0px;
height: 200%;
display: flex;
justify-content: space-around;
align-items: center;
flex-direction: column
}
body,
div {
background-image: url("https://i.imgur.com/wu7EkAX.jpg");
background-attachment: fixed;
}
div {
filter: saturate(0%);
width: 50%;
height: 40%;
}
<div></div>
<div></div>

SVG in css pseudo-class does not alway appear on print page

I am creating a stylesheet for print media that includes an inline SVG as the content of an element's pseudo-class (i.e., ::before, ::after).
When testing in Chrome, it seems to work just fine, but when the page is first loaded in Firefox and Safari, the SVG element does not appear in the print preview. It then appears on all subsequent attempts.
I am not exactly sure what is going on, but if I had to guess, my conjecture would be: when page hasn't been cached there is latency rendering the pseudo-element that is happening concurrently to the browser creating the print page.
I am very curious to know why this is happening, and if there is any solution where an SVG pseudo-element can be used reliably.
Here is a stripped down code example. Please see if you can reproduce this issue:
var button = document.querySelector('button');
button.addEventListener('click', function () {
window.print();
});
div {
text-align: center;
}
button {
margin: 2em;
padding: 1em 2em;
}
#media print {
button {
display: none;
}
div::before {
content: 'Pseudo-elements';
font-weight: bold;
margin-top: 1em;
}
div::after {
position: relative;
display: block;
margin-top: 1em;
content: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'><circle cx='50' cy='50' r='50' /></svg>");
}
}
<div>
<button>
print
</button>
</div>
I can repro.
It seems to be a bug with the loading of the svg, I guess it would be the same with any image.
One workaround is to load it outside of your #print rules with display: none :
var button = document.querySelector('button');
button.addEventListener('click', function() {
window.print();
});
div {
text-align: center;
}
button {
margin: 2em;
padding: 1em 2em;
}
div::after {
display: none;
content: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100'><circle cx='50' cy='50' r='50' /></svg>");
}
#media print {
button {
display: none;
}
div::before {
content: 'Pseudo-elements';
font-weight: bold;
margin-top: 1em;
}
div::after {
opacity: 1;
position: relative;
display: block;
margin-top: 1em;
}
}
<div>
<button>
print
</button>
</div>
An other one would be to preload it via js before hand.

Frameless window with controls in electron (Windows)

I want my app to have no title bar but still be closeable, draggable, minimizable, maximizable, and resizable like a regular window. I can do this in OS X since there is a [titleBarStyle] 1 option called hidden-inset that I can use but unfortunately, it's not available for Windows, which is the platform that I'm developing for. How would I go about doing something like this in Windows?
Above is an example of what I'm talking about.
Assuming you don't want window chrome, you can accomplish this by removing the frame around Electron and filling the rest in with html/css/js. I wrote an article that achieves what you are looking for on my blog here: http://mylifeforthecode.github.io/making-the-electron-shell-as-pretty-as-the-visual-studio-shell/. Code to get you started is also hosted here: https://github.com/srakowski/ElectronLikeVS
To summarize, you need to pass frame: false when you create the BrowserWindow:
mainWindow = new BrowserWindow({width: 800, height: 600, frame: false});
Then create and add control buttons for your title bar:
<div id="title-bar">
<div id="title">My Life For The Code</div>
<div id="title-bar-btns">
<button id="min-btn">-</button>
<button id="max-btn">+</button>
<button id="close-btn">x</button>
</div>
</div>
Bind in the max/min/close functions in js:
(function () {
var remote = require('remote');
var BrowserWindow = remote.require('browser-window');
function init() {
document.getElementById("min-btn").addEventListener("click", function (e) {
var window = BrowserWindow.getFocusedWindow();
window.minimize();
});
document.getElementById("max-btn").addEventListener("click", function (e) {
var window = BrowserWindow.getFocusedWindow();
window.maximize();
});
document.getElementById("close-btn").addEventListener("click", function (e) {
var window = BrowserWindow.getFocusedWindow();
window.close();
});
};
document.onreadystatechange = function () {
if (document.readyState == "complete") {
init();
}
};
})();
Styling the window can be tricky, but the key use to use special properties from webkit. Here is some minimal CSS:
body {
padding: 0px;
margin: 0px;
}
#title-bar {
-webkit-app-region: drag;
height: 24px;
background-color: darkviolet;
padding: none;
margin: 0px;
}
#title {
position: fixed;
top: 0px;
left: 6px;
}
#title-bar-btns {
-webkit-app-region: no-drag;
position: fixed;
top: 0px;
right: 6px;
}
Note that these are important:
-webkit-app-region: drag;
-webkit-app-region: no-drag;
-webkit-app-region: drag on your 'title bar' region will make it so that you can drag it around as is common with windows. The no-drag is applied to the buttons so that they do not cause dragging.
I was inspired by Shawn's article and apps like Hyper Terminal to figure out how to exactly replicate the Windows 10 style look as a seamless title bar, and wrote this tutorial (please note: as of 2022 this tutorial is somewhat outdated in terms of Electron).
It includes a fix for the resizing issue Shawn mentioned, and also switches between the maximise and restore buttons, even when e.g. the window is maximised by dragging the it to the top of the screen.
Quick reference
Title bar height: 32px
Title bar title font-size: 12px
Window control buttons: 46px wide, 32px high
Window control button assets from font Segoe MDL2 Assets (docs here), size: 10px
Minimise: 
Maximise: 
Restore: 
Close: 
Window control button colours: varies between UWP apps, but seems to be
Dark mode apps (white window controls): #FFF
Light mode apps (black window controls): #171717
Close button colours
Hover (:hover): background #E81123, colour #FFF
Pressed (:active): background #F1707A, colour #000 or #171717
Note: in the tutorial I have switched to PNG icons with different sizes for pixel-perfect scaling, but I leave the Segoe MDL2 Assets font characters above as an alternative
I use this in my apps:
const { remote } = require("electron");
var win = remote.BrowserWindow.getFocusedWindow();
var title = document.querySelector("title").innerHTML;
document.querySelector("#titleshown").innerHTML = title;
var minimize = document.querySelector("#minimize");
var maximize = document.querySelector("#maximize");
var quit = document.querySelector("#quit");
minimize.addEventListener("click", () => {
win.minimize();
});
maximize.addEventListener("click", () => {
win.setFullScreen(!win.isFullScreen());
});
quit.addEventListener("click", () => {
win.close();
});
nav {
display: block;
width: 100%;
height: 30px;
background-color: #333333;
-webkit-app-region: drag;
-webkit-user-select: none;
position: fixed;
z-index: 1;
}
nav #titleshown {
width: 30%;
height: 100%;
line-height: 30px;
color: #f7f7f7;
float: left;
padding: 0 0 0 1em;
}
nav #buttons {
float: right;
width: 150px;
height: 100%;
line-height: 30px;
background-color: #222222;
-webkit-app-region: no-drag;
}
nav #buttons #minimize,
nav #buttons #maximize,
nav #buttons #quit {
float: left;
height: 100%;
width: 33%;
text-align: center;
color: #f7f7f7;
cursor: default;
}
nav #buttons #minimize:hover {
background-color: #333333aa;
}
nav #buttons #maximize:hover {
background-color: #333333aa;
}
nav #buttons #quit:hover {
background-color: #ff0000dd;
}
main {
padding-top: 30px;
overflow: auto;
height: calc(100vh - 30px);
position: absolute;
top: 30px;
left: 0;
padding: 0;
width: 100%;
}
<html>
<head>
<meta charset="UTF-8">
<title>Hello World!</title>
</head>
<body>
<nav>
<div id="titleshown"></div>
<div id="buttons">
<div id="minimize"><span>&dash;</span></div>
<div id="maximize"><span>&square;</span></div>
<div id="quit"><span>×</span></div>
</div>
</nav>
<main>
<div class="container">
<h1>Hello World!</h1>
</div>
</main>
</body>
</html>
Ran into this problem and my solution was to keep the frame but set the title to blank i.e.
document.querySelector("title").innerHTML ="";
That solved my problem i.e. I got a window which can be closed, maximized or minimized without a title on it.

kendo sortable with kendo observable array

i am using kendo sortable data source is kendo observable array,
when we sorting the divs we are updating the array object in change event,
but array is updating properly but ui is not updating.
can u please help me.
<!DOCTYPE html>
<html>
<head>
<title></title>
<link href="http://cdn.kendostatic.com/2014.1.528/styles/kendo.common.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2014.1.528/styles/kendo.default.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2014.1.528/styles/kendo.dataviz.min.css" rel="stylesheet" />
<link href="http://cdn.kendostatic.com/2014.1.528/styles/kendo.dataviz.default.min.css" rel="stylesheet" />
<script src="http://cdn.kendostatic.com/2014.1.528/js/jquery.min.js"></script>
<script src="http://cdn.kendostatic.com/2014.1.528/js/kendo.all.min.js"></script>
</head>
<body>
<div id="example">
<div id="playlist">
<ul id="sortable-basic" data-bind="source:items" data-template="template">
</ul>
</div>
<script type="text/x-kendo-tmpl" id="template">
<li class="sortable">#:value#<span>#:time#</span></li>
</script>
<script>
var data;
$(document).ready(function () {
data = kendo.observable({
items: new kendo.data.ObservableArray([
{ value: 'Papercut', time: '3:12' },
{ value: 'One Step Closer ', time: '4:10' },
{ value: 'With You ', time: '5:00' },
{ value: 'Points of Authority ', time: '2:59' }]
)
});
kendo.bind($('#playlist'), data);
$("#sortable-basic").kendoSortable({
change: function (e) {
var daa = data.items.splice(e.oldIndex, 1);
data.items.splice(e.newIndex, 0, daa[0]);
}
});
});
</script>
<style>
#example
{
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#playlist
{
margin: 30px auto;
width: 300px;
background-color: #f3f5f7;
border-radius: 4px;
border: 1px solid rgba(0,0,0,.1);
}
#playlist-title
{
height: 80px;
border-radius: 4px 4px 0 0;
border-bottom: 1px solid rgba(0,0,0,.1);
}
#playlist-title span
{
display: none;
}
#sortable-basic
{
padding: 0;
margin: 0;
}
li.sortable
{
list-style-type: none;
padding: 6px 8px;
margin: 0;
color: #666;
font-size: 1.2em;
}
li.sortable:last-child
{
border-bottom: 0;
border-radius: 0 0 4px 4px;
}
li.sortable span
{
display: block;
float: right;
color: #666;
}
li.sortable:hover
{
background-color: #dceffd;
}
li.hint
{
display: block;
width: 200px;
background-color: #52aef7;
color: #fff;
}
li.hint:after
{
content: "";
display: block;
width: 0;
height: 0;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-left: 6px solid #52aef7;
position: absolute;
left: 216px;
top: 8px;
}
li.hint:last-child
{
border-radius: 4px;
}
li.hint span
{
color: #fff;
}
li.placeholder
{
background-color: #dceffd;
color: #52aef7;
text-align: right;
}
</style>
</div>
</body>
</html>
I think I found your problem. It seems to be the change function, just remove it and you can sort your list.
I've not used kendoSortable but I would assume that it is already maintaining the array sort because you have bound the array to the kendoSortable. That's the purpose of binding, it keeps the data and elements in sync for you. What you're doing in the change event is simply undoing the work that the binding just did, that is, sort the elements AND the bound array.
As per telerik,
https://www.telerik.com/forums/sortable-and-moving-items-in-observable-arrays
You have to do this manually and attaching sortable to an array doesn't do anything automatically. So what you are doing is correct, however even though your changes reflect correctly in observable array it doesn't on screen.
So we have to trigger clear and change event, to sync UI with the array. There may be a better way invoke sync without having to clear out array but this was a hack that worked for me.
Here is a sample code where we clear the array and then re-insert which fixes the issue.
$("#sortable-basic").kendoSortable({
change: function (e) {
var daa = data.items.splice(e.oldIndex, 1);
data.items.splice(e.newIndex, 0, daa[0]);
var copiedArray = data.items.splice(0, data.items.length);
$.each(copiedArray,
function (index, item) {
data.items.push(item);
});
}
});

Resources