Polymer paper buttons not working inside chrome extension - javascript

I'm trying to add some paper elements to a popup of a chrome extension. So far so good as to rendering them in the popup but I'm having trouble having my buttons work. Since Chrome extensions have to have separate files for the JavaScript here is the code I'm working with:
popup.html
<html>
<head>
<title>Popup</title>
<script src="bower_components/webcomponentsjs/webcomponents.js"></script>
<link rel="import" href="bower_components/core-toolbar/core-toolbar.html">
<link rel="import" href="bower_components/font-roboto/roboto.html">
<link rel="import" href="bower_components/paper-button/paper-button.html">
<link rel="import" href="bower_components/paper-fab/paper-fab.html">
<link rel="import" href="bower_components/paper-tabs/paper-tabs.html">
<link rel="import" href="bower_components/paper-toast/paper-toast.html">
<link rel="stylesheet" href="css/popup.css">
</head>
<body unresolved style="width: 750px">
<section>
<template id="buttonGroup" is="auto-binding">
<paper-button raised="" id="signin" role="button" tabindex="1" on-click="{{signIn}}">Sign in</paper-button>
<paper-button raised="" id="signout" role="button" tabindex="2" on-click="{{signOut}}" class="red" >Sign out</paper-button>
</template>
</section>
<script src="js/popup.js"></script>
</body>
</html>
popup.js
Polymer({
var buttonIn = document.querySelector('signin');
buttonIn.addEventListener('signin', function() {
chrome.runtime.sendMessage({message: "do_signin"}, function(response) {});
});
var buttonOut = document.querySelector('signout');
buttonOut.addEventListener('signout', function() {
chrome.runtime.sendMessage({message: "do_signout"}, function(response) {});
});
});
The problem is Chrome is returning with the following Uncaught SyntaxError: Unexpected identifier on the line var buttonIn = document.querySelector('signin');
Is this because of some problem between polymer and the chrome extension or because I'm doing something wrong?
P.S. When the button gets clicked, all I need it to do is send a message to the background.js file that will handle the signin/signout.

Although I'm not very familiar with Polymer, it is clear that Polymer is expecting you to pass something other than a function, where you seem to be trying to pass in a function without properly declaring the function. Really, I think you should have all your scripts outside of Polymer like such:
Polymer();
var buttonIn = document.getElementById('signin');
buttonIn.addEventListener('signin', function() {
chrome.runtime.sendMessage({message: "do_signin"}, function(response) {});
});
var buttonOut = document.getElementById('signout');
buttonOut.addEventListener('signout', function() {
chrome.runtime.sendMessage({message: "do_signout"}, function(response) {});
});
Also note that I changed querySelector('signin') to getElementById('signin') as you are looking for an element with an id. To use querySelector with an "id", prepend a "#" to "signin": querySelector('#signin').
Check out the documentation as to how to initiate Polymer.

Related

Running JavaScript libraries (Looper) in Blazor Server-side - some javascript code is not running

I am trying to implement Looper theme to my blazor server-side app, and I have the javascript libraries referenced at the end of the in _Host.cshtml.However some scripts in theme.min.js is not running. Why?
<script src="/Library/vendor/jquery/jquery.min.js"></script>
<script src="/Library/vendor/popper.js/umd/popper.min.js"></script>
<script src="/Library/vendor/bootstrap/js/bootstrap.min.js"></script>
<script src="/Library/vendor/pace-progress/pace.min.js"></script>
<script src="/Library/vendor/stacked-menu/js/stacked-menu.min.js"></script>
<script src="/Library/vendor/perfect-scrollbar/perfect-scrollbar.min.js"></script>
<script src="/Library/javascript/theme.min.js"></script>
<script src="_framework/blazor.server.js"></script>
My problem is that while
<div data-toggle="drowndown"></div> works, but hamburger menu toggle
<button class="hamburger hamburger-squeeze mr-2" type="button" data-toggle="aside-menu" aria-label="toggle aside menu"><span class="hamburger-box"><span class="hamburger-inner"></span></span></button>
does not work. What am I missing here? What am I doing wrong? My theme change script also isn't running. If I step through theme.js and I can see that this script runs when blazor is not active (commenting out blazor.js) but with blazor active, this script does not run.
(line 610) in /library/javascript/theme.js
}, {
key: "toggleAside",
value: function toggleAside() {
var _this4 = this;
var $trigger = $('[data-toggle="aside"]');
$trigger.on('click', function () {
var isShown = $('.app-aside').hasClass('show');
$trigger.toggleClass('active', !isShown);
if (isShown) _this4.hideAside();else _this4.showAside();
});
}
My educated guess is that theme.js is using something that blazor does not allow? Is anybody experienced enough with Looper theme (or with javascript in general) to know why it wouldn't work? Particularly the hamburger toggle and the theme switching code
(line 1992 in /library/javascript/theme.js)
var Looper = function () {
var Looper = new Theme(); // toggle skin thought button
$('[data-toggle="skin"]').on('click', function (e) {
e.preventDefault();
var skin = Looper.skin === 'dark' ? 'default' : 'dark';
Looper.setSkin(skin); // we need to refresh our page after change the skin
location.reload();
}).each(function () {
var isDarkSkin = Looper.skin === 'dark';
var $icon = $(this).find('.fa-moon');
if (isDarkSkin) {
$icon.addClass('far');
$icon.removeClass('fas');
}
}); // make it global
return Looper;
}();
This is the website https://worshipground.azurewebsites.net/ You can use the inspector tool to see that blazor has been correctly loaded and all the javascript files are loaded in /library/javascript and /library/vendor/...
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- End Required meta tags -->
<title> Starter Template | Looper - Bootstrap 4 Admin Theme </title>
<base href="~/" />
<meta name="theme-color" content="#3063A0">
<link rel="apple-touch-icon" sizes="144x144" href="Library/apple-touch-icon.png">
<link rel="shortcut icon" href="Library/favicon.ico">
<link href="https://fonts.googleapis.com/css?family=Fira+Sans:400,500,600" rel="stylesheet">
<link rel="stylesheet" href="/Library/vendor/open-iconic/font/css/open-iconic-bootstrap.min.css">
<link rel="stylesheet" href="/Library/vendor/fontawesome/fontawesome-free/css/all.min.css">
<link rel="stylesheet" href="/Library/stylesheets/theme.min.css" data-skin="default">
<link rel="stylesheet" href="/Library/stylesheets/theme-dark.min.css" data-skin="dark">
<link rel="stylesheet" href="/Library/stylesheets/custom-app.css">
<link rel="stylesheet" href="/Library/stylesheets/custom.css" data-skin="default">
<link rel="stylesheet" href="/Library/stylesheets/custom-dark.css" data-skin="dark">
<script>
var skin = localStorage.getItem('skin') || 'default';
var isCompact = JSON.parse(localStorage.getItem('hasCompactMenu'));
var disabledSkinStylesheet = document.querySelector('link[data-skin]:not([data-skin="' + skin + '"])');
// Disable unused skin immediately
disabledSkinStylesheet.setAttribute('rel', '');
disabledSkinStylesheet.setAttribute('disabled', true);
// add flag class to html immediately
if (isCompact == true) document.querySelector('html').classList.add('preparing-compact-menu');
</script>
</head>
<body>
<component type="typeof(App)" render-mode="ServerPrerendered" />
<div id="blazor-error-ui">
<environment include="Staging,Production">
An error has occurred. This application may no longer respond until reloaded.
</environment>
<environment include="Development">
An unhandled exception has occurred. See browser dev tools for details.
</environment>
Reload
<a class="dismiss">🗙</a>
</div>
<script src="/Library/vendor/jquery/jquery.min.js"></script>
<script src="/Library/vendor/popper.js/umd/popper.min.js"></script>
<script src="/Library/vendor/bootstrap/js/bootstrap.min.js"></script>
<script src="/Library/vendor/pace-progress/pace.min.js"></script>
<script src="/Library/vendor/stacked-menu/js/stacked-menu.min.js"></script>
<script src="/Library/vendor/perfect-scrollbar/perfect-scrollbar.min.js"></script>
<script src="/Library/javascript/theme.min.js"></script>
<script>
Object.defineProperty(WebSocket, 'OPEN', { value: 1, });
</script>
<script src="_framework/blazor.server.js"></script>
</body>
</html>
You may find you have your work cut out in terms of making a JavaScript heavy template work nicely in Blazor.
You will probably need to utilise IJSRuntime
https://learn.microsoft.com/en-us/aspnet/core/blazor/call-javascript-from-dotnet?view=aspnetcore-5.0
I think I know where this problem comes from! If you comment out the following code on the "Host.cshtml" file, this problem will most likely go away!
<script>
Object.defineProperty(WebSocket, 'OPEN', { value: 1, });
</script>
But!!!! You will get some javascript errors related to "WebSocket" instead! something like this:
"WebSocket is not in the OPEN state"
Or
"Uncaught (in promise) Error: Cannot send data if the connection is not in the 'Connected' State."
The cause of these errors is a conflict between "pace.min.js" file and "blazor.server.js" file! You can check this link for more information and get more help

Iframe: White screen after setting document.location 2x

I'm creating a web application that I aim to embed into my Wix site.
The web application that I need can basically be reduced into a text screen & a button to change the screen view/page (the html that is displayed).
However, the problem is that independent on whether I start from the "home page" or from the "page page", the application loads two next screens and gives me a white screen after.
I've also tried other options for changing the url - ie location.href, window.location and such, and even tried changing the page via <a href= URL , yet the problem persists.
Below is a simplification of my code:
Page HTML
<!DOCTYPE html>
<html>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<head>
<base target="_self">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
</head>
<body>
<h1>page page</h1>
<button id="pagebtn" class="font-family: Raleway; font-size: 16px; waves-effect waves-light btn-small blue accent-2"><i class="material-icons left">check</i> Navigate to home </button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script>
document.getElementById("pagebtn").addEventListener("click",changepage);
function changepage(){
var url_new = "https://script.google.com/macros/s/AKfycbzKN9vYBa1yQguooTnijIipyMdAMbXo7a61wjWHt0ybCynH2bxj/exec?v=home";
document.location = url_new;
}
</script>
</body>
</html>
Home HTML
<!DOCTYPE html>
<html>
<script src="https://apis.google.com/js/platform.js" async defer></script>
<head>
<base target="_self">
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
</head>
<body>
<h1>home page</h1>
<button id="homebtn" class="font-family: Raleway; font-size: 16px; waves-effect waves-light btn-small blue accent-2"><i class="material-icons left">check</i> Navigate to page </button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script>
document.getElementById("homebtn").addEventListener("click",changepage);
function changepage(){
var url_new = "https://script.google.com/macros/s/AKfycbzKN9vYBa1yQguooTnijIipyMdAMbXo7a61wjWHt0ybCynH2bxj/exec?v=page";
document.location = url_new;
}
</script>
</body>
</html>
JS Code // Code.gs
var Route = {};
Route.path = function(route, callback) {
Route[route] = callback;
}
function doGet(event) { //<!-- Not visible to the user, serverside -->
Route.path("page", loadPage);
Route.path("home", loadHome);
if (Route[event.parameters.v]) {
return Route[event.parameters.v]();
} else {
return HtmlService.createTemplateFromFile("home").evaluate();
}
Logger.log("do get1 " + event.parameters.v);
}
function loadPage() { //<!-- Not visible to the user, serverside -->
var tmp = HtmlService.createTemplateFromFile("page");
return tmp.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
function loadHome() { //<!-- Not visible to the user, serverside -->
var tmp = HtmlService.createTemplateFromFile("home");
return tmp.evaluate().setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
The links in the code are for redirecting to a different url "view".
Thanks!
//Edit:
Unfortunately still without a solution nor an understanding of the underlying cause of this problem. By simply testing around - I found that when using window.open the scripts works (however, it keeps opening new tabs/windows that is not desirable. As the URL of the site itself does not change - perhaps this is the underlying reason for this problem? (meaning that I should redo the router or input the url in a different way to actually change what is written)?
I resolved my issue by changing document.location to window.top.location
However, as I need to embed this inside of my website, it opens up a new window whenever (window.top after all), whenever clicking the "Navigate" buttons- it does not work as intended, but for a temporary fix it will do

Click event in event listener written in Google Closure not working?

I am new to JavaScript, My question is when I try this JS in chrome browser console it works, But in my JS file it's not working
I attached the code, For HTML design I used google MDL, For JS I used Google Closure
HTML :
<HTML>
<head>
<script src="../closure-library/closure/goog/base.js"></script>
<script src="../js/add.js"></script>
<script src="../js/material.js"></script>
<link rel="stylesheet" href="../css/material.css">
<link rel="stylesheet" href="../css/test_add.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
<div>
<button id="add" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect">
<i class="material-icons">add</i>
</button>
</div>
</body>
</HTML>
JS:
goog.provide('sample.add');
goog.require('goog.dom');
goog.require('goog.events');
sample.add = function() {
self = this;
};
goog.inherits(sample.add, goog.base);
sample.add.prototype.bindEvent = function() {
goog.events.listen(goog.dom.getElement('add'),
goog.events.EventType.CLICK, function(e) {
alert("HAPPY");
});
};
What is wrong with this code
When I try without goog.provide and goog.require its show error to all
When I use this there is no reaction to the click event
Is there any other best resource to see online
Kindly help me
So there's a few things I'd change here.
The biggest issue is that you're never calling sample.add or sample.add.bindEvent.
Then, your script will have to be moved to below your button, so that the button will be on the page when your script runs. Or you could use JS to delay the script running, up to you, but I will say, its pretty common to see scripts just before the end of the body tag.
<HTML>
<head>
<script src="../closure-library/closure/goog/base.js"></script>
<script src="../js/material.js"></script>
<link rel="stylesheet" href="../css/material.css">
<link rel="stylesheet" href="../css/test_add.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body>
<div>
<button id="add" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect">
<i class="material-icons">add</i>
</button>
</div>
<script src="../js/add.js"></script>
</body>
</HTML>
Also, I'd ditch the goog.base call, unless you specifically need that. If you do need that, please explain why and maybe we can help.
Finally we just need a few subtle tweaks;
goog.provide('sample.add');
goog.require('goog.dom');
goog.require('goog.events');
/** #export */
sample.add = function() {
self = this;
self.bindEvent();
};
sample.add.prototype.bindEvent = function() {
goog.events.listen(goog.dom.getElement('add'),
goog.events.EventType.CLICK, function(e) {
alert("HAPPY");
});
};
sample.add();
I suppose you could call sample.add.bindEvent directly, but I felt like this was probably just the first step to something larger and you'd want to go this way.

Making polymer dom-repeat to work when a HTML block is added using .innerHTML

I am working on a polymer app where I need to fetch some HTML code block of code from external file and append to active file. I have specified the content to add myself.
Below is the code
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title></title>
</head>
<body>
<!-- Bootstrap Core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<link rel="import" href="bower_components/polymer/polymer.html">
<dom-module id="trail-app">
<template>
<style>
</style>
<button on-tap="loadContent">click</button>
<button on-tap="showContent">show</button>
<template is="dom-repeat" items='{{celsius}}'>
<div>[[item]]</div>
</template>
<div id="content"></div>
</template>
<script>
Polymer({
is: "trail-app",
properties:{
celsius:{}
},
ready:function(){
this.celsius = ["36","37","38","39","40","41"];
},
loadContent:function(data){
document.getElementById("content").innerHTML = '<template is="dom-repeat" items="{{Celsius}}">'+
'<div>[[item]]</div>'+
'</template>';
},
showContent:function(){
console.log(document.getElementById("content").innerHTML);
},
});
</script>
</dom-module>
<trail-app></trail-app>
</body>
</html>
when I loop through celsius using dom-repeat its working fine.
but if the same code is added using document.getElementById("content").innerHTML its giving
Polymer::Attributes: couldnt decode Array as JSON warning.
How to resolve this.
So I've addressed dynamic content like this using the templatizer behavior (https://www.polymer-project.org/1.0/docs/api/Polymer.Templatizer).
To use, create just a plain template with your dom-repeat inside that. Then in your loadContent method that's where you'll apply templatize and then stamp the template into the DOM.
<template id="repeatTempl">
<template is="dom-repeat" items="{{Celsius}}">
<div>[[item]]</div>
</template>
</template>
Include the Templatizer behavior:
behaviors: [Polymer.Templatizer]
Then your loadContent method would look something like this:
loadContent: function(data) {
var templ = this.$.repeatTempl;
this.templatize(templ);
var elem = this.stamp({Celsius: data});
Polymer.dom(this.$.content).appendChild(elem.root);
}

Why can't I call a Polymer function on an element?

This is really bugging me, can't seem to get this to work and I figure it's got to be some small little thing I'm overlooking. I am getting this error: Uncaught TypeError: undefined is not a functiontest-index.html:16 (anonymous function)
Here's code to reproduce, first the element:
<link rel="import" href="bower_components/polymer/polymer.html">
<polymer-element name="test-element" >
<template>
<div>YOOOOO</div>
</template>
<script>
Polymer({
loaderup: function(event, detail, sender) {
alert("WAT?")
}
});
</script>
</polymer-element>
And here's the page that's trying to load it:
<!doctype html>
<html>
<head>
<title>MyApp</title>
<script src="bower_components/webcomponentsjs/webcomponents.min.js"></script>
<link rel="import" href="test-element.html">
</head>
<body unresolved>
<test-element id="test-el"></test-element>
<script>
var x = document.querySelector("#test-el");
console.log(x);
x.loaderup();
</script>
</body>
</html>
But it gives the error I posted about on x.loaderup(). Any ideas?
You need to wait for the polymer-ready event, because the Polymer element upgrade is performed asynchronously:
<script>
window.addEventListener('polymer-ready', function() {
var x = document.querySelector("#test-el");
console.log(x);
x.loaderup();
});
</script>

Categories

Resources