PageRenderTime 58ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-admin/js/image-edit.js

https://bitbucket.org/jstroschein/wordpress-3.5.1-clean
JavaScript | 573 lines | 458 code | 111 blank | 4 comment | 116 complexity | f2e5873b4cc923135fef4ebb4991e0ef MD5 | raw file
  1. var imageEdit;
  2. (function($) {
  3. imageEdit = {
  4. iasapi : {},
  5. hold : {},
  6. postid : '',
  7. intval : function(f) {
  8. return f | 0;
  9. },
  10. setDisabled : function(el, s) {
  11. if ( s ) {
  12. el.removeClass('disabled');
  13. $('input', el).removeAttr('disabled');
  14. } else {
  15. el.addClass('disabled');
  16. $('input', el).prop('disabled', true);
  17. }
  18. },
  19. init : function(postid, nonce) {
  20. var t = this, old = $('#image-editor-' + t.postid),
  21. x = t.intval( $('#imgedit-x-' + postid).val() ),
  22. y = t.intval( $('#imgedit-y-' + postid).val() );
  23. if ( t.postid != postid && old.length )
  24. t.close(t.postid);
  25. t.hold['w'] = t.hold['ow'] = x;
  26. t.hold['h'] = t.hold['oh'] = y;
  27. t.hold['xy_ratio'] = x / y;
  28. t.hold['sizer'] = parseFloat( $('#imgedit-sizer-' + postid).val() );
  29. t.postid = postid;
  30. $('#imgedit-response-' + postid).empty();
  31. $('input[type="text"]', '#imgedit-panel-' + postid).keypress(function(e) {
  32. var k = e.keyCode;
  33. if ( 36 < k && k < 41 )
  34. $(this).blur()
  35. if ( 13 == k ) {
  36. e.preventDefault();
  37. e.stopPropagation();
  38. return false;
  39. }
  40. });
  41. },
  42. toggleEditor : function(postid, toggle) {
  43. var wait = $('#imgedit-wait-' + postid);
  44. if ( toggle )
  45. wait.height( $('#imgedit-panel-' + postid).height() ).fadeIn('fast');
  46. else
  47. wait.fadeOut('fast');
  48. },
  49. toggleHelp : function(el) {
  50. $(el).siblings('.imgedit-help').slideToggle('fast');
  51. return false;
  52. },
  53. getTarget : function(postid) {
  54. return $('input[name="imgedit-target-' + postid + '"]:checked', '#imgedit-save-target-' + postid).val() || 'full';
  55. },
  56. scaleChanged : function(postid, x) {
  57. var w = $('#imgedit-scale-width-' + postid), h = $('#imgedit-scale-height-' + postid),
  58. warn = $('#imgedit-scale-warn-' + postid), w1 = '', h1 = '';
  59. if ( x ) {
  60. h1 = (w.val() != '') ? Math.round( w.val() / this.hold['xy_ratio'] ) : '';
  61. h.val( h1 );
  62. } else {
  63. w1 = (h.val() != '') ? Math.round( h.val() * this.hold['xy_ratio'] ) : '';
  64. w.val( w1 );
  65. }
  66. if ( ( h1 && h1 > this.hold['oh'] ) || ( w1 && w1 > this.hold['ow'] ) )
  67. warn.css('visibility', 'visible');
  68. else
  69. warn.css('visibility', 'hidden');
  70. },
  71. getSelRatio : function(postid) {
  72. var x = this.hold['w'], y = this.hold['h'],
  73. X = this.intval( $('#imgedit-crop-width-' + postid).val() ),
  74. Y = this.intval( $('#imgedit-crop-height-' + postid).val() );
  75. if ( X && Y )
  76. return X + ':' + Y;
  77. if ( x && y )
  78. return x + ':' + y;
  79. return '1:1';
  80. },
  81. filterHistory : function(postid, setSize) {
  82. // apply undo state to history
  83. var history = $('#imgedit-history-' + postid).val(), pop, n, o, i, op = [];
  84. if ( history != '' ) {
  85. history = JSON.parse(history);
  86. pop = this.intval( $('#imgedit-undone-' + postid).val() );
  87. if ( pop > 0 ) {
  88. while ( pop > 0 ) {
  89. history.pop();
  90. pop--;
  91. }
  92. }
  93. if ( setSize ) {
  94. if ( !history.length ) {
  95. this.hold['w'] = this.hold['ow'];
  96. this.hold['h'] = this.hold['oh'];
  97. return '';
  98. }
  99. // restore
  100. o = history[history.length - 1];
  101. o = o.c || o.r || o.f || false;
  102. if ( o ) {
  103. this.hold['w'] = o.fw;
  104. this.hold['h'] = o.fh;
  105. }
  106. }
  107. // filter the values
  108. for ( n in history ) {
  109. i = history[n];
  110. if ( i.hasOwnProperty('c') ) {
  111. op[n] = { 'c': { 'x': i.c.x, 'y': i.c.y, 'w': i.c.w, 'h': i.c.h } };
  112. } else if ( i.hasOwnProperty('r') ) {
  113. op[n] = { 'r': i.r.r };
  114. } else if ( i.hasOwnProperty('f') ) {
  115. op[n] = { 'f': i.f.f };
  116. }
  117. }
  118. return JSON.stringify(op);
  119. }
  120. return '';
  121. },
  122. refreshEditor : function(postid, nonce, callback) {
  123. var t = this, data, img;
  124. t.toggleEditor(postid, 1);
  125. data = {
  126. 'action': 'imgedit-preview',
  127. '_ajax_nonce': nonce,
  128. 'postid': postid,
  129. 'history': t.filterHistory(postid, 1),
  130. 'rand': t.intval(Math.random() * 1000000)
  131. };
  132. img = $('<img id="image-preview-' + postid + '" />');
  133. img.load( function() {
  134. var max1, max2, parent = $('#imgedit-crop-' + postid), t = imageEdit;
  135. parent.empty().append(img);
  136. // w, h are the new full size dims
  137. max1 = Math.max( t.hold.w, t.hold.h );
  138. max2 = Math.max( $(img).width(), $(img).height() );
  139. t.hold['sizer'] = max1 > max2 ? max2 / max1 : 1;
  140. t.initCrop(postid, img, parent);
  141. t.setCropSelection(postid, 0);
  142. if ( (typeof callback != "unknown") && callback != null )
  143. callback();
  144. if ( $('#imgedit-history-' + postid).val() && $('#imgedit-undone-' + postid).val() == 0 )
  145. $('input.imgedit-submit-btn', '#imgedit-panel-' + postid).removeAttr('disabled');
  146. else
  147. $('input.imgedit-submit-btn', '#imgedit-panel-' + postid).prop('disabled', true);
  148. t.toggleEditor(postid, 0);
  149. }).error(function(){
  150. $('#imgedit-crop-' + postid).empty().append('<div class="error"><p>' + imageEditL10n.error + '</p></div>');
  151. t.toggleEditor(postid, 0);
  152. }).attr('src', ajaxurl + '?' + $.param(data));
  153. },
  154. action : function(postid, nonce, action) {
  155. var t = this, data, w, h, fw, fh;
  156. if ( t.notsaved(postid) )
  157. return false;
  158. data = {
  159. 'action': 'image-editor',
  160. '_ajax_nonce': nonce,
  161. 'postid': postid
  162. };
  163. if ( 'scale' == action ) {
  164. w = $('#imgedit-scale-width-' + postid),
  165. h = $('#imgedit-scale-height-' + postid),
  166. fw = t.intval(w.val()),
  167. fh = t.intval(h.val());
  168. if ( fw < 1 ) {
  169. w.focus();
  170. return false;
  171. } else if ( fh < 1 ) {
  172. h.focus();
  173. return false;
  174. }
  175. if ( fw == t.hold.ow || fh == t.hold.oh )
  176. return false;
  177. data['do'] = 'scale';
  178. data['fwidth'] = fw;
  179. data['fheight'] = fh;
  180. } else if ( 'restore' == action ) {
  181. data['do'] = 'restore';
  182. } else {
  183. return false;
  184. }
  185. t.toggleEditor(postid, 1);
  186. $.post(ajaxurl, data, function(r) {
  187. $('#image-editor-' + postid).empty().append(r);
  188. t.toggleEditor(postid, 0);
  189. });
  190. },
  191. save : function(postid, nonce) {
  192. var data, target = this.getTarget(postid), history = this.filterHistory(postid, 0);
  193. if ( '' == history )
  194. return false;
  195. this.toggleEditor(postid, 1);
  196. data = {
  197. 'action': 'image-editor',
  198. '_ajax_nonce': nonce,
  199. 'postid': postid,
  200. 'history': history,
  201. 'target': target,
  202. 'context': $('#image-edit-context').length ? $('#image-edit-context').val() : null,
  203. 'do': 'save'
  204. };
  205. $.post(ajaxurl, data, function(r) {
  206. var ret = JSON.parse(r);
  207. if ( ret.error ) {
  208. $('#imgedit-response-' + postid).html('<div class="error"><p>' + ret.error + '</p><div>');
  209. imageEdit.close(postid);
  210. return;
  211. }
  212. if ( ret.fw && ret.fh )
  213. $('#media-dims-' + postid).html( ret.fw + ' &times; ' + ret.fh );
  214. if ( ret.thumbnail )
  215. $('.thumbnail', '#thumbnail-head-' + postid).attr('src', ''+ret.thumbnail);
  216. if ( ret.msg )
  217. $('#imgedit-response-' + postid).html('<div class="updated"><p>' + ret.msg + '</p></div>');
  218. imageEdit.close(postid);
  219. });
  220. },
  221. open : function(postid, nonce) {
  222. var data, elem = $('#image-editor-' + postid), head = $('#media-head-' + postid),
  223. btn = $('#imgedit-open-btn-' + postid), spin = btn.siblings('.spinner');
  224. btn.prop('disabled', true);
  225. spin.show();
  226. data = {
  227. 'action': 'image-editor',
  228. '_ajax_nonce': nonce,
  229. 'postid': postid,
  230. 'do': 'open'
  231. };
  232. elem.load(ajaxurl, data, function() {
  233. elem.fadeIn('fast');
  234. head.fadeOut('fast', function(){
  235. btn.removeAttr('disabled');
  236. spin.hide();
  237. });
  238. });
  239. },
  240. imgLoaded : function(postid) {
  241. var img = $('#image-preview-' + postid), parent = $('#imgedit-crop-' + postid);
  242. this.initCrop(postid, img, parent);
  243. this.setCropSelection(postid, 0);
  244. this.toggleEditor(postid, 0);
  245. },
  246. initCrop : function(postid, image, parent) {
  247. var t = this, selW = $('#imgedit-sel-width-' + postid),
  248. selH = $('#imgedit-sel-height-' + postid);
  249. t.iasapi = $(image).imgAreaSelect({
  250. parent: parent,
  251. instance: true,
  252. handles: true,
  253. keys: true,
  254. minWidth: 3,
  255. minHeight: 3,
  256. onInit: function(img, c) {
  257. parent.children().mousedown(function(e){
  258. var ratio = false, sel, defRatio;
  259. if ( e.shiftKey ) {
  260. sel = t.iasapi.getSelection();
  261. defRatio = t.getSelRatio(postid);
  262. ratio = ( sel && sel.width && sel.height ) ? sel.width + ':' + sel.height : defRatio;
  263. }
  264. t.iasapi.setOptions({
  265. aspectRatio: ratio
  266. });
  267. });
  268. },
  269. onSelectStart: function(img, c) {
  270. imageEdit.setDisabled($('#imgedit-crop-sel-' + postid), 1);
  271. },
  272. onSelectEnd: function(img, c) {
  273. imageEdit.setCropSelection(postid, c);
  274. },
  275. onSelectChange: function(img, c) {
  276. var sizer = imageEdit.hold.sizer;
  277. selW.val( imageEdit.round(c.width / sizer) );
  278. selH.val( imageEdit.round(c.height / sizer) );
  279. }
  280. });
  281. },
  282. setCropSelection : function(postid, c) {
  283. var sel, min = $('#imgedit-minthumb-' + postid).val() || '128:128',
  284. sizer = this.hold['sizer'];
  285. min = min.split(':');
  286. c = c || 0;
  287. if ( !c || ( c.width < 3 && c.height < 3 ) ) {
  288. this.setDisabled($('.imgedit-crop', '#imgedit-panel-' + postid), 0);
  289. this.setDisabled($('#imgedit-crop-sel-' + postid), 0);
  290. $('#imgedit-sel-width-' + postid).val('');
  291. $('#imgedit-sel-height-' + postid).val('');
  292. $('#imgedit-selection-' + postid).val('');
  293. return false;
  294. }
  295. if ( c.width < (min[0] * sizer) && c.height < (min[1] * sizer) ) {
  296. this.setDisabled($('.imgedit-crop', '#imgedit-panel-' + postid), 0);
  297. $('#imgedit-selection-' + postid).val('');
  298. return false;
  299. }
  300. sel = { 'x': c.x1, 'y': c.y1, 'w': c.width, 'h': c.height };
  301. this.setDisabled($('.imgedit-crop', '#imgedit-panel-' + postid), 1);
  302. $('#imgedit-selection-' + postid).val( JSON.stringify(sel) );
  303. },
  304. close : function(postid, warn) {
  305. warn = warn || false;
  306. if ( warn && this.notsaved(postid) )
  307. return false;
  308. this.iasapi = {};
  309. this.hold = {};
  310. $('#image-editor-' + postid).fadeOut('fast', function() {
  311. $('#media-head-' + postid).fadeIn('fast');
  312. $(this).empty();
  313. });
  314. },
  315. notsaved : function(postid) {
  316. var h = $('#imgedit-history-' + postid).val(),
  317. history = (h != '') ? JSON.parse(h) : new Array(),
  318. pop = this.intval( $('#imgedit-undone-' + postid).val() );
  319. if ( pop < history.length ) {
  320. if ( confirm( $('#imgedit-leaving-' + postid).html() ) )
  321. return false;
  322. return true;
  323. }
  324. return false;
  325. },
  326. addStep : function(op, postid, nonce) {
  327. var t = this, elem = $('#imgedit-history-' + postid),
  328. history = (elem.val() != '') ? JSON.parse(elem.val()) : new Array(),
  329. undone = $('#imgedit-undone-' + postid),
  330. pop = t.intval(undone.val());
  331. while ( pop > 0 ) {
  332. history.pop();
  333. pop--;
  334. }
  335. undone.val(0); // reset
  336. history.push(op);
  337. elem.val( JSON.stringify(history) );
  338. t.refreshEditor(postid, nonce, function() {
  339. t.setDisabled($('#image-undo-' + postid), true);
  340. t.setDisabled($('#image-redo-' + postid), false);
  341. });
  342. },
  343. rotate : function(angle, postid, nonce, t) {
  344. if ( $(t).hasClass('disabled') )
  345. return false;
  346. this.addStep({ 'r': { 'r': angle, 'fw': this.hold['h'], 'fh': this.hold['w'] }}, postid, nonce);
  347. },
  348. flip : function (axis, postid, nonce, t) {
  349. if ( $(t).hasClass('disabled') )
  350. return false;
  351. this.addStep({ 'f': { 'f': axis, 'fw': this.hold['w'], 'fh': this.hold['h'] }}, postid, nonce);
  352. },
  353. crop : function (postid, nonce, t) {
  354. var sel = $('#imgedit-selection-' + postid).val(),
  355. w = this.intval( $('#imgedit-sel-width-' + postid).val() ),
  356. h = this.intval( $('#imgedit-sel-height-' + postid).val() );
  357. if ( $(t).hasClass('disabled') || sel == '' )
  358. return false;
  359. sel = JSON.parse(sel);
  360. if ( sel.w > 0 && sel.h > 0 && w > 0 && h > 0 ) {
  361. sel['fw'] = w;
  362. sel['fh'] = h;
  363. this.addStep({ 'c': sel }, postid, nonce);
  364. }
  365. },
  366. undo : function (postid, nonce) {
  367. var t = this, button = $('#image-undo-' + postid), elem = $('#imgedit-undone-' + postid),
  368. pop = t.intval( elem.val() ) + 1;
  369. if ( button.hasClass('disabled') )
  370. return;
  371. elem.val(pop);
  372. t.refreshEditor(postid, nonce, function() {
  373. var elem = $('#imgedit-history-' + postid),
  374. history = (elem.val() != '') ? JSON.parse(elem.val()) : new Array();
  375. t.setDisabled($('#image-redo-' + postid), true);
  376. t.setDisabled(button, pop < history.length);
  377. });
  378. },
  379. redo : function(postid, nonce) {
  380. var t = this, button = $('#image-redo-' + postid), elem = $('#imgedit-undone-' + postid),
  381. pop = t.intval( elem.val() ) - 1;
  382. if ( button.hasClass('disabled') )
  383. return;
  384. elem.val(pop);
  385. t.refreshEditor(postid, nonce, function() {
  386. t.setDisabled($('#image-undo-' + postid), true);
  387. t.setDisabled(button, pop > 0);
  388. });
  389. },
  390. setNumSelection : function(postid) {
  391. var sel, elX = $('#imgedit-sel-width-' + postid), elY = $('#imgedit-sel-height-' + postid),
  392. x = this.intval( elX.val() ), y = this.intval( elY.val() ),
  393. img = $('#image-preview-' + postid), imgh = img.height(), imgw = img.width(),
  394. sizer = this.hold['sizer'], x1, y1, x2, y2, ias = this.iasapi;
  395. if ( x < 1 ) {
  396. elX.val('');
  397. return false;
  398. }
  399. if ( y < 1 ) {
  400. elY.val('');
  401. return false;
  402. }
  403. if ( x && y && ( sel = ias.getSelection() ) ) {
  404. x2 = sel.x1 + Math.round( x * sizer );
  405. y2 = sel.y1 + Math.round( y * sizer );
  406. x1 = sel.x1;
  407. y1 = sel.y1;
  408. if ( x2 > imgw ) {
  409. x1 = 0;
  410. x2 = imgw;
  411. elX.val( Math.round( x2 / sizer ) );
  412. }
  413. if ( y2 > imgh ) {
  414. y1 = 0;
  415. y2 = imgh;
  416. elY.val( Math.round( y2 / sizer ) );
  417. }
  418. ias.setSelection( x1, y1, x2, y2 );
  419. ias.update();
  420. this.setCropSelection(postid, ias.getSelection());
  421. }
  422. },
  423. round : function(num) {
  424. var s;
  425. num = Math.round(num);
  426. if ( this.hold.sizer > 0.6 )
  427. return num;
  428. s = num.toString().slice(-1);
  429. if ( '1' == s )
  430. return num - 1;
  431. else if ( '9' == s )
  432. return num + 1;
  433. return num;
  434. },
  435. setRatioSelection : function(postid, n, el) {
  436. var sel, r, x = this.intval( $('#imgedit-crop-width-' + postid).val() ),
  437. y = this.intval( $('#imgedit-crop-height-' + postid).val() ),
  438. h = $('#image-preview-' + postid).height();
  439. if ( !this.intval( $(el).val() ) ) {
  440. $(el).val('');
  441. return;
  442. }
  443. if ( x && y ) {
  444. this.iasapi.setOptions({
  445. aspectRatio: x + ':' + y
  446. });
  447. if ( sel = this.iasapi.getSelection(true) ) {
  448. r = Math.ceil( sel.y1 + ((sel.x2 - sel.x1) / (x / y)) );
  449. if ( r > h ) {
  450. r = h;
  451. if ( n )
  452. $('#imgedit-crop-height-' + postid).val('');
  453. else
  454. $('#imgedit-crop-width-' + postid).val('');
  455. }
  456. this.iasapi.setSelection( sel.x1, sel.y1, sel.x2, r );
  457. this.iasapi.update();
  458. }
  459. }
  460. }
  461. }
  462. })(jQuery);