getting error window.getselection() --- developing chrome extension - google-chrome-extension

I am developing a chrome extension , i need to get selected text from any page to chrome extension.I am unable to get the output
I just want to take selected image or any text to extension
In console getting the following error
Uncaught IndexSizeError: Index or size was negative, or greater than the allowed value.
//script.js
var selection = window.getSelection();
var range = selection.getRangeAt(0); //Getting error in this line.window.getSelection() is always null
if (range) {
var div = document.createElement('div');
div.appendChild(range.cloneContents());
vs=div.innerHTML;
}
chrome.extension.sendRequest({viewsource: vs}, function(response) {
console.log(response.farewell);
});
chrome.tabs.executeScript(null, {file:"script.js"});
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
document.getElementById("txtar").innerText=request.viewsource;
});
//popup.html
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="script.js"></script>
<style>
body {
margin:0px;
padding:0px;
overflow:hidden;
background:pink;
}
#txtar {
height: 200px;
width: 300px;
max-width:780px;
max-height:560px;
min-width:300px;
min-height:200px;
padding:6px;
margin:0px;
background-color:white;
color:#000088;
border:none;
}
#boohle {
position:absolute;
bottom:0px;
left:0px;
font-size:10px;
font-family:Arial;
float:left;
background-color:white;
z-index:200;
font-weight:normal;
}
#boohle a {
color:#008800;
text-decoration:none;
}
#boohle a:hover {
color:#ff0000;
}
</style>
</head>
<body>
<textarea id="txtar" readonly></textarea>
</body>
</html>
//manifest.json
{
"name": "Selection",
"version": "1.0",
"browser_action": {
"default_icon": "img/19x19.png",
"default_title": "View Selection Source",
"default_popup": "popup.html"
},
"manifest_version": 2,
"description": "View selection source in resizable popup. Drag the bottom right corner to resize. Simple, but very useful for web developers.",
"icons": {
"128": "img/128x128.png",
"16": "img/16x16.png",
"19": "img/19x19.png",
"32": "img/32x32.png",
"48": "img/48x48.png"
}
}
Please help.

Related

Clear storage data from popup when close browser

I want develop ( Chrome Extension with ) a popup with persistent data when close popup, but I want delete storage data when close browser.
This example save current status of button [start/stop] , but I want reset storage data when close the browser, how to delete storage data when close browser ?
Goal about this code example
When close popup save correctly status ( work )
When close browser, clean current status and set to start ( I need to implement )
I read this solution, but is not clear how to implement in my case
let button = document.querySelector('button');
let options = document.querySelector("#btn-start");
chrome.storage.local.get(['button'], function(status) {
console.log('Value currently is ' + status.button);
console.log(typeof(status.button))
if ( status.button === 'Stop') {
setButtonStop();
}
});
button.addEventListener("click", changeButtonStatus);
function changeButtonStatus(){
let buttonStatus = document.querySelector("button").innerText;
let status = '';
if ( buttonStatus === 'Start')
status = setButtonStop();
if ( buttonStatus === 'Stop')
status = setButtonStart();
chrome.storage.local.set({button: status }, function() {
console.log('Value is set to ' + [status]);
});
}
function setButtonStop () {
options.setAttribute("id", "btn-stop");
button.innerText = "Stop";
return button.innerText;
}
function setButtonStart () {
options.setAttribute("id", "btn-start");
button.innerText = "Start";
return button.innerText;
}
a:link,
a:visited,
a:hover,
a:active {
text-decoration: none;
}
/* Popup Window */
#modal-popup {
display: flex;
flex-direction: column;
background: gainsboro;
}
#btn-start button {
width: 100%;
background: green;
color:white;
}
#btn-start button:active {
border-color: green;
background: rgb(0, 255, 0);
color: black;
}
#btn-stop button {
width: 100%;
background: red;
color:white;
}
#btn-stop button:active {
border-color: red;
background: rgb(148, 0, 0);
color: rgb(255, 255, 255);
}
#btn-options button {
width: 100%;
background: white;
border: 0;
}
#btn-options button:active {
background-color: transparent;
animation: rotate 5s infinite;
}
#keyframes rotate {
0% {
transform: rotate(-45deg)
}
100% {
transform: rotate(45deg)
}
}
<!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">
<link rel="stylesheet" href="app.css">
<title>Popup</title>
</head>
<body>
<div id="modal-popup">
<div id="btn-start"><button type="button" name="control">Start</button></div>
<div id="btn-options"><button type="button" name="options">⚙️</button><div>
</div>
<script src="popup.js"></script>
</body>
</html>
{
"name": "popup tutorial #1",
"description": "persistent data settings",
"version": "0.0.1",
"manifest_version": 3,
"permissions": ["storage"],
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "/images/16.png",
"32": "/images/32.png",
"48": "/images/48.png",
"128": "/images/128.png"
}
},
"icons": {
"16": "/images/16.png",
"32": "/images/32.png",
"48": "/images/48.png",
"128": "/images/128.png"
}
}
use chrome.storage.session instead chrome.storage.local

Guide me on WebRTC PeerJS

I have wrong output of peerjs webrtc call. can anyone help me on how to show the remote and local video chat in the same screen? currently it is showing only one video chat user. Also, I want the design view like this.
https://drive.google.com/file/d/1KPnoEBanIUuThrPuavL1bnqIlG5yjC0o/view?usp=sharing
Can anyone help me by share the total code of this picture UX design view?
My project server is on peerjs cloud server, so no need to put hard coded ip address of 2 peer hosts.
The project has 3 files. main.js, index.html and style.css. Here is the code for main.js .
const peer = new Peer();
var currentCall;
peer.on("open", function (id) {
document.getElementById("uuid").textContent = id;
});
async function callUser() {
// get the id entered by the user
const peerId = document.querySelector("input").value;
// grab the camera and mic
const stream = await navigator.mediaDevices.getUserMedia({
video: true,
audio: true,
});
// switch to the video call and play the camera preview
document.getElementById("menu").style.display = "none";
document.getElementById("live").style.display = "block";
document.getElementById("local-video").srcObject = stream;
document.getElementById("local-video").play();
// make the call
const call = peer.call(peerId, stream);
call.on("stream", (stream) => {
document.getElementById("remote-video").srcObject = stream;
document.getElementById("remote-video").play();
});
call.on("data", (stream) => {
document.querySelector("#remote-video").srcObject = stream;
});
call.on("error", (err) => {
console.log(err);
});
call.on('close', () => {
endCall()
})
// save the close function
currentCall = call;
}
peer.on("call", (call) => {
if (confirm(`Accept call from ${call.peer}?`)) {
// grab the camera and mic
navigator.mediaDevices
.getUserMedia({ video: true, audio: true })
.then((stream) => {
// play the local preview
document.querySelector("#local-video").srcObject = stream;
document.querySelector("#local-video").play();
// answer the call
call.answer(stream);
// save the close function
currentCall = call;
// change to the video view
document.querySelector("#menu").style.display = "none";
document.querySelector("#live").style.display = "block";
call.on("stream", (remoteStream) => {
// when we receive the remote stream, play it
document.getElementById("remote-video").srcObject = remoteStream;
document.getElementById("remote-video").play();
});
})
.catch((err) => {
console.log("Failed to get local stream:", err);
});
} else {
// user rejected the call, close it
call.close();
}
});
function endCall() {
// Go back to the menu
document.querySelector("#menu").style.display = "block";
document.querySelector("#live").style.display = "none";
// If there is no current call, return
if (!currentCall) return;
// Close the call, and reset the function
try {
currentCall.close();
} catch {}
currentCall = undefined;
}
Here is code for style.css.
#live {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
background-color: #000;
display: none;
}
#local-video {
position: absolute;
bottom: 0;
left: 0;
width: 250px;
-webkit-transform: scaleX(-1);
transform: scaleX(-1);
margin: 16px;
border: 2px solid #fff;
}
#remote-video {
position: absolute;
max-width: 100%;
height: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#end-call {
position: absolute;
bottom: 0;
right: 0;
padding: 8px;
background-color: red;
color: white;
border: none;
margin: 16px;
}
Here is code for index.html .
<!DOCTYPE html>
<html lang="en">
<head>
<title>P2P Video Chat</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://unpkg.com/peerjs#1.3.1/dist/peerjs.min.js"></script>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<!-- App code -->
<div id="menu">
<p>Your ID:</p>
<p id="uuid"></p>
<input type="text" placeholder="Peer id" />
<button onclick="callUser()">Connect</button>
</div>
<div id="live">
<video id="remote-video"></video>
<video id="local-video" muted="true"></video>
<button id="end-call" onclick="endCall()">End Call</button>
</div>
<div id="menu">
<p>Your ID:</p>
<p id="uuid"></p>
<input type="text" placeholder="Peer id" />
<button onclick="callUser()">Connect</button>
</div>
<script src="main.js"></script>
</body>
</html>
Any one come with
complete solution and help by working code links
that is >>compatible on All modern browsers>> is much appreciated. what do you think, which one active/compatible on all browsers >> opensip or peerjs ?

scrollIntoView causes WKWebView to be partially unresponsive

I'm having a problem with my hybrid iOS application, in iOS 11 beta. It is basically a web app running within a WKWebView. The problem does not exist in iOS 10, but has been introduced with iOS 11. As of beta 8, the problem is still reproducible.
When the webapp calls the JavaScript function scrollIntoView a couple of times, parts of the GUI becomes unresponsive.
The following reduced HTML file demonstrates the problem:
<!DOCTYPE html>
<html><head>
<meta charset="UTF-8">
<meta id="viewportMeta" name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
<title>Testcase</title>
<script>
let numClicks = 0;
function runScrollIntoView() {
document.querySelector(".element-1").scrollIntoView();
}
function debugInfo() {
return {
"window.screen.height": window.screen.height,
"window.screen.availHeight": window.screen.availHeight,
"document.body.scrollTop": document.body.scrollTop,
"document.body.scrollHeight": document.body.scrollHeight
};
}
function clickHandler() {
numClicks++;
document.querySelector('.counter').innerText += numClicks + " clicks, " + JSON.stringify(debugInfo()) + "\n";
}
</script>
<style>
.instructions div {
border: 1px solid blue;
color: blue;
}
.counter {
width: 300px;
height: 300px;
border: 1px solid black;
}
</style>
</head>
<body>
<div class="instructions">
<div onclick="clickHandler()">1. Click me to run click handler</div>
<div onclick="runScrollIntoView()">2. Click me to run Element.scrollIntoView</div>
<div onclick="clickHandler()">3. Click me to run click handler again</div>
<div onclick="runScrollIntoView()">4. Click me to run Element.scrollIntoView again</div>
<div onclick="clickHandler()">5. Click me to try run click handler again - nothing happens</div>
<div>(Repeat 4-5 if necessary)</div>
</div>
<div class="counter">
Number of clicks
</div>
<div class="element-1">Target to scrollIntoView</div>
</body>
</html>
... when being loaded with this viewcontroller:
import UIKit
import WebKit
import Foundation
import SystemConfiguration
class ViewControllerNgf: UIViewController, WKNavigationDelegate, WKUIDelegate {
var webView: WKWebView!
override func loadView() {
self.webView = WKWebView(frame: CGRect.zero)
webView.navigationDelegate = self
webView.uiDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
self.loadWebApp()
}
fileprivate func loadWebApp() {
let htmlFile = Bundle.main.path(forResource: "htmlfile", ofType: "html")
let html = try? String(contentsOfFile: htmlFile!, encoding: String.Encoding.utf8)
DispatchQueue.main.async {
self.webView!.loadHTMLString(html!, baseURL: nil)
}
}
}
I have reported this as a bug to Apple, but no response yet, leading me to think I'm doing something wrong in the app. But the Swift code is basically copied from Apple's documentation.
So what could be the problem?
The problem seems to have been resolved in iOS 11.2.

Json file as amp-list source in Azure AppService

I have created a sample amp page with
<amp-list width=auto
height=100
layout=fixed-height
src="https://my-azurewebsite/Data/Services.json"
>
Its showing error as below :
o 'Access-Control-Allow-Origin' header is present on the requested resource.
If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I enabled CORS using Azure portal. But still its not working. I can access the json via the browser directly.
Please have a try to import the amp-list and amp-mustache components in the header, more details please refer to document
The amp-list component fetches dynamic content from a CORS JSON endpoint and renders it using a supplied template.
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.1.js"></script>
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
I create a demo for this. The following is my detail steps:
1. Published a Web App with AMP page
2. Enable the CORS for the Web App in the Azure Portal.
3. Try to view the page from the browser
AMP page code:
<!doctype html>
<html ⚡>
<head>
<meta charset="utf-8">
<link rel="canonical" href="https://ampbyexample.com/components/amp-list/">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<style amp-boilerplate>
body {
-webkit-animation: -amp-start 8s steps(1,end) 0s 1 normal both;
-moz-animation: -amp-start 8s steps(1,end) 0s 1 normal both;
-ms-animation: -amp-start 8s steps(1,end) 0s 1 normal both;
animation: -amp-start 8s steps(1,end) 0s 1 normal both;
}
#-webkit-keyframes -amp-start {
from {
visibility: hidden;
}
to {
visibility: visible;
}
}
#-moz-keyframes -amp-start {
from {
visibility: hidden;
}
to {
visibility: visible;
}
}
#-ms-keyframes -amp-start {
from {
visibility: hidden;
}
to {
visibility: visible;
}
}
#-o-keyframes -amp-start {
from {
visibility: hidden;
}
to {
visibility: visible;
}
}
#keyframes -amp-start {
from {
visibility: hidden;
}
to {
visibility: visible;
}
}
</style>
<noscript>
<style amp-boilerplate>
body {
-webkit-animation: none;
-moz-animation: none;
-ms-animation: none;
animation: none;
}
</style></noscript>
<style amp-custom>
amp-list {
margin-left: 16px;
}
.list-overflow {
position: absolute;
bottom: 0;
right: 0;
}
</style>
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.1.js"></script>
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
</head>
<body>
<amp-list width=auto
height=100
layout=fixed-height
src="https://my.azurewebsites.net/test.json"
template="amp-template-id"
>
</amp-list>
<template id="amp-template-id" type="amp-mustache">
<div>
<p>FirstName : {{firstName}}</p>
</div>
</template>
</body>
</html>
test.json :
{
"items": [
{
"firstName": "tom",
"lastName": "test"
},
{
"firstName": "tom1",
"lastName": "test"
},
{
"firstName": "tom2",
"lastName": "test"
}
]
}

While rendering html+js page in node.js using jade, getting html as text rendered instead of the html

I am trying to render an html+js page in nodejs using jade. I used the online available html to jade converters to convert my html to jade and then render it from my nodejs app. However, I am not able to render the jade properly.
The example that I used is the one provided by google in their documentation for google maps API
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Marker animations with google</title>
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
#panel {
position: absolute;
top: 5px;
left: 50%;
margin-left: -180px;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script>
var berlin = new google.maps.LatLng(52.520816, 13.410186);
var neighborhoods = [
new google.maps.LatLng(52.511467, 13.447179),
new google.maps.LatLng(52.549061, 13.422975),
new google.maps.LatLng(52.497622, 13.396110),
new google.maps.LatLng(52.517683, 13.394393)
];
var markers = [];
var iterator = 0;
var map;
function initialize() {
var mapOptions = {
zoom: 12,
center: berlin
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
}
function drop() {
for (var i = 0; i < neighborhoods.length; i++) {
setTimeout(function() {
addMarker();
}, i * 200);
}
}
function addMarker() {
markers.push(new google.maps.Marker({
position: neighborhoods[iterator],
map: map,
draggable: false,
animation: google.maps.Animation.DROP
}));
iterator++;
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="panel" style="margin-left: -52px">
<button id="drop" onclick="drop()">Drop Markers</button>
</div>
<div id="map-canvas"></div>
</body>
</html>
I tried many converters to convert but each of them gave me one or the other error. The http://html2jade.vida.io/ was able to convert it into jade.
I saved the file as maps_marker.jade in my views directory and from one of my APIs in web.js I made a call "res.render('maps_marker',{})" to render this page.
However the page rendered the following html as text
<!DOCTYPE html><html><head><meta charset="utf-8"><title>Marker animations with google</title><style><html>, body, #map-canvas {height: 100%;margin: 0px;padding: 0px}</html><div id="panel">{position: absolute;top: 5px;left: 50%;margin-left: -180px;z-index: 5;background-color: #fff;padding: 5px;border: 1px solid #999;}</div></style><script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script><script><var>berlin = new google.maps.LatLng(52.520816, 13.410186);</var><var>neighborhoods = [</var><new>google.maps.LatLng(52.511467, 13.447179),</new><new>google.maps.LatLng(52.549061, 13.422975),</new><new>google.maps.LatLng(52.497622, 13.396110),</new><new>google.maps.LatLng(52.517683, 13.394393)</new>];<var>markers = [];</var><var>iterator = 0;</var><var>map;</var><function>initialize() {</function><var>mapOptions = {zoom: 12,center: berlin};</var><map>= new google.maps.Map(document.getElementById('map-canvas'),mapOptions);}</map><function>drop() {for (var i = 0; i < neighborhoods.length; i++) {setTimeout(function() {addMarker();}, i * 200);}}</function><function>addMarker() {markers.push(new google.maps.Marker({position: neighborhoods[iterator],map: map,draggable: false,animation: google.maps.Animation.DROP}));iterator++;}</function><google window load initialize class="maps event addDomListener"></google></script></head><body><div id="panel" style="margin-left: -52px"><button id="drop" onclick="drop()">Drop Markers</button></div><div id="map-canvas"></div></body></html>
Can someone help me understand how to render such html+js in node.js.
I am currently try to use the jade template engine, but am open to using any other template engine as well.
UPdated to add snippet from my web.js and input from
I have an index.html(in public folder) with the following form within it
<form id="searchForm" action="/submit_search" method="POST" enctype="multipart/form-data">
<input name="latitude" type="text" id="latitude"/>
<input name="longitude" type="text" id="longitude"/>
<input type="submit" value="Submit" onclick="submitForm()">
</form>
In my javascript - I submit the form.
IN my web.js I have the following snippet for submit_search API
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.post('/submit_search', function(req,res){
console.log(JSON.stringify(req.body));
pg.connect(database_url, function(err, pgclient, done){
if(err)
{
console.log("Error in fetching pgclient from pool");
res.send(500, "Load the error connection page");
}
else if(pgclient != null)
{
console.log("Got an instance of pgclient");
generateDataForMap(req, res, pgclient, done);
}
});
});
And then I have defined my generateDataForMap method
var generateDataForMap = function(req, res, pgclient, done){
... some processing.....
..... create the required json.....
res.render('maps_marker',json);
}
I have put the maps_marker.jade file in the views folder..
The jade file produced by http://html2jade.vida.io/ is not valid. To fix it, you need to add a . (dot char) after the style and script tags to turn them in to style. and script. respectively.
doctype html
html
head
meta(charset="utf-8")
title Marker animations with google
style.
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
#panel {
position: absolute;
top: 5px;
left: 50%;
margin-left: -180px;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
}
script(src="https://maps.googleapis.com/maps/api/js?v=3.exp")
script.
var berlin = new google.maps.LatLng(52.520816, 13.410186);
var neighborhoods = [
new google.maps.LatLng(52.511467, 13.447179),
new google.maps.LatLng(52.549061, 13.422975),
new google.maps.LatLng(52.497622, 13.396110),
new google.maps.LatLng(52.517683, 13.394393)
];
var markers = [];
var iterator = 0;
var map;
function initialize() {
var mapOptions = {
zoom: 12,
center: berlin
};
map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
}
function drop() {
for (var i = 0; i < neighborhoods.length; i++) {
setTimeout(function() {
addMarker();
}, i * 200);
}
}
function addMarker() {
markers.push(new google.maps.Marker({
position: neighborhoods[iterator],
map: map,
draggable: false,
animation: google.maps.Animation.DROP
}));
iterator++;
}
google.maps.event.addDomListener(window, 'load', initialize);
body
#panel(style="margin-left: -52px")
button#drop(onclick="drop()") Drop Markers
#map-canvas

Resources