I wanted to create a firefox add-on, which will display a form to user.
I am started with SDK isntallaion and documentation. I am able to create a toggle button which will open a panel to user.
var { ToggleButton } = require('sdk/ui/button/toggle');
var panels = require('sdk/panel');
var self = require('sdk/self');
var button = ToggleButton({
id: 'btn-sc',
label: 'Test Addon',
icon: {
"16": "./icon-16.png",
"32": "./icon-32.png",
"64": "./icon-64.png"
},
onChange: handleChange
});
var panel = panels.Panel({
contentURL : self.data.url("./panel.html"),
onHide : handleHide
});
function handleChange(state){
if(state.checked){
panel.show({
position: button
});
}
}
function handleHide(){
button.state('window', {checked:false});
}
How do I add more buttons and textbox to this panel?
Create them with HTML in panel.html. If you don't have a panel.html file yet, place it in the data folder. Style with CSS, listen for clicks with JS. It's just a normal webpage.
Related
I have implemented kendo editor within it i have implemented kendo image browser.
I have implemented it the way it is guided in documentation with same backend controller.
I have implemented kendo confirmation box for other functionality too. I want kendo alert instead of javascript alert for confirmation when one delete image. so I have capture the delete event and using event.stopPropagation I manage stop the default delete behaviour and implemented kendo confirm box. on its ok button i have called backend destroy method of controller to delete image using ajax.
Fortunately it is successfully deleted from backend but from view side that is in image browser thumbnail it is not deleting, after refreshing the it goes from view side or remove from thumbnail . I have also try to manually delete the respective li it got deleted but as soon as I upload some new image that deleted li also comes up with deleted image although it has been deleted from backend.
Here is the code how I implemented image browser:
function createEditor(id)
{
//Kendo Editor for content
$(id).kendoEditor({
encoded: false,
tools: [
"bold",
"italic",
"underline",
"strikethrough",
],
imageBrowser: {
transport: {
read: "/ImageBrowser/Read",
destroy: {
url: '/ImageBrowser/Destroy',
type: "POST"
},
create: {
url: '/ImageBrowser/Create',
type: "POST"
},
thumbnailUrl: '/ImageBrowser/Thumbnail',
uploadUrl: '/ImageBrowser/Upload',
imageUrl: "../Content/article/" + userId + "/{0}"
},
}
});
//On click of imagebrowser icon of editor
$(".k-i-image").click(function () {
setTimeout(function () {
// Attach a select handler to the Upload embedded in the ImageBrowser.
$(".k-imagebrowser .k-upload").find("input").data("kendoUpload").bind("select",
function (e) {
// Prevent the event if the selected file is not of specified extension.
if (e.files[0].extension.toLowerCase() != ".jpg" && e.files[0].extension.toLowerCase() != ".jpeg" && e.files[0].extension.toLowerCase() != ".png" && e.files[0].extension.toLowerCase() != ".gif") {
e.preventDefault();
$("<div></div>").kendoAlert({
title: false,
content: "The file extension is not *.png,*.gif,*.jpg,*.jpeg.",
buttonLayout: "normal"
}).data("kendoAlert").open();
}
var s = e.files[0].size / Math.pow(1000, 2);
//Size validation
if (s > 5) {
e.preventDefault();
$("<div></div>").kendoAlert({
title: false,
content: "File size should not be more than 5 MB",
buttonLayout: "normal"
}).data("kendoAlert").open();
}
$('.k-reset.k-floats.k-tiles.k-widget.k-listview.k-selectable').children('li').each(function (index, value) {
// Prevent the event if the selected file is already exist.
if ($(this).children("strong").html() == e.files[0].name) {
e.preventDefault();
$("<div></div>").kendoAlert({
title: false,
content: "A file with name already exists in the current directory",
buttonLayout: "normal"
}).data("kendoAlert").open();
}
});
});
//Delete image from image browser
$(".k-toolbar-wrap>.k-button-icon").click(function (event) {
var type;
var name;
if ($(this).children().hasClass("k-i-close")) {
//alert();
//event.preventDefault();
event.stopPropagation();
var path = "";
var img;
$('.k-breadcrumbs-wrap').children('a').each(function (index, value) {
if ($(this).hasClass("k-link")) {
path = path + $(this).text() + "/";
}
});
$('.k-reset.k-floats.k-tiles.k-widget.k-listview.k-selectable').children('li').each(function (index, value) {
if ($(this).hasClass("k-tile k-state-selected")) {
img = $(this).attr("data-uid");
type = $(this).attr("data-type");
name = $(this).children("strong").html();
}
});
//alert(path);
window.OpenDeleteConfirm("Are you sure you want to delete this record?").then(function (e) {
$.ajax({
type: 'POST',
url: "/ImageBrowser/Destroy",
data: { "path": path, "type": type, "name": name },
success: function (response) {
//$(".k-reset.k-floats.k-tiles.k-widget.k-listview.k-selectable>.k-tile.k-state-selected").remove();
}
});
}, function () {
// window.myalert("You chose to Cancel action.");
});
}
else {
}
});
//End
});
});
}```
In short, kendoEditor has an internal ImageBrowser that has an internal ListView with the files that keeps the list of files in its dataSource, that it creates from your transport configuration. Your ajax call doesn't tell that dataSource that an item should be removed.
Since it's a poorly documented component of Kendo Professional, I suggest you file a ticket with Telerik.
I'm creating a firefox extension using Add-on SDK, which will display all the tab details including memory, title and url. I have tried to get the tab title using require("sdk/tabs"); tab package.
Below is the sample code:
popup.js
<body>
<ul>
<li>
Settings
</li>
</ul>
<script type="text/javascript" src="popup.js"></script>
</body>
popup.js
var tab_button = document.getElementById("tab_list");
tab_button.addEventListener("click", function() {
addon.port.emit("GET_TABS");
});
main file: index.js
const buttons = require("sdk/ui/button/action");
const { TogglePanel } = require("popupPanel");
var button = buttons.ActionButton({
id: "mem-tools",
label: "tabs info listing",
icon: {
"16": "./tab.png",
},
onClick: handleClick
});
let togglePanel = new TogglePanel();
function handleClick(state) {
togglePanel.panel.show({position:button});
}
Panel file: popupPanel.js
var Panel = require('sdk/panel');
var self = require('sdk/self');
var { MemoryHandler } = require('memory-handler');
var memoryHandler = new MemoryHandler();
function TogglePanel() {
this.panel = new Panel.Panel({
width: 150,
height: 200,
contentURL: self.data.url("popup.html")
});
this.panel.port.on("GET_TABS", function() {
memoryHandler.getAllTabs();
});
}
exports.TogglePanel = TogglePanel;
memory-handler.js
var tabs = require('sdk/tabs');
function MemoryHandler() {
return {
getAllTabs: () => {
for(let tab of tabs) {
console.log(tab.title);
}
}
}
}
exports.MemoryHandler = MemoryHandler;
This code only fetching all tab titles from the main window and child window, but not from all other new window's tabs which is opening using _blank attribute.
Note: we can easily recreate the issue just create an html page and use the below code:
Visit me
The page open using the "_blank" attribute is not coming under the tabs array.
Any help is appreciated.
Thanks in advance!!
We can get all the titles from all the window tabs by creating a custom array.
index.js
var memoryHandler = new MemoryHandler();
tabs.on('ready', function(tab) {
memoryHandler.addTabDetails({id: tab.id ,title: tab.title, url: tab.url});
});
If you want to get the title which is setting by using javascript after page load, you can inject a mutation observer code in the content script of tab
memory-handler.js
var presentTabs = []
function MemoryHandler() {
return {
addTabDetails: (tab_array) => {
presentTabs.push(tab_array);
}
}
}
exports.MemoryHandler = MemoryHandler;
I want open/show my panel widget by click on my context-menu item to send some data from the dom position click to my panel.
I'm open for lot of solutions !
I don't know if this works but try it out, its sdk style
var panels = require("sdk/panel");
var self = require("sdk/self");
var panel = panels.Panel({
contentURL: self.data.url("panel.html")
});
var cm = require("sdk/context-menu");
cm.Item({
label: "Edit Image",
context: cm.SelectorContext("img"),
contentScript: 'self.on("click", function () {' +
' self.postMessage(null);' +
'});',
onMessage: function (msg) {
panel.show({
//position: button //set position to some anchor
});
}
});
Helo, i try to develop a (my first) firefox add-on. It should show a panel at several defined url with some content. This works if i click on widget-symbol fine. Now i want, that the panel is displayed if the user loads the page.
panel.show(); displays the panel centered. I would like to map/anchor the panel to the widget, so that the panel ist displayed in the rigth bottom corner.
The solutions https://gist.github.com/azu/4413137 and Mozilla "Jetpack" Add-On: Anchor Panel to Widget did'nt work for me. (SDK 1.13.2 with Add-On Builder)
My code:
thePanel = panel.Panel({
width: 320,
height: 170,
contentScriptFile: [self.data.url('jquery.js'), self.data.url('panel.js')],
contentScriptWhen: "ready",
contentScript: "SOMESCRIPT",
contentURL: self.data.url('thecontent.html'),
onMessage: function (item) {
console.log('message : "' + item + '"');
tabs.open(item);
}
});
var widget = widgets.Widget({
id: "my-id",
label: ".de",
panel: thePanel,
contentURL: self.data.url("favicon.ico"),
onClick: function() {
/*blabla*/
}
});
tabs.on('ready', function(tab) {
check_content(); // loads thecontent.html for panel content
thePanel.show(); // Shows panel at center
});
Someone can help me?
thePanel = panel.Panel({
width: 320,
height: 170,
contentScriptFile: [self.data.url('jquery.js'), self.data.url('panel.js')],
contentScriptWhen: "ready",
contentScript: "SOMESCRIPT",
contentURL: self.data.url('thecontent.html'),
onMessage: function (item) {
console.log('message : "' + item + '"');
tabs.open(item);
}
});
var widget = widgets.Widget({
id: "my-id",
label: ".de",
//panel: thePanel,
contentURL: self.data.url("favicon.ico"),
onClick: function(view) {
/*This will work*/
view.panel = thePanel;
/*This will work*/
}
});
Instead of using panel.show(), use view.panel = thePanel;
I am designing a firefox extension, and I want to add a button near the address bar. And then I need to attach a bookmarklet to that button.
Someone can tell me what APIs do I have to use to create that button and to add the bookmarklet ?
Here's an example that uses Erik Vold's toolbarbutton library to add a button near the addressbar:
const data = require("self").data;
const tabs = require("tabs");
exports.main = function(options) {
var btn = require("toolbarbutton").ToolbarButton({
id: 'my-toolbar-button',
label: 'Add skull!',
image: data.url('skull-16.png'),
onCommand: function() {
if (typeof(tabs.activeTab._worker) == 'undefined') {
let worker = tabs.activeTab.attach({
contentScript: 'self.port.on("sayhello", function() { alert("Hello world!"); })'
});
tabs.activeTab._worker = worker;
}
tabs.activeTab._worker.port.emit("sayhello");
}
});
if (options.loadReason === "install") {
btn.moveTo({
toolbarID: "nav-bar",
forceMove: false // only move from palette
});
}
};
You can also see this as a runnable example on the Add-on Builder site:
https://builder.addons.mozilla.org/addon/1044724/latest/