my.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  1. /*!
  2. * jQuery Cookie Plugin v1.3.1
  3. * https://github.com/carhartl/jquery-cookie
  4. * Copyright 2013 Klaus Hartl
  5. * Released under the MIT license
  6. */
  7. !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){function c(a){return h.raw?a:encodeURIComponent(a)}function d(a){return h.raw?a:decodeURIComponent(a)}function e(a){return c(h.json?JSON.stringify(a):String(a))}function f(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(b," ")),h.json?JSON.parse(a):a}catch(c){}}function g(b,c){var d=h.raw?b:f(b);return a.isFunction(c)?c(d):d}var b=/\+/g,h=a.cookie=function(b,f,i){var j,k,l,m,n,o,p,q,r;if(arguments.length>1&&!a.isFunction(f))return i=a.extend({},h.defaults,i),"number"==typeof i.expires&&(j=i.expires,k=i.expires=new Date,k.setMilliseconds(k.getMilliseconds()+864e5*j)),document.cookie=[c(b),"=",e(f),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("");for(l=b?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;o>n;n++){if(p=m[n].split("="),q=d(p.shift()),r=p.join("="),b===q){l=g(r,f);break}b||void 0===(r=g(r))||(l[q]=r)}return l};h.defaults={},a.removeCookie=function(b,c){return a.cookie(b,"",a.extend({},c,{expires:-1})),!a.cookie(b)}});
  8. /**
  9. * Create link.
  10. *
  11. * @param string $moduleName
  12. * @param string $methodName
  13. * @param string $vars
  14. * @param string $viewType
  15. * @access public
  16. * @return string
  17. */
  18. function createLink(moduleName, methodName, vars, viewType, isOnlyBody)
  19. {
  20. if(!viewType) viewType = config.defaultView;
  21. if(!isOnlyBody) isOnlyBody = false;
  22. if(vars)
  23. {
  24. vars = vars.split('&');
  25. for(i = 0; i < vars.length; i ++) vars[i] = vars[i].split('=');
  26. }
  27. if(config.requestType != 'GET')
  28. {
  29. if(config.requestType == 'PATH_INFO') link = config.webRoot + moduleName + config.requestFix + methodName;
  30. if(config.requestType == 'PATH_INFO2') link = config.webRoot + 'index.php/' + moduleName + config.requestFix + methodName;
  31. if(vars)
  32. {
  33. for(i = 0; i < vars.length; i ++) link += config.requestFix + vars[i][1];
  34. }
  35. link += '.' + viewType;
  36. }
  37. else
  38. {
  39. link = config.router + '?' + config.moduleVar + '=' + moduleName + '&' + config.methodVar + '=' + methodName + '&' + config.viewVar + '=' + viewType;
  40. if(vars) for(i = 0; i < vars.length; i ++) link += '&' + vars[i][0] + '=' + vars[i][1];
  41. }
  42. /* if page has onlybody param then add this param in all link. the param hide header and footer. */
  43. if((typeof(config.onlybody) != 'undefined' && config.onlybody == 'yes') || isOnlyBody)
  44. {
  45. var onlybody = config.requestType != 'GET' ? "?onlybody=yes" : '&onlybody=yes';
  46. link = link + onlybody;
  47. }
  48. return link;
  49. }
  50. /**
  51. * Set language.
  52. *
  53. * @access public
  54. * @return void
  55. */
  56. function selectLang(lang)
  57. {
  58. $.cookie('lang', lang, {expires:config.cookieLife, path:config.webRoot});
  59. location.href = removeAnchor(location.href);
  60. }
  61. /**
  62. * Set theme.
  63. *
  64. * @access public
  65. * @return void
  66. */
  67. function selectTheme(theme)
  68. {
  69. $.cookie('theme', theme, {expires:config.cookieLife, path:config.webRoot});
  70. location.href = removeAnchor(location.href);
  71. }
  72. /**
  73. * Remove anchor from the url.
  74. *
  75. * @param string $url
  76. * @access public
  77. * @return string
  78. */
  79. function removeAnchor(url)
  80. {
  81. pos = url.indexOf('#');
  82. if(pos > 0) return url.substring(0, pos);
  83. return url;
  84. }
  85. /**
  86. * Init sort panel
  87. *
  88. * @access public
  89. * @return void
  90. */
  91. function initSortPanel()
  92. {
  93. var $sortTrigger = $('#sortTrigger');
  94. if(!$sortTrigger.length) return;
  95. var $list = $('#page > .box > .table tr');
  96. if(!$list.length) return $sortTrigger.addClass('hidden');
  97. var $sortPanel = $('#sortPanel');
  98. if($sortPanel.length)
  99. {
  100. var $sortItem = $sortPanel.children('.SortUp, .SortDown').first();
  101. var sortClass = $sortItem.hasClass('SortUp') ? 'SortUp' : 'SortDown';
  102. $sortTrigger.removeClass('SortUp SortDown').addClass(sortClass).find('span').text($sortItem.text());
  103. }
  104. }
  105. /**
  106. * Fix avatar has text
  107. */
  108. (function()
  109. {
  110. var fixAvatar = function()
  111. {
  112. var $avatar = $(this);
  113. if($avatar.hasClass('avatar-no-fix')) return;
  114. var text = $.trim($avatar.text());
  115. if(text && text.length > 1)
  116. {
  117. $avatar.text(text.substring(0, 1));
  118. }
  119. };
  120. $.fn.fixAvatar = function()
  121. {
  122. return this.each(fixAvatar);
  123. };
  124. $(document).on('display.displayed', function(e, dp, $e, options)
  125. {
  126. if(options && options.$target) options.$target.find('.avatar').fixAvatar();
  127. });
  128. $(function() {$('.avatar').fixAvatar();})
  129. })();
  130. /**
  131. * Refresh content with ajax
  132. *
  133. * @param string selector
  134. * @param string url
  135. * @access public
  136. * @return void
  137. */
  138. $.refresh = function(selector, url)
  139. {
  140. if(selector === true) selector = 'body';
  141. var $target = $(selector || 'body');
  142. var $tmp = $('<div/>');
  143. if(!url)
  144. {
  145. url = $target.data('refreshUrl') || $target.parent().data('refreshUrl') || window.location.href;
  146. }
  147. else if(url.indexOf(' ') < 1) url += ' body';
  148. $tmp.load(url, function()
  149. {
  150. var $tmpTarget = $tmp.find(selector);
  151. $target = $target.replaceWith($tmpTarget);
  152. $tmpTarget.find('[data-skin]').skin();
  153. $tmpTarget.find('[data-display]').display();
  154. $tmpTarget.find('.avatar').fixAvatar();
  155. $tmpTarget.find('.nav-auto').navAuto();
  156. });
  157. };
  158. /**
  159. * Init list with actions
  160. *
  161. * @access public
  162. * @return void
  163. */
  164. $.Display.plugs(
  165. {
  166. _listAction: function(options)
  167. {
  168. return $.extend(options,
  169. {
  170. targetDismiss: true,
  171. selector: options.selector || '.item',
  172. trigger: 'longTap'
  173. });
  174. },
  175. listAction: function(options)
  176. {
  177. return $.extend(options,
  178. {
  179. backdrop: true,
  180. remote: false,
  181. load: false,
  182. target: options.actionsPanel || '#actionsPanel',
  183. show: function(thisOptions)
  184. {
  185. var $target = thisOptions.$target,
  186. $element = $(thisOptions.element),
  187. actions = $element.data('actions');
  188. $target.css('pointerEvents', 'none').children('.item').each(function()
  189. {
  190. var $item = $(this),
  191. action = actions[$item.data('action')];
  192. if(action)
  193. {
  194. $item.removeClass('disabled').attr(
  195. {
  196. disabled: null,
  197. 'data-href': action
  198. }).data('remote', action);
  199. if($item.data('refresh'))
  200. {
  201. $item.data({refresh: '[data-id="' + $element.data('id') + '"]'});
  202. }
  203. if($item.data('ajaxDelete'))
  204. {
  205. $item.data({ajaxDelete: '[data-id="' + $element.data('id') + '"]'});
  206. }
  207. } else $item.addClass('disabled').attr('disabled', 'disabled');
  208. });
  209. $target.children('.selected').replaceWith($element.clone().attr('data-id', '').addClass('selected'));
  210. setTimeout(function(){$target.css('pointerEvents', 'auto');}, 1000);
  211. }
  212. });
  213. },
  214. ajaxAction: function(options)
  215. {
  216. var $element = $(options.element);
  217. var options = $.Display.plugs.messager.call(this, options);
  218. var oldTemplate = options.template;
  219. var isAjaxDelete = options.ajaxDelete;
  220. return $.extend(options,
  221. {
  222. confirm: options.confirm !== undefined ? options.confirm : (options.ajaxDelete ? lang.confirmDelete : false),
  223. remoteType: 'json',
  224. show: function(thisOptions)
  225. {
  226. return !thisOptions.confirm || confirm(thisOptions.confirm);
  227. },
  228. template: function(response, thisOptions)
  229. {
  230. var data = $.extend(thisOptions, response);
  231. var isSuccess = data.result === 'success';
  232. if(isSuccess)
  233. {
  234. if(data.refresh) $.refresh(data.refresh, data.refreshUrl);
  235. if(data.ajaxDelete) $(data.ajaxDelete).remove();
  236. if($.isFunction(data.success)) data.success(response);
  237. }
  238. var locate = data.locate;
  239. if(data.resetLocate !== undefined) locate = data.resetLocate;
  240. if(locate)
  241. {
  242. setTimeout(function()
  243. {
  244. if(locate === 'self')
  245. {
  246. window.location.reload();
  247. }
  248. else if(data.locateDisplay == 'modal')
  249. {
  250. var myDisplay = new $.Display({ display: 'modal' });
  251. myDisplay.show({ remote: locate, placement: 'bottom'});
  252. }
  253. else
  254. {
  255. window.location.href = locate;
  256. }
  257. }, 1500);
  258. }
  259. return data.message ? oldTemplate(data.message, $.extend(data, {type: isSuccess ? 'success' : 'danger', icon: isSuccess ? 'ok-sign' : 'exclamation-sign'})) : false;
  260. },
  261. remoteError: function()
  262. {
  263. return {result: 'fail', message: lang.timeout || 'Network error.'};
  264. }
  265. });
  266. }
  267. });
  268. /**
  269. * Disable context menu
  270. *
  271. * @param object $context
  272. * @access public
  273. * @return void
  274. */
  275. function disableContextMenu($context)
  276. {
  277. ($context || $('.no-contextmenu')).on('contextmenu', function(e) {e.preventDefault(); e.returnValue = false; return false});
  278. }
  279. /**
  280. * Init list with pager
  281. *
  282. * @param object $list
  283. * @access public
  284. * @return void
  285. */
  286. function initListWithPager($list)
  287. {
  288. ($list || $('.list-with-pager')).on($.TapName, '.pager-more', function()
  289. {
  290. var $pager = $(this);
  291. if($pager.hasClass('loading')) return;
  292. $pager.addClass('loading loading-light');
  293. var $tmp = $('<div/>');
  294. $tmp.load($pager.data('more') + ' .list-with-pager', function(data) {
  295. var $tmpList = $tmp.find('.list');
  296. $tmpList.children('.item').each(function()
  297. {
  298. var $tmpItem = $(this);
  299. var $item = $('[data-id="' + $tmpItem.data('id') + '"]');
  300. if($item.length)
  301. {
  302. $item.replaceWith($tmpItem.clone());
  303. $tmpItem.remove();
  304. }
  305. });
  306. $pager.parent().before($tmp.find('.list'));
  307. $pager.replaceWith($tmp.find('.pager-more'));
  308. });
  309. });
  310. }
  311. /**
  312. * Reverse toggle
  313. */
  314. (function()
  315. {
  316. // http://lab.arc90.com/2008/05/22/jquery-reverse-order-plugin/#licensing
  317. $.fn.reverseOrder = function(){return this.each(function(){$(this).prependTo( $(this).parent() );});};
  318. $(function()
  319. {
  320. $('body').on($.TapName, '[data-toggle="reverse"]', function()
  321. {
  322. var $this = $(this);
  323. $($this.data('target')).reverseOrder();
  324. $this.find('.icon-sort-by-order, .icon-sort-by-order-alt').toggleClass('icon-sort-by-order').toggleClass('icon-sort-by-order-alt');
  325. });
  326. });
  327. })();
  328. /**
  329. * Ajax form
  330. */
  331. (function()
  332. {
  333. $.fn.modalForm = function(options)
  334. {
  335. return $(this).each(function()
  336. {
  337. var $form = $(this);
  338. var thisOptions = $.extend($form.data(), options);
  339. if(!thisOptions.onResult && !thisOptions.onSuccess && !thisOptions.onComplete)
  340. {
  341. thisOptions.onSuccess = function(response)
  342. {
  343. if(response.result === 'success')
  344. {
  345. $.Display.dismiss();
  346. response.locate = false;
  347. if(thisOptions.formRefresh) $.refresh(thisOptions.formRefresh);
  348. if(thisOptions.displayFrom) $.Display.all[thisOptions.displayFrom].show();
  349. $form.find('[data-default-val]').each(function()
  350. {
  351. var $control = $(this);
  352. $control.val($control.data('defaultVal'));
  353. });
  354. }
  355. };
  356. }
  357. $.ajaxForm($form, thisOptions);
  358. });
  359. }
  360. $(function() {$('.modal-form').modalForm();});
  361. $(document).on('display.displayed', function(e, dp, $e, options)
  362. {
  363. if(options && options.$target) options.$target.find('.modal-form').modalForm();
  364. });
  365. })();
  366. /**
  367. * Nav auto justified
  368. */
  369. (function()
  370. {
  371. var winWidth = $(window).width();
  372. $.fn.navAuto = function(options)
  373. {
  374. return $(this).each(function()
  375. {
  376. var $nav = $(this), width = 0;
  377. $nav.children('a').each(function(){width += $(this).width();});
  378. $nav.toggleClass('justified', width < winWidth);
  379. });
  380. };
  381. $(function(){$('.nav-auto').navAuto();});
  382. })();
  383. /**
  384. * Initialization
  385. */
  386. $(function()
  387. {
  388. /**
  389. * Submit button
  390. */
  391. $('body').on($.TapName, '[data-submit]', function()
  392. {
  393. $($(this).data('submit')).submit();
  394. });
  395. /**
  396. * Auto intent headline
  397. */
  398. var winWidth = $(window).width();
  399. $('.headline.indent-auto').each(function()
  400. {
  401. var $this = $(this);
  402. $this.toggleClass('indent', ($.trim($this.text()).length * 20 + 100) < winWidth);
  403. });
  404. /*
  405. * Set accent color for mobile app
  406. */
  407. if(window.webkit && window.webkit.messageHandlers.App)
  408. {
  409. window.App = {};
  410. window.App.setAccentColor = function(color)
  411. {
  412. window.webkit.messageHandlers.App.postMessage({method: 'setAccentColor', color: color});
  413. }
  414. }
  415. $('body').on($.TapName, '.table tr', function(e)
  416. {
  417. if($(e.target).closest('a').length) return;
  418. if($(this).data('url')) window.location = $(this).data('url');
  419. })
  420. });
  421. $(function()
  422. {
  423. if(typeof wx === 'undefined') return;
  424. wx.config(
  425. {
  426. debug: false,
  427. appId: v.appId, //此处的appId等同于企业的CorpID
  428. timestamp: iitimestamp,
  429. nonceStr: v.nonceStr,
  430. signature: v.signature,
  431. jsApiList: ['checkJsApi', 'chooseImage', 'scanQRCode']
  432. });
  433. wx.ready(function()
  434. {
  435. $('body').on($.TapName, '.scanQRCode', function()
  436. {
  437. wx.scanQRCode(
  438. {
  439. desc: 'scanQRCode desc',
  440. needResult: 0,
  441. scanType: ['qrCode', 'barCode'],
  442. success: function(response)
  443. {
  444. alert(response.errMsg);
  445. },
  446. error: function(response)
  447. {
  448. if(response.errMsg.indexOf('function_not_exist') > 0){alert('版本过低请升级');}
  449. }
  450. });
  451. })
  452. $('body').on($.TapName, '.chooseImage', function()
  453. {
  454. wx.chooseImage(
  455. {
  456. count: 1,
  457. sizeType: ['original', 'compressed'],
  458. sourceType: ['album', 'camera'],
  459. success: function (response)
  460. {
  461. wx.uploadImage(
  462. {
  463. localId: response.localIds[0],
  464. isShowProcess: 1,
  465. success: function(res)
  466. {
  467. var imageID = window.btoa(res.serverId);
  468. var url = $('.chooseImage').data('url').replace('imageID', imageID);
  469. $.getJSON(url, function(data)
  470. {
  471. alert(data.message)
  472. })
  473. }
  474. })
  475. }
  476. });
  477. })
  478. })
  479. })
  480. function fixAppnav()
  481. {
  482. var winWidth = $(window).width();
  483. var width = 0;
  484. $('#appnav a').each(function()
  485. {
  486. width += $(this).outerWidth();
  487. });
  488. if(width > winWidth)
  489. {
  490. $('#appnav a.moreAppnav').removeClass('hidden');
  491. var lastNav = $('#appnav > a').not('.moreAppnav').last();
  492. lastNav.addClass('item').css('display', lastNav.css('display'));
  493. $('#moreAppnav').prepend("<div class='divider no-margin'></div>");
  494. $('#moreAppnav').prepend(lastNav);
  495. fixAppnav();
  496. }
  497. }
  498. function fixMenu()
  499. {
  500. var winWidth = $(window).width();
  501. var width = 0;
  502. $('#menu a').each(function()
  503. {
  504. width += $(this).outerWidth();
  505. });
  506. if($('#menu select').length > 0)
  507. {
  508. width += $('#menu select').outerWidth();
  509. }
  510. if($('#menu #dateBox').length > 0)
  511. {
  512. width += $('#menu #dateBox').outerWidth();
  513. }
  514. if(width > winWidth)
  515. {
  516. $('#menu a.moreMenu').removeClass('hidden');
  517. var $lastMenu = $('#menu > a').not('.moreMenu').last();
  518. $lastMenu.addClass('item').css('display', $lastMenu.css('display'));
  519. $('#moreMenu').prepend("<div class='divider no-margin'></div>").prepend($lastMenu);
  520. fixMenu();
  521. }
  522. }
  523. /**
  524. * Set mailto
  525. *
  526. * @param string mailto
  527. * @param int $contactListID
  528. * @access public
  529. * @return void
  530. */
  531. function setMailto(mailto, contactListID)
  532. {
  533. link = createLink('user', 'ajaxGetContactUsers', 'listID=' + contactListID);
  534. $.get(link, function(users)
  535. {
  536. $('#' + mailto).replaceWith(users);
  537. });
  538. }
  539. /**
  540. * Show search drop menu.
  541. *
  542. * @param string $objectType product|project
  543. * @param int $objectID
  544. * @param string $module
  545. * @param string $method
  546. * @param string $extra
  547. * @access public
  548. * @return void
  549. */
  550. function showSearchMenu(objectType, objectID, module, method, extra)
  551. {
  552. var main = objectType == 'branch' ? 'currentBranch' : 'currentItem';
  553. var $menu = $('#' + main + 'DropMenu');
  554. var searchItems = function($menu, $items, $search)
  555. {
  556. var searchText = $.trim($search.val());
  557. $menu.removeClass('searching');
  558. $items.removeClass('active');
  559. if(searchText !== null && searchText.length)
  560. {
  561. $items.removeClass('show-search');
  562. $menu.addClass('searching');
  563. var isTag = searchText.length > 1 && (searchText[0] === ':' || searchText[0] === '@' || searchText[0] === '#');
  564. $items.each(function()
  565. {
  566. var $item = $(this);
  567. var item = $item.data();
  568. item.key = (item.key || '') + $item.text();
  569. item.tag = (item.tag || '') + '#' + item.id;
  570. if((isTag && item.tag.indexOf(searchText) > -1) || item.key.indexOf(searchText) > -1)
  571. {
  572. $item.addClass('show-search');
  573. }
  574. });
  575. var $resultItems = $items.filter('.show-search');
  576. if(!$resultItems.filter('.active').length)
  577. {
  578. $resultItems.first().addClass('active');
  579. }
  580. }
  581. };
  582. if(!$menu.data('initData'))
  583. {
  584. var remoteUrl = createLink(objectType, 'ajaxGetDropMenu', "objectID=" + objectID + "&module=" + module + "&method=" + method + "&extra=" + extra);
  585. $.get(remoteUrl, function(data)
  586. {
  587. $menu.html(data);
  588. dropMenuDisplay = new $.Display({display: 'modal', source: $menu.html(), placement: 'top'});
  589. dropMenuDisplay.show(function()
  590. {
  591. var $menu = $('.display.modal.in');
  592. var $search = $menu.find('#search');
  593. var $items = $menu.find('#searchResult .list > .item');
  594. var searchCallTask = null;
  595. $search.on('change keyup paste input propertychange', function()
  596. {
  597. clearTimeout(searchCallTask);
  598. searchCallTask = setTimeout(searchItems($menu, $items, $search), 100);
  599. }).focus();
  600. });
  601. });
  602. $menu.data('initData', true);
  603. }
  604. else
  605. {
  606. dropMenuDisplay = new $.Display({display: 'modal', source: $menu.html(), placement: 'top'});
  607. dropMenuDisplay.show(function()
  608. {
  609. var $menu = $('.display.modal.in');
  610. var $search = $menu.find('#search');
  611. var $items = $menu.find('#searchResult .list > .item');
  612. var searchCallTask = null;
  613. $search.on('change keyup paste input propertychange', function()
  614. {
  615. clearTimeout(searchCallTask);
  616. searchCallTask = setTimeout(searchItems($menu, $items, $search), 100);
  617. }).focus();
  618. });
  619. }
  620. $('#' + main).on('click', function(e){e.stopPropagation();});
  621. }
  622. /**
  623. * Set the max with of image.
  624. *
  625. * @access public
  626. * @return void
  627. */
  628. function setImageSize(image, maxWidth)
  629. {
  630. /* If not set maxWidth, set it auto. */
  631. if(!maxWidth)
  632. {
  633. bodyWidth = $('body').width();
  634. maxWidth = bodyWidth - 470; // The side bar's width is 336, and add some margins.
  635. }
  636. if($(image).width() > maxWidth) $(image).attr('width', maxWidth);
  637. $(image).wrap('<a href="' + $(image).attr('src') + '" target="_blank"></a>');
  638. }
  639. /**
  640. * Adjust header title width.
  641. *
  642. * @access public
  643. * @return void
  644. */
  645. function adjustHeaderTitleWidth()
  646. {
  647. var titleMaxWidth = $('#appbar').width() - 44 * 2 - 30;
  648. if($('#appbar #headerTitle').width() > titleMaxWidth)
  649. {
  650. $('#appbar #headerTitle').width(titleMaxWidth).css({'overflow': 'hidden', "text-overflow": 'ellipsis'});
  651. }
  652. }
  653. function showSearchObjectID()
  654. {
  655. var reg = /[^0-9]/;
  656. var $searchBox = $('#searchBox');
  657. var $dropmenu = $searchBox.children('.dropdown-search-menu');
  658. var $searchQuery = $searchBox.find('#words');
  659. var searchType = $('#searchType').val();
  660. var refreshMenu = function()
  661. {
  662. var val = $searchQuery.val();
  663. $dropmenu.addClass('hidden')
  664. if(val !== null && val !== "")
  665. {
  666. var isQuickGo = !reg.test(val);
  667. $dropmenu.toggleClass('show-quick-go', isQuickGo);
  668. if(isQuickGo)
  669. {
  670. $dropmenu.removeClass('with-active').find('li > a').each(function()
  671. {
  672. var $this = $(this);
  673. var isActiveType = $this.data('value') === searchType && searchType !== 'all';
  674. $this.closest('li').toggleClass('active', isActiveType);
  675. $this.html($this.data('name') + ' <span>#' + (val.length > 4 ? (val.substr(0, 4) + '...') : val) + "</span>");
  676. if(isActiveType) $dropmenu.addClass('with-active');
  677. });
  678. $dropmenu.removeClass('hidden')
  679. }
  680. }
  681. };
  682. $dropmenu.on('click', 'a', function(e)
  683. {
  684. self.location.href= createLink($(this).data('value'), 'view', 'id=' + $searchQuery.val());
  685. e.stopPropagation();
  686. }).find('li > a').each(function()
  687. {
  688. var $this = $(this);
  689. $this.attr('data-name', $this.text());
  690. });
  691. $searchQuery.on('change keyup paste input propertychange', refreshMenu).on('focus', function()
  692. {
  693. setTimeout(refreshMenu, 300);
  694. });
  695. }
  696. function computePasswordStrength(password)
  697. {
  698. if(password.length == 0) return 0;
  699. var strength = 0;
  700. var length = password.length;
  701. var uniqueChars = '';
  702. var complexity = new Array();
  703. for(i = 0; i < length; i++)
  704. {
  705. letter = password.charAt(i);
  706. var asc = letter.charCodeAt();
  707. if(asc >= 48 && asc <= 57)
  708. {
  709. complexity[2] = 2;
  710. }
  711. else if((asc >= 65 && asc <= 90))
  712. {
  713. complexity[1] = 2;
  714. }
  715. else if(asc >= 97 && asc <= 122)
  716. {
  717. complexity[0] = 1;
  718. }
  719. else
  720. {
  721. complexity[3] = 3;
  722. }
  723. if(uniqueChars.indexOf(letter) == -1) uniqueChars += letter;
  724. }
  725. if(uniqueChars.length > 4) strength += uniqueChars.length - 4;
  726. var sumComplexity = 0;
  727. var complexitySize = 0;
  728. for(i in complexity)
  729. {
  730. complexitySize += 1;
  731. sumComplexity += complexity[i];
  732. }
  733. strength += sumComplexity + (2 * (complexitySize - 1));
  734. if(length < 6 && strength >= 10) strength = 9;
  735. strength = strength > 29 ? 29 : strength;
  736. strength = Math.floor(strength / 10);
  737. return strength;
  738. }
  739. function setPing()
  740. {
  741. $('#hiddenwin').attr('src', createLink('misc', 'ping'));
  742. }
  743. needPing = true;
  744. $(function()
  745. {
  746. $('body').on($.TapName, '.lang-menu > a', function()
  747. {
  748. selectLang($(this).data('value'));
  749. });
  750. if(needPing) setTimeout('setPing()', 1000 * 60 * 10); // After 10 minutes, begin ping.
  751. showSearchObjectID()
  752. adjustHeaderTitleWidth();
  753. initSortPanel();
  754. disableContextMenu();
  755. initListWithPager();
  756. fixAppnav();
  757. fixMenu();
  758. });