1 /*!SIE under the MIT Lisence
\r
3 /*! Copyright 2016 dhrname and other contributors
\r
4 * http://sie.osdn.jp/
\r
6 * Permission is hereby granted, free of charge, to any person obtaining
\r
7 * a copy of this software and associated documentation files (the
\r
8 * "Software"), to deal in the Software without restriction, including
\r
9 * without limitation the rights to use, copy, modify, merge, publish,
\r
10 * distribute, sublicense, and/or sell copies of the Software, and to
\r
11 * permit persons to whom the Software is furnished to do so, subject to
\r
12 * the following conditions:
\r
14 * The above copyright notice and this permission notice shall be
\r
15 * included in all copies or substantial portions of the Software.
\r
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\r
21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\r
22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\r
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
29 /*本体オブジェクト。base関数の裏に隠蔽されている*/
\r
32 /*_base.objはbase関数やupメソッドで呼び出されるオブジェクトの始祖となるオブジェクト*/
\r
35 * 自身をプロトタイプとして、新たにオブジェクトを生成する
\r
37 up: function(name) {
\r
38 var s = Object.create(this);
\r
50 * 別のオブジェクトと合成ができるメソッド
\r
52 mix: function(obj) {
\r
54 throw new Error("No arguments error");
\r
56 if (typeof obj !== "function") {
\r
57 var alias = _base.__ng_;
\r
58 for (var i in obj) {
\r
60 /*hasOwnPropertyメソッドを使わないのは、プロトタイプチェーンをたどるようにするため
\r
61 *なお、Object.prototypeのプロパティなどは外した方がエラーがおきにくい
\r
68 obj.call(this, this);
\r
75 * 指定した名前nameのメソッドが呼び出された場合、便乗して指定関数funcをメソッドとして実行することができる
\r
77 on: function(name, func) {
\r
79 throw new Error("No arguments error");
\r
80 } else if (/^(?:up|on|mix|of)$/.test(name)) {
\r
81 throw new Error("Invalid method name error");
\r
82 } else if (typeof func !== "function") {
\r
83 throw new Error("Not support arguments type");
\r
85 var tev = this._eventList__,
\r
87 if (!this._eventList__) {
\r
88 tev = this._eventList__ = [];
\r
89 } else if (!this.hasOwnProperty("_eventList__")) { //祖先がすでにonメソッドを呼び出していれば
\r
92 tev = this._eventList__ = s;
\r
95 if (!this[name] || !tn.isOn) { //まだ、onメソッドが呼び出されていなければ
\r
96 /*nameで指定されたメソッドの初期化*/
\r
97 if (typeof tn === "function") {
\r
98 /*nameで指定されたメソッドがすでにある場合は、配列tevの親をたどれないようにしておく*/
\r
103 tev._parent = null;
\r
105 this[name] = function() {
\r
106 var te = this._eventList__,
\r
107 _name = name, //スコープチェーンのエイリアス
\r
111 isCalled = false;//返り値の制御で使う
\r
113 while (tp = te._parent) { //親をさかのぼっていく
\r
117 while (te) { //子をたどっていく
\r
118 /*最初の返り値の結果はsとして記録して、後で返す*/
\r
119 for (var i=0, tli=te.length;i<tli;++i) {
\r
120 if(te[i].name === _name) {
\r
121 ts = te[i].func.apply(this, arguments);
\r
130 te = ts = _name = isCalled = void 0;
\r
133 this[name].isOn = true;
\r
139 tev = tn = func= void 0;
\r
143 /*__argsと__appプロパティは後のofメソッドで使う*/
\r
148 * 指定されたオブジェクトのプロパティを遅延処理で実行できるメソッド
\r
149 * 後述のcallメソッドと組み合わせて使う
\r
151 of: function(obj) {
\r
153 throw new Error("No arguments error");
\r
154 } else if(this.hasOwnProperty("__of")) {
\r
156 throw new Error("Reset error");
\r
158 /*__appと__argsプロパティに、指定されたプロパティを記録しておく*/
\r
159 var args = this.__args || [];
\r
160 for (var i in obj) {
\r
161 if(obj.hasOwnProperty(i) && (i !== "call")) {
\r
162 /*一度登録されたプロパティは二度書きしないようにする*/
\r
163 args[i] || args.push(i);
\r
164 args[i] = this[i] = obj[i];
\r
167 obj.call && (this.__app = { call: obj.call });
\r
168 this.__args = args;
\r
170 args = i = obj = void 0;
\r
175 * ofメソッドで指定されているオブジェクトのcallメソッドを実行できるメソッド
\r
176 * そのさい、オブジェクトのプロパティとメソッドは、自動で実行展開される
\r
179 if (!this.__app) { //ofメソッドが呼び出されていないか、callメソッドが一度も設定されていない場合
\r
182 var args = this.__args,
\r
183 call = this.call; //callメソッドの一時的なキャッシュ
\r
184 /*循環参照を避けるためcallメソッドの入れ替え*/
\r
185 this.call = this.callFunc;
\r
186 for (var i=0, ali=args.length;i<ali;++i) {
\r
187 /*callメソッドがあるオブジェクトは展開*/
\r
190 if (argi && argi.call) {
\r
191 this[ai] = argi.call(this);
\r
195 args = ai = argi = call = void 0;
\r
196 return this.__app.call.apply(this, arguments);
\r
198 callFunc: function() { return this; }
\r
202 /*base関数でキャッシュとして使うオブジェクト*/
\r
203 var baseCache = {};
\r
205 base = function (name) {
\r
206 var __base = _base,
\r
207 _cache = baseCache; //エイリアス作成
\r
209 throw new Error("No arguments error");
\r
210 } else if (_cache[name]) {
\r
211 /*キャッシュに登録されている場合は、登録されたオブジェクトを返す*/
\r
212 return _cache[name];
\r
214 var s = Object.create(__base.obj);
\r
215 this[name] = _cache[name] = s;
\r
216 /*自身が値であるようなプロパティを設定する*/
\r
223 /*mixメソッドで使うNGハッシュを作成*/
\r
225 proto = Object.prototype;
\r
226 for (var i in proto) {
\r
228 /*上記のキャッシュについて、すべてのプロパティをnullかundefinedにしておく*/
\r
229 baseCache[i] = null;
\r
231 hash.constructor = false; //constructorはNGハッシュに追加しない
\r
232 _base.__ng_ = hash;
\r
233 hash = proto = void 0;
\r
236 * 即時関数の内部で作っていおいたオブジェクトを解放させるための関数
\r
238 base.free = function() {
\r
240 _base = baseCache = callFunc = void 0;
\r
243 /*IE8などObject.createをサポートしていないブラウザ用*/
\r
244 Object.create || (Object.create = function(obj) {
\r
245 var F = function() {};
\r