js.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842
  1. /**
  2. * Disable console output unless DEBUG mode is enabled.
  3. * Add
  4. * define('DEBUG', true);
  5. * To the end of config/config.php to enable debug mode.
  6. * The undefined checks fix the broken ie8 console
  7. */
  8. var oc_debug;
  9. var oc_webroot;
  10. var oc_requesttoken;
  11. if (typeof oc_webroot === "undefined") {
  12. oc_webroot = location.pathname.substr(0, location.pathname.lastIndexOf('/'));
  13. }
  14. if (oc_debug !== true || typeof console === "undefined" || typeof console.log === "undefined") {
  15. if (!window.console) {
  16. window.console = {};
  17. }
  18. var methods = ['log', 'debug', 'warn', 'info', 'error', 'assert'];
  19. for (var i = 0; i < methods.length; i++) {
  20. console[methods[i]] = function () { };
  21. }
  22. }
  23. /**
  24. * translate a string
  25. * @param app the id of the app for which to translate the string
  26. * @param text the string to translate
  27. * @return string
  28. */
  29. function t(app,text, vars){
  30. if( !( t.cache[app] )){
  31. $.ajax(OC.filePath('core','ajax','translations.php'),{
  32. async:false,//todo a proper sollution for this without sync ajax calls
  33. data:{'app': app},
  34. type:'POST',
  35. success:function(jsondata){
  36. t.cache[app] = jsondata.data;
  37. }
  38. });
  39. // Bad answer ...
  40. if( !( t.cache[app] )){
  41. t.cache[app] = [];
  42. }
  43. }
  44. var _build = function (text, vars) {
  45. return text.replace(/{([^{}]*)}/g,
  46. function (a, b) {
  47. var r = vars[b];
  48. return typeof r === 'string' || typeof r === 'number' ? r : a;
  49. }
  50. );
  51. };
  52. if( typeof( t.cache[app][text] ) !== 'undefined' ){
  53. if(typeof vars === 'object') {
  54. return _build(t.cache[app][text], vars);
  55. } else {
  56. return t.cache[app][text];
  57. }
  58. }
  59. else{
  60. if(typeof vars === 'object') {
  61. return _build(text, vars);
  62. } else {
  63. return text;
  64. }
  65. }
  66. }
  67. t.cache={};
  68. /*
  69. * Sanitizes a HTML string
  70. * @param string
  71. * @return Sanitized string
  72. */
  73. function escapeHTML(s) {
  74. return s.toString().split('&').join('&amp;').split('<').join('&lt;').split('"').join('&quot;');
  75. }
  76. /**
  77. * Get the path to download a file
  78. * @param file The filename
  79. * @param dir The directory the file is in - e.g. $('#dir').val()
  80. * @return string
  81. */
  82. function fileDownloadPath(dir, file) {
  83. return OC.filePath('files', 'ajax', 'download.php')+'?files='+encodeURIComponent(file)+'&dir='+encodeURIComponent(dir);
  84. }
  85. var OC={
  86. PERMISSION_CREATE:4,
  87. PERMISSION_READ:1,
  88. PERMISSION_UPDATE:2,
  89. PERMISSION_DELETE:8,
  90. PERMISSION_SHARE:16,
  91. webroot:oc_webroot,
  92. appswebroots:(typeof oc_appswebroots !== 'undefined') ? oc_appswebroots:false,
  93. currentUser:(typeof oc_current_user!=='undefined')?oc_current_user:false,
  94. coreApps:['', 'admin','log','search','settings','core','3rdparty'],
  95. /**
  96. * get an absolute url to a file in an appen
  97. * @param app the id of the app the file belongs to
  98. * @param file the file path relative to the app folder
  99. * @return string
  100. */
  101. linkTo:function(app,file){
  102. return OC.filePath(app,'',file);
  103. },
  104. /**
  105. * Creates an url for remote use
  106. * @param string $service id
  107. * @return string the url
  108. *
  109. * Returns a url to the given service.
  110. */
  111. linkToRemoteBase:function(service) {
  112. return OC.webroot + '/remote.php/' + service;
  113. },
  114. /**
  115. * @brief Creates an absolute url for remote use
  116. * @param string $service id
  117. * @param bool $add_slash
  118. * @return string the url
  119. *
  120. * Returns a absolute url to the given service.
  121. */
  122. linkToRemote:function(service) {
  123. return window.location.protocol + '//' + window.location.host + OC.linkToRemoteBase(service);
  124. },
  125. /**
  126. * get the absolute url for a file in an app
  127. * @param app the id of the app
  128. * @param type the type of the file to link to (e.g. css,img,ajax.template)
  129. * @param file the filename
  130. * @return string
  131. */
  132. filePath:function(app,type,file){
  133. var isCore=OC.coreApps.indexOf(app)!==-1,
  134. link=OC.webroot;
  135. if((file.substring(file.length-3) === 'php' || file.substring(file.length-3) === 'css') && !isCore){
  136. link+='/index.php/apps/' + app;
  137. if (file != 'index.php') {
  138. link+='/';
  139. if(type){
  140. link+=encodeURI(type + '/');
  141. }
  142. link+= file;
  143. }
  144. }else if(file.substring(file.length-3) !== 'php' && !isCore){
  145. link=OC.appswebroots[app];
  146. if(type){
  147. link+= '/'+type+'/';
  148. }
  149. if(link.substring(link.length-1) !== '/'){
  150. link+='/';
  151. }
  152. link+=file;
  153. }else{
  154. if ((app == 'settings' || app == 'core' || app == 'search') && type == 'ajax') {
  155. link+='/index.php/';
  156. }
  157. else {
  158. link+='/';
  159. }
  160. if(!isCore){
  161. link+='apps/';
  162. }
  163. if (app !== '') {
  164. app+='/';
  165. link+=app;
  166. }
  167. if(type){
  168. link+=type+'/';
  169. }
  170. link+=file;
  171. }
  172. return link;
  173. },
  174. /**
  175. * get the absolute path to an image file
  176. * @param app the app id to which the image belongs
  177. * @param file the name of the image file
  178. * @return string
  179. *
  180. * if no extension is given for the image, it will automatically decide between .png and .svg based on what the browser supports
  181. */
  182. imagePath:function(app,file){
  183. if(file.indexOf('.')==-1){//if no extension is given, use png or svg depending on browser support
  184. file+=(SVGSupport())?'.svg':'.png';
  185. }
  186. return OC.filePath(app,'img',file);
  187. },
  188. /**
  189. * load a script for the server and load it
  190. * @param app the app id to which the script belongs
  191. * @param script the filename of the script
  192. * @param ready event handeler to be called when the script is loaded
  193. *
  194. * if the script is already loaded, the event handeler will be called directly
  195. */
  196. addScript:function(app,script,ready){
  197. var deferred, path=OC.filePath(app,'js',script+'.js');
  198. if(!OC.addScript.loaded[path]){
  199. if(ready){
  200. deferred=$.getScript(path,ready);
  201. }else{
  202. deferred=$.getScript(path);
  203. }
  204. OC.addScript.loaded[path]=deferred;
  205. }else{
  206. if(ready){
  207. ready();
  208. }
  209. }
  210. return OC.addScript.loaded[path];
  211. },
  212. /**
  213. * load a css file and load it
  214. * @param app the app id to which the css style belongs
  215. * @param style the filename of the css file
  216. */
  217. addStyle:function(app,style){
  218. var path=OC.filePath(app,'css',style+'.css');
  219. if(OC.addStyle.loaded.indexOf(path)===-1){
  220. OC.addStyle.loaded.push(path);
  221. style=$('<link rel="stylesheet" type="text/css" href="'+path+'"/>');
  222. $('head').append(style);
  223. }
  224. },
  225. basename: function(path) {
  226. return path.replace(/\\/g,'/').replace( /.*\//, '' );
  227. },
  228. dirname: function(path) {
  229. return path.replace(/\\/g,'/').replace(/\/[^\/]*$/, '');
  230. },
  231. /**
  232. * do a search query and display the results
  233. * @param query the search query
  234. */
  235. search:function(query){
  236. if(query){
  237. OC.addStyle('search','results');
  238. $.getJSON(OC.filePath('search','ajax','search.php')+'?query='+encodeURIComponent(query), function(results){
  239. OC.search.lastResults=results;
  240. OC.search.showResults(results);
  241. });
  242. }
  243. },
  244. dialogs:OCdialogs,
  245. mtime2date:function(mtime) {
  246. mtime = parseInt(mtime,10);
  247. var date = new Date(1000*mtime);
  248. return date.getDate()+'.'+(date.getMonth()+1)+'.'+date.getFullYear()+', '+date.getHours()+':'+date.getMinutes();
  249. },
  250. /**
  251. * Opens a popup with the setting for an app.
  252. * @param appid String. The ID of the app e.g. 'calendar', 'contacts' or 'files'.
  253. * @param loadJS boolean or String. If true 'js/settings.js' is loaded. If it's a string
  254. * it will attempt to load a script by that name in the 'js' directory.
  255. * @param cache boolean. If true the javascript file won't be forced refreshed. Defaults to true.
  256. * @param scriptName String. The name of the PHP file to load. Defaults to 'settings.php' in
  257. * the root of the app directory hierarchy.
  258. */
  259. appSettings:function(args) {
  260. if(typeof args === 'undefined' || typeof args.appid === 'undefined') {
  261. throw { name: 'MissingParameter', message: 'The parameter appid is missing' };
  262. }
  263. var props = {scriptName:'settings.php', cache:true};
  264. $.extend(props, args);
  265. var settings = $('#appsettings');
  266. if(settings.length == 0) {
  267. throw { name: 'MissingDOMElement', message: 'There has be be an element with id "appsettings" for the popup to show.' };
  268. }
  269. var popup = $('#appsettings_popup');
  270. if(popup.length == 0) {
  271. $('body').prepend('<div class="popup hidden" id="appsettings_popup"></div>');
  272. popup = $('#appsettings_popup');
  273. popup.addClass(settings.hasClass('topright') ? 'topright' : 'bottomleft');
  274. }
  275. if(popup.is(':visible')) {
  276. popup.hide().remove();
  277. } else {
  278. var arrowclass = settings.hasClass('topright') ? 'up' : 'left';
  279. var jqxhr = $.get(OC.filePath(props.appid, '', props.scriptName), function(data) {
  280. popup.html(data).ready(function() {
  281. popup.prepend('<span class="arrow '+arrowclass+'"></span><h2>'+t('core', 'Settings')+'</h2><a class="close svg"></a>').show();
  282. popup.find('.close').bind('click', function() {
  283. popup.remove();
  284. });
  285. if(typeof props.loadJS !== 'undefined') {
  286. var scriptname;
  287. if(props.loadJS === true) {
  288. scriptname = 'settings.js';
  289. } else if(typeof props.loadJS === 'string') {
  290. scriptname = props.loadJS;
  291. } else {
  292. throw { name: 'InvalidParameter', message: 'The "loadJS" parameter must be either boolean or a string.' };
  293. }
  294. if(props.cache) {
  295. $.ajaxSetup({cache: true});
  296. }
  297. $.getScript(OC.filePath(props.appid, 'js', scriptname))
  298. .fail(function(jqxhr, settings, e) {
  299. throw e;
  300. });
  301. }
  302. }).show();
  303. }, 'html');
  304. }
  305. }
  306. };
  307. OC.search.customResults={};
  308. OC.search.currentResult=-1;
  309. OC.search.lastQuery='';
  310. OC.search.lastResults={};
  311. OC.addStyle.loaded=[];
  312. OC.addScript.loaded=[];
  313. OC.Notification={
  314. queuedNotifications: [],
  315. getDefaultNotificationFunction: null,
  316. setDefault: function(callback) {
  317. OC.Notification.getDefaultNotificationFunction = callback;
  318. },
  319. hide: function(callback) {
  320. $('#notification').fadeOut('400', function(){
  321. if (OC.Notification.isHidden()) {
  322. if (OC.Notification.getDefaultNotificationFunction) {
  323. OC.Notification.getDefaultNotificationFunction.call();
  324. }
  325. }
  326. if (callback) {
  327. callback.call();
  328. }
  329. $('#notification').empty();
  330. if(OC.Notification.queuedNotifications.length > 0){
  331. OC.Notification.showHtml(OC.Notification.queuedNotifications[0]);
  332. OC.Notification.queuedNotifications.shift();
  333. }
  334. });
  335. },
  336. showHtml: function(html) {
  337. if(($('#notification').filter('span.undo').length == 1) || OC.Notification.isHidden()){
  338. $('#notification').html(html);
  339. $('#notification').fadeIn().css("display","inline");
  340. }else{
  341. OC.Notification.queuedNotifications.push(html);
  342. }
  343. },
  344. show: function(text) {
  345. if(($('#notification').filter('span.undo').length == 1) || OC.Notification.isHidden()){
  346. $('#notification').html(text);
  347. $('#notification').fadeIn().css("display","inline");
  348. }else{
  349. OC.Notification.queuedNotifications.push($(text).html());
  350. }
  351. },
  352. isHidden: function() {
  353. return ($("#notification").text() === '');
  354. }
  355. };
  356. OC.Breadcrumb={
  357. container:null,
  358. crumbs:[],
  359. push:function(name, link){
  360. if(!OC.Breadcrumb.container){//default
  361. OC.Breadcrumb.container=$('#controls');
  362. }
  363. var crumb=$('<div/>');
  364. crumb.addClass('crumb').addClass('last');
  365. var crumbLink=$('<a/>');
  366. crumbLink.attr('href',link);
  367. crumbLink.text(name);
  368. crumb.append(crumbLink);
  369. var existing=OC.Breadcrumb.container.find('div.crumb');
  370. if(existing.length){
  371. existing.removeClass('last');
  372. existing.last().after(crumb);
  373. }else{
  374. OC.Breadcrumb.container.append(crumb);
  375. }
  376. OC.Breadcrumb.crumbs.push(crumb);
  377. return crumb;
  378. },
  379. pop:function(){
  380. if(!OC.Breadcrumb.container){//default
  381. OC.Breadcrumb.container=$('#controls');
  382. }
  383. OC.Breadcrumb.container.find('div.crumb').last().remove();
  384. OC.Breadcrumb.container.find('div.crumb').last().addClass('last');
  385. OC.Breadcrumb.crumbs.pop();
  386. },
  387. clear:function(){
  388. if(!OC.Breadcrumb.container){//default
  389. OC.Breadcrumb.container=$('#controls');
  390. }
  391. OC.Breadcrumb.container.find('div.crumb').remove();
  392. OC.Breadcrumb.crumbs=[];
  393. }
  394. };
  395. if(typeof localStorage !=='undefined' && localStorage !== null){
  396. //user and instance aware localstorage
  397. OC.localStorage={
  398. namespace:'oc_'+OC.currentUser+'_'+OC.webroot+'_',
  399. hasItem:function(name){
  400. return OC.localStorage.getItem(name)!==null;
  401. },
  402. setItem:function(name,item){
  403. return localStorage.setItem(OC.localStorage.namespace+name,JSON.stringify(item));
  404. },
  405. getItem:function(name){
  406. var item = localStorage.getItem(OC.localStorage.namespace+name);
  407. if(item===null) {
  408. return null;
  409. } else if (typeof JSON === 'undefined') {
  410. //fallback to jquery for IE6/7/8
  411. return $.parseJSON(item);
  412. } else {
  413. return JSON.parse(item);
  414. }
  415. }
  416. };
  417. }else{
  418. //dummy localstorage
  419. OC.localStorage={
  420. hasItem:function(){
  421. return false;
  422. },
  423. setItem:function(){
  424. return false;
  425. },
  426. getItem:function(){
  427. return null;
  428. }
  429. };
  430. }
  431. /**
  432. * implement Array.filter for browsers without native support
  433. */
  434. if (!Array.prototype.filter) {
  435. Array.prototype.filter = function(fun /*, thisp*/) {
  436. var len = this.length >>> 0;
  437. if (typeof fun !== "function"){
  438. throw new TypeError();
  439. }
  440. var res = [];
  441. var thisp = arguments[1];
  442. for (var i = 0; i < len; i++) {
  443. if (i in this) {
  444. var val = this[i]; // in case fun mutates this
  445. if (fun.call(thisp, val, i, this))
  446. res.push(val);
  447. }
  448. }
  449. return res;
  450. };
  451. }
  452. /**
  453. * implement Array.indexOf for browsers without native support
  454. */
  455. if (!Array.prototype.indexOf){
  456. Array.prototype.indexOf = function(elt /*, from*/)
  457. {
  458. var len = this.length;
  459. var from = Number(arguments[1]) || 0;
  460. from = (from < 0) ? Math.ceil(from) : Math.floor(from);
  461. if (from < 0){
  462. from += len;
  463. }
  464. for (; from < len; from++)
  465. {
  466. if (from in this && this[from] === elt){
  467. return from;
  468. }
  469. }
  470. return -1;
  471. };
  472. }
  473. /**
  474. * check if the browser support svg images
  475. */
  476. function SVGSupport() {
  477. return SVGSupport.checkMimeType.correct && !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', "svg").createSVGRect;
  478. }
  479. SVGSupport.checkMimeType=function(){
  480. $.ajax({
  481. url: OC.imagePath('core','breadcrumb.svg'),
  482. success:function(data,text,xhr){
  483. var headerParts=xhr.getAllResponseHeaders().split("\n");
  484. var headers={};
  485. $.each(headerParts,function(i,text){
  486. if(text){
  487. var parts=text.split(':',2);
  488. if(parts.length===2){
  489. var value=parts[1].trim();
  490. if(value[0]==='"'){
  491. value=value.substr(1,value.length-2);
  492. }
  493. headers[parts[0]]=value;
  494. }
  495. }
  496. });
  497. if(headers["Content-Type"]!=='image/svg+xml'){
  498. replaceSVG();
  499. SVGSupport.checkMimeType.correct=false;
  500. }
  501. }
  502. });
  503. };
  504. SVGSupport.checkMimeType.correct=true;
  505. //replace all svg images with png for browser compatibility
  506. function replaceSVG(){
  507. $('img.svg').each(function(index,element){
  508. element=$(element);
  509. var src=element.attr('src');
  510. element.attr('src',src.substr(0,src.length-3)+'png');
  511. });
  512. $('.svg').each(function(index,element){
  513. element=$(element);
  514. var background=element.css('background-image');
  515. if(background){
  516. var i=background.lastIndexOf('.svg');
  517. if(i>=0){
  518. background=background.substr(0,i)+'.png'+background.substr(i+4);
  519. element.css('background-image',background);
  520. }
  521. }
  522. element.find('*').each(function(index,element) {
  523. element=$(element);
  524. var background=element.css('background-image');
  525. if(background){
  526. var i=background.lastIndexOf('.svg');
  527. if(i>=0){
  528. background=background.substr(0,i)+'.png'+background.substr(i+4);
  529. element.css('background-image',background);
  530. }
  531. }
  532. });
  533. });
  534. }
  535. /**
  536. * prototypal inharitence functions
  537. *
  538. * usage:
  539. * MySubObject=object(MyObject)
  540. */
  541. function object(o) {
  542. function F() {}
  543. F.prototype = o;
  544. return new F();
  545. }
  546. /**
  547. * Fills height of window. (more precise than height: 100%;)
  548. */
  549. function fillHeight(selector) {
  550. if (selector.length === 0) {
  551. return;
  552. }
  553. var height = parseFloat($(window).height())-selector.offset().top;
  554. selector.css('height', height + 'px');
  555. if(selector.outerHeight() > selector.height()){
  556. selector.css('height', height-(selector.outerHeight()-selector.height()) + 'px');
  557. }
  558. console.warn("This function is deprecated! Use CSS instead");
  559. }
  560. /**
  561. * Fills height and width of window. (more precise than height: 100%; or width: 100%;)
  562. */
  563. function fillWindow(selector) {
  564. if (selector.length === 0) {
  565. return;
  566. }
  567. fillHeight(selector);
  568. var width = parseFloat($(window).width())-selector.offset().left;
  569. selector.css('width', width + 'px');
  570. if(selector.outerWidth() > selector.width()){
  571. selector.css('width', width-(selector.outerWidth()-selector.width()) + 'px');
  572. }
  573. console.warn("This function is deprecated! Use CSS instead");
  574. }
  575. $(document).ready(function(){
  576. sessionHeartBeat();
  577. if(!SVGSupport()){ //replace all svg images with png images for browser that dont support svg
  578. replaceSVG();
  579. }else{
  580. SVGSupport.checkMimeType();
  581. }
  582. $('form.searchbox').submit(function(event){
  583. event.preventDefault();
  584. });
  585. $('#searchbox').keyup(function(event){
  586. if(event.keyCode===13){//enter
  587. if(OC.search.currentResult>-1){
  588. var result=$('#searchresults tr.result a')[OC.search.currentResult];
  589. window.location = $(result).attr('href');
  590. }
  591. }else if(event.keyCode===38){//up
  592. if(OC.search.currentResult>0){
  593. OC.search.currentResult--;
  594. OC.search.renderCurrent();
  595. }
  596. }else if(event.keyCode===40){//down
  597. if(OC.search.lastResults.length>OC.search.currentResult+1){
  598. OC.search.currentResult++;
  599. OC.search.renderCurrent();
  600. }
  601. }else if(event.keyCode===27){//esc
  602. OC.search.hide();
  603. }else{
  604. var query=$('#searchbox').val();
  605. if(OC.search.lastQuery!==query){
  606. OC.search.lastQuery=query;
  607. OC.search.currentResult=-1;
  608. if(query.length>2){
  609. OC.search(query);
  610. }else{
  611. if(OC.search.hide){
  612. OC.search.hide();
  613. }
  614. }
  615. }
  616. }
  617. });
  618. // 'show password' checkbox
  619. $('#password').showPassword();
  620. $('#adminpass').showPassword();
  621. $('#pass2').showPassword();
  622. //use infield labels
  623. $("label.infield").inFieldLabels();
  624. var checkShowCredentials = function() {
  625. var empty = false;
  626. $('input#user, input#password').each(function() {
  627. if ($(this).val() === '') {
  628. empty = true;
  629. }
  630. });
  631. if(empty) {
  632. $('#submit').fadeOut();
  633. $('#remember_login').hide();
  634. $('#remember_login+label').fadeOut();
  635. } else {
  636. $('#submit').fadeIn();
  637. $('#remember_login').show();
  638. $('#remember_login+label').fadeIn();
  639. }
  640. };
  641. // hide log in button etc. when form fields not filled
  642. // commented out due to some browsers having issues with it
  643. // checkShowCredentials();
  644. // $('input#user, input#password').keyup(checkShowCredentials);
  645. $('#settings #expand').keydown(function(event) {
  646. if (event.which === 13 || event.which === 32) {
  647. $('#expand').click()
  648. }
  649. });
  650. $('#settings #expand').click(function(event) {
  651. $('#settings #expanddiv').slideToggle(200);
  652. event.stopPropagation();
  653. });
  654. $('#settings #expanddiv').click(function(event){
  655. event.stopPropagation();
  656. });
  657. $(document).click(function(){//hide the settings menu when clicking outside it
  658. $('#settings #expanddiv').slideUp(200);
  659. });
  660. // all the tipsy stuff needs to be here (in reverse order) to work
  661. $('.jp-controls .jp-previous').tipsy({gravity:'nw', fade:true, live:true});
  662. $('.jp-controls .jp-next').tipsy({gravity:'n', fade:true, live:true});
  663. $('.displayName .action').tipsy({gravity:'se', fade:true, live:true});
  664. $('.password .action').tipsy({gravity:'se', fade:true, live:true});
  665. $('#upload').tipsy({gravity:'w', fade:true});
  666. $('.selectedActions a').tipsy({gravity:'s', fade:true, live:true});
  667. $('a.delete').tipsy({gravity: 'e', fade:true, live:true});
  668. $('a.action').tipsy({gravity:'s', fade:true, live:true});
  669. $('#headerSize').tipsy({gravity:'s', fade:true, live:true});
  670. $('td.filesize').tipsy({gravity:'s', fade:true, live:true});
  671. $('td .modified').tipsy({gravity:'s', fade:true, live:true});
  672. $('input').tipsy({gravity:'w', fade:true});
  673. $('input[type=text]').focus(function(){
  674. this.select();
  675. });
  676. });
  677. if (!Array.prototype.map){
  678. Array.prototype.map = function(fun /*, thisp */){
  679. "use strict";
  680. if (this === void 0 || this === null){
  681. throw new TypeError();
  682. }
  683. var t = Object(this);
  684. var len = t.length >>> 0;
  685. if (typeof fun !== "function"){
  686. throw new TypeError();
  687. }
  688. var res = new Array(len);
  689. var thisp = arguments[1];
  690. for (var i = 0; i < len; i++){
  691. if (i in t){
  692. res[i] = fun.call(thisp, t[i], i, t);
  693. }
  694. }
  695. return res;
  696. };
  697. }
  698. /**
  699. * Filter Jquery selector by attribute value
  700. */
  701. $.fn.filterAttr = function(attr_name, attr_value) {
  702. return this.filter(function() { return $(this).attr(attr_name) === attr_value; });
  703. };
  704. function humanFileSize(size) {
  705. var humanList = ['B', 'kB', 'MB', 'GB', 'TB'];
  706. // Calculate Log with base 1024: size = 1024 ** order
  707. var order = size?Math.floor(Math.log(size) / Math.log(1024)):0;
  708. // Stay in range of the byte sizes that are defined
  709. order = Math.min(humanList.length - 1, order);
  710. var readableFormat = humanList[order];
  711. var relativeSize = (size / Math.pow(1024, order)).toFixed(1);
  712. if(relativeSize.substr(relativeSize.length-2,2)=='.0'){
  713. relativeSize=relativeSize.substr(0,relativeSize.length-2);
  714. }
  715. return relativeSize + ' ' + readableFormat;
  716. }
  717. function simpleFileSize(bytes) {
  718. var mbytes = Math.round(bytes/(1024*1024/10))/10;
  719. if(bytes == 0) { return '0'; }
  720. else if(mbytes < 0.1) { return '< 0.1'; }
  721. else if(mbytes > 1000) { return '> 1000'; }
  722. else { return mbytes.toFixed(1); }
  723. }
  724. function formatDate(date){
  725. if(typeof date=='number'){
  726. date=new Date(date);
  727. }
  728. return $.datepicker.formatDate(datepickerFormatDate, date)+' '+date.getHours()+':'+((date.getMinutes()<10)?'0':'')+date.getMinutes();
  729. }
  730. /**
  731. * takes an absolute timestamp and return a string with a human-friendly relative date
  732. * @param int a Unix timestamp
  733. */
  734. function relative_modified_date(timestamp) {
  735. var timediff = Math.round((new Date()).getTime() / 1000) - timestamp;
  736. var diffminutes = Math.round(timediff/60);
  737. var diffhours = Math.round(diffminutes/60);
  738. var diffdays = Math.round(diffhours/24);
  739. var diffmonths = Math.round(diffdays/31);
  740. if(timediff < 60) { return t('core','seconds ago'); }
  741. else if(timediff < 120) { return t('core','1 minute ago'); }
  742. else if(timediff < 3600) { return t('core','{minutes} minutes ago',{minutes: diffminutes}); }
  743. else if(timediff < 7200) { return t('core','1 hour ago'); }
  744. else if(timediff < 86400) { return t('core','{hours} hours ago',{hours: diffhours}); }
  745. else if(timediff < 86400) { return t('core','today'); }
  746. else if(timediff < 172800) { return t('core','yesterday'); }
  747. else if(timediff < 2678400) { return t('core','{days} days ago',{days: diffdays}); }
  748. else if(timediff < 5184000) { return t('core','last month'); }
  749. else if(timediff < 31556926) { return t('core','{months} months ago',{months: diffmonths}); }
  750. //else if(timediff < 31556926) { return t('core','months ago'); }
  751. else if(timediff < 63113852) { return t('core','last year'); }
  752. else { return t('core','years ago'); }
  753. }
  754. /**
  755. * get a variable by name
  756. * @param string name
  757. */
  758. OC.get=function(name) {
  759. var namespaces = name.split(".");
  760. var tail = namespaces.pop();
  761. var context=window;
  762. for(var i = 0; i < namespaces.length; i++) {
  763. context = context[namespaces[i]];
  764. if(!context){
  765. return false;
  766. }
  767. }
  768. return context[tail];
  769. };
  770. /**
  771. * set a variable by name
  772. * @param string name
  773. * @param mixed value
  774. */
  775. OC.set=function(name, value) {
  776. var namespaces = name.split(".");
  777. var tail = namespaces.pop();
  778. var context=window;
  779. for(var i = 0; i < namespaces.length; i++) {
  780. if(!context[namespaces[i]]){
  781. context[namespaces[i]]={};
  782. }
  783. context = context[namespaces[i]];
  784. }
  785. context[tail]=value;
  786. };
  787. /**
  788. * Calls the server periodically every 15 mins to ensure that session doesnt
  789. * time out
  790. */
  791. function sessionHeartBeat(){
  792. OC.Router.registerLoadedCallback(function(){
  793. var url = OC.Router.generate('heartbeat');
  794. setInterval(function(){
  795. $.post(url);
  796. }, 900000);
  797. });
  798. }