/Frameworks/Objective-J/Objective-J.js

http://github.com/polymar/polish · JavaScript · 2436 lines · 2414 code · 1 blank · 21 comment · 393 complexity · 1bd1583396e5b51a52e552f95501ff94 MD5 · raw file

Large files are truncated click here to view the full file

  1. /*
  2. * Objective-J.js
  3. * Objective-J
  4. *
  5. * Created by Francisco Tolmasky.
  6. * Copyright 2008, 280 North, Inc.
  7. *
  8. * This library is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2.1 of the License, or (at your option) any later version.
  12. *
  13. * This library is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this library; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. var NO = false,
  23. YES = true,
  24. nil = null,
  25. Nil = null,
  26. NULL = null,
  27. ABS = Math.abs,
  28. ASIN = Math.asin,
  29. ACOS = Math.acos,
  30. ATAN = Math.atan,
  31. ATAN2 = Math.atan2,
  32. SIN = Math.sin,
  33. COS = Math.cos,
  34. TAN = Math.tan,
  35. EXP = Math.exp,
  36. POW = Math.pow,
  37. CEIL = Math.ceil,
  38. FLOOR = Math.floor,
  39. ROUND = Math.round,
  40. MIN = Math.min,
  41. MAX = Math.max,
  42. RAND = Math.random,
  43. SQRT = Math.sqrt,
  44. E = Math.E,
  45. LN2 = Math.LN2,
  46. LN10 = Math.LN10,
  47. LOG2E = Math.LOG2E,
  48. LOG10E = Math.LOG10E,
  49. PI = Math.PI,
  50. PI2 = Math.PI * 2.0,
  51. PI_2 = Math.PI / 2.0,
  52. SQRT1_2 = Math.SQRT1_2,
  53. SQRT2 = Math.SQRT2;
  54. window.setNativeTimeout = window.setTimeout;
  55. window.clearNativeTimeout = window.clearTimeout;
  56. window.setNativeInterval = window.setInterval;
  57. window.clearNativeInterval = window.clearInterval;
  58. var objj_continue_alerting = NO;
  59. function objj_alert(aString)
  60. {
  61. if (!objj_continue_alerting)
  62. return;
  63. objj_continue_alerting = confirm(aString + "\n\nClick cancel to prevent further alerts.");
  64. }
  65. function objj_fprintf(stream, string)
  66. {
  67. stream(string);
  68. }
  69. function objj_printf(string)
  70. {
  71. objj_fprintf(alert, string);
  72. }
  73. if (window.console && window.console.warn)
  74. var warning_stream = function(aString) { window.console.warn(aString); }
  75. else
  76. var warning_stream = function(){};
  77. var _sprintfFormatRegex = new RegExp("([^%]+|%[\\+\\-\\ \\#0]*[0-9\\*]*(.[0-9\\*]+)?[hlL]?[cbBdieEfgGosuxXpn%@])", "g");
  78. var _sprintfTagRegex = new RegExp("(%)([\\+\\-\\ \\#0]*)([0-9\\*]*)((.[0-9\\*]+)?)([hlL]?)([cbBdieEfgGosuxXpn%@])");
  79. function sprintf(format)
  80. {
  81. var format = arguments[0],
  82. tokens = format.match(_sprintfFormatRegex),
  83. index = 0,
  84. result = "",
  85. arg = 1;
  86. for (var i = 0; i < tokens.length; i++)
  87. {
  88. var t = tokens[i];
  89. if (format.substring(index, index + t.length) != t)
  90. {
  91. return result;
  92. }
  93. index += t.length;
  94. if (t.charAt(0) != "%")
  95. {
  96. result += t;
  97. }
  98. else
  99. {
  100. var subtokens = t.match(_sprintfTagRegex);
  101. if (subtokens.length != 8 || subtokens[0] != t)
  102. {
  103. return result;
  104. }
  105. var percentSign = subtokens[1],
  106. flags = subtokens[2],
  107. widthString = subtokens[3],
  108. precisionString = subtokens[4],
  109. length = subtokens[6],
  110. specifier = subtokens[7];
  111. var width = null;
  112. if (widthString == "*")
  113. width = arguments[arg++];
  114. else if (widthString != "")
  115. width = Number(widthString);
  116. var precision = null;
  117. if (precisionString == ".*")
  118. precision = arguments[arg++];
  119. else if (precisionString != "")
  120. precision = Number(precisionString.substring(1));
  121. var leftJustify = (flags.indexOf("-") >= 0);
  122. var padZeros = (flags.indexOf("0") >= 0);
  123. var subresult = "";
  124. if (RegExp("[bBdiufeExXo]").test(specifier))
  125. {
  126. var num = Number(arguments[arg++]);
  127. var sign = "";
  128. if (num < 0)
  129. {
  130. sign = "-";
  131. }
  132. else
  133. {
  134. if (flags.indexOf("+") >= 0)
  135. sign = "+";
  136. else if (flags.indexOf(" ") >= 0)
  137. sign = " ";
  138. }
  139. if (specifier == "d" || specifier == "i" || specifier == "u")
  140. {
  141. var number = String(Math.abs(Math.floor(num)));
  142. subresult = _sprintf_justify(sign, "", number, "", width, leftJustify, padZeros)
  143. }
  144. if (specifier == "f")
  145. {
  146. var number = String((precision != null) ? Math.abs(num).toFixed(precision) : Math.abs(num));
  147. var suffix = (flags.indexOf("#") >= 0 && number.indexOf(".") < 0) ? "." : "";
  148. subresult = _sprintf_justify(sign, "", number, suffix, width, leftJustify, padZeros);
  149. }
  150. if (specifier == "e" || specifier == "E")
  151. {
  152. var number = String(Math.abs(num).toExponential(precision != null ? precision : 21));
  153. var suffix = (flags.indexOf("#") >= 0 && number.indexOf(".") < 0) ? "." : "";
  154. subresult = _sprintf_justify(sign, "", number, suffix, width, leftJustify, padZeros);
  155. }
  156. if (specifier == "x" || specifier == "X")
  157. {
  158. var number = String(Math.abs(num).toString(16));
  159. var prefix = (flags.indexOf("#") >= 0 && num != 0) ? "0x" : "";
  160. subresult = _sprintf_justify(sign, prefix, number, "", width, leftJustify, padZeros);
  161. }
  162. if (specifier == "b" || specifier == "B")
  163. {
  164. var number = String(Math.abs(num).toString(2));
  165. var prefix = (flags.indexOf("#") >= 0 && num != 0) ? "0b" : "";
  166. subresult = _sprintf_justify(sign, prefix, number, "", width, leftJustify, padZeros);
  167. }
  168. if (specifier == "o")
  169. {
  170. var number = String(Math.abs(num).toString(8));
  171. var prefix = (flags.indexOf("#") >= 0 && num != 0) ? "0" : "";
  172. subresult = _sprintf_justify(sign, prefix, number, "", width, leftJustify, padZeros);
  173. }
  174. if (RegExp("[A-Z]").test(specifier))
  175. subresult = subresult.toUpperCase();
  176. else
  177. subresult = subresult.toLowerCase();
  178. }
  179. else
  180. {
  181. var subresult = "";
  182. if (specifier == "%")
  183. subresult = "%";
  184. else if (specifier == "c")
  185. subresult = String(arguments[arg++]).charAt(0);
  186. else if (specifier == "s" || specifier == "@")
  187. subresult = String(arguments[arg++]);
  188. else if (specifier == "p" || specifier == "n")
  189. {
  190. arg++;
  191. subresult = "";
  192. }
  193. subresult = _sprintf_justify("", "", subresult, "", width, leftJustify, false);
  194. }
  195. result += subresult;
  196. }
  197. }
  198. return result;
  199. }
  200. var _sprintf_justify = function(sign, prefix, string, suffix, width, leftJustify, padZeros)
  201. {
  202. var length = (sign.length + prefix.length + string.length + suffix.length);
  203. if (leftJustify)
  204. {
  205. return sign + prefix + string + suffix + _sprintf_pad(width - length, " ");
  206. }
  207. else
  208. {
  209. if (padZeros)
  210. return sign + prefix + _sprintf_pad(width - length, "0") + string + suffix;
  211. else
  212. return _sprintf_pad(width - length, " ") + sign + prefix + string + suffix;
  213. }
  214. }
  215. var _sprintf_pad = function(n, ch)
  216. {
  217. var result = "";
  218. for (var i = 0; i < n; i++)
  219. result += ch;
  220. return result;
  221. }
  222. var base64_map_to = [
  223. "A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z",
  224. "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z",
  225. "0","1","2","3","4","5","6","7","8","9","+","/","="],
  226. base64_map_from = [];
  227. for (var i = 0; i < base64_map_to.length; i++)
  228. base64_map_from[base64_map_to[i].charCodeAt(0)] = i;
  229. function base64_decode_to_array(input, strip)
  230. {
  231. if (strip)
  232. input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
  233. var pad = (input[input.length-1] == "=" ? 1 : 0) + (input[input.length-2] == "=" ? 1 : 0),
  234. length = input.length,
  235. output = [];
  236. var i = 0;
  237. while (i < length)
  238. {
  239. var bits = (base64_map_from[input.charCodeAt(i++)] << 18) |
  240. (base64_map_from[input.charCodeAt(i++)] << 12) |
  241. (base64_map_from[input.charCodeAt(i++)] << 6) |
  242. (base64_map_from[input.charCodeAt(i++)]);
  243. output.push((bits & 0xFF0000) >> 16);
  244. output.push((bits & 0xFF00) >> 8);
  245. output.push(bits & 0xFF);
  246. }
  247. if (pad > 0)
  248. return output.slice(0, -1 * pad);
  249. return output;
  250. }
  251. function base64_encode_array(input)
  252. {
  253. var pad = (3 - (input.length % 3)) % 3,
  254. length = input.length + pad,
  255. output = [];
  256. if (pad > 0) input.push(0);
  257. if (pad > 1) input.push(0);
  258. var i = 0;
  259. while (i < length)
  260. {
  261. var bits = (input[i++] << 16) |
  262. (input[i++] << 8) |
  263. (input[i++]);
  264. output.push(base64_map_to[(bits & 0xFC0000) >> 18]);
  265. output.push(base64_map_to[(bits & 0x3F000) >> 12]);
  266. output.push(base64_map_to[(bits & 0xFC0) >> 6]);
  267. output.push(base64_map_to[bits & 0x3F]);
  268. }
  269. if (pad > 0)
  270. {
  271. output[output.length-1] = "=";
  272. input.pop();
  273. }
  274. if (pad > 1)
  275. {
  276. output[output.length-2] = "=";
  277. input.pop();
  278. }
  279. return output.join("");
  280. }
  281. function base64_decode_to_string(input, strip)
  282. {
  283. return bytes_to_string(base64_decode_to_array(input, strip));
  284. }
  285. function bytes_to_string(bytes)
  286. {
  287. return String.fromCharCode.apply(null, bytes);
  288. }
  289. function base64_encode_string(input)
  290. {
  291. var temp = [];
  292. for (var i = 0; i < input.length; i++)
  293. temp.push(input.charCodeAt(i));
  294. return base64_encode_array(temp);
  295. }
  296. var CLS_CLASS = 0x1,
  297. CLS_META = 0x2,
  298. CLS_INITIALIZED = 0x4,
  299. CLS_INITIALIZING = 0x8;
  300. function objj_ivar( aName, aType)
  301. {
  302. this.name = aName;
  303. this.type = aType;
  304. }
  305. function objj_method( aName, anImplementation, types)
  306. {
  307. this.name = aName;
  308. this.method_imp = anImplementation;
  309. this.types = types;
  310. }
  311. function objj_class()
  312. {
  313. this.isa = NULL;
  314. this.super_class = NULL;
  315. this.sub_classes = [];
  316. this.name = NULL;
  317. this.info = 0;
  318. this.ivars = [];
  319. this.method_list = [];
  320. this.method_hash = {};
  321. this.method_store = function() { };
  322. this.method_dtable = this.method_store.prototype;
  323. this.allocator = function() { };
  324. this.__address = -1;
  325. }
  326. function objj_object()
  327. {
  328. this.isa = NULL;
  329. this.__address = -1;
  330. }
  331. var OBJECT_COUNT = 0;
  332. function _objj_generateObjectHash()
  333. {
  334. return OBJECT_COUNT++;
  335. }
  336. function class_getName( aClass)
  337. {
  338. if (aClass == Nil)
  339. return "";
  340. return aClass.name;
  341. }
  342. function class_isMetaClass( aClass)
  343. {
  344. if (!aClass)
  345. return NO;
  346. return ((aClass.info & (CLS_META)));
  347. }
  348. function class_getSuperclass( aClass)
  349. {
  350. if (aClass == Nil)
  351. return Nil;
  352. return aClass.super_class;
  353. }
  354. function class_setSuperclass( aClass, aSuperClass)
  355. {
  356. }
  357. function class_isMetaClass( aClass)
  358. {
  359. return ((aClass.info & (CLS_META)));
  360. }
  361. function class_addIvar( aClass, aName, aType)
  362. {
  363. var thePrototype = aClass.allocator.prototype;
  364. if (typeof thePrototype[aName] != "undefined")
  365. return NO;
  366. aClass.ivars.push(new objj_ivar(aName, aType));
  367. thePrototype[aName] = NULL;
  368. return YES;
  369. }
  370. function class_addIvars( aClass, ivars)
  371. {
  372. var index = 0,
  373. count = ivars.length,
  374. thePrototype = aClass.allocator.prototype;
  375. for (; index < count; ++index)
  376. {
  377. var ivar = ivars[index],
  378. name = ivar.name;
  379. if (typeof thePrototype[name] === "undefined")
  380. {
  381. aClass.ivars.push(ivar);
  382. thePrototype[name] = NULL;
  383. }
  384. }
  385. }
  386. function class_copyIvarList( aClass)
  387. {
  388. return aClass.ivars.slice(0);
  389. }
  390. function class_addMethod( aClass, aName, anImplementation, aType)
  391. {
  392. if (aClass.method_hash[aName])
  393. return NO;
  394. var method = new objj_method(aName, anImplementation, aType);
  395. aClass.method_list.push(method);
  396. aClass.method_dtable[aName] = method;
  397. method.method_imp.displayName = (((aClass.info & (CLS_META))) ? '+' : '-') + " [" + class_getName(aClass) + ' ' + method_getName(method) + ']';
  398. if (!((aClass.info & (CLS_META))) && (((aClass.info & (CLS_META))) ? aClass : aClass.isa).isa === (((aClass.info & (CLS_META))) ? aClass : aClass.isa))
  399. class_addMethods((((aClass.info & (CLS_META))) ? aClass : aClass.isa), methods);
  400. return YES;
  401. }
  402. function class_addMethods( aClass, methods)
  403. {
  404. var index = 0,
  405. count = methods.length,
  406. method_list = aClass.method_list,
  407. method_dtable = aClass.method_dtable;
  408. for (; index < count; ++index)
  409. {
  410. var method = methods[index];
  411. if (aClass.method_hash[method.name])
  412. continue;
  413. method_list.push(method);
  414. method_dtable[method.name] = method;
  415. method.method_imp.displayName = (((aClass.info & (CLS_META))) ? '+' : '-') + " [" + class_getName(aClass) + ' ' + method_getName(method) + ']';
  416. }
  417. if (!((aClass.info & (CLS_META))) && (((aClass.info & (CLS_META))) ? aClass : aClass.isa).isa === (((aClass.info & (CLS_META))) ? aClass : aClass.isa))
  418. class_addMethods((((aClass.info & (CLS_META))) ? aClass : aClass.isa), methods);
  419. }
  420. function class_getInstanceMethod( aClass, aSelector)
  421. {
  422. if (!aClass || !aSelector)
  423. return NULL;
  424. var method = aClass.method_dtable[aSelector];
  425. return method ? method : NULL;
  426. }
  427. function class_getClassMethod( aClass, aSelector)
  428. {
  429. if (!aClass || !aSelector)
  430. return NULL;
  431. var method = (((aClass.info & (CLS_META))) ? aClass : aClass.isa).method_dtable[aSelector];
  432. return method ? method : NULL;
  433. }
  434. function class_copyMethodList( aClass)
  435. {
  436. return aClass.method_list.slice(0);
  437. }
  438. function class_replaceMethod( aClass, aSelector, aMethodImplementation)
  439. {
  440. if (!aClass || !aSelector)
  441. return NULL;
  442. var method = aClass.method_dtable[aSelector],
  443. method_imp = NULL;
  444. if (method)
  445. method_imp = method.method_imp;
  446. method.method_imp = aMethodImplementation;
  447. return method_imp;
  448. }
  449. var _class_initialize = function( aClass)
  450. {
  451. var meta = (((aClass.info & (CLS_META))) ? aClass : aClass.isa);
  452. if ((aClass.info & (CLS_META)))
  453. aClass = objj_getClass(aClass.name);
  454. if (aClass.super_class && !((((aClass.super_class.info & (CLS_META))) ? aClass.super_class : aClass.super_class.isa).info & (CLS_INITIALIZED)))
  455. _class_initialize(aClass.super_class);
  456. if (!(meta.info & (CLS_INITIALIZED)) && !(meta.info & (CLS_INITIALIZING)))
  457. {
  458. meta.info = (meta.info | (CLS_INITIALIZING)) & ~(0);
  459. objj_msgSend(aClass, "initialize");
  460. meta.info = (meta.info | (CLS_INITIALIZED)) & ~(CLS_INITIALIZING);
  461. }
  462. }
  463. var _objj_forward = new objj_method("forward", function(self, _cmd)
  464. {
  465. return objj_msgSend(self, "forward::", _cmd, arguments);
  466. });
  467. function class_getMethodImplementation( aClass, aSelector)
  468. {
  469. if (!((((aClass.info & (CLS_META))) ? aClass : aClass.isa).info & (CLS_INITIALIZED))) _class_initialize(aClass); var method = aClass.method_dtable[aSelector]; if (!method) method = _objj_forward; var implementation = method.method_imp;;
  470. return implementation;
  471. }
  472. var GLOBAL_NAMESPACE = window,
  473. REGISTERED_CLASSES = {};
  474. function objj_allocateClassPair( superclass, aName)
  475. {
  476. var classObject = new objj_class(),
  477. metaClassObject = new objj_class(),
  478. rootClassObject = classObject;
  479. if (superclass)
  480. {
  481. rootClassObject = superclass;
  482. while (rootClassObject.superclass)
  483. rootClassObject = rootClassObject.superclass;
  484. classObject.allocator.prototype = new superclass.allocator;
  485. classObject.method_store.prototype = new superclass.method_store;
  486. classObject.method_dtable = classObject.method_store.prototype;
  487. metaClassObject.method_store.prototype = new superclass.isa.method_store;
  488. metaClassObject.method_dtable = metaClassObject.method_store.prototype;
  489. classObject.super_class = superclass;
  490. metaClassObject.super_class = superclass.isa;
  491. }
  492. else
  493. classObject.allocator.prototype = new objj_object();
  494. classObject.isa = metaClassObject;
  495. classObject.name = aName;
  496. classObject.info = CLS_CLASS;
  497. classObject.__address = (OBJECT_COUNT++);
  498. metaClassObject.isa = rootClassObject.isa;
  499. metaClassObject.name = aName;
  500. metaClassObject.info = CLS_META;
  501. metaClassObject.__address = (OBJECT_COUNT++);
  502. return classObject;
  503. }
  504. function objj_registerClassPair( aClass)
  505. {
  506. GLOBAL_NAMESPACE[aClass.name] = aClass;
  507. REGISTERED_CLASSES[aClass.name] = aClass;
  508. }
  509. function class_createInstance( aClass)
  510. {
  511. if (!aClass)
  512. objj_exception_throw(new objj_exception(OBJJNilClassException, "*** Attempting to create object with Nil class."));
  513. var object = new aClass.allocator;
  514. object.__address = (OBJECT_COUNT++);
  515. object.isa = aClass;
  516. return object;
  517. }
  518. var prototype_bug = function() { }
  519. prototype_bug.prototype.member = false;
  520. with (new prototype_bug())
  521. member = true;
  522. if (new prototype_bug().member)
  523. {
  524. var fast_class_createInstance = class_createInstance;
  525. class_createInstance = function( aClass)
  526. {
  527. var object = fast_class_createInstance(aClass);
  528. if (object)
  529. {
  530. var theClass = object.isa,
  531. actualClass = theClass;
  532. while (theClass)
  533. {
  534. var ivars = theClass.ivars;
  535. count = ivars.length;
  536. while (count--)
  537. object[ivars[count].name] = NULL;
  538. theClass = theClass.super_class;
  539. }
  540. object.isa = actualClass;
  541. }
  542. return object;
  543. }
  544. }
  545. function object_getClassName( anObject)
  546. {
  547. if (!anObject)
  548. return "";
  549. var theClass = anObject.isa;
  550. return theClass ? class_getName(theClass) : "";
  551. }
  552. function objj_lookUpClass( aName)
  553. {
  554. var theClass = REGISTERED_CLASSES[aName];
  555. return theClass ? theClass : Nil;
  556. }
  557. function objj_getClass( aName)
  558. {
  559. var theClass = REGISTERED_CLASSES[aName];
  560. if (!theClass)
  561. {
  562. }
  563. return theClass ? theClass : Nil;
  564. }
  565. function objj_getMetaClass( aName)
  566. {
  567. var theClass = objj_getClass(aName);
  568. return (((theClass.info & (CLS_META))) ? theClass : theClass.isa);
  569. }
  570. function ivar_getName(anIvar)
  571. {
  572. return anIvar.name;
  573. }
  574. function ivar_getTypeEncoding(anIvar)
  575. {
  576. return anIvar.type;
  577. }
  578. function objj_msgSend( aReceiver, aSelector)
  579. {
  580. if (aReceiver == nil)
  581. return nil;
  582. if (!((((aReceiver.isa.info & (CLS_META))) ? aReceiver.isa : aReceiver.isa.isa).info & (CLS_INITIALIZED))) _class_initialize(aReceiver.isa); var method = aReceiver.isa.method_dtable[aSelector]; if (!method) method = _objj_forward; var implementation = method.method_imp;;
  583. switch(arguments.length)
  584. {
  585. case 2:
  586. return implementation(aReceiver, aSelector);
  587. case 3:
  588. return implementation(aReceiver, aSelector, arguments[2]);
  589. case 4:
  590. return implementation(aReceiver, aSelector, arguments[2], arguments[3]);
  591. }
  592. return implementation.apply(aReceiver, arguments);
  593. }
  594. function objj_msgSendSuper( aSuper, aSelector)
  595. {
  596. var super_class = aSuper.super_class;
  597. arguments[0] = aSuper.receiver;
  598. if (!((((super_class.info & (CLS_META))) ? super_class : super_class.isa).info & (CLS_INITIALIZED))) _class_initialize(super_class); var method = super_class.method_dtable[aSelector]; if (!method) method = _objj_forward; var implementation = method.method_imp;;
  599. return implementation.apply(aSuper.receiver, arguments);
  600. }
  601. function method_getName( aMethod)
  602. {
  603. return aMethod.name;
  604. }
  605. function method_getImplementation( aMethod)
  606. {
  607. return aMethod.method_imp;
  608. }
  609. function method_setImplementation( aMethod, anImplementation)
  610. {
  611. var oldImplementation = aMethod.method_imp;
  612. aMethod.method_imp = anImplementation;
  613. return oldImplementation;
  614. }
  615. function method_exchangeImplementations( lhs, rhs)
  616. {
  617. var lhs_imp = method_getImplementation(lhs),
  618. rhs_imp = method_getImplementation(rhs);
  619. method_setImplementation(lhs, rhs_imp);
  620. method_setImplementation(rhs, lhs_imp);
  621. }
  622. function sel_getName(aSelector)
  623. {
  624. return aSelector ? aSelector : "<null selector>";
  625. }
  626. function sel_getUid( aName)
  627. {
  628. return aName;
  629. }
  630. function sel_isEqual( lhs, rhs)
  631. {
  632. return lhs === rhs;
  633. }
  634. function sel_registerName(aName)
  635. {
  636. return aName;
  637. }
  638. function objj_dictionary()
  639. {
  640. this._keys = [];
  641. this.count = 0;
  642. this._buckets = {};
  643. this.__address = (OBJECT_COUNT++);
  644. }
  645. function dictionary_containsKey(aDictionary, aKey)
  646. {
  647. return aDictionary._buckets[aKey] != NULL;
  648. }
  649. function dictionary_getCount(aDictionary)
  650. {
  651. return aDictionary.count;
  652. }
  653. function dictionary_getValue(aDictionary, aKey)
  654. {
  655. return aDictionary._buckets[aKey];
  656. }
  657. function dictionary_setValue(aDictionary, aKey, aValue)
  658. {
  659. if (aDictionary._buckets[aKey] == NULL)
  660. {
  661. aDictionary._keys.push(aKey);
  662. ++aDictionary.count;
  663. }
  664. if ((aDictionary._buckets[aKey] = aValue) == NULL)
  665. --aDictionary.count;
  666. }
  667. function dictionary_removeValue(aDictionary, aKey)
  668. {
  669. if (aDictionary._buckets[aKey] == NULL)
  670. return;
  671. --aDictionary.count;
  672. if (aDictionary._keys.indexOf)
  673. aDictionary._keys.splice(aDictionary._keys.indexOf(aKey), 1);
  674. else
  675. {
  676. var keys = aDictionary._keys,
  677. index = 0,
  678. count = keys.length;
  679. for (; index < count; ++index)
  680. if (keys[index] == aKey)
  681. {
  682. keys.splice(index, 1);
  683. break;
  684. }
  685. }
  686. delete aDictionary._buckets[aKey];
  687. }
  688. function dictionary_replaceValue(aDictionary, aKey, aValue)
  689. {
  690. if (aDictionary[aKey] == NULL)
  691. return;
  692. }
  693. function dictionary_description(aDictionary)
  694. {
  695. var str = "{ ";
  696. for ( x in aDictionary._buckets)
  697. str += x + ":" + aDictionary._buckets[x] + ",";
  698. str += " }";
  699. return str;
  700. }
  701. var kCFPropertyListOpenStepFormat = 1,
  702. kCFPropertyListXMLFormat_v1_0 = 100,
  703. kCFPropertyListBinaryFormat_v1_0 = 200,
  704. kCFPropertyList280NorthFormat_v1_0 = -1000;
  705. var OBJJPlistParseException = "OBJJPlistParseException",
  706. OBJJPlistSerializeException = "OBJJPlistSerializeException";
  707. var kCFPropertyList280NorthMagicNumber = "280NPLIST";
  708. function objj_data()
  709. {
  710. this.string = "";
  711. this._plistObject = NULL;
  712. this.bytes = NULL;
  713. this.base64 = NULL;
  714. }
  715. var objj_markedStream = function(aString)
  716. {
  717. var index = aString.indexOf(';');
  718. this._magicNumber = aString.substr(0, index);
  719. this._location = aString.indexOf(';', ++index);
  720. this._version = aString.substring(index, this._location++);
  721. this._string = aString;
  722. }
  723. objj_markedStream.prototype.magicNumber = function()
  724. {
  725. return this._magicNumber;
  726. }
  727. objj_markedStream.prototype.version = function()
  728. {
  729. return this._version;
  730. }
  731. objj_markedStream.prototype.getMarker = function()
  732. {
  733. var string = this._string,
  734. location = this._location;
  735. if (location >= string.length)
  736. return NULL;
  737. var next = string.indexOf(';', location);
  738. if (next < 0)
  739. return NULL;
  740. var marker = string.substring(location, next);
  741. this._location = next + 1;
  742. return marker;
  743. }
  744. objj_markedStream.prototype.getString = function()
  745. {
  746. var string = this._string,
  747. location = this._location;
  748. if (location >= string.length)
  749. return NULL;
  750. var next = string.indexOf(';', location);
  751. if (next < 0)
  752. return NULL;
  753. var size = parseInt(string.substring(location, next)),
  754. text = string.substr(next + 1, size);
  755. this._location = next + 1 + size;
  756. return text;
  757. }
  758. function CPPropertyListCreateData(aPlistObject, aFormat)
  759. {
  760. if (aFormat == kCFPropertyListXMLFormat_v1_0)
  761. return CPPropertyListCreateXMLData(aPlistObject);
  762. if (aFormat == kCFPropertyList280NorthFormat_v1_0)
  763. return CPPropertyListCreate280NorthData(aPlistObject);
  764. return NULL;
  765. }
  766. function CPPropertyListCreateFromData(aData, aFormat)
  767. {
  768. if (!aFormat)
  769. {
  770. if (aData instanceof objj_data)
  771. {
  772. var string = aData.string ? aData.string : objj_msgSend(aData, "string");
  773. if (string.substr(0, kCFPropertyList280NorthMagicNumber.length) == kCFPropertyList280NorthMagicNumber)
  774. aFormat = kCFPropertyList280NorthFormat_v1_0;
  775. else
  776. aFormat = kCFPropertyListXMLFormat_v1_0;
  777. }
  778. else
  779. aFormat = kCFPropertyListXMLFormat_v1_0;
  780. }
  781. if (aFormat == kCFPropertyListXMLFormat_v1_0)
  782. return CPPropertyListCreateFromXMLData(aData);
  783. if (aFormat == kCFPropertyList280NorthFormat_v1_0)
  784. return CPPropertyListCreateFrom280NorthData(aData);
  785. return NULL;
  786. }
  787. var _CPPropertyListSerializeObject = function(aPlist, serializers)
  788. {
  789. var type = typeof aPlist,
  790. valueOf = aPlist.valueOf(),
  791. typeValueOf = typeof valueOf;
  792. if (type != typeValueOf)
  793. {
  794. type = typeValueOf;
  795. aPlist = valueOf;
  796. }
  797. if (type == "string")
  798. return serializers["string"](aPlist, serializers);
  799. else if (aPlist === true || aPlist === false)
  800. return serializers["boolean"](aPlist, serializers);
  801. else if (type == "number")
  802. {
  803. var integer = FLOOR(aPlist);
  804. if (integer == aPlist)
  805. return serializers["integer"](aPlist, serializers);
  806. else
  807. return serializers["real"](aPlist, serializers);
  808. }
  809. else if (aPlist.slice)
  810. return serializers["array"](aPlist, serializers);
  811. else
  812. return serializers["dictionary"](aPlist, serializers);
  813. }
  814. var XML_XML = "xml",
  815. XML_DOCUMENT = "#document",
  816. PLIST_PLIST = "plist",
  817. PLIST_KEY = "key",
  818. PLIST_DICTIONARY = "dict",
  819. PLIST_ARRAY = "array",
  820. PLIST_STRING = "string",
  821. PLIST_BOOLEAN_TRUE = "true",
  822. PLIST_BOOLEAN_FALSE = "false",
  823. PLIST_NUMBER_REAL = "real",
  824. PLIST_NUMBER_INTEGER = "integer",
  825. PLIST_DATA = "data";
  826. var _plist_traverseNextNode = function(anXMLNode, stayWithin, stack)
  827. {
  828. var node = anXMLNode;
  829. node = (node.firstChild); if (node != NULL && ((node.nodeType) == 8 || (node.nodeType) == 3)) while ((node = (node.nextSibling)) && ((node.nodeType) == 8 || (node.nodeType) == 3)) ;;
  830. if (node)
  831. return node;
  832. if ((String(anXMLNode.nodeName)) == PLIST_ARRAY || (String(anXMLNode.nodeName)) == PLIST_DICTIONARY)
  833. stack.pop();
  834. else
  835. {
  836. if (node == stayWithin)
  837. return NULL;
  838. node = anXMLNode;
  839. while ((node = (node.nextSibling)) && ((node.nodeType) == 8 || (node.nodeType) == 3)) ;;
  840. if (node)
  841. return node;
  842. }
  843. node = anXMLNode;
  844. while (node)
  845. {
  846. var next = node;
  847. while ((next = (next.nextSibling)) && ((next.nodeType) == 8 || (next.nodeType) == 3)) ;;
  848. if (next)
  849. return next;
  850. var node = (node.parentNode);
  851. if (stayWithin && node == stayWithin)
  852. return NULL;
  853. stack.pop();
  854. }
  855. return NULL;
  856. }
  857. function CPPropertyListCreateFromXMLData(XMLNodeOrData)
  858. {
  859. var XMLNode = XMLNodeOrData;
  860. if (XMLNode.string)
  861. {
  862. if (window.ActiveXObject)
  863. {
  864. XMLNode = new ActiveXObject("Microsoft.XMLDOM");
  865. XMLNode.loadXML(XMLNodeOrData.string.substr(XMLNodeOrData.string.indexOf(".dtd\">") + 6));
  866. }
  867. else
  868. XMLNode = (new DOMParser().parseFromString(XMLNodeOrData.string, "text/xml").documentElement);
  869. }
  870. while (((String(XMLNode.nodeName)) == XML_DOCUMENT) || ((String(XMLNode.nodeName)) == XML_XML))
  871. XMLNode = (XMLNode.firstChild); if (XMLNode != NULL && ((XMLNode.nodeType) == 8 || (XMLNode.nodeType) == 3)) while ((XMLNode = (XMLNode.nextSibling)) && ((XMLNode.nodeType) == 8 || (XMLNode.nodeType) == 3)) ;;
  872. if (((XMLNode.nodeType) == 10))
  873. while ((XMLNode = (XMLNode.nextSibling)) && ((XMLNode.nodeType) == 8 || (XMLNode.nodeType) == 3)) ;;
  874. if (!((String(XMLNode.nodeName)) == PLIST_PLIST))
  875. return NULL;
  876. var key = "",
  877. object = NULL,
  878. plistObject = NULL,
  879. plistNode = XMLNode,
  880. containers = [],
  881. currentContainer = NULL;
  882. while (XMLNode = _plist_traverseNextNode(XMLNode, plistNode, containers))
  883. {
  884. var count = containers.length;
  885. if (count)
  886. currentContainer = containers[count - 1];
  887. if ((String(XMLNode.nodeName)) == PLIST_KEY)
  888. {
  889. key = ((String((XMLNode.firstChild).nodeValue)));
  890. while ((XMLNode = (XMLNode.nextSibling)) && ((XMLNode.nodeType) == 8 || (XMLNode.nodeType) == 3)) ;;
  891. }
  892. switch (String((String(XMLNode.nodeName))))
  893. {
  894. case PLIST_ARRAY: object = []
  895. containers.push(object);
  896. break;
  897. case PLIST_DICTIONARY: object = new objj_dictionary();
  898. containers.push(object);
  899. break;
  900. case PLIST_NUMBER_REAL: object = parseFloat(((String((XMLNode.firstChild).nodeValue))));
  901. break;
  902. case PLIST_NUMBER_INTEGER: object = parseInt(((String((XMLNode.firstChild).nodeValue))));
  903. break;
  904. case PLIST_STRING: object = _decodeHTMLComponent((XMLNode.firstChild) ? ((String((XMLNode.firstChild).nodeValue))) : "");
  905. break;
  906. case PLIST_BOOLEAN_TRUE: object = true;
  907. break;
  908. case PLIST_BOOLEAN_FALSE: object = false;
  909. break;
  910. case PLIST_DATA: object = new objj_data();
  911. object.bytes = (XMLNode.firstChild) ? base64_decode_to_array(((String((XMLNode.firstChild).nodeValue))), true) : [];
  912. break;
  913. default: objj_exception_throw(new objj_exception(OBJJPlistParseException, "*** " + (String(XMLNode.nodeName)) + " tag not recognized in Plist."));
  914. }
  915. if (!plistObject)
  916. plistObject = object;
  917. else if (currentContainer)
  918. if (currentContainer.slice)
  919. currentContainer.push(object);
  920. else
  921. { if ((currentContainer)._buckets[key] == NULL) { (currentContainer)._keys.push(key); ++(currentContainer).count; } if (((currentContainer)._buckets[key] = object) == NULL) --(currentContainer).count;};
  922. }
  923. return plistObject;
  924. }
  925. function CPPropertyListCreateXMLData(aPlist)
  926. {
  927. var data = new objj_data();
  928. data.string = "";
  929. data.string += "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
  930. data.string += "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">";
  931. data.string += "<plist version = \"1.0\">";
  932. _CPPropertyListAppendXMLData(data, aPlist, "");
  933. data.string += "</plist>";
  934. return data;
  935. }
  936. var _CPArrayAppendXMLData = function(XMLData, anArray)
  937. {
  938. var i = 0,
  939. count = anArray.length;
  940. XMLData.string += "<array>";
  941. for (; i < count; ++i)
  942. _CPPropertyListAppendXMLData(XMLData, anArray[i]);
  943. XMLData.string += "</array>";
  944. }
  945. var _CPDictionaryAppendXMLData = function(XMLData, aDictionary)
  946. {
  947. var keys = aDictionary._keys,
  948. i = 0,
  949. count = keys.length;
  950. XMLData.string += "<dict>";
  951. for (; i < count; ++i)
  952. {
  953. XMLData.string += "<key>" + keys[i] + "</key>";
  954. _CPPropertyListAppendXMLData(XMLData, ((aDictionary)._buckets[keys[i]]));
  955. }
  956. XMLData.string += "</dict>";
  957. }
  958. var _encodeHTMLComponent = function(aString)
  959. {
  960. return aString.replace('<', "&lt;").replace('>', "&gt;").replace('\"', "&quot;").replace('\'', "&apos;").replace('&', "&amp;");
  961. }
  962. var _decodeHTMLComponent = function(aString)
  963. {
  964. return aString.replace("&lt;", '<').replace("&gt;", '>').replace("&quot;", '\"').replace("&apos;", '\'').replace("&amp;", '&');
  965. }
  966. var _CPPropertyListAppendXMLData = function(XMLData, aPlist)
  967. {
  968. var type = typeof aPlist,
  969. valueOf = aPlist.valueOf(),
  970. typeValueOf = typeof valueOf;
  971. if (type != typeValueOf)
  972. {
  973. type = typeValueOf;
  974. aPlist = valueOf;
  975. }
  976. if (type == "string")
  977. XMLData.string += "<string>" + _encodeHTMLComponent(aPlist) + "</string>";
  978. else if (aPlist === true)
  979. XMLData.string += "<true/>";
  980. else if (aPlist === false)
  981. XMLData.string += "<false/>";
  982. else if (type == "number")
  983. {
  984. var integer = FLOOR(aPlist);
  985. if (integer == aPlist)
  986. XMLData.string += "<integer>" + aPlist + "</integer>";
  987. else
  988. XMLData.string += "<real>" + aPlist + "</real>";
  989. }
  990. else if (aPlist.slice)
  991. _CPArrayAppendXMLData(XMLData, aPlist);
  992. else if (aPlist._keys)
  993. _CPDictionaryAppendXMLData(XMLData, aPlist);
  994. else
  995. objj_exception_throw(new objj_exception(OBJJPlistSerializeException, "*** unknown plist ("+aPlist+") type: " + type));
  996. }
  997. var ARRAY_MARKER = "A",
  998. DICTIONARY_MARKER = "D",
  999. FLOAT_MARKER = "f",
  1000. INTEGER_MARKER = "d",
  1001. STRING_MARKER = "S",
  1002. TRUE_MARKER = "T",
  1003. FALSE_MARKER = "F",
  1004. KEY_MARKER = "K",
  1005. END_MARKER = "E";
  1006. function CPPropertyListCreateFrom280NorthData(aData)
  1007. {
  1008. var stream = new objj_markedStream(aData.string),
  1009. marker = NULL,
  1010. key = "",
  1011. object = NULL,
  1012. plistObject = NULL,
  1013. containers = [],
  1014. currentContainer = NULL;
  1015. while (marker = stream.getMarker())
  1016. {
  1017. if (marker === END_MARKER)
  1018. {
  1019. containers.pop();
  1020. continue;
  1021. }
  1022. var count = containers.length;
  1023. if (count)
  1024. currentContainer = containers[count - 1];
  1025. if (marker === KEY_MARKER)
  1026. {
  1027. key = stream.getString();
  1028. marker = stream.getMarker();
  1029. }
  1030. switch (marker)
  1031. {
  1032. case ARRAY_MARKER: object = []
  1033. containers.push(object);
  1034. break;
  1035. case DICTIONARY_MARKER: object = new objj_dictionary();
  1036. containers.push(object);
  1037. break;
  1038. case FLOAT_MARKER: object = parseFloat(stream.getString());
  1039. break;
  1040. case INTEGER_MARKER: object = parseInt(stream.getString());
  1041. break;
  1042. case STRING_MARKER: object = stream.getString();
  1043. break;
  1044. case TRUE_MARKER: object = true;
  1045. break;
  1046. case FALSE_MARKER: object = false;
  1047. break;
  1048. default: objj_exception_throw(new objj_exception(OBJJPlistParseException, "*** " + marker + " marker not recognized in Plist."));
  1049. }
  1050. if (!plistObject)
  1051. plistObject = object;
  1052. else if (currentContainer)
  1053. if (currentContainer.slice)
  1054. currentContainer.push(object);
  1055. else
  1056. { if ((currentContainer)._buckets[key] == NULL) { (currentContainer)._keys.push(key); ++(currentContainer).count; } if (((currentContainer)._buckets[key] = object) == NULL) --(currentContainer).count;};
  1057. }
  1058. return plistObject;
  1059. }
  1060. function CPPropertyListCreate280NorthData(aPlist)
  1061. {
  1062. var data = new objj_data();
  1063. data.string = kCFPropertyList280NorthMagicNumber + ";1.0;" + _CPPropertyListSerializeObject(aPlist, _CPPropertyList280NorthSerializers);
  1064. return data;
  1065. }
  1066. var _CPPropertyList280NorthSerializers = {};
  1067. _CPPropertyList280NorthSerializers["string"] = function(aString)
  1068. {
  1069. return STRING_MARKER + ';' + aString.length + ';' + aString;
  1070. }
  1071. _CPPropertyList280NorthSerializers["boolean"] = function(aBoolean)
  1072. {
  1073. return (aBoolean ? TRUE_MARKER : FALSE_MARKER) + ';';
  1074. }
  1075. _CPPropertyList280NorthSerializers["integer"] = function(anInteger)
  1076. {
  1077. var string = "" + anInteger;
  1078. return INTEGER_MARKER + ';' + string.length + ';' + string;
  1079. }
  1080. _CPPropertyList280NorthSerializers["real"] = function(aFloat)
  1081. {
  1082. var string = "" + aFloat;
  1083. return FLOAT_MARKER + ';' + string.length + ';' + string;
  1084. }
  1085. _CPPropertyList280NorthSerializers["array"] = function(anArray, serializers)
  1086. {
  1087. var index = 0,
  1088. count = anArray.length,
  1089. string = ARRAY_MARKER + ';';
  1090. for (; index < count; ++index)
  1091. string += _CPPropertyListSerializeObject(anArray[index], serializers);
  1092. return string + END_MARKER + ';';
  1093. }
  1094. _CPPropertyList280NorthSerializers["dictionary"] = function(aDictionary, serializers)
  1095. {
  1096. var keys = aDictionary._keys,
  1097. index = 0,
  1098. count = keys.length,
  1099. string = DICTIONARY_MARKER +';';
  1100. for (; index < count; ++index)
  1101. {
  1102. var key = keys[index];
  1103. string += KEY_MARKER + ';' + key.length + ';' + key;
  1104. string += _CPPropertyListSerializeObject(((aDictionary)._buckets[key]), serializers);
  1105. }
  1106. return string + END_MARKER + ';';
  1107. }
  1108. var OBJJ_PLATFORMS = ["browser", "objj"];
  1109. var OBJJFileNotFoundException = "OBJJFileNotFoundException",
  1110. OBJJExecutableNotFoundException = "OBJJExecutableNotFoundException";
  1111. var objj_files = { },
  1112. objj_bundles = { },
  1113. objj_bundlesForClass = { },
  1114. objj_searches = { };
  1115. var OBJJ_NO_FILE = {};
  1116. if (typeof OBJJ_INCLUDE_PATHS === "undefined")
  1117. OBJJ_INCLUDE_PATHS = ["Frameworks", "SomethingElse"];
  1118. var OBJJ_BASE_URI = "";
  1119. if (window.opera) {
  1120. var DOMBaseElement = document.getElementsByTagName("base")[0];
  1121. if (DOMBaseElement)
  1122. OBJJ_BASE_URI = (DOMBaseElement.getAttribute('href')).substr(0, (DOMBaseElement.getAttribute('href')).lastIndexOf('/') + 1);
  1123. }
  1124. function objj_file()
  1125. {
  1126. this.path = NULL;
  1127. this.bundle = NULL;
  1128. this.included = NO;
  1129. this.contents = NULL;
  1130. this.fragments = NULL;
  1131. }
  1132. function objj_bundle()
  1133. {
  1134. this.path = NULL;
  1135. this.info = NULL;
  1136. this.__address = (OBJECT_COUNT++);
  1137. }
  1138. function objj_getBundleWithPath(aPath)
  1139. {
  1140. return objj_bundles[aPath];
  1141. }
  1142. function objj_setBundleForPath(aPath, aBundle)
  1143. {
  1144. objj_bundles[aPath] = aBundle;
  1145. }
  1146. function objj_bundleForClass(aClass)
  1147. {
  1148. return objj_bundlesForClass[aClass.name];
  1149. }
  1150. function objj_addClassForBundle(aClass, aBundle)
  1151. {
  1152. objj_bundlesForClass[aClass.name] = aBundle;
  1153. }
  1154. function objj_request_file(aFilePath, shouldSearchLocally, aCallback)
  1155. {
  1156. new objj_search(aFilePath, shouldSearchLocally, aCallback).attemptNextSearchPath();
  1157. }
  1158. var objj_search = function(aFilePath, shouldSearchLocally, aCallback)
  1159. {
  1160. this.filePath = aFilePath;
  1161. this.bundle = NULL;
  1162. this.bundleObservers = [];
  1163. this.searchPath = NULL;
  1164. this.searchedPaths = [];
  1165. this.includePathsIndex = shouldSearchLocally ? -1 : 0;
  1166. this.searchRequest = NULL;
  1167. this.didCompleteCallback = aCallback;
  1168. }
  1169. objj_search.prototype.nextSearchPath = function()
  1170. {
  1171. var path = objj_standardize_path((this.includePathsIndex == -1 ? "" : OBJJ_INCLUDE_PATHS[this.includePathsIndex] + '/') + this.filePath);
  1172. ++this.includePathsIndex;
  1173. return path;
  1174. }
  1175. objj_search.prototype.attemptNextSearchPath = function()
  1176. {
  1177. var searchPath = this.nextSearchPath();
  1178. file = objj_files[searchPath];
  1179. objj_alert("Will attempt to find " + this.filePath + " at " + searchPath);
  1180. if (file)
  1181. {
  1182. objj_alert("The file request at " + this.filePath + " has already been downloaded at " + searchPath);
  1183. if (this.didCompleteCallback)
  1184. this.didCompleteCallback(file);
  1185. return;
  1186. }
  1187. var existingSearch = objj_searches[searchPath];
  1188. if (existingSearch)
  1189. {
  1190. if (this.didCompleteCallback)
  1191. existingSearch.didCompleteCallback = this.didCompleteCallback;
  1192. return;
  1193. }
  1194. this.searchedPaths.push(this.searchPath = searchPath);
  1195. var infoPath = objj_standardize_path((searchPath).substr(0, (searchPath).lastIndexOf('/') + 1) + "Info.plist"),
  1196. bundle = objj_bundles[infoPath];
  1197. if (bundle)
  1198. {
  1199. this.bundle = bundle;
  1200. this.request(searchPath, this.didReceiveSearchResponse);
  1201. }
  1202. else
  1203. {
  1204. var existingBundleSearch = objj_searches[infoPath];
  1205. if (existingBundleSearch)
  1206. {
  1207. --this.includePathsIndex;
  1208. this.searchedPaths.pop();
  1209. if (this.searchedPaths.length)
  1210. this.searchPath = this.searchedPaths[this.searchedPaths.length - 1];
  1211. else
  1212. this.searchPath = NULL;
  1213. existingBundleSearch.bundleObservers.push(this);
  1214. return;
  1215. }
  1216. else
  1217. {
  1218. this.bundleObservers.push(this);
  1219. this.request(infoPath, this.didReceiveBundleResponse);
  1220. if (!this.searchReplaced)
  1221. this.searchRequest = this.request(searchPath, this.didReceiveSearchResponse);
  1222. }
  1223. }
  1224. }
  1225. if (window.ActiveXObject) {
  1226. objj_search.responseCallbackLock = NO;
  1227. objj_search.responseCallbackQueue = [];
  1228. objj_search.removeResponseCallbackForFilePath = function(aFilePath)
  1229. {
  1230. var queue = objj_search.responseCallbackQueue,
  1231. index = queue.length;
  1232. while (index--)
  1233. if (queue[index][3] == aFilePath)
  1234. {
  1235. queue.splice(index, 1);
  1236. return;
  1237. }
  1238. }
  1239. objj_search.serializeResponseCallback = function(aMethod, aSearch, aResponse, aFilePath)
  1240. {
  1241. var queue = objj_search.responseCallbackQueue;
  1242. queue.push([aMethod, aSearch, aResponse, aFilePath]);
  1243. if (objj_search.responseCallbackLock)
  1244. return;
  1245. objj_search.responseCallbackLock = YES;
  1246. while (queue.length)
  1247. {
  1248. var callback = queue[0];
  1249. queue.splice(0, 1);
  1250. callback[0].apply(callback[1], [callback[2]]);
  1251. }
  1252. objj_search.responseCallbackLock = NO;
  1253. }
  1254. }
  1255. objj_search.prototype.request = function(aFilePath, aMethod)
  1256. {
  1257. var search = this,
  1258. isPlist = aFilePath.substr(aFilePath.length - 6, 6) == ".plist",
  1259. request = objj_request_xmlhttp(),
  1260. response = objj_response_xmlhttp();
  1261. response.filePath = aFilePath;
  1262. request.onreadystatechange = function()
  1263. {
  1264. if (request.readyState == 4)
  1265. {
  1266. if (response.success = (request.status != 404 && request.responseText && request.responseText.length) ? YES : NO)
  1267. {
  1268. if (window.files_total)
  1269. {
  1270. if (!window.files_loaded)
  1271. window.files_loaded = 0;
  1272. window.files_loaded += request.responseText.length;
  1273. if (window.update_progress)
  1274. window.update_progress(window.files_loaded / window.files_total);
  1275. }
  1276. if (isPlist)
  1277. response.xml = objj_standardize_xml(request);
  1278. else
  1279. response.text = request.responseText;
  1280. }
  1281. if (window.ActiveXObject)
  1282. objj_search.serializeResponseCallback(aMethod, search, response, aFilePath);
  1283. else
  1284. aMethod.apply(search, [response]);
  1285. }
  1286. }
  1287. objj_searches[aFilePath] = this;
  1288. if (request.overrideMimeType && isPlist)
  1289. request.overrideMimeType('text/xml');
  1290. if (window.opera && aFilePath.charAt(0) != '/')
  1291. aFilePath = OBJJ_BASE_URI + aFilePath;
  1292. try
  1293. {
  1294. request.open("GET", aFilePath, YES);
  1295. request.send("");
  1296. }
  1297. catch (anException)
  1298. {
  1299. response.success = NO;
  1300. if (window.ActiveXObject)
  1301. objj_search.serializeResponseCallback(aMethod, search, response, aFilePath);
  1302. else
  1303. aMethod.apply(search, [response]);
  1304. }
  1305. return request;
  1306. }
  1307. objj_search.prototype.didReceiveSearchResponse = function(aResponse)
  1308. {
  1309. if (!this.bundle)
  1310. {
  1311. this.cachedSearchResponse = aResponse;
  1312. return;
  1313. }
  1314. if (aResponse.success)
  1315. {
  1316. file = new objj_file();
  1317. file.path = aResponse.filePath;
  1318. file.bundle = this.bundle
  1319. file.contents = aResponse.text;
  1320. this.complete(file);
  1321. }
  1322. else if (this.includePathsIndex < OBJJ_INCLUDE_PATHS.length)
  1323. {
  1324. this.bundle = NULL;
  1325. this.attemptNextSearchPath();
  1326. }
  1327. else
  1328. objj_exception_throw(new objj_exception(OBJJFileNotFoundException, "*** Could not locate file named \"" + this.filePath + "\" in search paths."));
  1329. }
  1330. objj_search.prototype.didReceiveBundleResponse = function(aResponse)
  1331. {
  1332. var bundle = new objj_bundle();
  1333. bundle.path = aResponse.filePath;
  1334. if (aResponse.success)
  1335. bundle.info = CPPropertyListCreateFromXMLData(aResponse.xml);
  1336. else
  1337. bundle.info = new objj_dictionary();
  1338. objj_bundles[aResponse.filePath] = bundle;
  1339. var executablePath = ((bundle.info)._buckets["CPBundleExecutable"]);
  1340. if (executablePath)
  1341. {
  1342. var platform = NULL,
  1343. platforms = ((bundle.info)._buckets["CPBundlePlatforms"]),
  1344. index = 0,
  1345. count = OBJJ_PLATFORMS.length,
  1346. innerCount = platforms.length;
  1347. for(; index < count; ++index)
  1348. {
  1349. var innerIndex = 0,
  1350. currentPlatform = OBJJ_PLATFORMS[index];
  1351. for (; innerIndex < innerCount; ++innerIndex)
  1352. if(currentPlatform === platforms[innerIndex])
  1353. {
  1354. platform = currentPlatform;
  1355. break;
  1356. }
  1357. }
  1358. executablePath = platform + ".platform/" + executablePath;
  1359. this.request((aResponse.filePath).substr(0, (aResponse.filePath).lastIndexOf('/') + 1) + executablePath, this.didReceiveExecutableResponse);
  1360. var directory = (aResponse.filePath).substr(0, (aResponse.filePath).lastIndexOf('/') + 1),
  1361. replacedFiles = ((bundle.info)._buckets["CPBundleReplacedFiles"]),
  1362. index = 0,
  1363. count = replacedFiles.length;
  1364. for (; index < count; ++index)
  1365. {
  1366. objj_searches[directory + replacedFiles[index]] = this;
  1367. if (directory + replacedFiles[index] == this.searchPath)
  1368. {
  1369. this.searchReplaced = YES;
  1370. if (!this.cachedSearchResponse && this.searchRequest)
  1371. this.searchRequest.abort();
  1372. if (window.ActiveXObject)
  1373. objj_search.removeResponseCallbackForFilePath(this.searchPath);
  1374. }
  1375. }
  1376. }
  1377. this.bundle = bundle;
  1378. var observers = this.bundleObservers,
  1379. index = 0,
  1380. count = observers.length;
  1381. for(; index < count; ++index)
  1382. {
  1383. var observer = observers[index];
  1384. if (observer != this)
  1385. observer.attemptNextSearchPath();
  1386. else if (this.cachedSearchResponse && !this.searchReplaced)
  1387. this.didReceiveSearchResponse(this.cachedSearchResponse);
  1388. }
  1389. this.bundleObservers = [];
  1390. }
  1391. objj_search.prototype.didReceiveExecutableResponse = function(aResponse)
  1392. {
  1393. if (!aResponse.success)
  1394. objj_exception_throw(new objj_exception(OBJJExecutableNotFoundException, "*** The specified executable could not be located at \"" + this.filePath + "\"."));
  1395. var files = objj_decompile(aResponse.text, this.bundle),
  1396. index = 0,
  1397. count = files.length,
  1398. length = this.filePath.length;
  1399. for (; index < count; ++index)
  1400. {
  1401. var file = files[index],
  1402. path = file.path;
  1403. if (this.filePath == path.substr(path.length - length))
  1404. this.complete(file);
  1405. else
  1406. objj_files[path] = file;
  1407. }
  1408. }
  1409. objj_search.prototype.complete = function(aFile)
  1410. {
  1411. var index = 0,
  1412. count = this.searchedPaths.length;
  1413. for (; index < count; ++index)
  1414. {
  1415. objj_files[this.searchedPaths[index]] = aFile;
  1416. }
  1417. if (this.didCompleteCallback)
  1418. this.didCompleteCallback(aFile);
  1419. }
  1420. function objj_standardize_path(aPath)
  1421. {
  1422. if (aPath.indexOf("/./") != -1 && aPath.indexOf("//") != -1 && aPath.indexOf("/../") != -1)
  1423. return aPath;
  1424. var index = 0,
  1425. components = aPath.split('/');
  1426. for(;index < components.length; ++index)
  1427. if(components[index] == "..")
  1428. {
  1429. components.splice(index - 1, 2);
  1430. index -= 2;
  1431. }
  1432. else if(index != 0 && !components[index].length || components[index] == '.' || components[index] == "..")
  1433. components.splice(index--, 1);
  1434. return components.join('/');
  1435. }
  1436. if (window.ActiveXObject) {
  1437. var objj_standardize_xml = function(aRequest)
  1438. {
  1439. var XMLData = new ActiveXObject("Microsoft.XMLDOM");
  1440. XMLData.loadXML(aRequest.responseText.substr(aRequest.responseText.indexOf(".dtd\">") + 6));
  1441. return XMLData;
  1442. }
  1443. } else {
  1444. var objj_standardize_xml = function(aRequest)
  1445. {
  1446. return aRequest.responseXML;
  1447. }
  1448. }
  1449. function objj_response_xmlhttp()
  1450. {
  1451. return new Object;
  1452. }
  1453. if (window.XMLHttpRequest) {
  1454. var objj_request_xmlhttp = function()
  1455. {
  1456. return new XMLHttpRequest();
  1457. }
  1458. } else if (window.ActiveXObject) {
  1459. var MSXML_XMLHTTP_OBJECTS = [ "Microsoft.XMLHTTP", "Msxml2.XMLHTTP", "Msxml2.XMLHTTP.3.0", "Msxml2.XMLHTTP.6.0" ],
  1460. index = MSXML_XMLHTTP_OBJECTS.length;
  1461. while (index--)
  1462. {
  1463. try
  1464. {
  1465. new ActiveXO