Unable to show Desktop Notifications using Google Chrome - html

I followed the instructions as given in Using The Notifications API. Also I faced many problems like the below, because I added the document.querySelector() inside the <head> part:
Uncaught TypeError: Cannot call method 'addEventListener' of null
Now I have the below source, where I am able to Check Notification Support, and Check Notification Permissions links.
Guide me how to bring in notifications in a simpler way. Also, I tried this:
$("#html").click(function() {
if (window.webkitNotifications.checkPermission() == 0) {
createNotificationInstance({ notificationType: 'html' });
} else {
window.webkitNotifications.requestPermission();
}
});
Now I am stuck with this source. I need to generate HTML & Simple Notifications. Am I missing something? Please guide me.
Source:
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>Desktop Notifications</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
function checkNotifications() {
if (window.webkitNotifications)
alert("Notifications are supported!");
else
alert("Notifications are not supported for this Browser/OS version yet.");
}
function createNotificationInstance(options) {
if (window.webkitNotifications.checkPermission() == 0) { // 0 is PERMISSION_ALLOWED
if (options.notificationType == 'simple') {
return window.webkitNotifications.createNotification('icon.png', 'Notification Title', 'Notification content...');
} else if (options.notificationType == 'html') {
return window.webkitNotifications.createHTMLNotification('http://localhost/');
}
} else {
window.webkitNotifications.requestPermission();
}
}
</script>
<style type="text/css">
* {font-family: Verdana, sans-serif;}
body {font-size: 10pt; margin: 0; padding: 0;}
p {margin: 5px;}
a {color: #09f; text-decoration: none;}
a:hover {color: #f00;}
</style>
</head>
<body>
<p><strong>Desktop Notifications</strong></p>
<p>Lets see how the notifications work in this browser.</p>
<p>
Check Notification Support.
Next Check Notification Permissions
and if permissions are not there,
Request Permissions.
Create a
Simple Notification
or
HTML Notification.
</p>
</body>
<script type="text/javascript">
document.querySelector("#html").addEventListener('click', function() {
if (window.webkitNotifications.checkPermission() == 0) {
createNotificationInstance({ notificationType: 'html' });
} else {
window.webkitNotifications.requestPermission();
}
}, false);
document.querySelector("#text").addEventListener('click', function() {
if (window.webkitNotifications.checkPermission() == 0) {
createNotificationInstance({ notificationType: 'simple' });
} else {
window.webkitNotifications.requestPermission();
}
}, false);
</script>
</html>

After creating the notification, you need to call show() on it, so instead of just:
createNotificationInstance({ notificationType: 'simple' });
you need to do:
var n = createNotificationInstance({ notificationType: 'simple' });
n.show();
The other thing is: when doing jQuery code, wrap it inside
$(document).ready(function() {
// ...
// your jQuery code
// ...
});
When doing actions on the DOM with jQuery inside the head, the DOM isn't build yet. $(document).ready waits until the DOM is build and you can savely access and manipulate it.
Here is a working example: http://jsfiddle.net/fkMA4/
BTW: I think HTML notifications are deprecated, see here: http://www.html5rocks.com/en/tutorials/notifications/quick/?redirect_from_locale=de
Notifications with HTML content have been deprecated. Samples and text
have been modified accordingly.

Related

Why does reading localStorage values require a page refresh to show CSS changes toggled by jQuery?

I'm trying to use the value of localStorage to display one of two Twitter feeds, one for a light mode theme, the other for dark mode. It works, but I have to refresh the webpage for the correct CSS - either twitter-dark-display-none or twitter-light-display-none - to work.
Using jQuery(document).ready(function () doesn't help.
The Fiddle: https://jsfiddle.net/zpsf5q3x/2/ But the sample tweets don't show due to JSFiddle limits on displaying third party frames. And, localstorage may not work there, either.
Fiddle calls two external libraries:
https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle#3.6.1/css/bootstrap4-toggle.min.css and https://cdn.jsdelivr.net/gh/gitbrent/bootstrap4-toggle#3.6.1/js/bootstrap4-toggle.min.js
HTML:
Note the data-theme="dark" in the first block.
<div class="twitter-dark-display-none">
<a class="twitter-timeline" data-width="170" data-height="200" data-theme="dark"
data-tweet-limit="1" data-chrome="transparent nofooter noborders" href="https://twitter.com/StackOverflow?ref_src=twsrc%5Etfw">Tweets</a>
</div>
<div class="twitter-light-display-none">
<a class="twitter-timeline" data-width="170" data-height="200" data-tweet-limit="1" data-chrome="transparent nofooter noborders" href="https://twitter.com/StackOverflow?ref_src=twsrc%5Etfw">Tweets</a>
</div>
jQuery:
Overall function that uses localStorage to toggle the entire site between dark and normal mode.
$('body').toggleClass(localStorage.toggled);
function darkLight() {
if (localStorage.toggled != 'dark') {
$('body').toggleClass('dark', true);
localStorage.toggled = "dark";
} else {
$('body').toggleClass('dark', false);
localStorage.toggled = "";
}
}
What I'm trying to use to toggle CSS:
if (localStorage.toggled === 'dark') {
$('.twitter-light-display-none').addClass("display-none");
$('.twitter-dark-display-none').addClass("display-block");
} else {
$('.twitter-dark-display-none').addClass("display-none");
$('.twitter-light-display-none').addClass("display-block");
}
CSS:
.display-none {
display: none !important;
}
.display-block {
display: block !important;
}
Edit 10/24/2020:
johannchopin's answer works, with the addition of $('body').toggleClass(localStorage.toggled);
as in my original code above.
But. There is some sort of conflict with the gitbrent dark mode JS and CSS libraries, so I switched to https://github.com/coliff/dark-mode-switch and that results in a simpler way to both toggle dark mode and use localstorage in addition to the function johannchopin provided to switch between twitter widget divs:
<script>
(function() {
var darkSwitch = document.getElementById("darkSwitch");
if (darkSwitch) {
initTheme();
darkSwitch.addEventListener("change", function(event) {
resetTheme();
});
function initTheme() {
var darkThemeSelected =
localStorage.getItem("darkSwitch") !== null &&
localStorage.getItem("darkSwitch") === "dark";
darkSwitch.checked = darkThemeSelected;
darkThemeSelected
? document.body.setAttribute("data-theme", "dark")
: document.body.removeAttribute("data-theme");
}
function resetTheme() {
if (darkSwitch.checked) {
document.body.setAttribute("data-theme", "dark");
localStorage.setItem("darkSwitch", "dark");
} else {
document.body.removeAttribute("data-theme");
localStorage.removeItem("darkSwitch");
}
updatedarkSwitch();
}
}
})();
function updatedarkSwitch() {
if (localStorage.darkSwitch === 'dark') {
$('.twitter-light-display-none').addClass("display-none").removeClass('display-block');
$('.twitter-dark-display-none').addClass("display-block").removeClass('display-none');
} else {
$('.twitter-dark-display-none').addClass("display-none").removeClass('display-block');
$('.twitter-light-display-none').addClass("display-block").removeClass('display-none');
}
}
updatedarkSwitch()
</script>
And then use the most basic dark mode rule in the style sheet:
[data-theme="dark"] {
background-color: #000000 !important;
}
and also add any other more specific CSS rules needed, i.e.
[data-theme="dark"] .post-title{
color:#fff !important;
}
You have multiple issues in you code. First, you toggle the CSS, but only when the page loads because this code is only run once (when the script is loaded):
if (localStorage.toggled === 'dark') {
// ...
Just move this script in the function (ex: updateInterfaceTheme) that you call at the end of darkLight().
Another issue is that you forget to clean the previous class and that leads to a styling conflict:
$('.twitter-light-display-none').addClass("display-none"); // class .display-block still exist
$('.twitter-dark-display-none').addClass("display-block"); // class .display-none still exist
So don't forget to clean them:
if (localStorage.toggled === 'dark') {
$('.twitter-light-display-none').addClass("display-none").removeClass('display-block');
$('.twitter-dark-display-none').addClass("display-block").removeClass('display-none');
} else {
$('.twitter-dark-display-none').addClass("display-none").removeClass('display-block');
$('.twitter-light-display-none').addClass("display-block").removeClass('display-none');
}
And like that it's working:
function darkLight() {
if (localStorage.toggled !== 'dark') {
$('body').toggleClass('dark', true);
localStorage.toggled = "dark";
} else {
$('body').toggleClass('dark', false);
localStorage.toggled = "";
}
updateInterfaceTheme();
}
function updateInterfaceTheme() {
if (localStorage.toggled === 'dark') {
$('.twitter-light-display-none').addClass("display-none").removeClass('display-block');
$('.twitter-dark-display-none').addClass("display-block").removeClass('display-none');
} else {
$('.twitter-dark-display-none').addClass("display-none").removeClass('display-block');
$('.twitter-light-display-none').addClass("display-block").removeClass('display-none');
}
}
updateInterfaceTheme()
.display-none {
display: none !important;
}
.display-block {
display: block !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label class="switch"><span class="switchtext">Dark</span>
<input type="checkbox" data-style="ios" data-onstyle="outline-secondary" data-offstyle="outline-secondary" data-size="sm" data-toggle="toggle" onchange="darkLight()">
<span class="slider"></span><span class="switchtext">Mode</span>
</label>
<div class="twitter-dark-display-none">Dark Mode
<a class="twitter-timeline" data-width="170" data-height="200" data-theme="dark" data-tweet-limit="1" data-chrome="transparent nofooter noborders" href="https://twitter.com/StackOverflow?ref_src=twsrc%5Etfw">Tweets</a>
</div>
<div class="twitter-light-display-none">Light Mode
<a class="twitter-timeline" data-width="170" data-height="200" data-tweet-limit="1" data-chrome="transparent nofooter noborders" href="https://twitter.com/StackOverflow?ref_src=twsrc%5Etfw">Tweets</a>
</div>
Checkout the jsfiddle to see it working with localStorage.
You should use method getItem().
let x = localStorage.getItem('toggled');
And than make a check for a variable.
https://developer.mozilla.org/ru/docs/Web/API/Storage/getItem

display user selected text in html popup and update it in chrome extension

I have a background script which is fired upon clicking of chrome icon:
background.js:
chrome.browserAction.onClicked.addListener(function (tab) {
console.log("chrome.browserAction.onClicked...." + tab);
var openSeleniumEditor = window.open(
chrome.extension.getURL("Editor.html"),
"Words Misspelled",
"width=600,height=400"
);
});
My target is to collect all the words in the article which needs correction. User selects the text from the current page and content script should collect that and append to the list in the editor. The Editor.html is always open unlike the normal pop up. When user closes this Editor.html the text from Editor.html should be saved to local storage so that it can be referred later.
content.js:
function getSelectedParagraphText() {
if (window.getSelection) {
selection = window.getSelection();
} else if (document.selection) {
selection = document.selection.createRange();
}
var parent = selection.anchorNode;
while (parent != null && parent.localName != "P") {
parent = parent.parentNode;
}
if (parent == null) {
return "";
} else {
return parent.innerText || parent.textContent;
}
}
Editor.html:
<!DOCTYPE html>
<html>
<head>
<script src="Editor.js"></script>
<style>
body { width: 300px; }
textarea { width: 250px; height: 100px;}
</style>
</head>
<body>
<textarea id="text"> </textarea>
</body>
</html>
I would like to keep the code of Editor.html/Editor.js in a separate folder so that i can make use of it in every browser. Now how do i call/update the Editor.js or Editor.html to append the user selected text from content.js ?

Webcam Video Stream Working in Chrome but not Firefox

I've got a tiny little issue here O.o
I've got my webcam video stream displaying on a webpage... only thing is it only works in Chrome. When I use Firefox it requests permission to share the camera and once accepted the LED on the webcam comes on but my video element remains empty :/ I'm currently testing on Firefox 31 and Chrome 28.
Any ideas or helpful hints would be greatly appreciated ;)
Thanks :)
Below is my code used for testing:
<!DOCTYPE html>
<html>
<head>
<title>Web Cam Feed</title>
<style>
#container
{
margin: 0px auto;
width: 640px;
height: 480px;
border: 10px #333 solid;
}
#videoElement
{
width: 640px;
height: 480px;
background-color: #666;
}
</style>
</head>
<body>
<div id="container">
<video autoplay id="videoElement">
</video>
</div>
<script type="text/javascript">
var video = document.querySelector("video");
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;
if (navigator.getUserMedia)
{
navigator.getUserMedia(
{ video: true },
function (stream)
{
if (video.mozSrcObject !== undefined)
{
video.mozSrcObject = stream;
}
else
{
video.src = (window.URL && window.URL.createObjectURL(stream)) || stream;
};
},
function (err)
{
alert('Something broke');
});
}
else
{
alert('No User Media API');
}
</script>
</body>
</html>
I'm pretty sure, that you need to start the video in firefox by calling the play method, after the loadstart event:
$(function () {
navigator.getUserMedia(
// constraints
{
video: true,
audio: false
},
// successCallback
function (localMediaStream) {
var $video = $('video');
$video.on('loadstart', function () {
$video.play();
});
$video.prop('src', URL.createObjectURL(localMediaStream));
//or use $video.prop('srcObject', localMediaStream);
},
// errorCallback
function (err) {
alert('you need to give us access to your webcam for this. '+err.name);
});
});
Here is a simple demo.
After being MIA for a while and getting back into this issue I found that it's not a code issue >.<
It seems to be either my webcam drivers or an issue with Windows 8 or a combination of both because my code worked perfectly on a Windows 7 machine using default Windows drivers, but still on Firefox 31.
Anyways, thanks to alexander farkas for the help. I used some of your code to tweak my own ;)

Angular does not update UI for keyboard event

I want to update page for keyboard event.
I wired the keyboard event through $window.document.onkeydown. (I know this is not good but it is supposed to work)
However, I find that the page is not updating even the model is changed!
Where am I missing ?
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<script>
function Main ($scope, $window) {
$scope.keyCode = 0;
$window.document.onkeydown = function (event) {
$scope.keyCode = event.keyCode;
console.log($scope.keyCode); //the model is changed here
};
}
</script>
</head>
<body ng-app>
<div ng-controller="Main">
{{keyCode}}
</div>
<script type="text/javascript" src="bower_components/angular/angular.js"></script>
</body>
</html>
---Edit---
Here is the code snippet you can try
http://plnkr.co/edit/DFUfHzQPla031IEDdCo3?p=preview
Whenever you want to execute an expression that is outside Angular's scope you need to let Angular know that a change has been made so it can perform a proper digest cycle. You can do this using the $scope.$apply() method. So your example becomes:
function Main ($scope, $window) {
$scope.keyCode = 0;
$window.document.onkeydown = function (event) {
$scope.$apply(function () {
$scope.keyCode = event.keyCode;
console.log($scope.keyCode);
});
};
}
Please see updated plunker here

How do i make a div/iframe clickable only once

The title says it all : How do i make a div/iframe clickable only once
Im stuck with this for a long time,so I decided to ask for a little help.
Please,if you wanna help,put the whole script in here,not just a part of it so I get confused.
Thank you.
This is not very clear question though and it has no tags, but i try..
Assuming that you are using javascript. You can add counter variabel and check it every time you run the event.
window.load = function() {
var count = 0;
document.getElementById('div_or_iframe').onclick = function() {
if(count == 0) { // check if counter is 0
return true; // continue
count++; // update counter by +1
}
else { // if counter is 0 > clicking anything doesn't work
return false; // prevent action
}
}
}
I think that #aksu's answer is much easier, but I got it to work with classes and jquery. This will allow you to have several elements on your page be clickable only once.
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript">
function someFunction(obj) {
if ($(obj).hasClass("clickable")) {
// perform the code you want
alert("Function will be performed");
// make not clickable
$(obj).removeClass("clickable");
} else {
alert("Already Clicked");
}
}
</script>
</head>
<body>
<div class="clickable" onclick="someFunction(this)">CLICK HERE</span>
</body>
</html>