June 24, 2014

IDE hidden in Firefox nightly

Today I read interesting article on the Mozilla Hacks blog about new WebIDE and I have to say that on my low-cost netbook is this the first IDE targeted on mobile system that actually works and is usable on slower machines (including emulator of course).
Below is a screencast which I borrowed from the original article:



I must say that while Firefox maybe have not market-share as some time ago but still it is the perfect solution for the professionals.

June 23, 2014

TagsSidebar - new UI proposals

Currently I'm working on next version of TagsSidebar - besides I'm trying Mozilla Add-on SDK I also created new layout for the main view - here are the screenshots:


Default view


No details and no favicons


No details but with favicons


Full details but no favicons

Hopefully, you will like them :)

PS: While now I'm dealing with Add-on SDK I want to create blog post where I will compare add-on development using SDK and the old-school way - so stay tuned.

June 11, 2014

TagsSidebar 1.0

I just finished (and published on AMO) my new add-on TagsSidebar. It extends Mozilla Firefox with sidebar that allows easy and quick browsing your bookmarks by selecting tags that have attached.

Here are some important links:

And here goes few screenshots:

June 8, 2014

Creating sidebar add-on for the Firefox with Australis UI

I'm creating simple add-on for Mozilla Firefox and even I did such add-ons before I run into the troubles. It's because of new Firefox UI called Australis and because I want this add-on to be bootstrapped (so it doesn't require browser restart to complete the installation).
After a short googling I found CustomizableUI.jsm and I finally got the working solution.
So here is my bootstrap.js which adds the sidebar:

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const { classes: CC, interfaces: CI, utils: CU } = Components;
const self = {
    id: "tagssidebar@ondrejd.info",
    name: "TagsSidebar",
    path: {
        chrome: "chrome://tagssidebar/"
    }
};
const prefPrefix = "extensions." + self.id + ".";

CU.import("resource://gre/modules/Services.jsm");
CU.import("resource:///modules/CustomizableUI.jsm");

var gStylesSrv;
var gStylesURI;

// Bootstrap API: install(aData, aReason)
function install(aData, aReason) {
    if (aReason == ADDON_INSTALL) {
        // Set default preferences
        let prefs = Services.prefs.getBranch(prefPrefix);
        prefs.setBoolPref("showInSidebar", true);
        prefs.setBoolPref("showTagCloud", false);
        prefs.setBoolPref("showFavicons", false);
    }
} // end install(aData, aReason)

// Bootstrap API: uninstall(aData, aReason)
function uninstall(aData, aReason) {
    if (aReason == ADDON_UNINSTALL) {
        // Remove default preferences
        Services.prefs.deleteBranch(prefPrefix);
    }
} // end uninstall(aData, aReason)

// Bootstrap API: startup(aData, aReason)
function startup(aData, aReason) {
    // Create new toolbar button
    CustomizableUI.createWidget({
        id: "tagssidebar-toolbarbutton",
        defaultArea: CustomizableUI.AREA_NAVBAR,
        label: "TagsSidebar",
        tooltiptext: "Toggle visibility of TagsSidebar.",
        type: "button", 
        onBeforeCreated: function(aDocument) {
            // We need to add more UI than the toolbarbutton (broadcaster, key and menuitem):
            // Broadcaster
            let bcset = aDocument.getElementById("mainBroadcasterSet");
            if (bcset) {
                let bc = aDocument.createElementNS(XUL_NS, "broadcaster");
                bc.setAttribute("autoCheck", "false");
                bc.setAttribute("group", "sidebar");
                bc.setAttribute("id", "viewSidebar_tagssidebar");
                bc.setAttribute("oncommand", "toggleSidebar('viewSidebar_tagssidebar');");
                bc.setAttribute("sidebarurl", "chrome://tagssidebar/content/sidebar.xul");
                bc.setAttribute("sidebartitle", "TagsSidebar");
                bc.setAttribute("type", "checkbox");
                bcset.appendChild(bc);
            }
            // Key
            let keyset = aDocument.getElementById("mainKeyset");
            if (keyset) {
                let key = aDocument.createElementNS(XUL_NS, "key");
                key.setAttribute("command", "viewSidebar_tagssidebar");
                key.setAttribute("id", "key_openSidebar_tagssidebar");
                key.setAttribute("key", "t");
                key.setAttribute("modifiers", "accel,shift");
                keyset.appendChild(key);
            }
            // Menuitem
            let mp = aDocument.getElementById("viewSidebarMenu");
            if (mp) {
                let mi = aDocument.createElementNS(XUL_NS, "menuitem");
                mi.setAttribute("key", "key_openSidebar_tagssidebar");
                mi.setAttribute("label", "TagsSidebar");
                mi.setAttribute("observes", "viewSidebar_tagssidebar");
                mi.setAttribute("tooltiptext", "Toggle visibility of TagsSidebar!");
                mp.appendChild(mi);
            }
        },
        onCreated: function(aNode) {
            // Add ID of broadcaster we created before as a command:
            aNode.setAttribute("command", "viewSidebar_tagssidebar");
            return aNode;
        }
    });

    // Load stylesheet
    gStylesSrv = CC["@mozilla.org/content/style-sheet-service;1"].getService(CI.nsIStyleSheetService);
    gStylesURI = Services.io.newURI(self.path.chrome + "skin/overlay.css", null, null);
    gStylesSrv.loadAndRegisterSheet(gStylesURI, gStylesSrv.USER_SHEET); 
} // end startup(aData, aReason)

// Bootstrap API: shutdown(aData, aReason)
function shutdown(aData, aReason) {
    if (aReason == APP_SHUTDOWN) return;

    // Destroy our widget
    CustomizableUI.destroyWidget("tagssidebar-toolbarbutton");

    // Unload stylesheet
    if (gStylesSrv.sheetRegistered(gStylesURI, gStylesSrv.USER_SHEET)) {
        gStylesSrv.unregisterSheet(gStylesURI, gStylesSrv.USER_SHEET);
    }
} // end shutdown(aData, aReason)

May 27, 2014

24 Free programming books

Today I found interesting post on LinuxLinks.com - you can find here links to twenty four free books each for different programming languages:

May 20, 2014

Nice Bash find-and-replace script

It's some time when I read the post Scripting a 'Find-and-Replace' for big text files by Bob Mesibov. Yesterday I finally got some time to look at it and use it as a learning material. I must frankly admit that I would have real troubles to write something like this in Bash - usually I'm using PHP in such cases.
Because in the original post is only the image not the source of script self I saved it into one my repository so you can easily use it - fandr.sh.

April 16, 2014

WordPress: Anonymous PHP functions

Recently I wrote about my problem with WordPress editor and now I realize that I wanted to write also about something different - using anonymous functions in WordPress development - it's amazing how using of them can simplify your code (if you forget older PHP versions).

Compare these examples:

<?php
// Sets WordPress admin bar hidden.
// Old:
add_filter('show_admin_bar', '__return_false');
// New:
add_filter('show_admin_bar', function() { return false; });

// Activate widgets
// Old:
add_action('widgets_init',
     create_function('', 'return register_widget("Your_Widget_Class");')
);
// New:
add_action('widgets_init', function() {
    register_widget('Your_Widget_Class');
});

And of course that this can be used everywhere you're using function such add_action, add_filter etc.







April 15, 2014

WordPress: Custom font family in TinyMCE editor

I tried to add custom font family to the WordPress editor but it turns to the little battle - firstly I just do what is described in the WordPress Codex:

your-theme/functions.php:
<?php
function your_theme_editor_styles() {
    add_editor_style('assets/css/editor-style.css');
}
add_action('init', 'your_theme_editor_styles');
?>

your-theme/assets/css/editor-style.css:
@font-face {
    font-family: CharisSILBold;
    src: url(../fonts/CharisSIL-Bold.woff);
}

body#tinymce.wp-editor { 
    font-family: CharisSILBold; 
    font-size: 14pt;
}

But it doesn't work (of course). Then I look into the default theme and found the solution (code in functions.php is the same as before so here only editor-style.css):

your-theme/assets/css/editor-style.css:
@font-face {
    font-family: CharisSILBold;
    src: url(../fonts/CharisSIL-Bold.woff);
}

html .mceContentBody { 
    font-family: CharisSILBold;
    font-size: 14pt;
}

It sucks that small things take so much time (but of course it's my fault).

Tested on WP 3.8.*.



April 11, 2014

Firefox OS 2.0 Screenshots

Today I found screenshots of design proposals for Firefox OS 2.0. I must say that I like it a lot - especially the calendar screen:

I think the time to throw all iPhones etc. will be here soon :) . You can see more screenshots here (original post by Sören Hentzschel).

March 10, 2014

Mozilla Brick - UI Components for Modern Web Apps

I just discovered Mozilla Brick - a bundle of reusable UI components for rapid development of cross-browser and mobile-friendly HTML5 applications. What is interesting is made using X-Tag which JavaScript library that provide the same as old and powerful XBL.
Hopefully I will get opportunity to try it on same real project soon.