Dynamically Adding VS Menu Item

We can extend VS by using VS SDK. It provides a way to add a menu and menu items. When we do that, we may need to solvee cases where we only determine the menu items at run time. That requires us to dynamically add menu items. Luckily, there's a document and example in MSDN about how to do that (http://msdn.microsoft.com/en-us/library/bb166492.aspx). The approach seems straightforward. However, when I tried that out, I fell in a tricky trap, in my opinion. That took me a few days to figure out. So I want to write it down.

Let me summarize the approach:

1. Create a place holder menu item in the .vsct file. This menu item must have the CommandFlag DynamicVisibility. Other than that, it is similar to other menu items in the .vsct file. It is in a group and a menu, and it has its own guid and id.

2. Create a menu command class that inherits from OleMenuCommand. Override method DynamicItemMatch.
The place holder menu item is always a valid menu item. Then DynamicItemMatch is called for each consecutive id until it returns false.

3.  Add BeforeQueryStatus and other handlers for your menu items.
You can set status, text and other properties of the menu item in BeforeQueryStatus handler.

Here are my lessons.

1. The place holder menu item is always a valid .vsct menu item and shown in the menu, because it's declared in the .vsct file. DynamicItemMatch doesn't really determine it's validity. If you return false in this method, the framework just doesn't query for next id.

2. Be cautious of the id of the place holder menu item and the number of menu items you want to create. You don't want the ids of dynamically created menu items to overlap any one you use for other menu items. It can be out of control especially when you have multiple areas that you want to dynamically add menu item, and all of them are in the same menu and group.

3. DynamicItemMatch is just a way to let the framework know when to stop querying for dynamically generated menu items. You still need to set the right status and text for the generated menu item in BeforeQueryStatus handler.

4. We cannot rely on MatchedCommandId to identify a dynamically created menu item.

In the example in the MSDN document, MatchedCommandId is set to the command id if it's a match. In BeforeQueryStatus, it's used to identify a menu item and gets reset afterwards. But it's not used in the invoke handler. I didn't understand that at first. I didn't reset MatchedCommandId in BeforeQueryStatus handler, and use MatchedCommandId in the invoke handler. And when I click the first menu item, it's actually invoked on the last generated menu item. After a few debugging, I realized that all those dynamically generated menu items and the place holder menu item are actually the same instance. That means, the framework creates an instance of OleMenuCommand for the place holder menu item, and calls DynamicItemMatchBeforeQueryStatus handler and other handlers on the same instance. Once you set a property of that instance, it remains there. For example, MatchedCommandId will keep the last assigned value. Don't need to worry that dynamically generated menu items get weird text. It'll always call BeforeQueryStatus handler before setting the text or other status. Thus you always have a chance to set it to the right value for that particular menu item in the BeforeQueryStatus handler.

The approach in Visual Studio 2012 (https://msdn.microsoft.com/en-us/library/Bb166492%28v=vs.110%29.aspx) creates an instance for the place holder menu item, as well as an instance for each generated menu item. However, I believe that's not the right approach.

1. The framework still calls DynamicItemMatch of all the created instances to determine whether it should query for the next id.

2. The document of DynamicItemMatch indicates that it's used in the case where we dynamically add menu item. The approach in Visual Studio 2012 doesn't use it at all.

The above are what I learned. And since I have a data structure to represent the menu item, I don't need to use MatchedCommandId. I am not quite sure yet the usage of it. But at least, the Visual Studio 2015 approach still works and you should try to debug it if you see any problems.

Use Grunt to Develop a Web Application

Sstart web development recently and use Grunt to run tasks automatically. Once the the configuration file Gruntfile.js is set up, everything will run smoothly. It's straightforward to get started. And there're plenty of plugins that just make life much easier. I'm using jshint, htmlhint, less, watch. They're providing grunt task and you can use them out of box. Besides these plugins, you can also use any npm modules as you use them in your regular JavaScript file. I don't plan to repeat the setup of Grunt and the tasks I list above. I'm going to write down some changes I make to meet my requirements, as well as something that is worth noting.

1. Only compile changed files.

This is done by the task watch and there's an example here https://github.com/gruntjs/grunt-contrib-watch.

var changedFiles = Object.create(null);
var onChange = grunt.util._.debounce(function() {
    grunt.config('jshint.all.src', Object.keys(changedFiles));
    changedFiles = Object.create(null);
}, 200);
grunt.event.on('watch', function(action, filepath) {
    changedFiles[filepath] = action;
    onChange();
});

It only checks changes in JavaScript files. Below are the problems I need to solve.

1. Watch changes on other files.

2. Handle the case when a file is deleted.

Let's first look at the parameters that are passed to the event handler for watch. they're action, filepath and target. The parameter target is listed in the above example. It's the target in the task watch which will execute when the file filepath is changed. And the action is "added", "changed", "deleted". And below is the solution I used for solving the above problem.

1. Record the target.
Use a dictionary of a target to a list of changed files instead of the other way as in the example. That is:

grunt.event.on('watch', function(action, filepath, target) {
    var filesForTarget = changedFilesForTargets[target];

    if (filesForTarget === undefined || filesForTarget === null) {
        filesForTarget = [];
        changedFilesForTargets[target] = filesForTarget;
    }

    filesForTarget.push(filepath);
}

Then in onChange, I iterate through the keys in changedFilesForChanges, and then change the corresponding task/target's file paths.

var targets = Object.keys(changedFilesForTargets);
for (var i = 0; i < targets.length; ++i) {
    switch (targets[i]) {
    case 'target1':
       // similar to the example.
    break;
    // more targets.
    }
}

Note the target name here is the target you set in the task watch.
That's done for adding/changing any file.
2. Handle the action "deleted".
I have all source files (js, less, html) in one folder (let's say src/). And need to compile and copy the result files to another folder (let's say build/). When I delete a file in src/, I also want to delete it from build/. When the action is "deleted", I add the file path to a different list. And in onChange(), I compute the path in build/ and delete the file there. I use fs.unlinkSync() to delete a file. fs is an internal module in node.js

2. File path separator

I want to have it work cross platform. And I want to only copy the changed files from source folder to destination folder. I also need to copy files in other scenarios. So I need to build my own path. I found some cases where separators are mixed on Windows. '/', '\' are used in the same path. I ended up using a node.js internal module path to build the path.

3. Work on cygwin

This may be the trickiest one. I used to run grunt watch in cygwin. When I deleted a file, the watch task didn't start. I tried to debug a couple times and didn't understand it. But when I tried the node.js environment using Windows console. It picked up the deleted changes. So I just used the Windows command line now.

4. Log and debug

I log verbose message with grunt.verbose.writeln() and run commands with option "--verbose" to see more information.

I'm glad I found a task grunt-debug-task. After installed, I can run "grunt debug task:target" to start debugging. It requires node-inspector to run. It will start the Chrome browser and you can debugger your Gruntfile.js like a client side JavaScript file.

The above are what I do and what I learn during my project. It's always good to practice to learn. Grunt is working as expected in my project. Next will be to make it work with cordova and require.js optimization.

Experience and Lessons of Ember.js

The best way to learn is to practice. So I made a small component with Ember.js.
This component is a tree grid. It's a grid, and it acts like a tree too. It presents a tree in a grid. Each node in the tree is a row in the grid. So node and row are used interchangeable. There is a parent-children relationship between rows. All children rows are displayed under their parent row. These children rows are indented. There are operations on rows too. You can choose to show or hide their children rows.
I'm not going to write an Ember.js tutorial. You can find good ones online, for example, http://code.tutsplus.com/tutorials/ember-components-a-deep-dive--net-35551 and http://coding.smashingmagazine.com/2013/11/07/an-in-depth-introduction-to-ember-js/#what_is_handlebars_template_precompiling. I'm not going through all details of how I made it. You can read the code and history from Github https://github.com/kceiw/treegrid-emberjs. The purpose of this blog is to share the lessons I learned, something that are not obvious or I didn't pay attention to it at the beginning. You may have a much better idea of how to make it and how to use ember.js. But as I began, I made these mistakes.
1. User .get('propertyName') instead of .propertyName.
Accessing to properties directly will give you undefined. e.g. ArrayProxy.length is undefined. You have to use ArrayProxy.get('length') or ArrayProxy.set('length');
It confused me at first, especially when I looked at the API. There is length in ArrayProxy. How come it's undefined. But later I realized that I needed to use get() to get property values. It's documented in the official guide. But I didn't think too much of it at the beginning. I think this is weird to some extent that properties are not accessible directly.
2. Set tagName in view/component.
If it's not set, the default value <div> will be used. Everything in the template is wrapped in the tagName. I think it's always a good idea to set a tagName in view/component because <div> is not always the correct one.

I didn't set tagName in TreeGridRowComponent. Since it's used to show each row in a table, so I had <tr> in the template. This should be in <tbody>. Ember.js wraps the template in <div>. The Html is supposed to be <tbody><div><tr>...</tr></div></tbody>. But for some reason Firefox rearranges it to <div></div><tbody><tr>...</tr></tbody>. It looked fine at the beginning. But when I tried to update the row, it failed. What happened was that Ember.js looked up the target element from <div> element. <tr> was't a descendant of <div> any more. Ember.js failed to find the element and it didttn't do anything.

3. classNameBindings value is an array of string. Each string is a class name or expression to determine the class name. It's in the form ['property1:style1:style2', 'property2:style3:style4'].
You should read this API.
The view API:
4. Css icon
This page http://www.dynamicdrive.com/style/csslibrary/item/css_triangle_arrow_divs/ explains how it works. Didn't know it before.
Don't need to set both height and width to 0 though.
They'll affect the perceivable width and height.
In my tree grid, I shown the down arrow when the row is expanded and right arrow the the row is collapsed. I used to set both height and width to 0. When I expanded and collapsed, I noticed that the height of the row changed too. So I just set only one of them to zero and the other was the size that the icon should be.
5. Keyboard focus
Focus is always the prerequisite of keyboard events. There is a way to set the focus to the tree grid in initialization.
6 Only one action
One thing I like to be in Ember.js is to support multiple actions. Each component can only send one action now.
There are a few things worth writing down in the end.
There are a few confusions such as render and component and view. There are no clear guidelines when/how to use them.
Action is a good concept to handle semantic events. But it has the limitation that one component/controller can only send one action.
Css icon is an interesting way to draw simple icons. I'm not clear the performance v.s. image icon.

Universe Model

When I talked to one guy in a meetup months ago, this thought stroke me.

The topic turned to be robot, human, life, and then the universe.

Some thoughts are summarized below.
Let's start with the human. There are two possibilities about its origin:
1. It's related to alien. Either it's created by an alien or it's offspring of an alien.
Then what's the origin of the alien?
2. It's evolving from life on the earth.
From what life it evolved from? How did the life come out at the very beginning.

Once we have the answer. we can ask again: where is that from? If we keep probing and tracing back, we will need to figure out why there was Big Bang or we'll find something that is far astonishing. In my opinion, both findings are about the origin of the universe.

There is one less difficult question: what is life. We already have a definition...... But is every object, for example, stone, sand, etc, a form of life? From our definition, No. But that's just our definition.

Then it comes a model.
Assuming we can develop a complex system in computer. In this system, some programs can modify (evolve) itself. They can probe the system where they're. They can give definitions to what they "observe". Doesn't that sound like an intellectual life? Then we only need to figure out a way to observe that those programs have the abilities of doing these.

Maybe we're living in such a system. It's not necessarily be a computer in somewhere though.

Setting up PPTPD on Linux

I used to have a VPN on Linux. It is running PPTPD on CentOS 5  on a OpenVZ. It used to work fine but last week I found it didn't work any more. I checked the configuration and the iptables and didn't find anything wrong. I also contacted the VPS vendor and couldn't solve this issue. At last I reinstalled the OS and start everything from scratch. When I went on to the setting of the new server, I found the possible reasons why it didn't work before.

I first set up the PPTPD with the standard step, similar to this link. And I connected to it from my iPhone and it worked. What it didn't work is to open web pages and ping to external IPs didn't work either. I sent an email to the vendor asking them to look into the iptables issues and I went on other settings. I add "ALL:ALL" to /etc/hosts.deny and "sshd:ALL" to /etc/hosts.allow. I changed the pam (/etc/pam.d/system-auth). I also modified iptables in aim of making it more secure. After doing this, I found that it didn't work again. It just looks like what I had encountered. I looked at the log. There was only message when PPTPD started. Nothing else is there. I believed some of the settings failed it. Then I rolled back the settings and it worked. I made the one change at a time and tested if everything is fine. And I found:
1. "ALL:ALL" in /etc/hosts.deny fails PPTPD. I believes it is also the reason why I couldn't connect and had to reinstall the OS. And I added a line "pptpd:ALL" to /etc/hosts.allow and it worked.
2. pam may also failed the authentication. I made the change according to this link. And the iPhone failed to connect to the vpn. I also looked at the log. It showed that PPTPD received requests.
3. the name of network card. The name should be venet0. But I used eth0 in all iptables settings. And that is why I couldn't open web pages or ping to any IPs.