Tooltips (Titles) in XUL browser content are not working? - firefox-addon

I'm developing an extension for FireFox. I use a XUL deck element that contains a XUL browser element. Unfortunately, whenever the page displayed in the browser has an HTML title attribute, the value of this title attribute will not show up as a tooltip.
How can I get tooltips to display correctly?

There is no mechanism to automatically display title attributes in tooltips - the browser window has special code for that and you need to replicate this code in your extension. This means that you need to define a <tooltip> element, e.g.:
<popupset>
<tooltip id="browserTooltip" onpopupshowing="return fillTooltip(this);"/>
</popupset>
You should use this tooltip in your <browser> element, like this:
<browser tooltip="browserTooltip"/>
And you should create a fillTooltip() function that will be called whenever your tooltip shows up. It will need to look at the HTML element that the mouse pointer hovers over, check its title attribute and put the value of the attribute into the tooltip. The function performing this job in Firefox is FillInHTMLTooltip() though you might want to go with a simpler variant like this (untested code):
function fillTooltip(tooltip)
{
// Walk up the DOM hierarchy until we find something with a title attribute
var node = document.tooltipNode;
while (node && !node.hasAttribute("title"))
node = node.parentNode;
// Don't show tooltip if we didn't find anything
if (!node)
return false;
// Fill in tooltip text and show it
tooltip.setAttribute("label", node.getAttribute("title"));
return true;
}

I found the solution for those who are interested, it's by adding a tooltip property to the XUL browser element with the following value:
tooltip="aHTMLTooltip"
Or adding it programmatically using javascript like this:
browser.setAttribute('tooltip','aHTMLTooltip');
for more details check: https://bugzilla.mozilla.org/show_bug.cgi?id=451792#c1

Working example:
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<window id="mainWindow" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" title="NanoFL" width="800" height="600" persist="screenX screenY width height sizemode">
<script>
<![CDATA[
function fillTooltip(tooltip)
{
var nodes = document.getElementById("browser").contentWindow.document.querySelectorAll(":hover");
for (var i=nodes.length-1; i>=0; i--)
{
if (nodes[i].hasAttribute("title"))
{
tooltip.setAttribute("label", nodes[i].getAttribute("title"));
return true;
}
}
return false;
}
]]>
</script>
<browser id="browser" src="chrome://nanofl/content/index.html" flex="1" disablehistory="true" tooltip="browserTooltip" />
<tooltip id="browserTooltip" onpopupshowing="return fillTooltip(this)"/>
</window>

Related

How to programmatically clear PaperInput and have the floating label drop down to the input line

I have the following markup:
<paper-input id="alias-input" floatingLabel label="Person Alias (eg: King, Eldest Son, Mooch, etc.)"></paper-input>
<paper-input id="birth-year-input" floatingLabel label="Birth Year (eg: 1969)" validate="^[12][0-9][0-9][0-9]$"></paper-input>
<div center horizontal layout>
<paper-button id="add-button" on-click="{{addPerson}}" class="add" label="Add Person"></paper-button>
</div>
To go along with this markup I have an addButton method which does:
addPerson(_) {
// Add the person
// ...
// Clear the inputs
($['alias-input'] as PaperInput)..inputValue = ''..commit()..blur();
($['birth-year-input'] as PaperInput)..inputValue = ''..commit()..blur();
}
This correctly clears the contents of the inputs, which I want. But I also want the PaperInput help label to drop down onto the line as it is when the control is first loaded. My hope was that the call to blur() would do that. Is there some other call to achieve this?
It seems you need to call blur on the actual <input id='input'> element inside <paper-input> not the <paper-input> itself.
I got it working with
import 'dart:js' as js;
var inp = $['alias-input'] as PaperInput;
inp.inputValue = '';
new js.JsObject.fromBrowserObject(inp).callMethod('inputBlurAction', []);
alternatively you can do it like
var inp = $['alias-input'] as PaperInput;
inp.inputValue = '';
inp.querySelector('* /deep/ #input') // not yet supported with polyfills
..focus() // blur doesn't work when the field doesn't have the focus
..blur();

Using drag and drop in phonegap installed

I'm using simple HTML code to work on a drag and drop function as part of my IOS app. This piece of code works perfectly in the browser however when I copy it into my xcode file the image won't drag.
<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">
#div1 {width:350px;height:70px;padding:10px;border:1px solid #aaaaaa;}
</style>
<script>
function allowDrop(ev)
{
ev.preventDefault();
}
function drag(ev)
{
ev.dataTransfer.setData("Text",ev.target.id);
}
function drop(ev)
{
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>
<p>Drag the image into the rectangle:</p>
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="drag1" src="images/face.png" draggable="true" ondragstart="drag(event)" width="336" height="69">
</body>
</html>
Reading over Apple's webview capabilities document states that you have to set a CSS property for this to work.
From the docs:
Making an Element Draggable
WebKit provides automatic support to let users drag common items, such as images, links
and selected text. You can extend this support to include specific elements on an HTML
page. For example, you could mark a particular div or span tag as draggable.
To mark an arbitrary element as draggable, add the -webkit-user-drag attribute
(previously -khtml-user-drag) to the style definition of the element. Because it is a
cascading style sheet (CSS) attribute, you can include it as part of a style definition
or as an inline style attribute on the element tag. The values for this attribute are
listed in Table 1.
So standard draggables will work out of the box, but other elements like div or span require the -webkit-user-drag attribute to be appended.
Example:
#drag1 { -webkit-user-drag: element; }
Source: https://developer.apple.com/library/mac/documentation/AppleApplications/Conceptual/SafariJSProgTopics/Tasks/DragAndDrop.html
This code is what worked in the end.
<script>
var nodeList = document.getElementsByClassName('contents');
for(var i=0;i<nodeList.length;i++) {
var obj = nodeList[i];
obj.addEventListener('touchmove', function(event) {
var touch = event.targetTouches[0];
// Place element where the finger is
event.target.style.left = touch.pageX + 'px';
event.target.style.top = touch.pageY + 'px';
event.preventDefault();
});
}
</script>

How to get the index of the element selected in ListView JQUERYMOBILE

I have created a dynamic listview with a link with id="a".
<ul id="accpmenu" data-role="listview" >
</ul>
$("#accpmenu").append('<li>'+ this.textContent +' </li>');
Now i want to identify the index of the element that I have clicked from this listview.
$("#a").live("click",function(e)
{
//What should i write here to get the selected index?.
}
I want the index number based on this I need to load the dynamic XML.
Please help me in resolving this.
Thanks
Shyam
$('#accpmenu').on('click', ' > li', function () {
var selected_index = $(this).index();
});
Here is a demo: http://jsfiddle.net/w2JZU/
This will bind an event handler to the list-items in the #accpmenu list for the click event that finds the index of the clicked list-item (compared to other list-item elements).
On a side-note you have what appears to be some invalid HTML in your code:
$("#accpmenu").append('<li>'+ this.textContent +' </li>');
Should change to (notice the removed double-quote after the id attribute):
$("#accpmenu").append('<li>'+ this.textContent +' </li>');
My example above added the click event handler to the li elements since it is easy to ascertain the index of the clicked element but you can also bind to links in the list:
$('#accpmenu').on('click', 'a', function () {
//this gets the index by finding the first parent list-item element and getting it's index compared do its siblings
var selected_index = $(this).parents('li').eq(0).index();
});
Note that .on() is new in jQuery 1.7 and in the cases above replaces .delegate() (from earlier versions).
Here are some docs for ya to help explain the above examples:
.on(): http://api.jquery.com/on
.index(): http://api.jquery.com/index
.parents(): http://api.jquery.com/parents

Styling Panels of a Firefox Addon

So I created a Widget that the user clicks on and it opens up a Panel, I have a couple of Questions about the panel.
How Do I style the Panels borders, background color, etc..? I'm including an HTML file in it's contentURL, can I add CSS to alter it? If so how do I select it via CSS?
I also want to add a Close Button and keep the panel open always unless they click the close button.
On second thought, for the Add-on i'm trying to program it might be better if I make a window, is a window pretty stylable so I can make it look cooler?
Thanks for any help.
I don't think you can style panel borders. The panel border styles depend on the operating system and you cannot touch them. You can only really influence the inner area of the panel, effectively you get an iframe inside the panel that you can play with. E.g. to change the background your panel can contain:
<style type="text/css">
html
{
background-color: red;
}
</style>
You cannot, the panel is not a real HTML object, but a XUL window with an iframe or HTML inside.
I believe since Firefox 30 you can access to this object, you can read:
Avoid panel to autoHide in Firefox extension
Of course it's a kind of hack, looks like Mozilla is not really "open" ^^
I was able to modify the border of the panel:
/*run this first*/
var win = Services.wm.getMostRecentWindow('navigator:browser');
var panel = win.document.createElement('panel');
var screen = Services.appShell.hiddenDOMWindow.screen;
var props = {
noautohide: true,
noautofocus: false,
level: 'top',
style: 'padding:15px; margin:0; width:150px; height:200px; background-color:steelblue;border-radius:15px'
}
for (var p in props) {
panel.setAttribute(p, props[p]);
}
win.document.querySelector('#mainPopupSet').appendChild(panel);
panel.addEventListener('dblclick', function () {
panel.parentNode.removeChild(panel)
}, false);
panel.openPopup(null, 'overlap', screen.availLeft, screen.availTop);
So if you know the panel of your id just do this:
var sss = Cc['#mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
var css = '';
css += '#YourPanelIdHere { border-radius:15px; opacity:.5; border:1px solid red; }';
var cssEnc = encodeURIComponent(css);
var newURIParam = {
aURL: 'data:text/css,' + cssEnc,
aOriginCharset: null,
aBaseURI: null
}
var cssUri = Services.io.newURI(newURIParam.aURL, newURIParam.aOriginCharset, newURIParam.aBaseURI);
sss.loadAndRegisterSheet(cssUri, sss.USER_SHEET);
//sss.unregisterSheet(cssUri, sss.USER_SHEET);
That will style your panel. You don't have to use panel id in the style sheet, just anything that target your panel will do.

jQuery combobox: standard script to catch selected value of combobox does not work

I'm using jqueryui combobox example at http://jqueryui.com/demos/autocomplete/combobox.html
I added the script seen below to catch the selected value of combobox:
<div id="selectedOpt">
</div>
<script>
$(document).ready(function() {
$("#combobox").change(function() {
var retval = $(this).val();
$("#selectedOpt").html("retval=" + retval);
});
});
</script>
However, it does not work as expected:
the div selectedOpt does not show selected value of combobox each time
the change event occurs
If "show underlying effect" is selected (pls try at url above), a standard dropdown list
appear. When trying to change value of
that dropdown list, then the div
selectedOpt is able to show value
correctly.
The goal is to have div selectedOpt display the selected option of the combobox.
Please advise and please explain why (1) does not work while (2) works.
PS: all neccessary js, css are correctly included.
Thanks for your kind attention.
SOLUTION FOUND:
http://robertmarkbramprogrammer.blogspot.com/2010/09/event-handling-with-jquery-autocomplete.html
Please change your script to match the code below:
<script>
function test()
{
var retval = $("[id *=dropdown] :selected").val();
$("#selectedOpt").html("retval=" + retval);
}
</script>
And call this script from the server side like this:
dropdown.Attributes.Add("onchange","javascript: return test();")
To show label or value of combobox in your div you have to include your function as an option. Something like this:
$( ".selector" ).autocomplete({
change: function(event, ui) {
$("#selectedOpt").html("retval=" + ui.item.value);
}
});
Use ui.item.label if you want a label instead.

Resources