選択文字をフォーマットに沿って展開するマクロ

現時点では繰り返し展開のみ実装しています。
例) ★{10}☆ → ★★★★★★★★★★☆

//SimpleExtend.jsee
var parseTarget = document.selection.Text;
if(parseTarget.match('^(.+)\{(\\d+)\}(.*)$') != null){
	var str = RegExp.$1;
	var cnt = RegExp.$2;
	var footer = RegExp.$3;
	
	var ret = "";
	for(var i=0;i<cnt;i++){
		ret += str;
	}
	ret += footer;
	
	document.selection.Text = ret;
}

AngularJS - IEではエレメントのstyle属性に定義したバインド式({{..}})が動作しない??

ChromeとIE11でしか確認していません。
IEでは、スタイル属性のなかでは バインド式が動きませんでした。
ちなみに、data-*属性のなかでは動作し、値が展開されました。

下記コードのisLimitOver()が呼び出しされないのです。。

<li ng-repeat="item in items"
    data-task-id="{{item.id}}"
    data-task-limit="{{item.limit}}"
    data-task-finished="{{item.finished}}">
    <p ng-click="showDetail($index)">
        <input type="checkbox" style="margin-right:30px;" value="{{item.finished}}" />
        <span style="{{ isLimitOver(item.limit) ? 'color:red' : 'color:black' }}">{{item.title}}</span>
    </p>
</li>

AngularJS + jQuery + jQueryUI(ダイアログ) を試してみた

なんとなくTodoアプリを作ってみました。
実際に動くものは ここ で確認できます。

独自ディレクティブについて。
リファクタリングすれば多少はきれいになるとは思いますが、
凝ったことをやろうと思うと結構考えないと、すぐにぐちゃぐちゃになりそうですね。
あと、サービスと同様な感じで分離させれないかなぁ考えています。
今回みたいにcompileでスコープ取得したい場合の公式なやり方が見つけれなくて
独自に実装した(_target変数使ってるところ)んですけど、標準的なやり方ってどんなんでしょう?

地味に詰まったのが、ラジオボタンのON/OFF設定。attr()じゃなくてprop()を使うんですね。。


テンプレート

見た目まんまhtmlです。これがAngularJSによってコンパイルされ、ビューとなります。
独自ディレクティブを作成する必要はありますが、jQueryを使うこともできます。今回はjQueryUIのダイアログを使用しています。

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>タスク管理</title>
	<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.0.min.js"></script>
	<script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.10.3/jquery-ui.min.js"></script>
	<link rel="stylesheet" href="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.10.3/themes/smoothness/jquery-ui.css" />
	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js"></script>
	<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular-route.min.js"></script>
	<script src="http://underscorejs.org/underscore-min.js"></script>
	<script src="services.js"></script>
	<script src="app.js"></script>
	<style>
		li:hover{
			background : #CEF2F5;
			cursor : pointer;
		}
		.todo-item-finished{
			color : green;
		}
		.todo-item-working{
			color : red;
		}
	</style>
</head>
<body ng-app="app">
	<div ng-controller="todoCtrl">
		<form name="form1">
			<p>【新規登録】</p>
			<input type="text" name="newTitle" ng-model="newTitle" ng-init="" required></input>
			<button ng-click="addNewTask()" ng-disabled="form1.$invalid">追加</button>
		</form>
		<div style="margin-top:50px;">
			<p>【タスク一覧】</p>
			<ul style="padding-left:5px;list-style-type:none;">
				<li ng-repeat="item in items" style="hover: background:red;">
					<p todo-editable class="todo-item-{{item.finished ? 'finished' : 'working'}}">{{item.id}} - {{item.title}} / {{item.finished ? '完了' : '未完了'}}</p>
				</li>
			</ul>
		</div>
	</div>
	<div id="dialog-form" title="タスクの編集">
		<p><input type="text" name="title" /></p>
		<p><input type="radio" name="status" id="task-finished" value="true">完了</input>
		<input type="radio" name="status" id="task-working" value="false">未完了</input></p>
	</div>
</body>
</html>

サービス

var services = {};

(function(){
	/**
	* Todoサービス
	*/
	services.TodoService = (function(){
		var Todo = function(){
			this._items = [
				{id : 1, title : "タスク1", finished : false},
				{id : 2, title : "タスク2", finished : true},
				{id : 3, title : "タスク3", finished : false},
				{id : 4, title : "タスク4", finished : true},
				{id : 5, title : "タスク5", finished : false}
			];
		};

		Todo.prototype.getAll = function(){
			return this._items;
		};

		var _add = function(title){
			this._items.push({
				id : this._items.length+1,
				title : title,
				finished : false
			});
		};
		
		var _update = function(item){
			var updateTgt = _.find(this._items, function(i){ return i.id === item.id;});
			if(updateTgt === undefined){
				_add.call(this, item.title);
			}else{
				updateTgt.title = item.title;
				updateTgt.finished = item.finished;
			}
		};

		Todo.prototype.update = function(item){
			_.isString(item) ? _add.call(this, item) : _update.call(this, item);
		};

		Todo.prototype.delete = function(item){
			//todo:実装
		};
		
		return Todo;
	})();
	
	
	/**
	* 非同期Todoサービス
	*/
	services.AsyncTodoService = (function(){
		
		//memo:定義場所について。
		//このサービスはAngularJSの$timeoutサービスに依存している。
		//ファクトリの登録関数内で定義するのが正解かもしれない。
		
		var AsyncTodo = function($timeout){
			this.$timeout = $timeout || function(action){action()};
			this.todo = new services.TodoService();
		};
		
		AsyncTodo.prototype.getAll = function(){
			return this.todo.getAll();
		};

		var _applyCurrying = function(me, fnc){
			return function(){
				return fnc.apply(me, arguments);
			}
		};

		AsyncTodo.prototype.update = function(item){
			var updAction = _applyCurrying(this.todo, this.todo.update);
			this.$timeout(function(){
				updAction(item);
			}, 1000);
		};

		AsyncTodo.prototype.delete = function(item){
			var delAction = _applyCurrying(this.todo, this.todo.delete);
			this.$timeout(function(){
				delAction(item);
			}, 2000);
		};
		
		return AsyncTodo;
	})();
	
})();

コントローラーと独自ディレクティブ

todoCtrlコントローラーとサービス登録、todoEditableディレクティブの定義を行います。

(function(){
	//AngularJSの1.2以降はngRouteのインストール?を明示的に指定する必要がある。
	//http://docs.angularjs.org/error/$injector/modulerr?p0=app&p1=Error:%20%5B$injector:nomod
	var ngtodoApp = angular.module("app",["ngRoute"]);

	ngtodoApp.factory("Todo", ["$timeout", function($timeout){
		return new services.AsyncTodoService($timeout);
	}]);
	
	ngtodoApp.controller("todoCtrl", ["$scope", "Todo", function($scope, todo){
		$scope.items = todo.getAll();
		$scope.addNewTask = function(){
			todo.update($scope.newTitle);
			alert("登録しました。");
			$scope.newTitle = "";
		};
	}]);
	
	//以下は http://angularjsninja.com/blog/2013/11/22/angularjs-custom-directives/ より抜粋
	//
	//■compile と link の使い分け
	//compileの function はng-repeatの繰り返しに関係なく一度だけ呼び出されるのに対し、linkの function はイテレーションのたびに呼び出されることになる。
	//compileとlinkの両方を指定した場合にはlinkが無視される仕様になっているため、両方を利用した実装をしたい場合にはcompilefunction からlinkfunction を return するよう実装することになる。
	//
	//
	//■いろいろある link の書き方
	//単にfunctionを return するだけという書き方ができて、これはlinkプロパティだけを持つオブジェクトを返しているのと同じことになる。link以外のプロパティを指定する必要が無ければ、こう書くことでシンプルなコードにできる。
	//
	//  ngtodoApp.directive("listRow", function(){
	//  	return function(scope, element, attrs){
	//  		...
	//  	};
	//  });
	//
	ngtodoApp.directive("todoEditable", ["Todo", function(todo){
		
		var _target = (function(){
			
			function Target(){
				this.scope = {};
			}
			
			Target.prototype.clear = function(){
				this.scope = undefined;
				this.scope = { $index : -1 };  //ダミースコープオブジェクトのセット
			};
			
			var tgtObj = new Target();
			tgtObj.clear();
			return tgtObj;
		})();
		
		return {
			restrict: 'A',
			compile : function(element, attrs){
				var okClick = function(){
					var dialog = $("#dialog-form");
					var title = $("input[name='title']",dialog).val();
					var finished = $("input[type='radio']:eq(0)",dialog).prop("checked");
					
					if(_.isEmpty(title)){
						alert("タイトルが未入力です");
						return;
					}
					
					todo.update({
						id : _target.scope.item.id,
						title : title,
						finished : finished
					});
					
					$(this).dialog("close");
					_target.clear();
				};
				
				var cancelClick = function(){
					$(this).dialog("close");
					_target.clear();
				};
				
				$("#dialog-form").dialog({
					autoOpen: false,
					height: 280,
					width: 350,
					modal: true,
					buttons: [
						{
							text: "OK",
							click : okClick
						},
						{
							text: "Cancel",
							click : cancelClick
						}
					]
				});
				
				return function(scope, element, attrs){
					$(element).click(function(){
						_target.scope = scope;
						var dialog = $("#dialog-form");
						$("input[name='title']", dialog).val(scope.item.title);
						
						if(scope.item.finished)
							$("#task-finished", dialog).prop("checked", true);
						else
							$("#task-working", dialog).prop("checked", true);
						
						dialog.dialog("open");
					});
				};
			}
		};
	}]);
})();

ASP.NET WebForms で非同期処理を行う (.net4.5)

WebPageではasync/awaitをそのまま使うことができません。
利用するには以下の手順を踏みます。

1,Web.config設定

/configuration/appSettingsに、key=UseTaskFriendlySynchronizationContextな項目を追加。
詳細は下記を参照。

<configuration>
  ....
  <appSettings>
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
    ....
  </appSettings>
  ....
</configuration>

2,aspxファイルのページディレクティブ設定

末尾の「Async="true"」を追加する。コード例は下記を参照。

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm.aspx.cs" Inherits="Sample.WebForm" Async="true" %>

3,RegisterAsyncTaskメソッドに非同期タスク登録

Page.RegisterAsyncTask()に非同期なタスクを登録する。コード例は下記を参照。
登録タスクを実行するには、Page.ExecuteRegisteredAsyncTasks()を明示的に呼び出す必要あり。
未実行タスクはPreRenderイベントとPreRenderCompleteイベントの間で実行される。

protected override void OnLoad(EventArgs e)
{
    ....
    RegisterAsyncTask(new PageAsyncTask(async () =>
    {
        var httpClient = new System.Net.Http.HttpClient();
        var res = await httpClient.GetAsync("http://localhost/Hogege");
        ....
    }));
    ....
}

2階層以上のプロトタイプチェーンについて

「prototypeオブジェクトにベースオブジェクトインスタンスを設定したら、多重継承ってどうやるんだ??ベースクラスを設定したらサブクラスのprototype書き換えられないじゃん???」
という考えから抜け出せられず、また継承使わずとも十分実装できることもあり、
prototypeとは深くかかわらないようにしてたのですが、今回ようやくスッキリすることができました。


確認用コード

var BaseHoge = (function(){
    function BaseHoge() {
      this.hoge = "ベースオブジェクト";
    }
  BaseHoge.prototype.getHoge = function(){
      return this.hoge;
  };
  BaseHoge.prototype.setHoge = function(val){
    this.hoge = val;
  };
  return BaseHoge;
})();

var SubFoo = (function(){
  function SubFoo() {
      this.foo = "サブオブジェクト"; 
  }
  SubFoo.prototype = new BaseHoge.prototype.constructor();
  SubFoo.prototype.constructor = SubFoo;
  SubFoo.prototype.getFoo = function(){
      return this.foo;
  };
  
  return SubFoo;
})();

var SubSubBar = (function(){
  function SubSubBar() {
      this.bar = "サブサブオブジェクト"; 
  }
  
  //BaseHogeインスタンスオブジェクトを
  //prototypeプロパティにセットする。下記構成になる。
  //※コードの通り、prototypeオブジェクトの中身が
  //SubFooインスタンスオブジェクトになるだけ。
  //
  //  prototype {
  //    foo : "サブオブジェクト",
  //    constructor : SubFoo,
  //    __proto__ : SubFoo.prototype
  //  }
  //
  SubSubBar.prototype = new SubFoo.prototype.constructor();
  
  //コンストラクタプロパティを時オブジェクトに書き換える
  //これを行わないと、外からオブジェクトタイプを調べたりすることができなくなってしまう。
  //変更後は、下記構成になる。
  //
  //  prototype {
  //    foo : "サブオブジェクト",
  //    constructor : SubSubBar,
  //    __proto__ : SubFoo.prototype
  //  }
  //
  SubSubBar.prototype.constructor = SubSubBar;
  
  //自オブジェクトに持たせる関数の定義
  SubSubBar.prototype.getBar = function(){
      return this.bar;
  };
  
  //最終的にはこんな感じ。
  //constructorが指す関数と、暗黙リンク(__proto__)が
  //指す関数が異なる構成だけど、問題なく動作する。
  //prototypeオブジェクトも他オブジェクトとなんら変わりない普通の
  //オブジェクトで、プロトタイプチェーンに必要なプロパティを持っていれば
  //どんなオブジェクトでも動作する。
  //
  //  prototype {
  //    foo : "サブオブジェクト",
  //    getFoo : function(){ ... },
  //    constructor : SubSubBar,
  //    __proto__ : SubFoo.prototype
  //  }
  //
  return SubSubBar;
})();

console.clear();

//インスタンスオブジェクトの中身はこんな感じ
//{
//  bar : "サブサブオブジェクト",
//  prototype : {
//    foo : "サブオブジェクト"
//    getFoo : function(){ ... },
//    constructor : SubSubBar,
//    __proto__ : SubFoo.prototype
//  },
//  constructor : SubSubBar,
//  __proto__ : SubSubBar.prototype
//}
//
var obj = new SubSubBar();
console.dir(obj);

//obj.__proto__.__proto__.__proto__.setHoge()を実行する。
//実行後のオブジェクトの中身は以下な感じ。
//
//{
//  bar : "サブサブオブジェクト",
//  hoge : "ほげ~",
//  prototype : { ... }
//  constructor : SubSubBar,
//  __proto__ : SubSubBar.prototype
//}
//
obj.setHoge("ほげ~");

//メソッド場所の検索、処理フローはsetHoge()と同様。
console.log("getHoge() : ", obj.getHoge());

Edit fiddle - JSFiddle

参考書籍

開眼!  JavaScript ―言語仕様から学ぶJavaScriptの本質

開眼! JavaScript ―言語仕様から学ぶJavaScriptの本質

これに全部載ってます。

関数デコレーターの動作

処理フロー

  1. 実行時、インタプリタがデコレーター割り付けを見つけると、直ちにそのデコレーター関数を呼び出す。関数の戻り値は関数オブジェクト(呼び出し可能:callable)であること。
  2. デコられた(被デコ)関数(例ではhello/hello2)を呼び出したときの動きとしては以下のようになる。
    1. 手順1の戻り値関数(例ではlambda/inner)を呼び出す。このときの第一パラメーターに被デコ関数オブジェクトを渡す。
    2. 手順2-2の戻り値関数(例ではhello/hello2)を呼び出す。

割り付けが見つかった時点でデコレーター関数が呼び出される。
「被デコ関数呼び出し直前にデコレーターを呼びだしたい!」という場合は
デコレーター割り付けを内包する関数を定義するのがよろしいかと思われる。

コード例

def mydecorator():
	print("this is decorator!!")
	return lambda f : f

def mydecorator2(num):
	def inner(func):
		for i in range(int(num)):
			print("this is innerdeco!!!!")
		return func
	return inner

#パラメーターなしデコレーター
@mydecorator()
def hello(name):
	print("hello, ",name)

#パラメーター付きデコレーター
@mydecorator2(3)
def hello2(name):
	print("hello, ",name)

#デコレーター割り付けを内包する関数
def call_hello(name):
	@mydecorator()
	def hello3(name):
		print("hello, ", name)
	hello3(name)

if __name__ == "__main__":
	hello2("john")
	call_hello("tom")

Ubuntu12.4.1 + Python3 + Bottle + Jinja2 の組み合わせ

少しハマったのでメモ。
Ubuntuのapt-getでインストールできるPython3系は3.2なのですが、
これだとJinja2が動かないようです。

Jinja 2.7 brings experimental support for Python >=3.3.
Introduction — Jinja2 2.8-dev documentation

ソースをビルドしてインストールする必要があります。
次のページを参照しました。
Ubuntu12.04にPython3.3をインストール - Qiita [キータ]