For many reasons, I have to open up XUL in a tab, instead of using a standard window. I wish to send custom events to this tab, and here's how my code looks like :
myextension.js :
..
var pTab = window.gBrowser.loadOneTab("chrome://myextension/path/options.xul",
{inBackground: false});
var pWin = window;
var event = new pWin.CustomEvent("prefwindow-event");
pWin.dispatchEvent(event);
..
options.xul code:
window.addEventListener("load", init, false);
window.addEventListener("prefwindow-event", myevent, false, true);
..
myevent: function(e) {
dump("My event : " + e.details );
},
..
However, I don't get the event. I have tried all possible options. Enabled/Disabled useCapture and wantsUntrusted of addEventListener(). After realizing that there are restrictions in sending custom events between windows, I also tried dispatching event with the tab element, like this :
pTab.dispatchEvent(event);
That wouldn't work either. 1) The event dispatch would work perfectly fine if I use a dialog window instead of a tab (openDialog instead of loadOneTab). 2) The tab element only inherits dispatchEvent and not a CustomEvent
So the question is, is there a way to send custom events and have it received in a tab?
var event = new pTab.linkedBrowser._contentWindow.CustomEvent("prefwindow-event");
edit:
Proof of concept, open scratchpad, switch environment to browser, run the following snippet
var url = 'data:text/html;charset=utf-8,';
var content = '<html><script>addEventListener("Hello",function(){alert("Hello")},false)</script></html>'
var tab = gBrowser.loadOneTab(url+encodeURIComponent(content), {inBackground: false});
tab.addEventListener("load", function(){
var evt = new tab.linkedBrowser.contentWindow.CustomEvent("Hello");
tab.linkedBrowser.contentWindow.dispatchEvent(evt);
}, false);
Related
I'm using this code to fade-out the website whenever there's a redirect, and it seems to work pretty well most of the time.
var body = document.body;
addEventListener('beforeunload', event => {
function redirect() {
location.href = event.target.href;
body.removeEventListener('transitionend', redirect);
}
body.addEventListener('transitionend', redirect);
body.style.opacity = 0;
event.preventDefault();
});
(I have a CSS transition for opacity here)
Occasionally though, maybe once every five times, I get redirected to https://example.com/undefined (example being my website) instead of the correct location. This happens with both relative and absolute URLs. Why is this happening, and why does it only happen sometimes? And, how can I fix it?
Just in case, I'll mention that I'm using an Express.js server here, but the issue doesn't seem to be server-side.
UPDATE:
Apparently, if I remove the redirect function entirely, it still works (and fixes the problem). My current theory is that since it still redirects even with preventDefault() (as #stephancasas mentioned), the transition only happens because the page takes a few fractions of a second to load. My edited code looks like this:
addEventListener('beforeunload', event => {
body.style.opacity = 0;
});
I still don't completely understand what's going on though, any explanation would be helpful.
Since your code is using event.target.href, I've assumed you want to set body.style.opacity = 0, when a user clicks a link on the page.
I would prefer attaching event listener on all 'a' tags (it's costly though) as it'll give you better control over 'beforeunload', it's easy to debug and it'll always redirect with correct href.
document.addEventListener('DOMContentLoaded', function() { // Make sure DOM is loaded
// init global vars
var url = '';
var body = document.body;
function redirect() {
window.location.href = url; // comment this if you want to debug css change effects before redirecting
body.removeEventListener('transitionend', redirect);
}
// Add event listner to transitionend
// Use webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd or transitionend based on browser
body.addEventListener('transitionend', redirect);
// Add event listner to all anchor tags on the page
var aTags = document.querySelectorAll('a');
aTags.forEach(function(a) {
a.addEventListener('click', e => {
var href = e.target.href;
if(!href || href == window.location.href) { // return, if the target is same url
// add more validations as per your requirements
return;
}
e.preventDefault();
url = href; // update golbal url var
body.style.opacity = 0;
body.style.transition = 'all 0.5s ease'; // this is important for transitionend listner to trigger
});
});
}, false);
This likely won't work or will work very inconsistently. You can't intercept the beforeunload event to do much else other than confirm that the user wants to leave the page (e.g. they've entered form data and would lose it on a reload/redirect).
Per the standard, the event listener's callback should return a string which is to be displayed in the dialog with which the user will be prompted.
This is done with great purpose, as allowing freeform interception of this event could be misused to trap users' browsers on specific locations.
I am working on a bookmarklet that makes an href link of the current browser tab and copies it to the clipboard. This bookmarklet works in Safari:
javascript:
!function(a){
var%20b=document.createElement("textarea"),
c=document.getSelection();
b.textContent=a,document.body.appendChild(b),
c.removeAllRanges(),b.select(),
document.execCommand("copy"),
c.removeAllRanges(),
document.body.removeChild(b)}
('<a%20title="'+document.title+'"%20href="'+document.location.href+'">'+document.title+'</a>');
But in Firefox 65, I get the error "document.execCommand(‘cut’/‘copy’) was denied because it was not called from inside a short running user-generated event handler." In looking at Copying to clipboard with document.execCommand('copy') fails with big texts I'm trying to generate the html of the link before the function to solve the issue pointed out in the answer. But, with the code below, I get a new browser tab with the text "true" and no copied link to the clipboard.
javascript:
const text = ('<a%20title="'+document.title+'"%20href="'+document.location.href+'">'+document.title+'</a>');
!function(a){
var%20b=document.createElement("textarea"),
c=document.getSelection();
b.textContent=a,document.body.appendChild(b),
c.removeAllRanges(),
b.select(),
document.execCommand("copy"),
c.removeAllRanges(),
document.body.removeChild(b)}('text');
Is this a timing issue with the generation of the href link? Or something else?
Your problem is not the same than in the other Q/A: In your case, you don't have any user-triggered event.
So no, it is not a timing issue, it's just that you need such an event.
To force it, you could show a splash screen, requiring that the bookmarklet's user clicks on the page. From this click event you'd call execCommand('copy').
javascript:(function(a){
var splash = document.createElement('div'),
msg = document.createElement('span');
splash.style='position:fixed;top:0;left:0;width:100vw;height:100vh;display:flex;justify-content:center;align-items:center;background:#FFF;z-index:999999';
msg.textContent = 'click me';
splash.append(msg);
// wait for the click event
splash.onclick = evt => {
var b=document.createElement("textarea"),
c=document.getSelection();
b.textContent=a,
document.body.appendChild(b),
c.removeAllRanges(),
b.select(),
document.execCommand("copy"),
c.removeAllRanges(),
document.body.removeChild(b),
document.body.removeChild(splash);
};
document.body.append(splash);
})
Here is a live example of what happens (obviously not as a bookmarklet):
(function(a){
var splash = document.createElement('div'),
msg = document.createElement('span');
splash.style='position:fixed;top:0;left:0;width:100vw;height:100vh;display:flex;justify-content:center;align-items:center;background:#FFF;z-index:999999';
msg.textContent = 'click me';
splash.append(msg);
// wait for the click event
splash.onclick = evt => {
var b=document.createElement("textarea"),
c=document.getSelection();
b.textContent=a,
document.body.appendChild(b),
c.removeAllRanges(),
b.select(),
document.execCommand("copy"),
c.removeAllRanges(),
document.body.removeChild(b),
document.body.removeChild(splash);
};
document.body.append(splash);
})
('<a%20title="'+document.title+'"%20href="'+document.location.href+'">'+document.title+'</a>');
<textarea>You can paste here to check what's been copied</textarea>
I want to place a button on CRM 2011 form.
function create_button(fldName, btnLabel, btnWidth, evt)
{
try{
fldName = "inmate_button_submit";
btnLable="Click Me";
// btnWidth="200px";
var btn = '<button class="ms-crm-Button" onclick="evt()" style="width:50px" id="' + fldName + '" onmouseover="Mscrm.ButtonUtils.hoverOn(this);" onmouseout="Mscrm.ButtonUtils.hoverOff(this);" >Click Me</button>';
var ctrl = null;
try {
ctrl = Xrm.Page.ui.controls.get(fldName).get_chromeElement()[0];
} catch (e) {
ctrl = Xrm.Page.ui.controls.get(fldName)._control.get_element();
}
// Add the new button
ctrl.innerHTML += btn;
// Hide the textbox
ctrl.children[0].style.display = 'none';
ctrl.children[1].style.display = 'none';
// Hide the label
Xrm.Page.ui.controls.get(fldName).setLabel(btnLable);
// Add Event to the newly created button
ctrl.children[0].attachEvent('onclick', evt);
}
catch(e){alert(e.description);}
}
function evt()
{
alert("You have clicked me!!");
}
The above is my following code which places the button on the form. When i click on the button, after showing the alert crm gives me the following error.
ERROR
An error has occurred.
Try this action again. If the problem continues, check the Microsoft Dynamics CRM Community or you for solutions or contact....
I have no idea why this is happening. Any help guys?
Keep in mind that using getElementById is going to be unsupported and may not work (does not work in Outlook 2007) in some browsers.
I would recommend placing this is in a web resource, or utilizing the ribbon for this functionality. Would either of those meet your requirements?
If you use your js as a webresource then you shouldnt have any problems.
Or you can even trigger the function OnLoad
Please see following :
http://www.mscrmconsultant.com/2012/07/insert-custom-button-on-crm-form-using.html
i will recommend add custom webresource ( HTML page which contanis javascript functionality on in onload event ) if you need access to form, use window.parent.document.Xrm.Page ....
2 things might cause this issue:
evt function is not accessible to your button
Resolution: try registering the evt function in global scope i.e.
evt = function() { alert("…"); }
or
window.evt = function() {}
2. Your button is using the same field name as the placeholder field.
This might cause internal issues.
Resolution: Try giving your button another (bogus) id instead i.e. fieldname + "_button"
Have you tried the 3rd party applications...
http://crmvisualribbonedit.codeplex.com/
Call the function from a web resource.
NOTE: Remember to add $ to reference the web resource location
Example $webresource:ButtonScript.js
I have written a basic function to allow me to display a popup from a link outside the map. The functionality to open the popup is working fine, but I can't then close it.
Demo link: http://www.catchingtherain.com/bikestats/stations.php - click on links in left-hand tabbed panels.
Here's a bit more detail ...
A typical map has about 300 features on a vector layer 'stations' loaded from kml. These are activated onload using
select = new OpenLayers.Control.SelectFeature(stations);
stations.events.on({
"featureselected": onFeatureSelect,
"featureunselected": onFeatureUnselect
});
map.addLayer(stations);
map.addControl(select);
select.activate();
which works fine - I can open and close popups.
With my off-map links I am calling onclick="showMyPopup([x]) with [x] being an ID attribute loaded in from the kml. The showMyPopup function is
function showMyPopup(myID){
for(var a = 0; a < stations.features.length; a++){ //loop through all the features
var feature = stations.features[a];
if (feature.attributes.ID.value == myID) { //until it finds the one with the matching ID attribute
var content = "<h4>" + feature.attributes.name + "</h4>" + feature.attributes.description;
popup = new OpenLayers.Popup.FramedCloud("chicken",
feature.geometry.getBounds().getCenterLonLat(),
new OpenLayers.Size(200,200),
content,
null, true, onPopupClose);
feature.popup = popup;
map.addPopup(popup);
}
}
}
This opens the correct popup from the stations layer as expected, and I can see the popup using the DOM inspector on the stations layer just as it would appear if loaded by clicking on the map feature, but there's then seemingly no way of closing it. The original features on the stations layer are working fine though (opening and closing).
Any help would be much appreciated (maybe there's a simpler way of tackling this?)
Thanks, James
PS and just in case, here's the onFeatureUnselect function ...
function onFeatureUnselect(event) {
var feature = event.feature;
if(feature.popup) {
map.removePopup(feature.popup);
feature.popup.destroy();
delete feature.popup;
}
}
Your on onPopupClose() function is:
function onPopupClose(evt) {
select.unselectAll();
}
When you select feature from map and click on popup's Close icon, then feature will be unselected, but popup is not closed yet. Then, onFeatureUnselect event is triggered, and popup is actually closed.
When you create popup by showMyPopup() function, you are not selecting it. onPopupClose() is called, but it doesn't close popup. onFeatureUnselect is not triggered.
I suggest to select feature in showMyPopup() function. featureselected event will be fired and popup is created by onFeatureSelect(), and user can close popup both with popup's Close icon and unselecting feature on map.
But alas, there's a possible bug (or unexpected behaviour) in OL, when you select feature with code and try to unselect it with clickout. It's described here: http://lists.osgeo.org/pipermail/openlayers-users/2012-September/026349.html One possible fix is to set SelectControl.handlers.feature.lastFeature manually.
function showMyPopup(myID){
for(var a = 0; a < stations.features.length; a++){ //loop through all the features
var feature = stations.features[a];
if (feature.attributes.ID.value == myID) { //until it finds the one with the matching ID attribute
// select is your SelectFeature control
select.select(feature);
// Fix for unselect bug
select.handlers.feature.lastFeature = feature;
break;
}
}
}
I take a look in the OpenLayers sources and there is in Popup.js something like that ...
...
var closePopup = callback || function(e) {
this.hide();
OpenLayers.Event.stop(e);
};
OpenLayers.Event.observe(this.closeDiv, "touchend",
OpenLayers.Function.bindAsEventListener(closePopup, this));
OpenLayers.Event.observe(this.closeDiv, "click",
OpenLayers.Function.bindAsEventListener(closePopup, this));
...
It seems to me if you add your own closePopup function you need to call the hide function in your code.
I want to be able to run a function in my firefox sidebar js file when the selected tab in the main content window is reloaded or changed. So the sidebar can change depending on the site the user is looking at.
Anyone able to point me in the right direction?
My solution pilfered from somewhere but can't remember where:
//add the load eventListener to the window object
window.addEventListener("load", function() { functioname.init(); }, true);
var functionname = {
//add the listener for the document load event
init: function() {
var appcontent = document.getElementById("appcontent"); // browser
if(appcontent)
appcontent.addEventListener("DOMContentLoaded", functionname.onPageLoad, false);
},
//function called on document load
onPageLoad: function(aEvent) {
if(aEvent.originalTarget.nodeName == "#document"){
}
}
}
#oly1234 - your answer helped me to find the source:
Mozilla Developer Center - On page load
(https://developer.mozilla.org/en/Code_snippets/On_page_load)