Enabling application menu in a NW.js app for Mac OS - macos

I am using NW.js to create a standalone application for Mac OS X. The application launches fine, but the application menu (just to the right of the Apple menu) contains no items. I had understood that a default set of menus and menu items would be created, as shown in this screenshot, taken from Arvind Ravulavaru' tutorial.
Here are my bare-bones files:
index.html
<!DOCTYPE html>
<html>
<head>
<title>Hello World</title>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>
package.json
{
"name": "Hello World"
, "version": "0.0.1"
, "description": "Barebones NW.js app"
, "main": "index.html"
, "window": {
"toolbar": false
, "width": 800
, "height": 600
}
, "scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
, "author": ""
, "license": "MIT"
}
Here are my steps:
Select index.html and package.json and use Finder's File > Compress 2 items to create a ZIP file from them.
Rename this ZIP file app.nw
Download the 64-bit build of NW.js for Mac OS X
Unzip the downloaded file, to create a folder contain nwjs.app
Right-click on the nwjs.app and choose Show Package Contents from the contextual menu
Navigate to nwjs.app/Content/Resources
Place the app.nw file inside this Resources folder
Modify the file at nwjs.app/Content/Info.plist so that <key>CFBundleName</key> is associated with <string>Hello World</string>. (This defines the name of the application menu.)
Rename the nwjs.app as HelloWorld.app
Right-click on the HelloWorld.app and select Open from the contextual menu
Enter an admin username and password to allow the app to open
Click the Hello World application menu — nothing happens apart from a highlight
What do I need to do to get a functional application menu, with a Quit item to close the app?

A Google search for nwjs default menu mac led me to Dickson Tam's nwjs-osx-menu npm package.
My additional steps were:
In a Terminal window, cd to the folder containing the main index.html file
Run npm install nwjs-osx-menu. This adds (a node-modules folder containing) a folder named nwjs-osx-menu.
In a text editor, open the file nwjs-osx-menu/index.js
Change the line mb.createMacBuiltin('My App'); to mb.createMacBuiltin('Hello World');
Create a new ZIP, including the new nwjs-osx-menu folder
Rename the zip file as app.nw
Replace the existing file at HelloWorld.app/Content/Resources/app.nw with the new one
Launch the HelloWorld.app

Related

How can I log messages in content script of firefox extension?

I am new to Firefox extension (add-on) development. I'm injecting a content script through my sidebar code-behind using the browser.tabs.executeScript() API. And I run my extension using web-ext run command.
The problem is, my log doesn't appear in developer console and when I go to tools console, I can see the following error:
Error: Missing host permission for the tab
Mozilla defines a host permission as given through pattern matching of page URL. And of course adding the following to my manifest.json file fixes the issue:
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content-script.js"]
}
]
But I'd like to inject the content script on demand, not based on the page URL.
Another way is to send messages through API to my sidebar code-behind and then log it there in my extension console. But this requires a bit of implementation. On the other hand, It makes me wondering why shouldn't I be able to simply log a message to developer console through an injected script?
This is my code:
manifest.json:
{
"manifest_version": 2,
"name":"My Extension",
"version":"1.0",
"sidebar_action":{
"default_title": "My sidebar",
"default_panel": "sidebar/panel.html"
},
"permissions":[]
}
panel.js:
browser.tabs.executeScript({ file: "content-script.js" });
content-script.js:
console.log('first line of content script');
I found it. The term <all_urls> can be used as a permission:
"permissions":["<all_urls>"]
Then console.log() works within content script.
However, it is not recommended to include this permission: Avoid host permission "<all_urls>" if you can

Missing manifest.json when uploading Firefox Add-on to AMO

I'm unable to upload my firefox extension using the form provided by mozilla. I'm constantly getting the error Your add-on failed validation with 2 errors.
No install.rdf or manifest.json foundAdd-on missing manifest, which is very misleading because my application has a manifest.json.
The manifest.json looks like this:
{
"manifest_version": 2,
"version": 1.0,
"name": "my-extension-name",
"description": "Lorem ipsum dolor sit amet",
"background": {
"scripts": ["js/background.js"]
},
"main": "popup.js",
"browser_action": {
"default_icon": "img/icon_grey.png",
"default_popup": "popup.html",
"default_title": "loremipsum"
},
"engines": {
"firefox": ">=38.0a1"
},
"permissions": [
"activeTab",
"tabs",
"background",
"http://*/*",
"https://*/*",
"notifications",
"alarms",
"storage",
"webRequest",
"webRequestBlocking",
"clipboardRead"
]
}
What is missing for this to work?
I was running into the same problem but all of these instructions didn't solve it.
What i always did was to pack the whole folder, hence the manifest.json was not on the first level, when unpacked.
SOLUTION FOR ME
Select all files, instead of the folder, and then pack them as one .zip file and it should work. At least it did for me.
Here is a link to the MDN Documentation.
The very simple answer to this is that its unable to find the manifest in your zip file. This is caused because when you take a file and zip it using the default compressor in windows it takes the file and throws it into a sub folder of the zip file you created...
before compressing
folderYouWantCompressed
-FileInFolder.html
-Manifest.json
after compressing it will look like this
nameOfZip.zip
-folderYouWantCompressed
-FileInFolder.html
-Manifest.json
but what you want is
nameOfZip.zip
-FileInFolder.html
-Manifest.json
the reason Oliver Sauter answer works is because when you select all the files within the "folderYouWantCompressed" it compresses without the sub folder meaning you dont run into this problem and it has no problem finding the manifest file.
for what I can tell the "correct answer" seems to be signing the add-on itself and is able to get the manifest file properly, so it does work but just seems like a 3rd party way of doing it (I did not look into it too deeply)
Note: that I originally had my issue solved by looking at Oliver Sauter post I just wanted to make it clear for future people looking at this post.
When you open your addon package zip file, the manifest.json file should be visible to you in order to upload it on AMO.
In your case, it looks like when you open your package zip, there is a folder and inside that folder manifest.json is located.
As I have found a solution to my problem and would like to share it for future reference I answer my own question:
The issue at hand was that I did not use the web-ext command line tool to create the .zip / .xpi package. I was able to solve the problem by installing web-ext and using web-ext build to build the extension. The result of this operation is a .xpi file that contains the project which I was then able to upload to the AMO service. Note that the manifest.json in the newly created package is identical to the manifest.json I originally provided. However, in addition to the manifest.json a directory META-INF was created which contains a mozilla.mf, mozilla.rsa and mozilla.sf file.
This however, did not entirely solve my problem. After uploading the extension to AMO, it could not be installed and was said to be damaged. Apparently, which is what I read somewhere in the interwebz (and forgot the source), Mozilla opens the .zip / .xpi package that is uploaded to test it and since my package was not signed, Mozilla could not ensure its integrity and marked it as insecure (i.e. damaged).
In order to solve the second problem I had to sign the extension. This can be done using the following command:
web-ext sign --api-secret YOUR_API_SECTER --api-key YOUR_API_KEY
After this, I was able to upload and install the extension.
Got the same problem, the problem was thats the file name is case sensitive:
Manifest.jason -> error, no manifest found
manifest.json -> susscessful
my solution (in mac os):
zip a directory using zip in terminal command zip -r example.zip example instead of right-clicking files and clicking "Compress" in mac os

Programatically Get the Latest Version Number of Firefox

How can I parse the version number of Firefox programatically.
So, I don't have to visit the page every time.
All I would have to do is run the script, and it will give me the latest version.
http://download.cdn.mozilla.net/pub/mozilla.org/firefox/releases/latest/update/win32/en-US/
The file will always have ".complete.mar" in it. It's the only file with the word "complete" under this directory.
How can I parse the version "40.0.2" from it.
Download the latest release
The simple answer is Mozilla Release Engineering already provides a way to download the latest version. See https://ftp.mozilla.org/pub/firefox/releases/latest/README.txt
For example, I want to download the latest Linux 64-bit US English version of Firefox. So I would:
curl -Lo firefox.tar.bz2 'https://download.mozilla.org/?product=firefox-latest&os=linux64&lang=en-US'
tar -xjf firefox.tar.bz2
cd firefox
./firefox --version
Mind you those are stable releases and not RC or nightly. For those see release notes in the appropriate subfolder.
Notes:
The curl command URL is surrounded by single quotes (') to avoid bash interpreting the ampersands (&).
You would likely want to add your downloaded Firefox at the beginning of the $PATH (or %PATH% in Windows) environment variable.
Get latest release version number
To get the latest version number without downloading the archive you would use the HTTP HEAD method (curl -I option). Example,
curl -fI 'https://download.mozilla.org/?product=firefox-latest&os=linux64&lang=en-US' | grep -o 'firefox-[0-9.]\+[0-9]'
which will return something like firefox-67.0.4.
Because I have to know the lastest version numbers of many applications, I've created the online service called vergrabber which provides that information in json.
You may try this free service at http://vergrabber.kingu.pl/vergrabber.json
You are going to run into problems because the data you want to check is not within the same domain.
You can however using something like node webkit(now nwjs) to get pass the browser limitation.
To start download the nodewebkit files for your operating system from the following link:
http://nwjs.io/
Extract the contents.
Download JQuery and place it in the extracted folder(rename the file jquery.js).
create a new text file, add the following contents and save it as package.json
package.json contents:
{
"main": "index.html",
"name": "firefoxversion",
"version": "1",
"window": {
"title": "latest firefox version",
"icon": "link.png",
"toolbar": true,
"width": 800,
"height":600
}
}
Create a file name index.html and save the following contents:
index.html contents:
<html>
<head>
<title>Latest Firefox Version</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<div id="result"></div>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="main.js"></script>
</body>
</html>
Next create a file named main.js and save the following contents:
main.js contents:
var url ="http://download.cdn.mozilla.net/pub/mozilla.org/firefox/releases/latest/update/win32/en-US/";
var version;
$.get(url,function(data){//begin function
$(data).contents().find("a").each(function(){//begin each function
//create an array to hold the hmtl
var html = [];
if($(this).attr("href").indexOf("complete.mar" !== -1 )){//begin if then
version = $(this).attr("href").split(".c");
//start building your html to output
html.push("Download the latest Firefox Version " + version[0] + " below:<br>");
//add the download button
html.push("<input type ='button' id ='firefox-latest' value = 'Download Firefox'>");
//display the html in the #result div
$("#result").html(html.join(""));
}//end if then
});//end each function
});//end function
//on click event for #firefox-latest
$(document).on("click","#firefox-latest",function(){//begin on click event
//change the window location to the file for the latest firefox version
window.location.href = url + version[0] + ".complete.mar";
});//end on click event
Lastly click on the nw.exe icon inside of the folder you extracted earlier
and you should see the latest version number of firefox.

Sublime Automatically build New Build System

I have a js and html build system on sublime . I'd prefer not to have to switch my build system anytime I want to compile in those languages. Is there a way I can make the automatic build system choose html whenever the file has a .html suffix? Right now this is all I have in my html build system
"cmd": ["open", "-a", "Google Chrome", "$file"]
I'm running Mac OS 10.9.5. Thanks in advance for your help.
Change your build system to this:
{
"cmd": ["open", "-a", "Google Chrome", "$file"],
"selector": "text.html"
}
Next, go to Tools -> Build System and select Automatic. Now, whenever you're editing an HTML file, you can hit ⌘B and it will automatically use your HTML build system. You can read all about build systems here and here.

Using venkman in my xul application

I've tried to follow these steps to get venkman in my xul application:
Get Venkman from addons.mozilla.org To download the package, right-click the install link and save the package locally. (got the newest version).
Create a directory /distribution/bundles/venkman. Unzip the package into that directory.
Add <script src="chrome://venkman/content/venkman-overlay.js" /> to one of your XUL windows.
Add UI to open Venkman to your window (it could be a menu item or a toolbar button). Make it call start_venkman() when activated.
Not sure where to create the distribution directory, I've tried in the same directory as my application.ini in chrome and in chrome/content but when I try to include the script as in step 3 I get:
No chrome package registered for chrome://venkman/content/venkman-overlay.js
And step 4 gives me:
Error: ReferenceError: start_venkman is not defined
I start my application using the following command:
firefox.exe --app application.ini -jsconsole
Changed the BuildID in my application.ini a couple of times but that didn't change anything.
Created the directory: C:\Program Files (x86)\Mozilla Firefox\distribution\bundles and copied the venkman directory in there.
In my xul window I added:
<script src="test.js" />
<button label="Press Me"
oncommand="start_venkman();"/>
The content of test.js is:
function toOpenWindowByType(inType, uri) {
var winopts = "chrome,extrachrome,menubar,resizable,scrollbars,status,toolbar";
window.open(uri, "_blank", winopts);
}
When I click the button the Venkman window opens.

Resources