I'm developing a Firefox extension, trying to get a panel to overlay a browser element. Here is my javascript code:
var panel = oldTabBrowser.contentDocument.createElement('panel');
panel.setAttribute('noautohide','true');
var label = oldTabBrowser.contentDocument.createElement('label');
label.setAttribute('value','my text');
panel.appendChild(label);
elem.appendChild(panel);
panel.openPopup(elem, "overlap",0,0);
alert(panel.getAttribute('noautohide'));
The noautohide attribute is set fine and the panel appears as expected, but on clicking anywhere, the panel disappears. What am I missing?
I have a strong suspicion that noautohide attribute doesn't work correctly. At least for <xul:tooltip> the result isn't the one I expected. You can however make sure that your panel doesn't close prematurely using popuphiding event:
var canClose = false;
panel.addEventListener("popuphiding", function(event)
{
if (!canClose)
{
// Too early to close, prevent it
event.preventDefault();
}
}, false);
panel.openPopup(elem, "overlap",0,0);
...
// Now it is ok to close
canClose = true;
panel.hidePopup();
Related
I'm using jQuery Mobile to create a popup near an info image button (see picture below). The popup I'm creating has data-dismissable set as false. In red it has been highlighted the container created by jQuery Mobile.
If the user taps once on i icon, it works perfectly. The popup opens and popupafteropen event is called. To dismiss it, the user can tap (click) on the i or outside the red area (thanks to data-dismissable value). On the contrary, if the users performs a double tap (here I mean that the delay bewteen two taps is very short), the popup opens, popupafteropen is called but then also close is called (due to the second tap and data-dismissable value). The overall result is that the popup is not shown.
Are there any solutions to adopt? My goal is to prevent the second tap in order to display the popup correctly.
Thanks.
Kazekage Gaara has a good idea so look first at it.
Other one would require you to bind a doubletap event to popup opening icon and prevent default action, unfortunately jQuery Mobile don't have support for doubletap so you can use this plugin:
(function($) {
$.fn.doubleTap = function(doubleTapCallback) {
return this.each(function(){
var elm = this;
var lastTap = 0;
$(elm).bind('vmousedown', function (e) {
var now = (new Date()).valueOf();
var diff = (now - lastTap);
lastTap = now ;
if (diff < 250) {
if($.isFunction( doubleTapCallback ))
{
doubleTapCallback.call(elm);
}
}
});
});
}
})(jQuery);
and bind it like this:
$(".icon").doubleTap(function(event){
event.preventDefault();
});
There used to be much easier solution for this, jQUery Mobile used to have mobileinit configuration parameter that allowed you to set how long tap event can last.
Or you can monitor interval between taps and prevent allow actions, like this:
var lastTapTime;
function isJqmGhostClick(event) {
var currTapTime = new Date().getTime();
if(lastTapTime == null || currTapTime > (lastTapTime + 800)) {
lastTapTime = currTapTime;
return false;
}
else {
return true;
}
}
You can handle the event and ignore it if the popup is already open. Something like :
if ($.mobile.activePage.find("#popupID").is(":visible") {
// Do something here if the popup is open
}
When using tinyMCE in a jqueryUI modal dialog, I can't use the hyperlink or 'insert image' features.
Basically, after lots of searching, I've found this:
http://www.tinymce.com/develop/bugtracker_view.php?id=5917
The weird thing is that to me it seams less of a tinyMCE issue and more of a jqueryUI issue since the problem is not present when jqueryUI's modal property is set to false.
With a richer form I saw that what happens is that whenever the tinyMCE loses focus, the first element in the form gets focus even if it's not the one focused / clicked.
Does some JavaScript guru have any idea how I might be able to keep the dialog modal and make tinyMCE work?
This fixed it for me when overriding _allowInteraction would not:
$(document).on('focusin', function(e) {
if ($(event.target).closest(".mce-window").length) {
e.stopImmediatePropagation();
}
});
I can't really take credit for it. I got it from this thread on the TinyMCE forums.
(They have moved their bugtracker to github. tinymce/issues/703 is the corresponding github issue.)
It seems there are no propper solution for this issue yet. This is kind of a hack but it really worked for me.
Every time you open the Dialog remove the text area and re add it like following,
var myDialog = $('#myDialog');
var myTextarea = myDialog.find('textarea');
var clonedTextArea = myTextarea.clone(); // create a copy before deleting from the DOM
var myTextAreaParent = myTextarea.parent(); // get the parent to add the created copy later
myTextarea.remove(); // remove the textarea
myDialog.find('.mce-container').remove(); // remove existing mce control if exists
myTextAreaParent.append(clonedTextArea); // re-add the copy
myDialog.dialog({
open: function(e1,e2){
setTimeout(function () {
// Add your tinymce creation code here
},50);
}
});
myDialog.dialog('open');
This seems to fix it for me, or at least work around it (put it somewhere in your $(document).ready()):
$.widget('ui.dialog', $.ui.dialog, {
_allowInteraction: function(event) {
return ($('.mce-panel:visible').length > 0);
}
});
I'm trying to do something that seems (to me, at least) to be a fairly easy, common thing to do.
Here's the HTML for what I've got on a web page:
<div class="allergiesDiv">
<div>
<span class="editButton">Allergies</span><br />
</div>
<span>Allergies</span>
</div>
</div>
I turn the first <span> into a jQuery button with $('.editButton').button().
(I have many of these pairs on the page.)
What I am trying to do is the following:
When the button is clicked, it loads a jQuery Dialog with the value of the span that follows it loaded into a <textarea>. (BONUS: When the dialog is loaded, I'd like the <textarea> to be focused and all text inside highlighted.)
The user is able to edit the value and then click 'OK'.
When the user clicks 'OK', the Dialog is dismissed and the new value that was entered is used to replace the old value for the span.
Here's the code I'm trying to use (this works OK in IE, but breaks in Mobile Safari and Chrome for PC):
NOTE: I've been chopping the code up some to try to get each problem isolated. I have had this working, at least in IE.
// How I get the button and bind to the click event
$('.editButton')
.button({icons: {primary:'ui-icon-pencil'} })
.click(EditClicked);
// 'Edit' button click handler
function EditClicked() {
var span = $(this).parent().next().children().first();
var text = span[0].innerText;
var dialog = $('<div>').prop('title', 'Edit: ' + $(this).text());
var textArea = $('<textarea>').css('width', '98%').prop('rows', '4').html(text);
textArea.appendTo(dialog);
var windowWidth = $(window).width();
var buttonTop = $(this).button().offset().top;
$(dialog).dialog({
modal: true,
minWidth: windowWidth / 2,
position: ['center',buttonTop],
buttons: {
'Ok' : function () {
OKClicked(span);
},
'Cancel' : function () {
$(this).dialog('close').remove();
}
}
});
textArea.focus().select();
}
// Dialog 'OK' button click handler
function OKClicked(span) {
var text = $(this).find('textarea')[0].innerText;
span.html(text);
$(this).dialog('close').remove();
}
This is currently broken when it gets to var buttonTop..., with the error message of "button is undefined". I haven't yet figured out why that is (I used to have a variable in that method named 'button', but it's gone now. Not sure if that's a caching issue.)
Other than that, can anyone see what's wrong with my process? It seems like I've got some kind of misunderstanding with closure, but I'm not yet good enough with JavaScript to understand how to get the kink out of this code.
what about
var buttonTop = $(this).offset().top;
I am not sure, that $('<div>') is properly syntax for jQuery. Try to use $('div') instead.
When you use $(this).button() - you try to call button method of $(this) object. Seems like a bug.
Completely restated my question:
Problem: Losing reference to an iFrame with Mozilla firefox 3.6 and 4.0
More info:
- Works fine in internet explorer 8 64-bit and 32-bit version.
How to reproduce? In Mozilla: Open the editor accordion menu. Click the 'editor openen' link, in the editor fill in some random text, then click 'bestand opslaan'. Fill in a name and click on 'save'. The content of the editor will be downloaded in HTML format.
Close the save file dialog box by clickin outside of it or on the specified buttons. Click on the 'bestand opslaan' button again and try to save your content to a file. You'll see nothing happening.
The problem isn't there in IE8. Try opening it in there.
Firebug tells me this the second time you open the save dialog:
iFrame.document is null
Example Link: http://www.newsletter.c-tz.nl/
More info:
- switched from thickbox to colorbox to try and resolve this issue and because thickbox isn't supported for a long time now.
- colorbox gives me the same problem so I don't think it is this.
- tried googling for iframe reference error and like, found nothing.
- tried putting the iframe code outside of the div that is called by the colorbox script, it retains it reference but not when I put it back inside that div.
Thanks to: JohnP who offered to open a 'hunt' on this.
Edit:
I thought maybe the saveFile.php file was causing trouble to the parent of the iframe but after removing it from the action variable in the editor.php script it still fails with the same error after you open the dialog for a second time.
Can someone maybe write a script that iterates through iframes by name and when the rignt iframe is found reference it to a var? I want to try it but don't know how..
I can't explain why it's work the first time for Firefox, but in Firefox the function to used for get iframe is different of IE : How to get the body's content of an iframe in Javascript?.
So, replace your JavaScript function "saveToFile" to this :
function saveToFile() {
var saveAsFileName = document.getElementById('saveAs_filename').value;
var currentContent = tinyMCE.editors["editor_textarea"].getContent();
var editorFileName = document.getElementById('editor_filename');
var iFrameTag = document.getElementById('saveAs_Iframe');
var iFrame;
if ( iFrameTag.contentDocument )
{ // FF
iFrame = iFrameTag.contentDocument;
}
else if ( iFrame.contentWindow )
{ // IE
iFrame = iFrameTag.contentWindow.document;
}
var inframeEditorFileName = iFrame.getElementById('editor_filename');
var inframeEditorContent = iFrame.getElementById('editor_textarea');
editorFileName.value = saveAsFileName;
inframeEditorFileName.value = saveAsFileName;
inframeEditorContent.value = currentContent;
iFrame.editor_self.submit();
}
I replace the function with Firebug and it's works for me.
Update :
You can also used a crossbrowser solution, more simple, thanks to jQuery :
function saveToFile() {
var saveAsFileName = document.getElementById('saveAs_filename').value;
var currentContent = tinyMCE.editors["editor_textarea"].getContent();
var editorFileName = document.getElementById('editor_filename');
editorFileName.value = saveAsFileName;
$("#saveAs_Iframe").contents().find("#editor_filename").val(saveAsFileName)
$("#saveAs_Iframe").contents().find("#editor_textarea").val(currentContent)
$("#saveAs_Iframe").contents().find("form[name=editor_self]").submit();
}
I need to know if the user is currently viewing a tab or not in Google Chrome. I tried to use the events blur and focus binded to the window, but only the blur seems to be working correctly.
window.addEventListener('focus', function() {
document.title = 'focused';
});
window.addEventListener('blur', function() {
document.title = 'not focused';
});
The focus event works weird, only sometimes. If I switch to another tab and back, focus event won't activate. But if I click on the address bar and then back on the page, it will. Or if I switch to another program and then back to Chrome it will activate if the tab is currently focused.
2015 update: The new HTML5 way with visibility API (taken from Blowsie's comment):
document.addEventListener('visibilitychange', function(){
document.title = document.hidden; // change tab text for demo
})
The code the original poster gives (in the question) now works, as of 2011:
window.addEventListener('focus', function() {
document.title = 'focused';
});
window.addEventListener('blur', function() {
document.title = 'not focused';
});
edit: As of a few months later in Chrome 14, this will still work, but the user must have interacted with the page by clicking anywhere in the window at least once. Merely scrolling and such is insufficient to make this work. Doing window.focus() does not make this work automatically either. If anyone knows of a workaround, please mention.
The selected answer for the question Is there a way to detect if a browser window is not currently active? should work. It utilizes the Page Visibility API drafted by the W3C on 2011-06-02.
It might work after all, i got curious and wrote this code:
...
setInterval ( updateSize, 500 );
function updateSize(){
if(window.outerHeight == window.innerHeight){
document.title = 'not focused';
} else {
document.title = 'focused';
}
document.getElementById("arthur").innerHTML = window.outerHeight + " - " + window.innerHeight;
}
...
<div id="arthur">
dent
</div>
This code does precisly what you want, but on an ugly way. The thing is, Chrome seems to ignore the title change from time to time (when switching to the tab and holding the mouse down for 1 sec seems to always create this effect).
You will get different values on your screen, yet your title won't change.
conclusion:
Whatever you are doing, don't trust the result when testing it!
For anyone who wants to swap page titles on blur and then go back to the original page title on focus:
// Swapping page titles on blur
var originalPageTitle = document.title;
window.addEventListener('blur', function(){
document.title = 'Don\'t forget to read this...';
});
window.addEventListener('focus', function(){
document.title = originalPageTitle;
});
I found that adding onblur= and onfocus= events to inline bypassed the issue:
This could work with JQuery
$(function() {
$(window).focus(function() {
console.log('Focus');
});
$(window).blur(function() {
console.log('Blur');
});
});
In chrome you can run a background script with a timeout of less than 1 second, and when the tab does not have focus chrome will only run it every second. Example;
This doesn't work in Firefox or Opera. Don't know about other browsers, but I doubt it works there too.
var currentDate = new Date();
var a = currentDate.getTime();
function test() {
var currentDate = new Date();
var b = currentDate.getTime();
var c = b - a;
if (c > 900) {
//Tab does not have focus.
} else {
//It does
}
a = b;
setTimeout("test()",800);
}
setTimeout("test()",1);