Creating this kind of popup in Firefox Addons? - javascript

I'm trying to create a popup like this for use in my addon - is it possible? If so, how's it done?
Thanks in advance!

It's possible in Firefox/XUL, it's also called as door-hanger popup.
https://developer.mozilla.org/en/JavaScript_code_modules/PopupNotifications.jsm#Notification_events
http://scenari-platform.org/svn/dev-core/trunk/Lib_XulRunner/Darwin/modules/PopupNotifications.jsm
For example, the code here is popup notification with time out function, if you dont want you can remove the time out function.
The normal functionality of the time out function & it will disappear automatically if the user clicks any where on the browser.
Components.utils.import('resource://app/modules/PopupNotifications.jsm');
var notify = new PopupNotifications(gBrowser,
document.getElementById("notification-popup"),
document.getElementById("notification-popup-box"));
var notification = notify.show(
gBrowser.selectedBrowser, /*browser*/
"Extension-popup", /*id*/
"Hi, there!, I got a message for you!!",/*message*/
null, /* anchor ID */
/* mainAction */
{
label: "Build PDE",
accessKey: "D",
callback: function() {
if(nodeSRC!=null) pde.emptyNodeSRC(nodeSRC);
window.openDialog("chrome://myextension/content/mypage.xul", "hello", "chrome,width=400,height=360",userContent, nodeSRC);
}
},
null, /* secondaryActions*/
{ blablal:'options'}
);
setTimeout(function(){
notification.remove();
}, 900);

It is also possible to do this by creating a panel and setting it's type to "arrow". In fact that's almost the same example that they have on the panel.type reference page:
Here's how to do it:
<panel id="testPanel" type="arrow">
<vbox>
(... content goes here ...)
</vbox>
</panel>
Then you would open it with:
panel.openPopup(elementThatShouldTriggerIt, "before_start", 0, 0, false, false);
More information on MDN.Panel

Related

mmenu js API - menu not showing

I want to use the mmenu js API but I'm having some difficulties.
I was able to put a basic example up and running and all was fine. Next, I tried to add a searchfield but the searchfield wasn't showing. At that point I realized that the source js file I was using didn't have the searchfield add-on.
After some googling, I found a link to the jquery.mmenu.all.js file that supposedly has all of the add-ons. But then I hit another problem.
You can see the animation of the menu but, it show up blank because its css display property is set to "none".
I'm using the following javascript to call the API.
var myMenu = $("#menu");
// initialize mmenu
myMenu.mmenu({
"navbars": [
{
"position": "top",
"content": [
"searchfield"
]
}
],
"searchfield": {
"panel": true
}
}, {
"searchfield": {
"clear": true
}
});
// initialize mmenu API
var myMenuAPI = myMenu.data( "mmenu" );
// function to set to specific subMenu
function setMMenu(subMenu) {
// set to subMenu
var current = myMenu.find(subMenu);
// myMenuAPI.setSelected(current.first());
myMenuAPI.openPanel(current.closest(".mm-panel"));
}
// function to open mmmenu to specific subMenu
function openMMenu() {
myMenuAPI.open();
}
You can see my problem in this fiddle.
http://jsfiddle.net/6anbksxd/
Can you guys help me out here?
Thanks in advance
Add this to your CSS please.
mm-menu.mm-offcanvas.mm-hasnavbar-top-1.mm-opened {
display: block;
}
Updated JSFiddle.

TinyMCE Enable button while in read only mode

I have a TinyMCE 4.x instance where the text should be in read only mode. But I still have some buttons that I want to have enabled. For example, one button could provide a character count for the part of the text I've selected.
But when I turn on read only mode for TinyMCE all buttons are disabled. Can I enable just my buttons while still retaining read only mode?
It's probably too late for you but other people may pass by here.
I came up by writing this function
function enableTinyMceEditorPlugin(editorId, pluginName, commandName) {
var htmlEditorDiv = document.getElementById(editorId).previousSibling;
var editor = tinymce.get(editorId);
var buttonDiv = htmlEditorDiv.querySelectorAll('.mce-i-' + pluginName.toLowerCase())[0].parentElement.parentElement;
buttonDiv.className = buttonDiv.className.replace(' mce-disabled', '');
buttonDiv.removeAttribute('aria-disabled');
buttonDiv.firstChild.onclick = function () {
editor.execCommand(commandName);
};
}
It does the trick in 2 steps:
make the button clickable (remove mce-disabled CSS class and remove the aria-disabled property)
assign the good command to the click event
And in my editor init event I call the function.
editor.on('init', function () {
if (readOnly) {
editor.setMode('readonly');
enableTinyMceEditorPlugin(htmlEditorId, 'preview', 'mcePreview');
enableTinyMceEditorPlugin(htmlEditorId, 'code', 'mceCodeEditor');
}
});
Current version of TinyMCE for which I wrote this code is 4.4.3. It may break in a future version, specifically about the selectors to get and modify the good HTML elements.
Command identifiers can be found at this page otherwise you can also find them under tinymce\plugins\PluginName\plugin(.min).js
Here is a simple way to enable your custom toolbar button and attach a click event handler inside a read only TinyMCE editor using JQUERY:
//Initialize read only Tinymce editor so that Lock button is also disabled
function initReadOnlyTinyMCE() {
tinymce.init({
selector: '#main'
, toolbar: 'myLockButton'
, body_class: 'main-div'
, content_css: 'stylesheets/index.css'
, readonly: true
, setup: function (readOnlyMain) {
readOnlyMain.addButton('myLockButton', { //Lock button is disabled because readonly is set to true
image: 'images/lock.png'
, tooltip: 'Lock Editor'
});
}
});
}
function displayReadOnlyTinyMCEwithLockButtonEnabled() {
var edContent = $('main').html();
$("#main").empty();
initReadOnlyTinyMCE(true);
tinyMCE.activeEditor.setContent(edContent);
//enable the lock button and attach a click event handler
$('[aria-label="Lock Editor"]').removeClass("mce-disabled");
$('[aria-label="Lock Editor"]').removeAttr("aria-disabled");
$('[aria-label="Lock Editor"]').attr("onclick", "LockEditor()");
}
function LockEditor() {
alert("Tiny mce editor is locked by the current user!!");
//Write your logic to lock the editor...
}
I couldn't find an easy way to do this. The simplest way is to remove the contenteditable attribute from the iframe body instead and substitute a read only toolbar set. It also means that people will still be able to copy content from the editor.
$("iframe").contents().find("body").removeAttr("contenteditable");
How about this :
editor.addButton('yourButton', {
title: 'One can Enable/disable TinyMCE',
text: "Disable",
onclick: function (ee) {
editor.setMode('readonly');
if($(ee.target).text() == "Disable"){
var theEle = $(ee.target).toggle();
var edit = editor;
var newBut = "<input type='button' style='opacity:1;color:white; background-color:orange;' value='Enable'/>";
$(newBut).prependTo($(theEle).closest("div")).click(function(e){
edit.setMode('design');
$(e.target).remove();
$(theEle).toggle();
});
}
}
});
You can try to run the code below:
$("#tinymce").contentEditable="false";
if you have more than one editors, you can use their id like below
$("#tinymce[data-id='idOfTheEditor']").contentEditable="false";

Change a variable or activate a JS-linked <select> dropdown with Greasemonkey

I'm looking to change a javascript variable on page load with Greasemonkey.
The variable I'm looking to change is iDisplayLength the default value is 25, I want to change it to -1 on page load.
This is the script I tried; it did not work:
function changeTheDefaultViewVarLol() {
location.href = "javascript:void(windows.iDisplayLength = -1)";
};
changeTheDefaultViewVarLol();
Edit: From a comment below, the target page is tf2spreadsheet.blogspot.com.
The OP is actually trying to change the number of rows displayed on the page -- a function that is triggered by the "Show {x} entries" <select> dropdown.
You would just use:
unsafeWindow.iDisplayLength = -1;
No need for any of that changeTheDefaultViewVarLol() stuff.
However, this will not have the effect that you want if iDisplayLength is used by the page just after the page sets it to 25.
You will probably have to call a JS function to apply the new value. Link to the target page if this is the case.
Update for additional page information:
What you are actually trying to do is to invoke the "Show All entries" functionality of that page.
So, don't think in terms of poking JS variables, think in terms of activating whatever JS is tied to that <select>.
For a normal page similar to the one you specified, code like this would do it:
var showAllOpt = document.querySelector ('#main_table_length select option[value="-1"]');
var changeEvent = document.createEvent ("HTMLEvents");
if (showAllOpt) {
showAllOpt.parentNode.selectedIndex = showAllOpt.index;
changeEvent.initEvent ("change", true, true);
showAllOpt.parentNode.dispatchEvent (changeEvent);
}
BUT, that page AJAXes-in the desired table long after the page "loads". So, an additional step is needed, like so:
var showAllEntriesSelect = setInterval ( function() {
setSelectValueWhenitLoads (
"#main_table_length select option",
"-1",
showAllEntriesSelect
);
}
, 200
);
function setSelectValueWhenitLoads (cssSelector, targetValue, timerVar) {
var showAllOpt = document.querySelector (
cssSelector + '[value="' + targetValue + '"]'
);
if (showAllOpt) {
clearInterval (timerVar);
showAllOpt.parentNode.selectedIndex = showAllOpt.index;
var changeEvent = document.createEvent ("HTMLEvents");
changeEvent.initEvent ("change", true, true);
showAllOpt.parentNode.dispatchEvent (changeEvent);
}
}

jQuery conditionally change events depending on .html( 'string' ) values

http://jsfiddle.net/motocomdigital/Qh8fL/4/
Please feel free to change the heading if you think I've worded it wrong.
General
I'm running a wordpress site with multilingual control. And my menu/navigation is dynamic, controlled via the wordpress admin. The multilingual language plugin also changes the dynamic menu/navigation content, as well as page content.
My Contact button, which is in the dynamic navigation, opens a sliding menu using jQuery. Very simple animation using top css. The contact button is on the page twice, hence why I'm not using the .toggle for iterations. See jsFiddle.
Script
var $button = $(".contact-button"),
// var for button which controls sliding div
$slide = $("#content-slide");
// var for the div which slides up and down
$button.on('click', function () {
// function for when button is clicked
if ($button.html() == 'Close') {
// run this if button says 'Close'
$slide.stop().animate({ top: "-269px" }, 300);
// close slide animation
$button.html('Contact');
// change text back to 'Contact'
} else {
// else if button says Contact or anything else
$slide.stop().animate({ top: "0" }, 300);
// open slide animation
$button.html('Close');
// change text to 'Close'
}
});
Problem
Because I'm running multilingual on the site. The navigation spelling changes. See jsFiddle flag buttons for example. This is fine, the animation still runs OK, because it's using the button class 'contact-button'.
But because I'm using the .html to replace the text of the button to "Close" and then on the second iteration, back to "Contact" - obviously this is a problem for other languages, as it always changes to English 'close' and back to English 'Contact'
But my three languages and words that I need the iterations to run through are...
Contact - Close
Contatto - Cerca
Contacto - Chiudere
Can anyone help me expand my script to accommodate three languages, all my attempts have failed. The jsFiddle has the script.
The language functionality in the fiddle is only for demo purposes, so the iteration sequence can be tested from the beginning. I understand if you change the language whilst the menu is open (in the fiddle), it will confused it. But when the language is changed on my site, the whole page refreshes, which closes the slide and resets the sequence. So it does not matter.
Any pro help would be awesome thanks!!!
MY POOR ATTEMPT, BUT YOU CAN SEE WHAT I'M TRYING TO ACHIEVE
var $button = $(".contact-button"),
// Var for button which controls sliding div
$slide = $("#content-slide");
// Var for the div which slides up and down
$button.on('click', function () {
// function for when button is clicked
if ($button.html() == 'Close' || 'Cerca'|| 'Chiudere' ) {
// run this if button says Close or Cerca or Chiudere
$slide.stop().animate({ top: "-269px" }, 300);
// Close slide animation
$(function () {
if ($button.html(== 'Close') {
$button.html('Contact'); }
else if ($button.html(== 'Cerca') {
$button.html('Contatto'); }
else ($button.html(== 'Chiudere') {
$button.html('Contacto'); }
});
// Change text back to Contact in correct language
} else {
// else if button says Contact or anything else
$slide.stop().animate({ top: "0" }, 300);
// Open slide animation
$(function () {
if ($button.html(== 'Contact') {
$button.html('Close'); }
else if ($button.html(== 'Contatto') {
$button.html('Cerca'); }
else ($button.html(== 'Contacto') {
$button.html('Chiudere'); }
});
// Change text back to Close in the correct language
}
});
See my attempt script above which is not working on this jsFiddle.
Here's a working example: http://jsfiddle.net/Qh8fL/2/
When one of the language buttons gets clicked, it stores the strings for Contact and Close using jQuery's .data() method. Then, when the contact/close button gets clicked, it refers to those strings rather than having it hard-coded.
Here are the relevant lines of code:
$("#english").click(function() {
$(".contact-button").html('Contact').data('langTxt',{contact:'Contact',close:'Close'});
});
$("#spanish").click(function() {
$(".contact-button").html('Contatto').data('langTxt',{contact:'Contatto',close:'Close'});
});
$("#italian").click(function() {
$(".contact-button").html('Contacto').data('langTxt',{contact:'Contacto',close:'Close'});
});
if ($button.html() == 'Close') {
//...
$button.html($button.data('langTxt').contact);
} else {
//...
$button.html($button.data('langTxt').close);
}
All you need to do to modify the "close" text appropriately is by editing the close property inside the calls to data() that occur in each of the click events.
You should never depend on label strings ... especially in a multilingual environment. Instead you should use placeholders that you store in an attribute (maybe using .data()). Then you write your own setters for the labels depending on the value of the attribute.
var myLabels = {'close': ['Close', 'Cerca', 'Chiudere'], 'contact' : ['Contact', 'Contatto', 'Contacto']};
var currLang = 2; // to select italian
....
// to set the label
$button.data('mylabel', 'close');
$button.html(myLabels['close'][currLang]);
....
if($button.data('mylabel') == 'close') {
$button.data('mylabel', 'contact');
$button.html(myLabels['contact'][currLang]);
} else {
$button.data('mylabel', 'close');
$button.html(myLabels['close'][currLang]);
}

Customising CKEditors Link Plugin

I am editing the link plugin to allow staff to select links to internal content.
I have managed to add another tab to the link plugin dialog with a text input with an onKeyup event. The idea is, when they type it will list the results below where they can select the link they want. Once selected I was just going to update the info tab with the url and protocol.
Here is my code sections from the existing link plugin:
....
....
//Should update info tab with value
function AddLink(txtLink)
{
var dialog = this.getDialog();
dialog.setValueOf('info', 'url', txtLink);
dialog.setValueOf('info', 'protocol', '');
}
//called when the user types in the search box. currently just uses text for basic testing
var searchBoxChanged = function ()
{
var dialog = this.getDialog();
var href = $(this).attr('href');
var txt = dialog.getValueOf('article', 'searchWords');
$('#searchResults').html("Test Title");
}
....
....
{
//Adds extra tab to the link plugin for custom link searching
id: 'article',
label: linkLang.article,
title: linkLang.article,
elements:
[
{
type: 'text',
id: 'searchWords',
label: linkLang.articleSearch,
style: 'height:40px',
size: 29,
onKeyUp: searchBoxChanged
},
{
type: 'html',
html: '<div id="searchResults">Please start tying to get results</div>'
}
]
}
....
....
At the moment I am just using some basic static data from the textbox. The link in creating on the page ok, but when it is clicked I get the error:
CRIPT5009: 'AddLink' is undefined
Can anyone shed some light on where I am going wrong?
In my experience, ["x" is undefined] errors quite often mean there's a syntax error or, often, something in the function does not evaluate to what you think it does.
Possibly, this.getDialog() is out of context so it doesn't return anything. Then, dialog.setValueOf() won't work.

Categories

Resources