js.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. /**
  2. * translate a string
  3. * @param app the id of the app for which to translate the string
  4. * @param text the string to translate
  5. * @return string
  6. */
  7. function t(app,text){
  8. if( !( app in t.cache )){
  9. $.post( OC.filePath('core','ajax','translations.php'), {'app': app}, function(jsondata){
  10. t.cache[app] = jsondata.data;
  11. });
  12. // Bad answer ...
  13. if( !( app in t.cache )){
  14. t.cache[app] = [];
  15. }
  16. }
  17. if( typeof( t.cache[app][text] ) !== 'undefined' ){
  18. return t.cache[app][text];
  19. }
  20. else{
  21. return text;
  22. }
  23. }
  24. t.cache={};
  25. OC={
  26. webroot:oc_webroot,
  27. currentUser:(typeof oc_current_user!=='undefined')?oc_current_user:false,
  28. coreApps:['files','admin','log','search','settings','core','3rdparty'],
  29. /**
  30. * get an absolute url to a file in an appen
  31. * @param app the id of the app the file belongs to
  32. * @param file the file path relative to the app folder
  33. * @return string
  34. */
  35. linkTo:function(app,file){
  36. return OC.filePath(app,'',file);
  37. },
  38. /**
  39. * get the absolute url for a file in an app
  40. * @param app the id of the app
  41. * @param type the type of the file to link to (e.g. css,img,ajax.template)
  42. * @param file the filename
  43. * @return string
  44. */
  45. filePath:function(app,type,file){
  46. var isCore=OC.coreApps.indexOf(app)!=-1;
  47. app+='/';
  48. var link=OC.webroot+'/';
  49. if(!isCore){
  50. link+='apps/';
  51. }
  52. link+=app;
  53. if(type){
  54. link+=type+'/'
  55. }
  56. link+=file;
  57. return link;
  58. },
  59. /**
  60. * get the absolute path to an image file
  61. * @param app the app id to which the image belongs
  62. * @param file the name of the image file
  63. * @return string
  64. *
  65. * if no extention is given for the image, it will automatically decide between .png and .svg based on what the browser supports
  66. */
  67. imagePath:function(app,file){
  68. if(file.indexOf('.')==-1){//if no extention is given, use png or svg depending on browser support
  69. file+=(SVGSupport())?'.svg':'.png'
  70. }
  71. return OC.filePath(app,'img',file);
  72. },
  73. /**
  74. * load a script for the server and load it
  75. * @param app the app id to which the script belongs
  76. * @param script the filename of the script
  77. * @param ready event handeler to be called when the script is loaded
  78. *
  79. * if the script is already loaded, the event handeler will be called directly
  80. */
  81. addScript:function(app,script,ready){
  82. var path=OC.filePath(app,'js',script+'.js');
  83. if(OC.addScript.loaded.indexOf(path)==-1){
  84. OC.addScript.loaded.push(path);
  85. if(ready){
  86. $.getScript(path,ready);
  87. }else{
  88. $.getScript(path);
  89. }
  90. }else{
  91. if(ready){
  92. ready();
  93. }
  94. }
  95. },
  96. /**
  97. * load a css file and load it
  98. * @param app the app id to which the css style belongs
  99. * @param style the filename of the css file
  100. */
  101. addStyle:function(app,style){
  102. var path=OC.filePath(app,'css',style+'.css');
  103. if(OC.addStyle.loaded.indexOf(path)==-1){
  104. OC.addStyle.loaded.push(path);
  105. var style=$('<link rel="stylesheet" type="text/css" href="'+path+'"/>');
  106. $('head').append(style);
  107. }
  108. },
  109. /**
  110. * do a search query and display the results
  111. * @param query the search query
  112. */
  113. search:function(query){
  114. if(query){
  115. OC.addStyle('search','results');
  116. $.getJSON(OC.filePath('search','ajax','search.php')+'?query='+encodeURIComponent(query), function(results){
  117. OC.search.lastResults=results;
  118. OC.search.showResults(results);
  119. });
  120. }
  121. }
  122. }
  123. OC.search.customResults={};
  124. OC.search.currentResult=-1;
  125. OC.search.lastQuery='';
  126. OC.search.lastResults={};
  127. OC.addStyle.loaded=[];
  128. OC.addScript.loaded=[];
  129. /**
  130. * implement Array.filter for browsers without native support
  131. */
  132. if (!Array.prototype.filter) {
  133. Array.prototype.filter = function(fun /*, thisp*/) {
  134. var len = this.length >>> 0;
  135. if (typeof fun != "function")
  136. throw new TypeError();
  137. var res = [];
  138. var thisp = arguments[1];
  139. for (var i = 0; i < len; i++) {
  140. if (i in this) {
  141. var val = this[i]; // in case fun mutates this
  142. if (fun.call(thisp, val, i, this))
  143. res.push(val);
  144. }
  145. }
  146. return res;
  147. }
  148. }
  149. /**
  150. * implement Array.indexOf for browsers without native support
  151. */
  152. if (!Array.prototype.indexOf){
  153. Array.prototype.indexOf = function(elt /*, from*/)
  154. {
  155. var len = this.length;
  156. var from = Number(arguments[1]) || 0;
  157. from = (from < 0)
  158. ? Math.ceil(from)
  159. : Math.floor(from);
  160. if (from < 0)
  161. from += len;
  162. for (; from < len; from++)
  163. {
  164. if (from in this &&
  165. this[from] === elt)
  166. return from;
  167. }
  168. return -1;
  169. };
  170. }
  171. /**
  172. * check if the browser support svg images
  173. */
  174. function SVGSupport() {
  175. return SVGSupport.checkMimeType.correct && !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', "svg").createSVGRect;
  176. }
  177. SVGSupport.checkMimeType=function(){
  178. $.ajax({
  179. url: OC.imagePath('core','breadcrumb.svg'),
  180. success:function(data,text,xhr){
  181. var headerParts=xhr.getAllResponseHeaders().split("\n");
  182. var headers={};
  183. $.each(headerParts,function(i,text){
  184. if(text){
  185. var parts=text.split(':',2);
  186. var value=parts[1].trim();
  187. if(value[0]=='"'){
  188. value=value.substr(1,value.length-2);
  189. }
  190. headers[parts[0]]=value;
  191. }
  192. });
  193. if(headers["Content-Type"]!='image/svg+xml'){
  194. replaceSVG();
  195. SVGSupport.checkMimeType.correct=false
  196. }
  197. }
  198. });
  199. }
  200. SVGSupport.checkMimeType.correct=true;
  201. //replace all svg images with png for browser compatibility
  202. function replaceSVG(){
  203. $('img.svg').each(function(index,element){
  204. element=$(element);
  205. var src=element.attr('src');
  206. element.attr('src',src.substr(0,src.length-3)+'png');
  207. });
  208. $('.svg').each(function(index,element){
  209. element=$(element);
  210. var background=element.css('background-image');
  211. if(background && background!='none'){
  212. background=background.substr(0,background.length-4)+'png)';
  213. element.css('background-image',background);
  214. }
  215. element.find('*').each(function(index,element) {
  216. element=$(element);
  217. var background=element.css('background-image');
  218. if(background && background!='none'){
  219. background=background.substr(0,background.length-4)+'png)';
  220. element.css('background-image',background);
  221. }
  222. });
  223. });
  224. }
  225. /**
  226. * prototypal inharitence functions
  227. *
  228. * usage:
  229. * MySubObject=object(MyObject)
  230. */
  231. function object(o) {
  232. function F() {}
  233. F.prototype = o;
  234. return new F();
  235. }
  236. /**
  237. * Fills height of window. (more precise than height: 100%;)
  238. */
  239. function fillHeight(selector) {
  240. var height = parseFloat($(window).height())-parseFloat(selector.css('top'));
  241. selector.css('height', height + 'px');
  242. if(selector.outerHeight() > selector.height())
  243. selector.css('height', height-(selector.outerHeight()-selector.height()) + 'px');
  244. }
  245. /**
  246. * Fills height and width of window. (more precise than height: 100%; or width: 100%;)
  247. */
  248. function fillWindow(selector) {
  249. fillHeight(selector);
  250. var width = parseFloat($(window).width())-parseFloat(selector.css('left'));
  251. selector.css('width', width + 'px');
  252. if(selector.outerWidth() > selector.width())
  253. selector.css('width', width-(selector.outerWidth()-selector.width()) + 'px');
  254. }
  255. $(document).ready(function(){
  256. $(window).resize(function () {
  257. fillHeight($('#leftcontent'));
  258. fillWindow($('#rightcontent'));
  259. });
  260. $(window).trigger('resize');
  261. if(!SVGSupport()){//replace all svg images with png images for browser that dont support svg
  262. replaceSVG();
  263. }else{
  264. SVGSupport.checkMimeType();
  265. }
  266. $('form.searchbox').submit(function(event){
  267. event.preventDefault();
  268. });
  269. $('#searchbox').keyup(function(event){
  270. if(event.keyCode==13){//enter
  271. if(OC.search.currentResult>-1){
  272. var result=$('#searchresults tr.result a')[OC.search.currentResult];
  273. window.location = $(result).attr('href');
  274. }
  275. }else if(event.keyCode==38){//up
  276. if(OC.search.currentResult>0){
  277. OC.search.currentResult--;
  278. OC.search.renderCurrent();
  279. }
  280. }else if(event.keyCode==40){//down
  281. if(OC.search.lastResults.length>OC.search.currentResult+1){
  282. OC.search.currentResult++;
  283. OC.search.renderCurrent();
  284. }
  285. }else if(event.keyCode==27){//esc
  286. OC.search.hide();
  287. }else{
  288. var query=$('#searchbox').val();
  289. if(OC.search.lastQuery!=query){
  290. OC.search.lastQuery=query;
  291. OC.search.currentResult=-1;
  292. if(query.length>2){
  293. OC.search(query);
  294. }else{
  295. if(OC.search.hide){
  296. OC.search.hide();
  297. }
  298. }
  299. }
  300. }
  301. });
  302. // 'show password' checkbox
  303. $('#pass2').showPassword();
  304. //use infield labels
  305. $("label.infield").inFieldLabels();
  306. // hide log in button etc. when form fields not filled
  307. $('#submit').hide();
  308. $('#remember_login').hide();
  309. $('#remember_login+label').hide();
  310. $('#body-login input').keyup(function() {
  311. var empty = false;
  312. $('#body-login input').each(function() {
  313. if ($(this).val() == '') {
  314. empty = true;
  315. }
  316. });
  317. if(empty) {
  318. $('#submit').fadeOut();
  319. $('#remember_login').hide();
  320. $('#remember_login+label').fadeOut();
  321. } else {
  322. $('#submit').fadeIn();
  323. $('#remember_login').show();
  324. $('#remember_login+label').fadeIn();
  325. }
  326. });
  327. if($('body').attr("id")=="body-user") { $('#settings #expanddiv').hide(); }
  328. $('#settings #expand').click(function(event) {
  329. $('#settings #expanddiv').slideToggle();
  330. event.stopPropagation();
  331. });
  332. $('#settings #expanddiv').click(function(event){
  333. event.stopPropagation();
  334. });
  335. $('#settings #expand').hover(function(){
  336. $('#settings #expand+span').fadeToggle();
  337. });
  338. $(window).click(function(){//hide the settings menu when clicking oustide it
  339. if($('body').attr("id")=="body-user"){
  340. $('#settings #expanddiv').slideUp();
  341. }
  342. });
  343. // all the tipsy stuff needs to be here (in reverse order) to work
  344. $('.jp-controls .jp-previous').tipsy({gravity:'nw', fade:true, live:true});
  345. $('.jp-controls .jp-next').tipsy({gravity:'n', fade:true, live:true});
  346. $('.password .action').tipsy({gravity:'se', fade:true, live:true});
  347. $('.file_upload_button_wrapper').tipsy({gravity:'w', fade:true});
  348. $('.selectedActions a.delete').tipsy({gravity: 'se', fade:true, live:true});
  349. $('.selectedActions a').tipsy({gravity:'s', fade:true, live:true});
  350. $('#headerSize').tipsy({gravity:'s', fade:true, live:true});
  351. $('td.filesize').tipsy({gravity:'s', fade:true, live:true});
  352. $('td .modified').tipsy({gravity:'s', fade:true, live:true});
  353. $('input').tipsy({gravity:'w', fade:true});
  354. $('input[type=text]').focus(function(){
  355. this.select();
  356. });
  357. });
  358. if (!Array.prototype.map){
  359. Array.prototype.map = function(fun /*, thisp */){
  360. "use strict";
  361. if (this === void 0 || this === null)
  362. throw new TypeError();
  363. var t = Object(this);
  364. var len = t.length >>> 0;
  365. if (typeof fun !== "function")
  366. throw new TypeError();
  367. var res = new Array(len);
  368. var thisp = arguments[1];
  369. for (var i = 0; i < len; i++){
  370. if (i in t){
  371. res[i] = fun.call(thisp, t[i], i, t);
  372. }
  373. }
  374. return res;
  375. };
  376. }
  377. /**
  378. * Filter Jquery selector by attribute value
  379. **/
  380. $.fn.filterAttr = function(attr_name, attr_value) {
  381. return this.filter(function() { return $(this).attr(attr_name) === attr_value; });
  382. };