Polymer optimization with window.Polymer = {dom: 'shadow'} - polymer

For polymer performance optimization, I am trying to use window.Polymer = window.Polymer || {dom: 'shadow'};.
In chrome, when I use it I get Uncaught SyntaxError: Unexpected token ILLEGAL polymer.html:2 which is #license:
<!--
#license
Copyright (c) 2015 The Polymer Project Authors
Here is the script that I am using to load it:
var webComponentsSupported = ('registerElement' in document
&& 'import' in document.createElement('link')
&& 'content' in document.createElement('template'));
function createScript(file) {
var script = document.createElement('script');
script.async = true;
script.src = file;
document.head.appendChild(script);
}
function createLink(file) {
var link = document.createElement('link');
link.async = true;
link.href = file;
link.rel = 'import';
document.head.appendChild(link);
}
if (!webComponentsSupported) {
//not chrome
createScript('../bower_components/polymer/polymer.html');
createScript('../bower_components/webcomponentsjs/webcomponents-lite.min.js');
createLink('../css/non-chrome-shadow.html');
} else {
//chrome
window.Polymer = window.Polymer || {dom: 'shadow'};
createScript('../bower_components/polymer/polymer.html');
createLink('../css/chrome-shadow.html');
}
I'm sure I'm doing it wrong. Also, since it is in the if condition of the chrome block, couldn't I do window.Polymer = {dom: 'shadow'}; instead since it's chrome?

Basically this
createScript('../bower_components/polymer/polymer.html');
You are importing an HTML file instead of a script file. A more proper way would be like this:
createLink('../bower_components/polymer/polymer.html');
P.S.: You should also check if shadow DOM is available. 😑

Related

How to detect when documentViewer finish loading all document pages?

I am using primefaces documentViewer which is based on mozilla PDF.js: 2.11.338
https://www.primefaces.org/showcase-ext/views/documentViewer.jsf
and I want to know How to detect when documentViewer finish loading all document pages ?
The requirement is to show loading bar until all the document pages finish loading.
I tried this :
document.addEventListener('textlayerrendered', function (e) {
if (e.detail.pageNumber === PDFViewerApplication.page) {
// finished rendering
}
}, true);
and it's not working.
I was able to make it work as follows :
window.onload = function(){
PF('statusDialog').show();
var checkExist = setInterval(function() {
var iframe=document.getElementsByTagName('iframe')[0];
var innerDoc = iframe.contentDocument || iframe.contentWindow.document;
var viewer = innerDoc.getElementById('viewer');
var innerHTML = viewer.innerHTML;
if(innerHTML != null && innerHTML!='' && innerHTML!='undefined'){
clearInterval(checkExist);
PF('statusDialog').hide();
}
}, 1000);
}

How to overwrite asynch css?

I am using one of the SaaS for lead finding. I paste their code just like I paste google analytics code on top of my page (for example):
<script type="text/javascript">
var _lfuid = 'xxxxxxxxxxxxx';
(function (d) {
var w = d.createElement('script');
w.type = 'text/javascript';
w.asynch = true;
w.src = '//widget.website.come/widget/widget.js';
var s = d.getElementsByTagName('script')[0];
s.parentNode.insertBefore(w, s);
})(document);
</script>
However, the widgets position that I am receiving from the call, is set in the css file that I get in response. All the classes have !important tag there, so I cannot overwrite it using css classes that I've defined in my static files.
My question is: how can I overwrite this ansych css?
You need to add an Event Listener to the load of the async script and after append to the HEAD your CSS with !important rule.
Example
var _lfuid = 'xxxxxxxxxxxxx';
(function (d) {
var w = d.createElement('script');
w.type = 'text/javascript';
w.asynch = true;
w.src = '//widget.website.come/widget/widget.js';
w.addEventListener('load', function (e) {
/* We wait the load of the async script and after we use jQuery to append our CSS to the HEAD of the document.
p.s.: you need jQuery to use the dollar sing selector ($) */
$('head').append('<style> #yourCSSgoHere { display: none !important; }</style>');
}, false);
var s = d.getElementsByTagName('script')[0];
s.parentNode.insertBefore(w, s);
})(document);

Web Audio API Stream: why isn't dataArray changing?

EDIT 2: solved. See answer below.
EDIT 1:
I changed my code a little, added a gain node, moved a function. I also found that IF I use the microphone, it will work. Still doesn't work with usb audio input. Any idea? This is my current code:
window.AudioContext = window.AudioContext || window.webkitAudioContext;
window.onload = function(){
var audioContext = new AudioContext();
var analyser = audioContext.createAnalyser();
var gainNode = audioContext.createGain();
navigator.mediaDevices.getUserMedia({ audio:true, video:false }).then(function(stream){ //MediaStream
var source = audioContext.createMediaStreamSource(stream);
source.connect(analyser);
analyser.connect(gainNode);
gainNode.connect(audioContext.destination);
listen();
});
function listen(){
analyser.fftSize = 256;
var bufferLength = analyser.frequencyBinCount;
var dataArray = new Uint8Array(bufferLength);
var index = 0;
function write(){
requestAnimationFrame(listen);
analyser.getByteTimeDomainData(dataArray);
$('.monitor').html(JSON.stringify(dataArray) + ' -- ' + (index++));
}
write();
}
}
OLD/ORIGINAL POST:
my current code is this, and I currently connected a kewboard via a USB audio interface: I've got signal, already tried with other programs.. So:
window.AudioContext = window.AudioContext || window.webkitAudioContext;
window.onload = function(){
var audioContext = new AudioContext();
var analyser = audioContext.createAnalyser();
navigator.mediaDevices.getUserMedia({ audio:true, video:false }).then(function(stream){ //MediaStream
var source = audioContext.createMediaStreamSource(stream);
source.connect(analyser);
analyser.connect(audioContext.destination);
analyser.fftSize = 2048;
var bufferLength = analyser.frequencyBinCount;
var dataArray = new Uint8Array(bufferLength);
function listen(){
requestAnimationFrame(listen);
analyser.getByteTimeDomainData(dataArray);
$('.monitor').html(JSON.stringify(dataArray));
}
listen();
});
}
While I'm playing my keyboard, the dataArray doesn't change at all. Why? I'm new to this things so probably I'm doing something wrong...
Ok now it's working. My basic current test code is the following. Html has nothing but a div.monitor to write inside. Currently testing on firefox. My hardware is keyboard > mixer > behringer UCA222 > computer (usb). I get data when playing the keyboard and I'm happy now.
There are several differences from the original code, but I think the most important is that I'm saving the media source globally (window.audiosource). There are other posts here about a related issue, for example this: Chrome: onaudioprocess stops getting called after a while and this HTML5 Microphone capture stops after 5 seconds in Firefox.
window.AudioContext = window.AudioContext || window.webkitAudioContext;
navigator.getUserMedia = (navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
var audioContext = new (window.AudioContext || window.webkitAudioContext)();
var analyser = audioContext.createAnalyser();
if(navigator.getUserMedia){
navigator.getUserMedia(
{ audio: true }
,function(stream){
window.audiosource = audioContext.createMediaStreamSource(stream);
audiosource.connect(analyser);
listen();
}
,function(err){ console.log('The following gUM error occured: ' + err); }
);
}
function listen(){
requestAnimationFrame(listen);
analyser.fftSize = 256;
var bufferLength = analyser.frequencyBinCount;
var dataArray = new Uint8Array(bufferLength);
analyser.getByteTimeDomainData(dataArray);
$('.monitor').html(JSON.stringify(dataArray));
}

How to handle tvOS MenuBarTemplate selection?

I have a basic MenuBarTemplate set up and displaying.
How do I react to a user's Menu selection and load an appropriate content template?
In the menuItem tag include a template attribute pointing to the template to load and a presentation attribute set to menuBarItemPresenter.
<menuItem template="${this.BASEURL}templates/Explore.xml.js"
presentation="menuBarItemPresenter">
<title>Explore</title>
</menuItem>
You can then use the menu bar's MenuBarDocument feature to associate a document to each menu bar item.
menuBarItemPresenter: function(xml, ele) {
var feature = ele.parentNode.getFeature("MenuBarDocument");
if (feature) {
var currentDoc = feature.getDocument(ele);
if (!currentDoc) {
feature.setDocument(xml, ele);
}
}
This assumes you're using a Presenter.js file like the one in Apple's "TVML Catalog" sample. The load function specified there is what calls the function specified in the menuItem's presentation attribute.
I suppose that TVML and TVJS is similar with HTML and Javascript. When we want to add some interaction into the user interface, we should addEventListener to DOM.
In Apple's "TVML Catalog", Presenter.js is a nice example, but it is abstract, and it could be used in different Present actions.
When I develop my app, I had wrote this demo for handling menuBar selection.
Module : loadTemplate.js
var loadTemplate = function ( baseURL , templateData ){
if( !baseURL ){
throw("baseURL is required");
}
this.BASEURL = baseURL;
this.tpData = templateData;
}
loadTemplate.prototype.loadResource = function ( resource , callback ){
var self = this;
evaluateScripts([resource], function(success) {
if (success) {
var resource = Template.call(self);
callback.call(self, resource);
} else {
var title = "Resource Loader Error",
description = `There was an error attempting to load the resource '${resource}'. \n\n Please try again later.`,
alert = createAlert(title, description);
Presenter.removeLoadingIndicator();
navigationDocument.presentModal(alert);
}
});
}
module.exports = loadTemplate;
Module nav.js ( use menuBarTemplate ) :
import loadTemplate from '../helpers/loadTemplates.js'
let nav = function ( baseURL ){
var loader = new loadTemplate(
baseURL ,
{
"explore" : "EXPLORE",
"subscribe" : "SUBSCRIBE",
"profile" : "PROFILE",
"settings" : "SETTINGS"
}//need to use i18n here
);
loader.loadResource(`${baseURL}templates/main.xml.js`, function (resource){
var parser = new DOMParser();
var navDoc = parser.parseFromString(resource, "application/xml");
navDoc.addEventListener("select" , function ( event ){
console.log( event );
var ele = event.target,
templateURL = ele.getAttribute("template");
if (templateURL) {
loader.loadResource(templateURL,
function(resource) {
if (resource) {
let newParser = new DOMParser();
var doc = newParser.parseFromString( resource , "application/xml" );
var menuBarItemPresenter = function ( xml , ele ){
var feature = ele.parentNode.getFeature("MenuBarDocument");
if( feature ){
var currentDoc = feature.getDocument( ele );
if( !currentDoc ){
feature.setDocument( xml , ele );
}
}
};
menuBarItemPresenter( doc , ele );
}
}
);
}
});
navigationDocument.pushDocument(navDoc);
});//load from teamplate.
}
module.exports = nav;
My code is not the best practice, but as you can see, you just need to addEventListener like you are writing a web application. Then you can handle menuBarTemplate selection easily, even after XHR loading.
Avoid too many callbacks, you should rebuild your code again and again. :-)

Download attribute on A tag not working in IE

From the following code I'm creating a dynamic anchor tag which downloads a file. This code works well in Chrome but not in IE. How can I get this working
<div id="divContainer">
<h3>Sample title</h3>
</div>
<button onclick="clicker()">Click me</button>
<script type="text/javascript">
function clicker() {
var anchorTag = document.createElement('a');
anchorTag.href = "http://cdn1.dailymirror.lk/media/images/finance.jpg";
anchorTag.download = "download";
anchorTag.click();
var element = document.getElementById('divContainer');
element.appendChild(anchorTag);
}
</script>
Internet Explorer does not presently support the Download attribute on A tags.
See http://caniuse.com/download and http://status.modern.ie/adownloadattribute; the latter indicates that the feature is "Under consideration" for IE12.
In my case, since there's a requirement to support the usage of IE 11 (version 11.0.9600.18665), I ended up using the solution provided by #Henners on his comment:
// IE10+ : (has Blob, but not a[download] or URL)
if (navigator.msSaveBlob) {
return navigator.msSaveBlob(blob, fileName);
}
It's quite simple and practical.
Apparently, this solution was found on the Javascript download function created by dandavis.
Old question, but thought I'd add our solution. Here is the code I used on my last project. It's not perfect, but it passed QA in all browsers and IE9+.
downloadCSV(data,fileName){
var blob = new Blob([data], {type: "text/plain;charset=utf-8;"});
var anchor = angular.element('<a/>');
if (window.navigator.msSaveBlob) { // IE
window.navigator.msSaveOrOpenBlob(blob, fileName)
} else if (navigator.userAgent.search("Firefox") !== -1) { // Firefox
anchor.css({display: 'none'});
angular.element(document.body).append(anchor);
anchor.attr({
href: 'data:attachment/csv;charset=utf-8,' + encodeURIComponent(data),
target: '_blank',
download: fileName
})[0].click();
anchor.remove();
} else { // Chrome
anchor.attr({
href: URL.createObjectURL(blob),
target: '_blank',
download: fileName
})[0].click();
}
}
Using the ms specific API worked best for us in IE. Also note that some browsers require the anchor to actually be in the DOM for the download attribute to work, whereas Chrome, for example, does not. Also, we found some inconsistencies with how Blobs work in various browsers. Some browsers also have an export limit. This allows the largest possible CSV export in each browser afaik.
As of build 10547+, the Microsoft Edge browser is now supporting the download attribute on a tags.
Download Image
Edge features update: https://dev.windows.com/en-us/microsoft-edge/platform/changelog/desktop/10547/
a[download] standard: http://www.w3.org/html/wg/drafts/html/master/links.html#attr-hyperlink-download
This code fragment allows saving blob in the file in IE, Edge and other modern browsers.
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState === 4 && request.status === 200) {
// Extract filename form response using regex
var filename = "";
var disposition = request.getResponseHeader('Content-Disposition');
if (disposition && disposition.indexOf('attachment') !== -1) {
var filenameRegex = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/;
var matches = filenameRegex.exec(disposition);
if (matches != null && matches[1]) filename = matches[1].replace(/['"]/g, '');
}
if (window.navigator.msSaveOrOpenBlob) { // for IE and Edge
window.navigator.msSaveBlob(request.response, filename);
} else {
// for modern browsers
var a = document.createElement('a');
a.href = window.URL.createObjectURL(request.response);
a.download = filename;
a.style.display = 'none';
document.body.appendChild(a);
a.click();
}
}
button.disabled = false;
dragArea.removeAttribute('spinner-visible');
// spinner.style.display = "none";
};
request.open("POST", "download");
request.responseType = 'blob';
request.send(formData);
For IE and Edge use: msSaveBlob
Use my function
It bind your atag to download file in IE
function MS_bindDownload(el) {
if(el === undefined){
throw Error('I need element parameter.');
}
if(el.href === ''){
throw Error('The element has no href value.');
}
var filename = el.getAttribute('download');
if (filename === null || filename === ''){
var tmp = el.href.split('/');
filename = tmp[tmp.length-1];
}
el.addEventListener('click', function (evt) {
evt.preventDefault();
var xhr = new XMLHttpRequest();
xhr.onloadstart = function () {
xhr.responseType = 'blob';
};
xhr.onload = function () {
navigator.msSaveOrOpenBlob(xhr.response, filename);
};
xhr.open("GET", el.href, true);
xhr.send();
})
}
Append child first and then click
Or you can use window.location= 'url' ;
As mentioned in earlier answer , download attribute is not supported in IE . As a work around, you can use iFrames to download the file . Here is a sample code snippet.
function downloadFile(url){
var oIframe = window.document.createElement('iframe');
var $body = jQuery(document.body);
var $oIframe = jQuery(oIframe).attr({
src: url,
style: 'display:none'
});
$body.append($oIframe);
}
I copied the code from here and updated it for ES6 and ESLint and added it to my project.
You can save the code to download.js and use it in your project like this:
import Download from './download'
Download('/somefile.png', 'somefile.png')
Note that it supports dataURLs (from canvas objects), and more... see https://github.com/rndme for details.