Multiple URLs in manifest.json file - google-chrome-extension

I am trying to build a Chrome plugin. In the main folder, I have a popup.html which runs by default and uses the following syntax in manifest.json
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
the popup.html is working absolutely fine
what is my popup.html is doing?
It is inputting email from the user and storing it in local phpmyadmin.
Following is the code of popup.html
<!doctype html>
<html style="min-width:350px;">
<head>
<title>Welcome</title>
</head>
<body>
<h3> Enter email </h3>
<form action=”info.php” method=”post”>
Enter email: <input type=”email” name=”email” />
<input type="submit" value="Submit" >
</form>
</body>
</html>
The form action is linked to info.php where the php connects the database and inserts the data into the table in phpMyAdmin.
Following is the info.php code
<html>
<body>
<?php
$con = mysql_connect('127.0.0.1','root','');
if (!$con)
{
echo'Could not connect to the server';
}
if (!mysqli_select_db($con,'test'))
{
echo 'Database Not Selected';
}
$Email = $_POST[email];
$sql = "INSERT INTO test_table(Email) VALUES ('$Email')";
if(!mysqli_query($con,$sql))
{
echo 'Could not add to database';
}
else
{
echo 'Thank you the data is added';
}
header("refresh:2; url=popup.html");
?>
</body>
</html>
What problem am I facing?
After I enter the email in the input field it gives an error that Your file was not found It may have been moved or deleted.
ERR_FILE_NOT_FOUND
Maybe I am getting this error because info.php has to added in the manifest file? If this is the problem then how can I add multiple urls in the manifest.json file?

Your header won't work, since you have already echoed output.
Instead of outputting immediately, stick the output into an $html variable.
This might not completely fix your issue? But it will fix the header.
<?php
$html = '';
$con = mysql_connect('127.0.0.1','root','');
if (!$con)
{
$html .= 'Could not connect to the server';
}
if (!mysqli_select_db($con,'test'))
{
$html .= 'Database Not Selected';
}
$Email = $_POST[email];
$sql = "INSERT INTO test_table(Email) VALUES ('$Email')";
if(!mysqli_query($con,$sql))
{
$html .= 'Could not add to database';
}
if (empty($html)) {
header("refresh:2; url=popup.html");
}
echo $html;

with #wOxxOm help the problem was solved.
In the popup.html instead of giving info.html directly, it would have been through the server such as http://localhost/foldername/info.php

Related

Chrome Extension Manifest V3 permission for Javascript [duplicate]

This seems to be the easiest thing to do, but it's just not working. In a normal browser the .html and .js files works perfectly, but in the Chrome/Firefox extension the onClick function is not performing what it's supposed to do.
.js file:
function hellYeah(text) {
document.getElementById("text-holder").innerHTML = text;
}
.html file:
<!doctype html>
<html>
<head>
<title>
Getting Started Extension's Popup
</title>
<script src="popup.js"></script>
</head>
<body>
<div id="text-holder">
ha
</div>
<br />
<a onClick=hellYeah("xxx")>
hyhy
</a>
</body>
</html>
So basically once the user clicks "hyhy", "ha" should change into "xxx". And again - it works perfectly in the browser but does not work in the extension. Do you know why? Just in case I'm attaching the manifest.json below as well.
manifest.json:
{
"name": "My First Extension",
"version": "1.0",
"manifest_version": 2,
"description": "The first extension that I made.",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": [
"http://api.flickr.com/"
]
}
Chrome Extensions don't allow you to have inline JavaScript (documentation).
The same goes for Firefox WebExtensions (documentation).
You are going to have to do something similar to this:
Assign an ID to the link (<a onClick=hellYeah("xxx")> becomes <a id="link">), and use addEventListener to bind the event. Put the following in your popup.js file:
document.addEventListener('DOMContentLoaded', function() {
var link = document.getElementById('link');
// onClick's logic below:
link.addEventListener('click', function() {
hellYeah('xxx');
});
});
popup.js should be loaded as a separate script file:
<script src="popup.js"></script>
Reason
This does not work, because Chrome forbids any kind of inline code in extensions via Content Security Policy.
Inline JavaScript will not be executed. This restriction bans both inline <script> blocks and inline event handlers (e.g. <button onclick="...">).
How to detect
If this is indeed the problem, Chrome would produce the following error in the console:
Refused to execute inline script because it violates the following Content Security Policy directive: "script-src 'self' chrome-extension-resource:". Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.
To access a popup's JavaScript console (which is useful for debug in general), right-click your extension's button and select "Inspect popup" from the context menu.
More information on debugging a popup is available here.
How to fix
One needs to remove all inline JavaScript. There is a guide in Chrome documentation.
Suppose the original looks like:
<a onclick="handler()">Click this</a> <!-- Bad -->
One needs to remove the onclick attribute and give the element a unique id:
<a id="click-this">Click this</a> <!-- Fixed -->
And then attach the listener from a script (which must be in a .js file, suppose popup.js):
// Pure JS:
document.addEventListener('DOMContentLoaded', function() {
document.getElementById("click-this").addEventListener("click", handler);
});
// The handler also must go in a .js file
function handler() {
/* ... */
}
Note the wrapping in a DOMContentLoaded event. This ensures that the element exists at the time of execution. Now add the script tag, for instance in the <head> of the document:
<script src="popup.js"></script>
Alternative if you're using jQuery:
// jQuery
$(document).ready(function() {
$("#click-this").click(handler);
});
Relaxing the policy
Q: The error mentions ways to allow inline code. I don't want to / can't change my code, how do I enable inline scripts?
A: Despite what the error says, you cannot enable inline script:
There is no mechanism for relaxing the restriction against executing inline JavaScript. In particular, setting a script policy that includes 'unsafe-inline' will have no effect.
Update: Since Chrome 46, it's possible to whitelist specific inline code blocks:
As of Chrome 46, inline scripts can be whitelisted by specifying the base64-encoded hash of the source code in the policy. This hash must be prefixed by the used hash algorithm (sha256, sha384 or sha512). See Hash usage for <script> elements for an example.
However, I do not readily see a reason to use this, and it will not enable inline attributes like onclick="code".
I had the same problem, and didn´t want to rewrite the code, so I wrote a function to modify the code and create the inline declarated events:
function compile(qSel){
var matches = [];
var match = null;
var c = 0;
var html = $(qSel).html();
var pattern = /(<(.*?)on([a-zA-Z]+)\s*=\s*('|")(.*)('|")(.*?))(>)/mg;
while (match = pattern.exec(html)) {
var arr = [];
for (i in match) {
if (!isNaN(i)) {
arr.push(match[i]);
}
}
matches.push(arr);
}
var items_with_events = [];
var compiledHtml = html;
for ( var i in matches ){
var item_with_event = {
custom_id : "my_app_identifier_"+i,
code : matches[i][5],
on : matches[i][3],
};
items_with_events.push(item_with_event);
compiledHtml = compiledHtml.replace(/(<(.*?)on([a-zA-Z]+)\s*=\s*('|")(.*)('|")(.*?))(>)/m, "<$2 custom_id='"+item_with_event.custom_id+"' $7 $8");
}
$(qSel).html(compiledHtml);
for ( var i in items_with_events ){
$("[custom_id='"+items_with_events[i].custom_id+"']").bind(items_with_events[i].on, function(){
eval(items_with_events[i].code);
});
}
}
$(document).ready(function(){
compile('#content');
})
This should remove all inline events from the selected node, and recreate them with jquery instead.
I decide to publish my example that I used in my case. I tried to replace content in div using a script. My problem was that Chrome did not recognized / did not run that script.
In more detail What I wanted to do: To click on a link, and that link to "read" an external html file, that it will be loaded in a div section.
I found out that by placing the script before the DIV with ID that
was called, the script did not work.
If the script was in another DIV, also it does not work
The script must be coded using document.addEventListener('DOMContentLoaded', function() as it was told
<body>
<a id=id_page href ="#loving" onclick="load_services()"> loving </a>
<script>
// This script MUST BE under the "ID" that is calling
// Do not transfer it to a differ DIV than the caller "ID"
document.getElementById("id_page").addEventListener("click", function(){
document.getElementById("mainbody").innerHTML = '<object data="Services.html" class="loving_css_edit"; ></object>'; });
</script>
</body>
<div id="mainbody" class="main_body">
"here is loaded the external html file when the loving link will
be clicked. "
</div>
As already mentioned, Chrome Extensions don't allow to have inline JavaScript due to security reasons so you can try this workaround as well.
HTML file
<!doctype html>
<html>
<head>
<title>
Getting Started Extension's Popup
</title>
<script src="popup.js"></script>
</head>
<body>
<div id="text-holder">ha</div><br />
<a class="clickableBtn">
hyhy
</a>
</body>
</html>
<!doctype html>
popup.js
window.onclick = function(event) {
var target = event.target ;
if(target.matches('.clickableBtn')) {
var clickedEle = document.activeElement.id ;
var ele = document.getElementById(clickedEle);
alert(ele.text);
}
}
Or if you are having a Jquery file included then
window.onclick = function(event) {
var target = event.target ;
if(target.matches('.clickableBtn')) {
alert($(target).text());
}
}

Showing Error Message

When I run this program and enter Dan Dan inside of it, it works. Now when I enter http://sftpgamblerlotteryclub/www it doesn't work. I would like for it to catch the sftp, /, www and return back to the form and inform the user " this is not a username, please resubmit". Thanks you.
<?php
// define variables and set to empty values
$nameErr = $emailErr = "";
$name = $email = $subject = "";
if ($_SERVER["REQUEST_METHOD"] == "POST"){
if (empty($_POST["name"])) {
$nameErr = "Name is required";
} else {
$name = test_input($_POST["name"]);
// check if name only contains letters and whitespace
if (preg_match("/^[a-zA-Z-']*$/",$name)) {
$nameErr = "Only letters and white space allowed";
}
}
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
<html>
<head>
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Contact Form</title>
</head>
<body>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Name:
<input type="text" name="name">
<span class="error">* <?php echo $nameErr; ?> </span>
<br><br>
<input name="submit_btn" type="submit" id="submit-btn" value="Send Mail">
</form>
</div>
</body>
</html>
<?php
echo $name;
?>
Your test_input function is striping out the / so that is removed before you do your preg_match. As such you will never catch the /.
If I understand your question you want to make sure the user name is not in a list of prohibited names. For that I would create an array of prohibited names and then do a stripos on the json_encoded output of the array within a if condition. This makes it easy to expand the list of prohibited names.
This is based on your code snip-it.
$array = ["sftp", "http", "www"];
if (stripos(json_encode($array),$name) !== false) {
$nameErr = "This is not a valid user name"
}

How to make a extension/script/program that will refresh a browser until a certain phrase/keyword is found or is not found?

Is there any program/extension that I can use with browser that will refresh a webpage and search for a certain phrase or text and then stop once the phrase is found or is not found.
For example say I made a site that cycles using a randomizer through the words "One," "Two," and "Three."
This program would refresh the page until the word "Three" is found, If I set it to find that word, and then stop once it is found.
OR
This program would refresh the page until the word "Three" is not found, If I set it to find that word, and then stop once it is not found.
I know that we can use curl and grep to do that, but the page is not loaded on webbrowser. This is not what I want. see if there is solution that we can load on browser as well
If there no such things exists, any idea on how to write this kind of program? use what tool to do that?
You could very easily write an extension to do this. I would suggest instead of refreshing the page every time, you poll the data until you get the desired result then refresh the page once you find it. A short example using jQuery because I am familiar with it:
Manifest.json
{
"name": "Find Text",
"version": "0.1",
"description": "Find Text",
"manifest_version": 2,
"browser_action": {
"default_icon": "on.png",
"default_popup": "popup.html"
},
"permissions": [
"tabs","http://*/*","https://*/*"
],
"background": {
"scripts": ["bgp.js","jquery-1.8.3.min.js"],
"persistent": true
}
}
Popup.html
<!DOCTYPE html>
<html>
<head>
<style>
body { width: 300px; }
</style>
<script src="jquery-1.8.3.min.js"></script>
<script src="popup.js"></script>
</head>
<body>
<div>Desired Search Url</div>
<input type="text" id="searchUrl">
<div>Desired Search Text</div>
<input type="text" id="searchText">
<button id="searchButton">Search</button>
</body>
</html>
Popup.js
$(function(){
var tabId;
chrome.tabs.query({active:true,currentWindow:true}, function(tab) {
$('#searchUrl').val(tab[0].url);
tabId = tab[0].id;
});
$('#searchButton').click(function(){
chrome.extension.sendMessage({
url:$('#searchUrl').val(),
text:$('#searchText').val(),
tab:tabId
});
});
});
bgp.js
chrome.extension.onMessage.addListener(function(message,sender,sendResponse){
checkUrlForText(message.url,message.text,message.tab);
});
function checkUrlForText(url,text,tab){
var contains;
$.ajax({
url:url,
async:false,
success: function(data){
contains = $(':contains('+text+')',data);
while(contains.length == 0){
$.ajax({
url:url,
async:false,
success: function(dat){
contains = $(':contains('+text+')',dat);
}
});
}
}
});
chrome.tabs.reload(tab);
}
If having it refresh the tab every time is a requirement (the content would change between the time it found what you were looking for and when it refreshes the page) then you should use content scripts to test for the desired value and send a message to the background page if the desired text is not there to refresh the page and start again. Like this:
bgp.js
var contains;
chrome.extension.onMessage.addListener(function(message,sender,sendResponse){
checkTabForText(message.text,message.tab);
contains = false;
});
function checkTabForText(text,tab){
chrome.tabs.executeScript(tab,{file:"jquery-1.8.3.min.js"});
chrome.tabs.executeScript(tab,{file:"checkText.js"},function(){
chrome.tabs.sendMessage(tab, {text:text}, function(response){
contains = response.contains;
if(!contains){
chrome.tabs.reload(tab,function(){
checkTabForText(text,tab);
});
}
});
});
}
checkText.js
chrome.extension.onMessage.addListener(function(message,sender,sendResponse){
var contains = $(':contains('+message.text+')');
if(contains.length > 0)
sendResponse({contains:true});
else
sendResponse({contains:false});
});

Masonry Infinite Scroll with Database and Anchor Tag that links to the current document

I am new to PHP, Javascript and HTML. So maybe I'm missing something obvious but, I can't for the life of me figure out what is wrong with my code. I am trying to use Paul Irish's Infinite Scroll with a PHP file that has an anchor point that links back to itself with different GET values. The problem is that Anything I do gives me this error:
Sorry, we couldn't parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag.
I am at my wits end and desperately need someones help because I need this done by January 20th. It's going to be a birthday gift for someone I know.
Here is my code:
index.php (Code Snippet)
<div id="content-container" class="container-fluid" style="padding:0px;overflow:hidden;">
<div class="row-fluid full">
<div class="span12 full" style="overflow:scroll;position:relative;">
<div id="media-palette">
<?php
include('content.php');
?>
</div>
</div>
</div>
</div>
script.js (Code Snippet)
$("#media-palette").infinitescroll({
navSelector:"#next",
nextSelector:"#media-palette a#next:last",
itemSelector:".media-content",
bufferPx:50,
debug: true,
}, function(newElements) {
$("#media-palette").masonry('append', newElements,true);
});
content.php
(It is worth noting that the images found in this file are for testing purposes and the final PHP file will load images from a database.)
<?php
require('dbconnect.php');
$startIndex = $_GET['start'];
$endIndex = $_GET['end'];
$nextStartIndex = $endIndex-1;
$nextEndIndex = $endIndex-10;
?>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<?php
$files = scandir("images");
if ($files) {
$length = count($files);
static $allowedExts = array("jpg", "jpeg", "gif", "png");
for ($i = 0; $i < $length; $i++) {
$extension = end(explode(".", $files[$i]));
$extension = strtolower($extension);
if (in_array($extension,$allowedExts)) {
$rand = rand(0,10);
if (!$rand) echo "<img class='media-content medium' src='images/".$files[$i]."'/>";
else echo "<img class='media-content small' src='images/".$files[$i]."'/>";
}
}
}
echo '<a id="next" href="content.php?start='.$nextStartIndex.'&end='.$nextEndIndex.'"></a>';
?>
</body>

How to make a simple autocomplete searchbox that gets data from database?

I am bit of a noob when it comes to jQuery and MySQL... I have seen some of the tutorials, but I can't figure out how I have to combine the things with my database. For instance, I have a table (?) with all my topics in it that I have called "TOPICS" in my database. What I want is that if someone uses the searchbox, that they will get suggestions that are in these TOPICS.
http://jqueryui.com/autocomplete/
This is a very simple autocomplete that I want to use. I can make it with local suggestions, but I don't know how to combine it with my database. Any help would be appreciated.
I think this is what you are after (well, it's what I would do anyway):
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jQuery UI Autocomplete - Default functionality</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css" />
<script>
$(function() {
var availableTags = [
<?php
require "connect.php"; //connect to your database
$select = "
SELECT topicname
FROM topics
ORDER BY topicname
";
$query = mysqli_query($link, $select);
if(!$query) die("Error: " . mysqli_error($link) . "\nMySQL: " . $select); //for trouble shooting purposes
while($array = mysqli_fetch_array($query)){
echo '"' . $array['topicname'] . '",';
}
?>
];
$( "#tags" ).autocomplete({
source: availableTags
});
});
</script>
</head>
<body>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags" />
</div>
</body></html>
The autocomplete provides an example: http://jqueryui.com/autocomplete/#remote-jsonp
$( "#city" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "http://ws.geonames.org/searchJSON",
dataType: "jsonp",
data: {
featureClass: "P",
style: "full",
maxRows: 12,
name_startsWith: request.term
},
success: function( data ) {
response( $.map( data.geonames, function( item ) {
return {
label: item.name + (item.adminName1 ? ", " + item.adminName1 : "") + ", " + item.countryName,
value: item.name
}
}));
}
});
},
minLength: 2,
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.label :
"Nothing selected, input was " + this.value);
},
open: function() {
$( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
},
close: function() {
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
}
});
You can't connect directly from Javascript to MySQL. You need a php file, jsp file or similar that fetches the results from the database and returns them to the autocompletion. Look at http://www.htmlblog.us/jquery-autocomplete for a simple example.
Instead of connecting to MySQL through REST frontend, I think it makes sense to look at 3rd party solution such as www.rockitsearch.com. It has the basic autocomplete functionality out of the box. All you need to do is register, export your data and integrate a widget to your web site. All the rest of the work will be done for you automatically.
I think an Ajax call to a PHP script that returns JSON formatted list of first 10 avail answers, based on the search input text value, and displaying from Javascript ( inside the Ajax call function ) in a DIV, below the searchbox, the values that are selectable / clickable.

Resources