PageRenderTime 28ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 1ms

/a10/web/themes/classic/skins/js/plugins/jquery.ext.js

http://chenjin.googlecode.com/
JavaScript | 655 lines | 542 code | 96 blank | 17 comment | 119 complexity | bf59e607154edfc1ff875e21abf16bd9 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /*!
  2. * jQuery extention.
  3. */
  4. (function($, undefined) {
  5. // Test debug.
  6. $.debug = (function() {
  7. var scripts = document.getElementsByTagName('script'),
  8. script = scripts[scripts.length - 1];
  9. return !(/\.min\.js$/.test(script.getAttribute('src')));
  10. })();
  11. // Extend console some function to jQuery.
  12. $.each(['log', 'trace', 'error'], function(i, name) {
  13. if ($.debug && window.console && window.console[name]) {
  14. if ($.browser.webkit) {
  15. $[name] = $.proxy(window.console[name], window.console) || $.noop;
  16. } else {
  17. $[name] = window.console[name];
  18. }
  19. } else {
  20. $[name] = $.noop;
  21. }
  22. });
  23. // Add php function.
  24. $.php = $.php || {};
  25. (function() {
  26. var php = new window.PHP_JS(),
  27. rdashAlpha = /_([a-z]|[0-9])/ig,
  28. fcamelCase = function(all, letter) {
  29. return (letter + '').toUpperCase();
  30. },
  31. key;
  32. for (key in php) {
  33. if ($.isFunction(php[key]) && key !== 'constructor') {
  34. $.php[key.replace(rdashAlpha, fcamelCase)] = php[key];
  35. }
  36. }
  37. })();
  38. // Add ax special function.
  39. $.ax = $.ax || {};
  40. $.ax.CONST = $.ax.CONST || {};
  41. $.extend($.ax.CONST, {
  42. ASC_ERROR: 0,
  43. ASC_TPL: -1,
  44. ASC_LOGIN: -2,
  45. ASC_SUCCESS: -3,
  46. ASC_REDIRECT: -4,
  47. ASC_RELOAD: -5
  48. });
  49. $.extend($.ax, {
  50. t: function(message) {
  51. return message;
  52. },
  53. asset: function(url) {
  54. // @todo Remove the global variables.
  55. return '/skin/' + window.global_theme + '/' + window.global_skin + '/' + url;
  56. },
  57. msg: function(msg, delay, method) {
  58. var self = $.ax;
  59. self.msg.element = self.msg.element || $('<div class="gmsg"></div>').axMsg({classPrefix: 'gmsg-'}).prependTo('body');
  60. self.msg.element.axMsg(method, msg, delay);
  61. },
  62. success: function(msg, delay) {
  63. var self = $.ax;
  64. self.msg(msg, delay, 'success');
  65. },
  66. error: function(msg, delay) {
  67. var self = $.ax;
  68. self.msg(msg, delay, 'error');
  69. },
  70. info: function(msg, delay) {
  71. var self = $.ax;
  72. self.msg(msg, delay, 'info');
  73. },
  74. failure: function(msg, delay) {
  75. var self = $.ax;
  76. self.msg(msg, delay, 'error');
  77. },
  78. close: function() {
  79. var self = $.ax;
  80. self.msg('', 0, 'close');
  81. },
  82. clearUrl: function(url) {
  83. return (url.match(/^([^#]+)/)||[])[1];
  84. },
  85. format: $.validator && $.validator.format,
  86. string: function() {
  87. var i, len, ret = '';
  88. for (i = 0, len = arguments.length; i < len; i++) {
  89. if (arguments[i] !== undefined && arguments[i] !== null) {
  90. ret = arguments[i];
  91. break;
  92. }
  93. }
  94. if (typeof ret === 'boolean') {
  95. ret = ret ? '1' : '';
  96. } else if ($.isNumeric(ret)) {
  97. ret += '';
  98. }
  99. return ret;
  100. },
  101. rebuildUrl: function(url, params) {
  102. var path, query, fragment,
  103. pos, tmp,
  104. pair = {};
  105. path = query = fragment = '';
  106. if ((pos = url.indexOf('?')) !== -1) {
  107. path = url.substring(0, pos);
  108. query = url.substr(pos + 1);
  109. if ((pos = query.lastIndexOf('#')) !== -1) {
  110. tmp = query;
  111. query = tmp.substring(0, pos);
  112. fragment = tmp.substr(pos + 1);
  113. }
  114. } else {
  115. path = url;
  116. }
  117. if (!!query) {
  118. $.php.parseStr(query, pair);
  119. }
  120. query = $.php.httpBuildQuery($.extend(true, pair, params || {}));
  121. query = !!query ? ('?' + query) : '';
  122. fragment = !!fragment ? ('#' + fragment) : '';
  123. return path + query + fragment;
  124. },
  125. addCssRules: function(cssString) {
  126. var self = $.ax.addCssRules,
  127. cssText, heads;
  128. if (!self.style) {
  129. self.style = document.createElement('style');
  130. self.style.setAttribute('type', 'text/css');
  131. heads = document.getElementsByTagName('head');
  132. if (heads.length) {
  133. heads[0].appendChild(self.style);
  134. } else {
  135. document.documentElement.appendChild(self.style);
  136. }
  137. }
  138. if (self.style.styleSheet) {// IE
  139. self.style.styleSheet.cssText += cssString;
  140. } else {// W3C
  141. cssText = document.createTextNode(cssString);
  142. self.style.appendChild(cssText);
  143. }
  144. },
  145. callback: function(namespace, handler, defaults) {
  146. var self = $.ax.callback,
  147. key, keys = [], ret;
  148. self.callbacks = self.callbacks || {};
  149. if (typeof namespace === 'string') {
  150. if ($.isFunction(handler)) {
  151. self.callbacks[namespace] = {
  152. defaults: defaults || {},
  153. handler: handler
  154. };
  155. ret = self.callbacks;
  156. } else if (typeof handler === 'object') {
  157. self.callbacks[namespace] = handler;
  158. ret = self.callbacks;
  159. } else {
  160. ret = self.callbacks[namespace];
  161. }
  162. } else if (typeof namespace === 'object') {
  163. $.extend(self.callbacks, namespace);
  164. ret = self.callbacks;
  165. } else if (typeof namespace === 'boolean') {
  166. for (key in self.callbacks) {
  167. if (self.callbacks.hasOwnProperty(key)) {
  168. keys.push(key);
  169. }
  170. }
  171. ret = keys.join('\n');
  172. } else {
  173. ret = self.callbacks;
  174. }
  175. return ret;
  176. },
  177. isIpv4: function(ip) {
  178. return (/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/.test(ip)) && (RegExp.$1 < 256 && RegExp.$2 < 256 && RegExp.$3 < 256 && RegExp.$4 < 256);
  179. },
  180. isIpv6: function(ip) {
  181. return ip.match(/:/g) && ip.match(/:/g).length <= 7 && /::/.test(ip) ? (/^([\da-f]{1,4}(:|::)){1,6}[\da-f]{1,4}$/i.test(ip) || /::[\da-f]{1,4}/i.test(ip)) : /^([\da-f]{1,4}:){7}[\da-f]{1,4}$/i.test(ip);
  182. },
  183. ipMode: function(ip) {
  184. var self = $.ax;
  185. if (self.isIpv4(ip)) {
  186. return 4;
  187. } else if (self.isIpv6(ip)) {
  188. return 6;
  189. }
  190. return 0;
  191. },
  192. ipRange: function (from, to, max, step) {
  193. var self = $.ax,
  194. f = String.fromCharCode,
  195. ip6byte = 16,
  196. mode = self.ipMode(from),
  197. ret = [],
  198. ip, i,
  199. pton = function(ip) {
  200. var r = /^((?:[\da-f]{1,4}(?::|)){0,8})(::)?((?:[\da-f]{1,4}(?::|)){0,8})$/,
  201. m, j, i, x, c;
  202. ip = ip.toLowerCase();
  203. m = ip.match(r);
  204. for (j = 1; j < 4; j++) {
  205. if (j === 2 || m[j].length === 0) {
  206. continue;
  207. }
  208. m[j] = m[j].split(':');
  209. for (i = 0; i < m[j].length; i++) {
  210. m[j][i] = parseInt(m[j][i], 16);
  211. m[j][i] = f(m[j][i] >> 8) + f(m[j][i] & 0xFF);
  212. }
  213. m[j] = m[j].join('');
  214. }
  215. x = m[1].length + m[3].length;
  216. if (x === ip6byte) {
  217. c = m[1] + m[3];
  218. } else {
  219. c = m[1] + (new Array(ip6byte - x + 1)).join('\x00') + m[3];
  220. }
  221. return c;
  222. },
  223. ipadd = function(ip, step) {
  224. var c = [], i;
  225. for (i = 0; i < ip6byte; i++) {
  226. c[i] = ip.charCodeAt(i);
  227. }
  228. for (i = ip6byte - 1; i >= 0; i--) {
  229. if (i === ip6byte - 1) {
  230. c[i] += step;
  231. }
  232. if (c[i] >= 256) {
  233. c[i] -= 256;
  234. c[i - 1] += 1;
  235. } else {
  236. break;
  237. }
  238. }
  239. for (i = 0; i < ip6byte; i++) {
  240. c[i] = f(c[i]);
  241. }
  242. return c.join('');
  243. },
  244. ntop = function(ip) {
  245. var c = [],
  246. m = '',
  247. i;
  248. for (i = 0; i < ip6byte; i++) {
  249. c.push(((ip.charCodeAt(i++) << 8) + ip.charCodeAt(i)).toString(16));
  250. }
  251. return c.join(':').replace(/((^|:)0(?=:|$))+:?/g, function (t) {
  252. m = (t.length > m.length) ? t : m;
  253. return t;
  254. }).replace(m || ' ', '::');
  255. },
  256. ip2long = function(ip) {
  257. ip = ip.match(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/);
  258. return ip[1] * 16777216 + ip[2] * 65536 + ip[3] * 256 + ip[4] * 1;
  259. },
  260. long2ip = function(ip) {
  261. return Math.floor(ip / Math.pow(256, 3)) + '.' + Math.floor((ip % Math.pow(256, 3)) / Math.pow(256, 2)) + '.' + Math.floor(((ip % Math.pow(256, 3)) % Math.pow(256, 2)) / Math.pow(256, 1)) + '.' + Math.floor((((ip % Math.pow(256, 3)) % Math.pow(256, 2)) % Math.pow(256, 1)) / Math.pow(256, 0));
  262. };
  263. if (!mode) {
  264. return 1;
  265. }
  266. if (mode !== self.ipMode(to)) {
  267. return 2;
  268. }
  269. step = parseInt(step, 10);
  270. isNaN(step) && (step = 1);
  271. if (mode === 4) {
  272. from = ip2long(from);
  273. to = ip2long(to);
  274. if (from > to) {
  275. return 3;
  276. }
  277. ip = from;
  278. i = 0;
  279. while (ip <= to) {
  280. ret.push(long2ip(ip));
  281. ip += step;
  282. if (max && ++i >= max) {
  283. return 4;
  284. }
  285. }
  286. } else {
  287. from = pton(from);
  288. to = pton(to);
  289. if (from > to) {
  290. return 3;
  291. }
  292. ip = from;
  293. i = 0;
  294. while (ip <= to) {
  295. ret.push(ntop(ip));
  296. ip = ipadd(ip, step);
  297. if (max && ++i >= max) {
  298. return 4;
  299. }
  300. }
  301. }
  302. return ret;
  303. },
  304. dialog: function(id, options) {
  305. var self = $.ax,
  306. $el = $('#' + id),
  307. promise = {};
  308. self.dialog.list = self.dialog.list || {};
  309. self.dialog.list[id] = {};
  310. $.each(options.buttons || {}, function(name, props) {
  311. self.dialog.list[id][name] = $.Callbacks('once memory stopOnFalse');
  312. promise[name] = self.dialog.list[id][name].add;
  313. if (!props.click) {
  314. self.dialog.list[id][name].add(function() {
  315. $(this).axDialog('close');
  316. });
  317. } else {
  318. self.dialog.list[id][name].add(props.click);
  319. }
  320. });
  321. if (!$el.length) {
  322. $.each(options.buttons || {}, function(name, props) {
  323. options.buttons[name].click = function(e) {
  324. self.dialog.list[id][name].fireWith(this);
  325. e.stopPropagation();
  326. e.preventDefault();
  327. };
  328. });
  329. $el = $('<div id="' + id + '"></div>')
  330. .appendTo('body')
  331. .axDialog(options);
  332. }
  333. promise.element = $el;
  334. return promise;
  335. },
  336. confirm: function(message) {
  337. var self = $.ax,
  338. promise = self.dialog('JQ-AX-CONFIRM', {
  339. modal: true,
  340. title: 'Come from page message',
  341. autoOpen: false,
  342. buttons: {
  343. confirm: {text: 'Confirm'},
  344. cancel: {text: 'Cancel'}
  345. }
  346. });
  347. promise.element.html(message || 'Please give a message.').axDialog('open');
  348. return promise;
  349. },
  350. alert: function(message) {
  351. var $el = $('#JQ-AX-ALERT');
  352. if (!$el.length) {
  353. $el = $('<div id="JQ-AX-ALERT"></div>').appendTo('body');
  354. $el.axDialog({
  355. modal: true,
  356. title: 'Come from page message',
  357. autoOpen: false,
  358. buttons: [
  359. {
  360. text: 'Confirm',
  361. click: function(e) {
  362. $(this).axDialog('close');
  363. e.stopPropagation();
  364. e.preventDefault();
  365. }
  366. }
  367. ]
  368. });
  369. }
  370. $el.html(message || 'Please give a message.').axDialog('open');
  371. }
  372. });
  373. // Exend jQuery.fn
  374. $.extend($.fn, {
  375. axConfig: function(name) {
  376. var config = this.data('config'),
  377. res;
  378. if (typeof name === 'string') {
  379. try {
  380. res = config[name];
  381. } catch (e) {}
  382. } else {
  383. res = config;
  384. }
  385. return res;
  386. },
  387. axAjaxSubmit: function(options) {
  388. var stop = true, form;
  389. // using jquery.validator plugin verify the form field.
  390. if (this.is('form')) {
  391. form = this;
  392. stop = !form.valid();
  393. } else if ((form = this.find('form:first')) && form.length) {
  394. stop = !form.valid();
  395. } else {
  396. form = this;
  397. stop = !form.find(':input').not(':button').not(':hidden').valid();
  398. options.semantic = true;
  399. }
  400. if (stop) {
  401. return this;
  402. }
  403. // using jquery.form submit the form.
  404. form.ajaxSubmit(options);
  405. return this;
  406. },
  407. axSerializePartial: function() {
  408. return jQuery.param(this.axSerializePartialArray());
  409. },
  410. axSerializePartialArray: function() {
  411. return this.find(':input').serializeArray();
  412. }
  413. });
  414. // Extend jQuery.Widget.
  415. $.extend($.Widget.prototype, {
  416. _createWidget: function(options, element) {
  417. // $.widget.bridge stores the plugin instance, but we do it anyway
  418. // so that it's stored even before the _create function runs
  419. $.data(element, this.widgetName, this);
  420. this.element = $(element);
  421. this.options = $.extend(true, {},
  422. this.options,
  423. options,
  424. this._getCreateOptions()
  425. );
  426. var self = this;
  427. this.element.bind('remove.' + this.widgetName, function() {
  428. self.destroy();
  429. });
  430. this._create();
  431. this._trigger('create');
  432. this._init();
  433. },
  434. _getCreateOptions: function() {
  435. return (this.element.data('config') || {})[this.widgetName];
  436. },
  437. __trigger: $.Widget.prototype._trigger,
  438. _trigger: function(type, event, data) {
  439. var callback = this.options[type];
  440. if (typeof callback === 'string') {
  441. if (/^function\s*\(/i.test(callback)) {
  442. callback = (new Function('return ' + callback))();
  443. } else if (window.AX && $.isFunction(window.AX.App.Callbacks[this.widgetName][callback])) {
  444. callback = window.AX.App.Callbacks[this.widgetName][callback];
  445. }
  446. this.options[type] = callback;
  447. }
  448. return this.__trigger(type, event, data);
  449. }
  450. });
  451. // Extract to window
  452. // Deprecate
  453. $.extend(window, {
  454. asset: $.ax.asset,
  455. t: $.ax.t
  456. });
  457. // Ajax global settings.
  458. $.ajaxPrefilter(function(options, originalOptions, jqXhr) {
  459. var doneList = $.Callbacks('once memory stopOnFalse'),
  460. failList = $.Callbacks('once memory stopOnFalse'),
  461. $el, count;
  462. jqXhr.success = doneList.add;
  463. jqXhr.error = failList.add;
  464. jqXhr.done(function(data, status, jqXhr) {
  465. if (typeof data === 'object') {
  466. if (data) {
  467. if (data.info && data.info !== 'NULL') {
  468. $.log(data.info);
  469. }
  470. status = parseInt(data.status, 10);
  471. data = data.content;
  472. } else {
  473. $.error('Ajax returning data is empty');
  474. return false;
  475. }
  476. }
  477. try {
  478. doneList.fireWith(this, [data, status, jqXhr]);
  479. } catch (e) {
  480. $.error(e);
  481. }
  482. });
  483. jqXhr.fail(function() {
  484. try {
  485. failList.fireWith(this, arguments);
  486. } catch (e) {
  487. $.error(e);
  488. }
  489. });
  490. jqXhr.error(function(jqXhr, status, error) {
  491. if (status === 'parsererror') {
  492. $.ax.error('Response parse error.');
  493. $.error(error);
  494. return false;
  495. }
  496. });
  497. jqXhr.success(function(json, status, error) {
  498. if (status >= $.ax.CONST.ASC_ERROR) {
  499. $.ax.error(json);
  500. return false;
  501. }
  502. if (status === $.ax.CONST.ASC_SUCCESS) {
  503. $.ax.success(json);
  504. return !!originalOptions.pass;
  505. }
  506. });
  507. if (options.element) {
  508. $el = $(options.element);
  509. count = $el.data('JQ_AJAX_COUNT') || 0;
  510. if (count > 0) {
  511. jqXhr.abort();
  512. } else {
  513. $el.data('JQ_AJAX_COUNT', ++count);
  514. jqXhr.complete(function() {
  515. $el.data('JQ_AJAX_COUNT', --count);
  516. });
  517. }
  518. }
  519. });
  520. $.ajaxSetup({
  521. dataType: 'json',
  522. statusCode: {
  523. '401': function(jqXhr, status, error) {
  524. var id = 'JQ-LOGIN-FORM',
  525. json = $.parseJSON(jqXhr.responseText),
  526. $login = $('#' + id);
  527. if (!$login.length) {
  528. $login = $('<div id="' + id + '" class="dialog">' + (json.content || json) + '</div>');
  529. $login.css({'display': 'none'}).appendTo('body');
  530. $login.axDialog({
  531. modal: true,
  532. autoOpen: false,
  533. width: 480,
  534. height: 210,
  535. title: 'Please Login',
  536. buttons: [
  537. {
  538. text: 'Login',
  539. click: function(e) {
  540. $login.find('form').axAjaxSubmit({
  541. dataType: 'json',
  542. resetForm: true,
  543. success: function() {
  544. $login.axDialog('close');
  545. }
  546. });
  547. e.stopPropagation();
  548. e.preventDefault();
  549. }
  550. },
  551. 'cancel'
  552. ]
  553. });
  554. }
  555. $login.axDialog('open');
  556. }
  557. }
  558. });
  559. })(jQuery);