ResizeObserver don't work as expected on Windows - javascript

I was playing with ResizeObserver (that's supported by google chrome behind experimental web platform flag). I've create codepen demo using jQuery UI resizable. It work fine on chromium linux, but on Windows it stops after a while or execute only once.
My code look like this:
$('#node').css({
width: 140,
height: 50
}).resizable();
function resizer(node, callback) {
if (window.ResizeObserver) {
var resizer = new ResizeObserver(function(entries) {
callback(entries[0]);
});
resizer.observe(node);
return () => resizer.unobserve(node);
} else {
return () => undefined;
}
}
resizer(document.querySelector('.content'), function(entry) {
var width = entry.contentRect.width;
var height = entry.contentRect.height
console.log(width + 'x' + height);
// custom event found on
// https://ebidel.github.io/demos/dom_resize_events.html
entry.target.dispatchEvent(new CustomEvent('resize', {
detail: {width,height}
}));
});
document.querySelector('.content').addEventListener('resize', (e) => {
console.log(e.detail);
});
I've try to restart the browser, close/open developer tools also download the files to local drive and open using file protocol and got the same results.
the google chrome example works fine,
Here is a my pen

It seems that the observer get Garbage Collected, adding
var r;
...
function resizer(node, callback) {
...
var resizer = new ResizeObserver(...);
r = resizer;
...
}
solved the issue

Related

How to code for onMouseOver event in Autodesk Forge

I have created a simple extension in autodesk forge.
The idea is that when I make a mouse-over event on a 3D object it has to show me the ID of the hovered object/sub-object my extension code runs like this.
AutodeskNamespace("Autodesk.ADN.Viewing.Extension");
Autodesk.ADN.Viewing.Extension.MouseEvent = function (viewer, options) {
Autodesk.Viewing.Extension.call(this, viewer, options);
var _self = this;
var _viewer = viewer;
var _selectedId = null;
//On Load of the exension function
_self.load = function () {
_viewer.addEventListener(
Autodesk.Viewing.MOUSE_OVER_EVENT,
_self.onMouseOver);
console.log("Autodesk.ADN.MouseEvent loaded");
return true;
};
//On unload of the exension function
_self.unload = function () {
_viewer.removeEventListener(
Autodesk.Viewing.MOUSE_OVER_EVENT,
_self.onMouseOver);
console.log("Autodesk.ADN.MouseEvent unloaded");
return true;
};
// Event function initialization
_self.onMouseOver = function (event) {
var dbId = event.dbIdArray[0];
if (typeof dbId !== 'undefined') {
_selectedId = dbId;
alert('ID: ' + _selectedId);
}
else _selectedId = null;
}
};
Autodesk.ADN.Viewing.Extension.MouseEvent.prototype =
Object.create(Autodesk.Viewing.Extension.prototype);
Autodesk.ADN.Viewing.Extension.MouseEvent.prototype.constructor =
Autodesk.ADN.Viewing.Extension.MouseEvent;
Autodesk.Viewing.theExtensionManager.registerExtension(
'Autodesk.ADN.Viewing.Extension.MouseEvent',
Autodesk.ADN.Viewing.Extension.MouseEvent);
but the onMouseOver function is not working, can anyone please help me? thanks in advance.
PS: I have included the extensions in the script tags and the extension is loaded likewise.
oViewer.loadExtension('Autodesk.ADN.Viewing.Extension.MouseEvent');
I also get a confirmation from the console that the extension is loaded successfully.
There is no such event as Autodesk.Viewing.MOUSE_OVER_EVENT ... did you just made that up or you got it from some - apparently incorrect - source?
The way to handle that would be to use a viewer tool (see that post for details), then in handleMouseMove callback, do the following:
handleMouseMove (event) {
var hitTest = _self.viewer.clientToWorld(
event.canvasX,
event.canvasY,
true)
if (hitTest) {
console.log(hitTest)
}
}
Here is another post I wrote about viewer events, it is a bit old, so there are a couple more now but can give you a good starting point.

Chrome doesn't close the notification

I'm currently using this implementation to use Browsers based Notifications :
https://developer.mozilla.org/en-US/docs/Web/API/Notification
This works like a charm.
if ("Notification" in window) {
if(Notification.permission === "granted") {
if($('#notify-on-message').is(':checked')) {
var notification = new Notification(username + ' : ' + data, {'icon': "/custom/favicon.gif"});
}
if ($('#notify-on-hl').is(':checked')) {
var patt = new RegExp("(^|\\W)"+selfusername+"(\\W|$)");
if(patt.test(data)) {
var notification = new Notification(username + ' highlighted you.', {'icon': "/custom/favicon.gif"});
}
}
}
}
The main issue I have is that on chrome based browsers, the notification just doesn't close itself after the 3 seconds delay.
It tried adding this after the var notification = ...
setTimeout(function() {
notification.close();
}, 2000);
Though that doesn't change a single thing. The notification remains.
Is it a known issue ? Is there an easy way to fix this behaviour I don't want ?
EDIT 1:
According to this page :
https://developer.mozilla.org/en-US/docs/WebAPI/Using_Web_Notifications
This is a known issue :
Note: Firefox and Safari close the notifications automatically after a few moments, e.g. 4 seconds.
This can also be done at the web application level using the Notification.close() method, for example with the following code:
var n = new Notification("Hi!");
n.onshow = function () {
setTimeout(n.close, 5000);
}
Though that code doesn't work. There is an error in the console that says that the notification doesn't have the close method or something like that.
Well actually I was wrong, the code
var message_notification = new Notification("Data");
setTimeout(function(){
message_notification.close();
}, 3000);
Works in both Firefox and Chrome. (And Safari too I guess)
Adding a tag to the option will close active popup before showing new once
var options = {
body: msg,
icon: "logo.png",
dir: "ltr",
tag: "group1"
};

why is my save dialog not appearing chrome app

I am creating a HTML5 SVG editor for Chrome. As a packaged app, I implemented a save dialog using this code:
function prepareExport(){
var svg = document.getElementById("canvas");
svgDoc = svg.children;
var exported = document.querySelector('#canvasWrap').innerHTML;
/*old stuff, does not work in packed apps. well for me anyway
var output = document.querySelector(".opt");
var outputTextarea = document.querySelector(".optText");
output.style.display = "block";
outputTextarea.style.display = "none";
var dlButton = document.querySelector(".dragout");
dlButton.setAttribute("href" ,"data:image/xml+svg;base64," + window.btoa(exported));
dlButton.setAttribute("data-downloadurl" ,dlButton.dataset['downloadurl'] + window.btoa(exported));
dlButton.addEventListener('dragstart', function(e) {
e.dataTransfer.setData('DownloadURL', this.dataset.downloadurl);
}, false);
*/
chrome.fileSystem.chooseEntry({type: 'saveFile'}, function(writableFileEntry, unused) {
writableFileEntry.createWriter(function(writer) {
writer.onerror = errorHandler;
writer.onwriteend = function(e) {
console.log('write complete');
};
writer.write(new Blob([exported], {type: 'image/svg+xml'}));
}, errorHandler);
});
}
I ran this function using a button, Export SVG, and guess what? the dialog did not appear. I do not know why and this is my javascript console:
http://prntscr.com/1uklw7
This is probably a permission error. Have you added the write filesystem permission to your manifest? See http://developer.chrome.com/apps/fileSystem.html for details.
If that isn't the problem, you can get more details from chrome.lastError in your callback. See http://developer.chrome.com/apps/runtime.html#property-lastError for details of this.
Also you might want to check out the file system sample: https://github.com/GoogleChrome/chrome-app-samples/tree/master/filesystem-access.

Javascript works in FF and IE .. but Chrome says "cannot call method of null"!

The code that contains the error is:
var Slide = new Class({
initialize: function(triggers, panels) {
this.triggers = $(triggers).getElements('a[rel=content1-1]');
this.panels = $(panels).getElements('ul[class=rel-content1-1]');
this.active = -1;
this.toggle();
}, ...
})
This is called from later in the same file:
function activateSliders() {
var slide_1 = new Slide('aCol', 'content');
var slide_2 = new SlideTwo('content', 'content2', 'content2-hider');
}
window.onload = activateSliders();
Why does Chrome -- and only Chrome -- calculate $(triggers) as NULL?
In my experience, IE and FF tend to be sporadically generous with letting jQuery code work nicely without it being encapsulated within a $(document).ready( block. Try:
$(document).ready(function() {
activateSliders();
});

Check for when a user has selected to print using javascript

When a user chooses "File > Print" on a browser such as Firefox or Internet Explorer, or clicks on a link that runs the below javascript
window.print();
Is there a way to conditionally check for this mode and disable SOME javascript.
I am trying to do this because I have a plugin that adds in its own custom markup for rounded borders and even in a print specific stylesheet I can not override the styling for these, I dont want the borders to appear when printing out the page.
EDIT: Unrelated to the plugin there are style changes done via javascript that is used to create a tabbed user interface and I have done print specific CSS to override the styling and it works fine when I use the Firefox web developer toolbar > CSS > Display CSS by Media type > Print.. but when I print it out it doesn't work, the javascript takes over and changes the styling.. if I disable javascript completely then the printing obviously works fine again.
Thanks
There's a universal solution for this, along with a bit of hackery for older browsers. You can override the print() method in all browsers:
(function (oldPrint) {
window.print = function () {
document.getElementById("hideThis").style.display = 'none';
oldPrint();
}
})(window.print);
The problem here is that it will not fire for users pressing Ctrl+P or accessing the file menu to print. Internet Explorer has a solution by way of the onbeforeprint event:
if ("onbeforeprint" in window) {
var hideEl = document.getElementById("hideThis");
window.onbeforeprint = function () {
hideEl.style.display = 'none';
}
window.onafterprint = function () {
hideEl.style.display = '';
}
}
As for other browsers, you can add an event listener to a print MediaQueryList as detailed by TJ VanToll in another answer:
if (window.matchMedia) {
var mqList = window.matchMedia("print"),
hideEl = document.getElementById("hideThis");
mqList.addListener(function (mql) {
hideEl.style.display = mql.matches ? 'none' : '';
});
}
And putting it all together:
(function () {
var hideEl = document.getElementById("hideThis");
// HTML5 spec, IE 5.5+, Firefox 6.0+
if ("onbeforeprint" in window) {
window.onbeforeprint = function () {
hideEl.style.display = 'none';
}
window.onafterprint = function () {
hideEl.style.display = '';
}
}
// Chrome 9+, Opera 12.1+, Safari 5.1+
else if (window.matchMedia) {
var mqList = window.matchMedia("print");
mqList.addListener(function (mql) {
hideEl.style.display = mql.matches ? 'none' : '';
});
}
// Your fallback method, only working for JS initiated printing
else {
(function (oldPrint) {
window.print = function () {
hideEl.style.display = 'none';
oldPrint();
}
})(window.print);
}
})();
You can do:
window.old_print=window.print
window.print=function() {
alert('doing things');
window.old_print();
}
but this will only catch calls to print() from inside the page javascript.
Did you try putting !important on print-specific stylesheet?

Categories