scribble_cms 0.0.1a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. checksums.yaml +7 -0
  2. data/app/assets/javascripts/ext/jquery.Jcrop.min.js +22 -0
  3. data/app/assets/javascripts/scribbler.js +2 -0
  4. data/app/assets/stylesheets/ext/jquery.Jcrop.css +165 -0
  5. data/app/assets/stylesheets/scribbler.css.erb +14 -0
  6. data/app/assets/stylesheets/scribbler_layout.css.erb +21 -0
  7. data/app/controllers/scribbler_admin_controller.rb +77 -0
  8. data/app/helpers/scribbler_admin_helper.rb +2 -0
  9. data/app/helpers/scribbler_content_helper.rb +35 -0
  10. data/app/models/scribbler_container.rb +38 -0
  11. data/app/models/scribbler_group.rb +121 -0
  12. data/app/models/scribbler_image.rb +47 -0
  13. data/app/models/scribbler_link.rb +31 -0
  14. data/app/models/scribbler_text.rb +27 -0
  15. data/app/views/scribbler_admin/_scribbler_layout.html.erb +6 -0
  16. data/app/views/scribbler_admin/_scribbler_sidebar.html.erb +13 -0
  17. data/app/views/scribbler_admin/container_edit.html.erb +18 -0
  18. data/app/views/scribbler_admin/group_edit.html.erb +68 -0
  19. data/app/views/scribbler_admin/image_cropper.html.erb +43 -0
  20. data/app/views/scribbler_admin/index.html.erb +3 -0
  21. data/app/views/scribbler_content/forms/_image.html.erb +25 -0
  22. data/app/views/scribbler_content/forms/_link.html.erb +17 -0
  23. data/app/views/scribbler_content/forms/_row.html.erb +7 -0
  24. data/app/views/scribbler_content/forms/_text.html.erb +7 -0
  25. data/config/routes.rb +15 -0
  26. data/db/migrate/20140313012637_create_scribblers.rb +48 -0
  27. data/lib/paperclip_processors/cropper.rb +23 -0
  28. data/lib/scribbler/engine.rb +6 -0
  29. data/lib/scribbler/scribbler_element_setup.rb +29 -0
  30. data/lib/scribbler.rb +5 -0
  31. metadata +101 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7a202ec9cad63d8172f26cd08a65e1361a1cdde7
4
+ data.tar.gz: bcae9f248c0b0272d7d4377da0b085b0c8e13f07
5
+ SHA512:
6
+ metadata.gz: 67ae4670323eb7c2b72db1581736afa48582074a76238a6478442273b0423970cf050b7e3e3f0a102bb3cad31d0f6e6e3dc79e3cef1d45c00acd88cff220e191
7
+ data.tar.gz: 4f3543dee8de86992d1c79a07cb8a58f667b079845a4d9b23a6c83fec1716ed902d793ead40acdb973783b0cf0a08b0caa3780a9e00a503f8382cd79271d8dec
@@ -0,0 +1,22 @@
1
+ /**
2
+ * jquery.Jcrop.min.js v0.9.12 (build:20130202)
3
+ * jQuery Image Cropping Plugin - released under MIT License
4
+ * Copyright (c) 2008-2013 Tapmodo Interactive LLC
5
+ * https://github.com/tapmodo/Jcrop
6
+ */
7
+ (function(a){a.Jcrop=function(b,c){function i(a){return Math.round(a)+"px"}function j(a){return d.baseClass+"-"+a}function k(){return a.fx.step.hasOwnProperty("backgroundColor")}function l(b){var c=a(b).offset();return[c.left,c.top]}function m(a){return[a.pageX-e[0],a.pageY-e[1]]}function n(b){typeof b!="object"&&(b={}),d=a.extend(d,b),a.each(["onChange","onSelect","onRelease","onDblClick"],function(a,b){typeof d[b]!="function"&&(d[b]=function(){})})}function o(a,b,c){e=l(D),bc.setCursor(a==="move"?a:a+"-resize");if(a==="move")return bc.activateHandlers(q(b),v,c);var d=_.getFixed(),f=r(a),g=_.getCorner(r(f));_.setPressed(_.getCorner(f)),_.setCurrent(g),bc.activateHandlers(p(a,d),v,c)}function p(a,b){return function(c){if(!d.aspectRatio)switch(a){case"e":c[1]=b.y2;break;case"w":c[1]=b.y2;break;case"n":c[0]=b.x2;break;case"s":c[0]=b.x2}else switch(a){case"e":c[1]=b.y+1;break;case"w":c[1]=b.y+1;break;case"n":c[0]=b.x+1;break;case"s":c[0]=b.x+1}_.setCurrent(c),bb.update()}}function q(a){var b=a;return bd.watchKeys
8
+ (),function(a){_.moveOffset([a[0]-b[0],a[1]-b[1]]),b=a,bb.update()}}function r(a){switch(a){case"n":return"sw";case"s":return"nw";case"e":return"nw";case"w":return"ne";case"ne":return"sw";case"nw":return"se";case"se":return"nw";case"sw":return"ne"}}function s(a){return function(b){return d.disabled?!1:a==="move"&&!d.allowMove?!1:(e=l(D),W=!0,o(a,m(b)),b.stopPropagation(),b.preventDefault(),!1)}}function t(a,b,c){var d=a.width(),e=a.height();d>b&&b>0&&(d=b,e=b/a.width()*a.height()),e>c&&c>0&&(e=c,d=c/a.height()*a.width()),T=a.width()/d,U=a.height()/e,a.width(d).height(e)}function u(a){return{x:a.x*T,y:a.y*U,x2:a.x2*T,y2:a.y2*U,w:a.w*T,h:a.h*U}}function v(a){var b=_.getFixed();b.w>d.minSelect[0]&&b.h>d.minSelect[1]?(bb.enableHandles(),bb.done()):bb.release(),bc.setCursor(d.allowSelect?"crosshair":"default")}function w(a){if(d.disabled)return!1;if(!d.allowSelect)return!1;W=!0,e=l(D),bb.disableHandles(),bc.setCursor("crosshair");var b=m(a);return _.setPressed(b),bb.update(),bc.activateHandlers(x,v,a.type.substring
9
+ (0,5)==="touch"),bd.watchKeys(),a.stopPropagation(),a.preventDefault(),!1}function x(a){_.setCurrent(a),bb.update()}function y(){var b=a("<div></div>").addClass(j("tracker"));return g&&b.css({opacity:0,backgroundColor:"white"}),b}function be(a){G.removeClass().addClass(j("holder")).addClass(a)}function bf(a,b){function t(){window.setTimeout(u,l)}var c=a[0]/T,e=a[1]/U,f=a[2]/T,g=a[3]/U;if(X)return;var h=_.flipCoords(c,e,f,g),i=_.getFixed(),j=[i.x,i.y,i.x2,i.y2],k=j,l=d.animationDelay,m=h[0]-j[0],n=h[1]-j[1],o=h[2]-j[2],p=h[3]-j[3],q=0,r=d.swingSpeed;c=k[0],e=k[1],f=k[2],g=k[3],bb.animMode(!0);var s,u=function(){return function(){q+=(100-q)/r,k[0]=Math.round(c+q/100*m),k[1]=Math.round(e+q/100*n),k[2]=Math.round(f+q/100*o),k[3]=Math.round(g+q/100*p),q>=99.8&&(q=100),q<100?(bh(k),t()):(bb.done(),bb.animMode(!1),typeof b=="function"&&b.call(bs))}}();t()}function bg(a){bh([a[0]/T,a[1]/U,a[2]/T,a[3]/U]),d.onSelect.call(bs,u(_.getFixed())),bb.enableHandles()}function bh(a){_.setPressed([a[0],a[1]]),_.setCurrent([a[2],
10
+ a[3]]),bb.update()}function bi(){return u(_.getFixed())}function bj(){return _.getFixed()}function bk(a){n(a),br()}function bl(){d.disabled=!0,bb.disableHandles(),bb.setCursor("default"),bc.setCursor("default")}function bm(){d.disabled=!1,br()}function bn(){bb.done(),bc.activateHandlers(null,null)}function bo(){G.remove(),A.show(),A.css("visibility","visible"),a(b).removeData("Jcrop")}function bp(a,b){bb.release(),bl();var c=new Image;c.onload=function(){var e=c.width,f=c.height,g=d.boxWidth,h=d.boxHeight;D.width(e).height(f),D.attr("src",a),H.attr("src",a),t(D,g,h),E=D.width(),F=D.height(),H.width(E).height(F),M.width(E+L*2).height(F+L*2),G.width(E).height(F),ba.resize(E,F),bm(),typeof b=="function"&&b.call(bs)},c.src=a}function bq(a,b,c){var e=b||d.bgColor;d.bgFade&&k()&&d.fadeTime&&!c?a.animate({backgroundColor:e},{queue:!1,duration:d.fadeTime}):a.css("backgroundColor",e)}function br(a){d.allowResize?a?bb.enableOnly():bb.enableHandles():bb.disableHandles(),bc.setCursor(d.allowSelect?"crosshair":"default"),bb
11
+ .setCursor(d.allowMove?"move":"default"),d.hasOwnProperty("trueSize")&&(T=d.trueSize[0]/E,U=d.trueSize[1]/F),d.hasOwnProperty("setSelect")&&(bg(d.setSelect),bb.done(),delete d.setSelect),ba.refresh(),d.bgColor!=N&&(bq(d.shade?ba.getShades():G,d.shade?d.shadeColor||d.bgColor:d.bgColor),N=d.bgColor),O!=d.bgOpacity&&(O=d.bgOpacity,d.shade?ba.refresh():bb.setBgOpacity(O)),P=d.maxSize[0]||0,Q=d.maxSize[1]||0,R=d.minSize[0]||0,S=d.minSize[1]||0,d.hasOwnProperty("outerImage")&&(D.attr("src",d.outerImage),delete d.outerImage),bb.refresh()}var d=a.extend({},a.Jcrop.defaults),e,f=navigator.userAgent.toLowerCase(),g=/msie/.test(f),h=/msie [1-6]\./.test(f);typeof b!="object"&&(b=a(b)[0]),typeof c!="object"&&(c={}),n(c);var z={border:"none",visibility:"visible",margin:0,padding:0,position:"absolute",top:0,left:0},A=a(b),B=!0;if(b.tagName=="IMG"){if(A[0].width!=0&&A[0].height!=0)A.width(A[0].width),A.height(A[0].height);else{var C=new Image;C.src=A[0].src,A.width(C.width),A.height(C.height)}var D=A.clone().removeAttr("id").
12
+ css(z).show();D.width(A.width()),D.height(A.height()),A.after(D).hide()}else D=A.css(z).show(),B=!1,d.shade===null&&(d.shade=!0);t(D,d.boxWidth,d.boxHeight);var E=D.width(),F=D.height(),G=a("<div />").width(E).height(F).addClass(j("holder")).css({position:"relative",backgroundColor:d.bgColor}).insertAfter(A).append(D);d.addClass&&G.addClass(d.addClass);var H=a("<div />"),I=a("<div />").width("100%").height("100%").css({zIndex:310,position:"absolute",overflow:"hidden"}),J=a("<div />").width("100%").height("100%").css("zIndex",320),K=a("<div />").css({position:"absolute",zIndex:600}).dblclick(function(){var a=_.getFixed();d.onDblClick.call(bs,a)}).insertBefore(D).append(I,J);B&&(H=a("<img />").attr("src",D.attr("src")).css(z).width(E).height(F),I.append(H)),h&&K.css({overflowY:"hidden"});var L=d.boundary,M=y().width(E+L*2).height(F+L*2).css({position:"absolute",top:i(-L),left:i(-L),zIndex:290}).mousedown(w),N=d.bgColor,O=d.bgOpacity,P,Q,R,S,T,U,V=!0,W,X,Y;e=l(D);var Z=function(){function a(){var a={},b=["touchstart"
13
+ ,"touchmove","touchend"],c=document.createElement("div"),d;try{for(d=0;d<b.length;d++){var e=b[d];e="on"+e;var f=e in c;f||(c.setAttribute(e,"return;"),f=typeof c[e]=="function"),a[b[d]]=f}return a.touchstart&&a.touchend&&a.touchmove}catch(g){return!1}}function b(){return d.touchSupport===!0||d.touchSupport===!1?d.touchSupport:a()}return{createDragger:function(a){return function(b){return d.disabled?!1:a==="move"&&!d.allowMove?!1:(e=l(D),W=!0,o(a,m(Z.cfilter(b)),!0),b.stopPropagation(),b.preventDefault(),!1)}},newSelection:function(a){return w(Z.cfilter(a))},cfilter:function(a){return a.pageX=a.originalEvent.changedTouches[0].pageX,a.pageY=a.originalEvent.changedTouches[0].pageY,a},isSupported:a,support:b()}}(),_=function(){function h(d){d=n(d),c=a=d[0],e=b=d[1]}function i(a){a=n(a),f=a[0]-c,g=a[1]-e,c=a[0],e=a[1]}function j(){return[f,g]}function k(d){var f=d[0],g=d[1];0>a+f&&(f-=f+a),0>b+g&&(g-=g+b),F<e+g&&(g+=F-(e+g)),E<c+f&&(f+=E-(c+f)),a+=f,c+=f,b+=g,e+=g}function l(a){var b=m();switch(a){case"ne":return[
14
+ b.x2,b.y];case"nw":return[b.x,b.y];case"se":return[b.x2,b.y2];case"sw":return[b.x,b.y2]}}function m(){if(!d.aspectRatio)return p();var f=d.aspectRatio,g=d.minSize[0]/T,h=d.maxSize[0]/T,i=d.maxSize[1]/U,j=c-a,k=e-b,l=Math.abs(j),m=Math.abs(k),n=l/m,r,s,t,u;return h===0&&(h=E*10),i===0&&(i=F*10),n<f?(s=e,t=m*f,r=j<0?a-t:t+a,r<0?(r=0,u=Math.abs((r-a)/f),s=k<0?b-u:u+b):r>E&&(r=E,u=Math.abs((r-a)/f),s=k<0?b-u:u+b)):(r=c,u=l/f,s=k<0?b-u:b+u,s<0?(s=0,t=Math.abs((s-b)*f),r=j<0?a-t:t+a):s>F&&(s=F,t=Math.abs(s-b)*f,r=j<0?a-t:t+a)),r>a?(r-a<g?r=a+g:r-a>h&&(r=a+h),s>b?s=b+(r-a)/f:s=b-(r-a)/f):r<a&&(a-r<g?r=a-g:a-r>h&&(r=a-h),s>b?s=b+(a-r)/f:s=b-(a-r)/f),r<0?(a-=r,r=0):r>E&&(a-=r-E,r=E),s<0?(b-=s,s=0):s>F&&(b-=s-F,s=F),q(o(a,b,r,s))}function n(a){return a[0]<0&&(a[0]=0),a[1]<0&&(a[1]=0),a[0]>E&&(a[0]=E),a[1]>F&&(a[1]=F),[Math.round(a[0]),Math.round(a[1])]}function o(a,b,c,d){var e=a,f=c,g=b,h=d;return c<a&&(e=c,f=a),d<b&&(g=d,h=b),[e,g,f,h]}function p(){var d=c-a,f=e-b,g;return P&&Math.abs(d)>P&&(c=d>0?a+P:a-P),Q&&Math.abs
15
+ (f)>Q&&(e=f>0?b+Q:b-Q),S/U&&Math.abs(f)<S/U&&(e=f>0?b+S/U:b-S/U),R/T&&Math.abs(d)<R/T&&(c=d>0?a+R/T:a-R/T),a<0&&(c-=a,a-=a),b<0&&(e-=b,b-=b),c<0&&(a-=c,c-=c),e<0&&(b-=e,e-=e),c>E&&(g=c-E,a-=g,c-=g),e>F&&(g=e-F,b-=g,e-=g),a>E&&(g=a-F,e-=g,b-=g),b>F&&(g=b-F,e-=g,b-=g),q(o(a,b,c,e))}function q(a){return{x:a[0],y:a[1],x2:a[2],y2:a[3],w:a[2]-a[0],h:a[3]-a[1]}}var a=0,b=0,c=0,e=0,f,g;return{flipCoords:o,setPressed:h,setCurrent:i,getOffset:j,moveOffset:k,getCorner:l,getFixed:m}}(),ba=function(){function f(a,b){e.left.css({height:i(b)}),e.right.css({height:i(b)})}function g(){return h(_.getFixed())}function h(a){e.top.css({left:i(a.x),width:i(a.w),height:i(a.y)}),e.bottom.css({top:i(a.y2),left:i(a.x),width:i(a.w),height:i(F-a.y2)}),e.right.css({left:i(a.x2),width:i(E-a.x2)}),e.left.css({width:i(a.x)})}function j(){return a("<div />").css({position:"absolute",backgroundColor:d.shadeColor||d.bgColor}).appendTo(c)}function k(){b||(b=!0,c.insertBefore(D),g(),bb.setBgOpacity(1,0,1),H.hide(),l(d.shadeColor||d.bgColor,1),bb.
16
+ isAwake()?n(d.bgOpacity,1):n(1,1))}function l(a,b){bq(p(),a,b)}function m(){b&&(c.remove(),H.show(),b=!1,bb.isAwake()?bb.setBgOpacity(d.bgOpacity,1,1):(bb.setBgOpacity(1,1,1),bb.disableHandles()),bq(G,0,1))}function n(a,e){b&&(d.bgFade&&!e?c.animate({opacity:1-a},{queue:!1,duration:d.fadeTime}):c.css({opacity:1-a}))}function o(){d.shade?k():m(),bb.isAwake()&&n(d.bgOpacity)}function p(){return c.children()}var b=!1,c=a("<div />").css({position:"absolute",zIndex:240,opacity:0}),e={top:j(),left:j().height(F),right:j().height(F),bottom:j()};return{update:g,updateRaw:h,getShades:p,setBgColor:l,enable:k,disable:m,resize:f,refresh:o,opacity:n}}(),bb=function(){function k(b){var c=a("<div />").css({position:"absolute",opacity:d.borderOpacity}).addClass(j(b));return I.append(c),c}function l(b,c){var d=a("<div />").mousedown(s(b)).css({cursor:b+"-resize",position:"absolute",zIndex:c}).addClass("ord-"+b);return Z.support&&d.bind("touchstart.jcrop",Z.createDragger(b)),J.append(d),d}function m(a){var b=d.handleSize,e=l(a,c++
17
+ ).css({opacity:d.handleOpacity}).addClass(j("handle"));return b&&e.width(b).height(b),e}function n(a){return l(a,c++).addClass("jcrop-dragbar")}function o(a){var b;for(b=0;b<a.length;b++)g[a[b]]=n(a[b])}function p(a){var b,c;for(c=0;c<a.length;c++){switch(a[c]){case"n":b="hline";break;case"s":b="hline bottom";break;case"e":b="vline right";break;case"w":b="vline"}e[a[c]]=k(b)}}function q(a){var b;for(b=0;b<a.length;b++)f[a[b]]=m(a[b])}function r(a,b){d.shade||H.css({top:i(-b),left:i(-a)}),K.css({top:i(b),left:i(a)})}function t(a,b){K.width(Math.round(a)).height(Math.round(b))}function v(){var a=_.getFixed();_.setPressed([a.x,a.y]),_.setCurrent([a.x2,a.y2]),w()}function w(a){if(b)return x(a)}function x(a){var c=_.getFixed();t(c.w,c.h),r(c.x,c.y),d.shade&&ba.updateRaw(c),b||A(),a?d.onSelect.call(bs,u(c)):d.onChange.call(bs,u(c))}function z(a,c,e){if(!b&&!c)return;d.bgFade&&!e?D.animate({opacity:a},{queue:!1,duration:d.fadeTime}):D.css("opacity",a)}function A(){K.show(),d.shade?ba.opacity(O):z(O,!0),b=!0}function B
18
+ (){F(),K.hide(),d.shade?ba.opacity(1):z(1),b=!1,d.onRelease.call(bs)}function C(){h&&J.show()}function E(){h=!0;if(d.allowResize)return J.show(),!0}function F(){h=!1,J.hide()}function G(a){a?(X=!0,F()):(X=!1,E())}function L(){G(!1),v()}var b,c=370,e={},f={},g={},h=!1;d.dragEdges&&a.isArray(d.createDragbars)&&o(d.createDragbars),a.isArray(d.createHandles)&&q(d.createHandles),d.drawBorders&&a.isArray(d.createBorders)&&p(d.createBorders),a(document).bind("touchstart.jcrop-ios",function(b){a(b.currentTarget).hasClass("jcrop-tracker")&&b.stopPropagation()});var M=y().mousedown(s("move")).css({cursor:"move",position:"absolute",zIndex:360});return Z.support&&M.bind("touchstart.jcrop",Z.createDragger("move")),I.append(M),F(),{updateVisible:w,update:x,release:B,refresh:v,isAwake:function(){return b},setCursor:function(a){M.css("cursor",a)},enableHandles:E,enableOnly:function(){h=!0},showHandles:C,disableHandles:F,animMode:G,setBgOpacity:z,done:L}}(),bc=function(){function f(b){M.css({zIndex:450}),b?a(document).bind("touchmove.jcrop"
19
+ ,k).bind("touchend.jcrop",l):e&&a(document).bind("mousemove.jcrop",h).bind("mouseup.jcrop",i)}function g(){M.css({zIndex:290}),a(document).unbind(".jcrop")}function h(a){return b(m(a)),!1}function i(a){return a.preventDefault(),a.stopPropagation(),W&&(W=!1,c(m(a)),bb.isAwake()&&d.onSelect.call(bs,u(_.getFixed())),g(),b=function(){},c=function(){}),!1}function j(a,d,e){return W=!0,b=a,c=d,f(e),!1}function k(a){return b(m(Z.cfilter(a))),!1}function l(a){return i(Z.cfilter(a))}function n(a){M.css("cursor",a)}var b=function(){},c=function(){},e=d.trackDocument;return e||M.mousemove(h).mouseup(i).mouseout(i),D.before(M),{activateHandlers:j,setCursor:n}}(),bd=function(){function e(){d.keySupport&&(b.show(),b.focus())}function f(a){b.hide()}function g(a,b,c){d.allowMove&&(_.moveOffset([b,c]),bb.updateVisible(!0)),a.preventDefault(),a.stopPropagation()}function i(a){if(a.ctrlKey||a.metaKey)return!0;Y=a.shiftKey?!0:!1;var b=Y?10:1;switch(a.keyCode){case 37:g(a,-b,0);break;case 39:g(a,b,0);break;case 38:g(a,0,-b);break;
20
+ case 40:g(a,0,b);break;case 27:d.allowSelect&&bb.release();break;case 9:return!0}return!1}var b=a('<input type="radio" />').css({position:"fixed",left:"-120px",width:"12px"}).addClass("jcrop-keymgr"),c=a("<div />").css({position:"absolute",overflow:"hidden"}).append(b);return d.keySupport&&(b.keydown(i).blur(f),h||!d.fixedSupport?(b.css({position:"absolute",left:"-20px"}),c.append(b).insertBefore(D)):b.insertBefore(D)),{watchKeys:e}}();Z.support&&M.bind("touchstart.jcrop",Z.newSelection),J.hide(),br(!0);var bs={setImage:bp,animateTo:bf,setSelect:bg,setOptions:bk,tellSelect:bi,tellScaled:bj,setClass:be,disable:bl,enable:bm,cancel:bn,release:bb.release,destroy:bo,focus:bd.watchKeys,getBounds:function(){return[E*T,F*U]},getWidgetSize:function(){return[E,F]},getScaleFactor:function(){return[T,U]},getOptions:function(){return d},ui:{holder:G,selection:K}};return g&&G.bind("selectstart",function(){return!1}),A.data("Jcrop",bs),bs},a.fn.Jcrop=function(b,c){var d;return this.each(function(){if(a(this).data("Jcrop")){if(
21
+ b==="api")return a(this).data("Jcrop");a(this).data("Jcrop").setOptions(b)}else this.tagName=="IMG"?a.Jcrop.Loader(this,function(){a(this).css({display:"block",visibility:"hidden"}),d=a.Jcrop(this,b),a.isFunction(c)&&c.call(d)}):(a(this).css({display:"block",visibility:"hidden"}),d=a.Jcrop(this,b),a.isFunction(c)&&c.call(d))}),this},a.Jcrop.Loader=function(b,c,d){function g(){f.complete?(e.unbind(".jcloader"),a.isFunction(c)&&c.call(f)):window.setTimeout(g,50)}var e=a(b),f=e[0];e.bind("load.jcloader",g).bind("error.jcloader",function(b){e.unbind(".jcloader"),a.isFunction(d)&&d.call(f)}),f.complete&&a.isFunction(c)&&(e.unbind(".jcloader"),c.call(f))},a.Jcrop.defaults={allowSelect:!0,allowMove:!0,allowResize:!0,trackDocument:!0,baseClass:"jcrop",addClass:null,bgColor:"black",bgOpacity:.6,bgFade:!1,borderOpacity:.4,handleOpacity:.5,handleSize:null,aspectRatio:0,keySupport:!0,createHandles:["n","s","e","w","nw","ne","se","sw"],createDragbars:["n","s","e","w"],createBorders:["n","s","e","w"],drawBorders:!0,dragEdges
22
+ :!0,fixedSupport:!0,touchSupport:null,shade:null,boxWidth:0,boxHeight:0,boundary:2,fadeTime:400,animationDelay:20,swingSpeed:3,minSelect:[0,0],maxSize:[0,0],minSize:[0,0],onChange:function(){},onSelect:function(){},onDblClick:function(){},onRelease:function(){}}})(jQuery);
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,165 @@
1
+ /* jquery.Jcrop.css v0.9.12 - MIT License */
2
+ /*
3
+ The outer-most container in a typical Jcrop instance
4
+ If you are having difficulty with formatting related to styles
5
+ on a parent element, place any fixes here or in a like selector
6
+
7
+ You can also style this element if you want to add a border, etc
8
+ A better method for styling can be seen below with .jcrop-light
9
+ (Add a class to the holder and style elements for that extended class)
10
+ */
11
+ .jcrop-holder {
12
+ direction: ltr;
13
+ text-align: left;
14
+ }
15
+ /* Selection Border */
16
+ .jcrop-vline,
17
+ .jcrop-hline {
18
+ background: #ffffff url("Jcrop.gif");
19
+ font-size: 0;
20
+ position: absolute;
21
+ }
22
+ .jcrop-vline {
23
+ height: 100%;
24
+ width: 1px !important;
25
+ }
26
+ .jcrop-vline.right {
27
+ right: 0;
28
+ }
29
+ .jcrop-hline {
30
+ height: 1px !important;
31
+ width: 100%;
32
+ }
33
+ .jcrop-hline.bottom {
34
+ bottom: 0;
35
+ }
36
+ /* Invisible click targets */
37
+ .jcrop-tracker {
38
+ height: 100%;
39
+ width: 100%;
40
+ /* "turn off" link highlight */
41
+ -webkit-tap-highlight-color: transparent;
42
+ /* disable callout, image save panel */
43
+ -webkit-touch-callout: none;
44
+ /* disable cut copy paste */
45
+ -webkit-user-select: none;
46
+ }
47
+ /* Selection Handles */
48
+ .jcrop-handle {
49
+ background-color: #333333;
50
+ border: 1px #eeeeee solid;
51
+ width: 7px;
52
+ height: 7px;
53
+ font-size: 1px;
54
+ }
55
+ .jcrop-handle.ord-n {
56
+ left: 50%;
57
+ margin-left: -4px;
58
+ margin-top: -4px;
59
+ top: 0;
60
+ }
61
+ .jcrop-handle.ord-s {
62
+ bottom: 0;
63
+ left: 50%;
64
+ margin-bottom: -4px;
65
+ margin-left: -4px;
66
+ }
67
+ .jcrop-handle.ord-e {
68
+ margin-right: -4px;
69
+ margin-top: -4px;
70
+ right: 0;
71
+ top: 50%;
72
+ }
73
+ .jcrop-handle.ord-w {
74
+ left: 0;
75
+ margin-left: -4px;
76
+ margin-top: -4px;
77
+ top: 50%;
78
+ }
79
+ .jcrop-handle.ord-nw {
80
+ left: 0;
81
+ margin-left: -4px;
82
+ margin-top: -4px;
83
+ top: 0;
84
+ }
85
+ .jcrop-handle.ord-ne {
86
+ margin-right: -4px;
87
+ margin-top: -4px;
88
+ right: 0;
89
+ top: 0;
90
+ }
91
+ .jcrop-handle.ord-se {
92
+ bottom: 0;
93
+ margin-bottom: -4px;
94
+ margin-right: -4px;
95
+ right: 0;
96
+ }
97
+ .jcrop-handle.ord-sw {
98
+ bottom: 0;
99
+ left: 0;
100
+ margin-bottom: -4px;
101
+ margin-left: -4px;
102
+ }
103
+ /* Dragbars */
104
+ .jcrop-dragbar.ord-n,
105
+ .jcrop-dragbar.ord-s {
106
+ height: 7px;
107
+ width: 100%;
108
+ }
109
+ .jcrop-dragbar.ord-e,
110
+ .jcrop-dragbar.ord-w {
111
+ height: 100%;
112
+ width: 7px;
113
+ }
114
+ .jcrop-dragbar.ord-n {
115
+ margin-top: -4px;
116
+ }
117
+ .jcrop-dragbar.ord-s {
118
+ bottom: 0;
119
+ margin-bottom: -4px;
120
+ }
121
+ .jcrop-dragbar.ord-e {
122
+ margin-right: -4px;
123
+ right: 0;
124
+ }
125
+ .jcrop-dragbar.ord-w {
126
+ margin-left: -4px;
127
+ }
128
+ /* The "jcrop-light" class/extension */
129
+ .jcrop-light .jcrop-vline,
130
+ .jcrop-light .jcrop-hline {
131
+ background: #ffffff;
132
+ filter: alpha(opacity=70) !important;
133
+ opacity: .70!important;
134
+ }
135
+ .jcrop-light .jcrop-handle {
136
+ -moz-border-radius: 3px;
137
+ -webkit-border-radius: 3px;
138
+ background-color: #000000;
139
+ border-color: #ffffff;
140
+ border-radius: 3px;
141
+ }
142
+ /* The "jcrop-dark" class/extension */
143
+ .jcrop-dark .jcrop-vline,
144
+ .jcrop-dark .jcrop-hline {
145
+ background: #000000;
146
+ filter: alpha(opacity=70) !important;
147
+ opacity: 0.7 !important;
148
+ }
149
+ .jcrop-dark .jcrop-handle {
150
+ -moz-border-radius: 3px;
151
+ -webkit-border-radius: 3px;
152
+ background-color: #ffffff;
153
+ border-color: #000000;
154
+ border-radius: 3px;
155
+ }
156
+ /* Simple macro to turn off the antlines */
157
+ .solid-line .jcrop-vline,
158
+ .solid-line .jcrop-hline {
159
+ background: #ffffff;
160
+ }
161
+ /* Fix for twitter bootstrap et al. */
162
+ .jcrop-holder img,
163
+ img.jcrop-preview {
164
+ max-width: none;
165
+ }
@@ -0,0 +1,14 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into scribbler.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ *= require_tree ./ext
14
+ */
@@ -0,0 +1,21 @@
1
+ #scribbler-admin-area,
2
+ #scribbler-group-edit { width: 100%;}
3
+
4
+ #scribbler-edit-area { width: 70%;}
5
+
6
+ #scribbler-sidebar { float: left; width: 25%; background: #efefef; border-right: solid 1px #999; margin-right: 20px;}
7
+ #scribbler-sidebar ul { padding-left: 0; margin-right: 10px;}
8
+ #scribbler-sidebar ul { padding-left: 20px;}
9
+ #scribbler-sidebar li { list-style: none;}
10
+
11
+ .scribbler-group { border: solid 1px #ddd; padding: 5px; margin-bottom: 5px; background: #fff;}
12
+
13
+ .group-col { float: left; width: 48%;}
14
+ .group-col:last-child { float: right;}
15
+
16
+ #scribbler-edit-area { float: left; }
17
+
18
+ #scribbler-edit-area td { vertical-align: top;}
19
+
20
+ .metainfo { color: #333;}
21
+
@@ -0,0 +1,77 @@
1
+ class ScribblerAdminController < ApplicationController
2
+
3
+ before_filter :get_container, :only => %w(container_edit container_update container_add_item )
4
+ before_filter :get_group, :only => %w(group_edit group_update group_destroy)
5
+
6
+
7
+ def index
8
+ @containers = ScribblerContainer.all
9
+ end
10
+
11
+ # Containers
12
+ def container_edit
13
+ end
14
+
15
+ def container_update
16
+ @container.update_attributes(container_params)
17
+ flash[:notice] = "Container #{@container.name} was saved"
18
+ redirect_to :action => "index"
19
+ end
20
+
21
+ def container_add_item
22
+ @container.get_group("#{@container.id}-#{Time.now.to_i}")
23
+ flash[:notice] = "Neues Element für #{@container.name} wurde angelegt"
24
+ redirect_to :back
25
+ end
26
+
27
+
28
+
29
+
30
+ # Groups
31
+ def group_edit
32
+ render :layout => false
33
+ end
34
+
35
+ def group_update
36
+ @group.process_group_data(params[:scribbler_group])
37
+ flash[:notice] = "Änderungen wurden gespeichert"
38
+ redirect_to :back
39
+ end
40
+
41
+ def group_destroy
42
+ @group.destroy
43
+ flash[:notice] = "Daten wurden gelöscht"
44
+ redirect_to :action => "index"
45
+ end
46
+
47
+ # images
48
+ def image_cropper
49
+ @element = ScribblerImage.find(params[:id])
50
+ end
51
+
52
+ def crop_image
53
+ @element = ScribblerImage.find(params[:id])
54
+ @element.update_attributes(image_params)
55
+ @element.image.reprocess!
56
+ redirect_to :action => "group_edit", :id => @element.group_id
57
+ end
58
+
59
+ # Private - permit parameters
60
+ private
61
+
62
+ def get_container
63
+ @container = ScribblerContainer.find(params[:id])
64
+ end
65
+
66
+ def get_group
67
+ @group = ScribblerGroup.find(params[:id])
68
+ end
69
+
70
+ def container_params
71
+ params.require(:scribbler_container).permit(:description)
72
+ end
73
+
74
+ def image_params
75
+ params.require(:scribbler_image).permit(:crop_x, :crop_y, :crop_w, :crop_h)
76
+ end
77
+ end
@@ -0,0 +1,2 @@
1
+ module ScribblerAdminHelper
2
+ end
@@ -0,0 +1,35 @@
1
+ module ScribblerContentHelper
2
+
3
+ def scribbler_container(container_name, options = {}, &block)
4
+ container_name = "#{container_name}-#{options[:element].page.name}-#{options[:element].id}" if options[:element]
5
+ q = {:name => container_name, :scaleable => (options[:scaleable].nil? ? false : options[:scaleable]), :element_id => (options[:element] ? options[:element].id : nil)}
6
+ container = ScribblerContainer.where(:name => container_name).first || ScribblerContainer.create(q)
7
+ container.update_attributes(:scaleable => options[:scaleable]) if options[:scaleable] && container.scaleable != options[:scaleable]
8
+ capture(container, &block)
9
+ end
10
+
11
+ def scribbler_group(container, group, &block)
12
+ scribbler_container(container) do |c|
13
+ c.scribbler_group(group) do |g|
14
+ capture(g, &block)
15
+ end
16
+ end
17
+ end
18
+
19
+ def scribbler_element(container, group, type, name)
20
+ scribbler_group(container, group) do |g|
21
+ g.send(type, name)
22
+ end
23
+ end
24
+
25
+ # Form
26
+ def scribbler_form_element(element,form)
27
+ render :partial => "/scribbler_content/forms/#{element.element_type}", :locals => {:element => element, :f => form}
28
+ end
29
+
30
+
31
+ def scribbler_layout(&block)
32
+ render :partial => "/scribbler_admin/scribbler_layout", :locals => {:content => capture(&block)}
33
+ end
34
+
35
+ end
@@ -0,0 +1,38 @@
1
+ class ScribblerContainer < ActiveRecord::Base
2
+
3
+ #= Configuration
4
+ #== Associations
5
+ has_many :groups, :class_name => "::ScribblerGroup", :foreign_key => "container_id"
6
+ belongs_to :element, :class_name => "Alchemy::Element", :foreign_key => "element_id"
7
+ #== Plugins and modules
8
+ #=== PlugIns
9
+ # => Stuff in Here
10
+
11
+ #=== include Modules
12
+ # => Stuff in Here
13
+
14
+ #== Konstanten
15
+ # => Stuff in Here
16
+
17
+ #== Validation and Callbacks
18
+ #=== Validation
19
+ validates_uniqueness_of :name, :on => :create, :message => "must be unique"
20
+
21
+ #=== Callbacks
22
+ before_create { self.description = self.name }
23
+
24
+
25
+ # => END
26
+
27
+ def scribbler_group(name, &block)
28
+ yield(self.get_group(name))
29
+ end
30
+
31
+ def get_group(name)
32
+ ScribblerGroup.where(:name => name, :container_id => self.id).first || ScribblerGroup.create(:name => name, :container_id => self.id)
33
+ end
34
+
35
+
36
+
37
+
38
+ end
@@ -0,0 +1,121 @@
1
+ class ScribblerGroup < ActiveRecord::Base
2
+
3
+ #= Configuration
4
+ #== Associations
5
+ belongs_to :container, :class_name => "ScribblerContainer", :foreign_key => "container_id", :touch => true
6
+
7
+ has_many :texts, :class_name => "ScribblerText", :foreign_key => "group_id"
8
+ #== Plugins and modules
9
+ #=== PlugIns
10
+ # => Stuff in Here
11
+
12
+ #=== include Modules
13
+ # => Stuff in Here
14
+
15
+ #== Konstanten
16
+ ELEMENTS = {:row => ScribblerText,
17
+ :text => ScribblerText,
18
+ :link => ScribblerLink,
19
+ :image => ScribblerImage}
20
+
21
+ #== Validation and Callbacks
22
+ #=== Validation
23
+ validates_uniqueness_of :name, :scope => :container_id
24
+
25
+ #=== Callbacks
26
+ after_destroy :destroy_elements
27
+
28
+
29
+ # => END
30
+
31
+ # Display data
32
+ def row(row_name)
33
+ get_element(:row, row_name).content
34
+ end
35
+
36
+ def text(text_name)
37
+ get_element(:text, text_name).content.to_s.html_safe
38
+ end
39
+
40
+ def link(link_name, options = {})
41
+ link = get_element(:link, link_name)
42
+ options.merge!(:target => "_blank") if link.external
43
+ ActionController::Base.helpers.link_to(link.title, link.url, options)
44
+ end
45
+
46
+ def image(image_name, size)
47
+ get_element(:image, image_name, :opt_size => size).image.url(:default)
48
+ end
49
+
50
+ # Helpers
51
+ def get_element(type, name, options = {:released => true})
52
+ options[:released] ||= true
53
+
54
+ case type
55
+ when :row
56
+ options.merge!(:plain => true)
57
+ when :text
58
+ options.merge!(:plain => false)
59
+ when :link
60
+ # ...
61
+ when :image
62
+
63
+ end
64
+
65
+ options.merge!(:name => name, :group_id => self.id)
66
+
67
+ element_class = ELEMENTS[type]
68
+
69
+ element = element_class.where(options).first
70
+ if element.nil?
71
+ element_class.create(options.merge(:released => !options[:released]))
72
+ element = element_class.create(options)
73
+ end
74
+
75
+
76
+ return element
77
+ end
78
+
79
+ def elements(options = {:released => true})
80
+ ELEMENTS.values.uniq.map {|c| c.where(:group_id => self.id, :released => options[:released] == true)}.flatten.sort_by {|e| e.created_at}
81
+ end
82
+
83
+ def released_elements
84
+ self.elements(:released => true)
85
+ end
86
+
87
+ def unreleased_elements
88
+ self.elements(:released => false)
89
+ end
90
+
91
+ def destroy_elements
92
+ self.elements.each {|e| e.destroy }
93
+ end
94
+
95
+ # Save data
96
+ def process_group_data(data = {})
97
+ # Update realesed data
98
+ self.process_data!(data[:released])
99
+
100
+ # Update unrealesed data
101
+ self.process_data!(data[:unreleased])
102
+ end
103
+
104
+ def process_data!(data)
105
+ data.each do |key, content|
106
+ e_id = content.delete(:id)
107
+ e_type = content.delete(:type)
108
+ e_rel = content.delete(:release)
109
+ element = ELEMENTS[e_type.to_sym].find(e_id)
110
+ element.update_attributes(content)
111
+
112
+ if e_rel == "1"
113
+ element.release!
114
+ end
115
+ end
116
+ end
117
+
118
+
119
+
120
+
121
+ end
@@ -0,0 +1,47 @@
1
+ class ScribblerImage < ActiveRecord::Base
2
+
3
+ #= Configuration
4
+ has_attached_file :image, :styles => {:default => "300x200"}, :processors => [:cropper]
5
+ validates_attachment_content_type :image, :content_type => /\Aimage\/.*\Z/
6
+
7
+ attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
8
+ #== Associations
9
+
10
+ #== Plugins and modules
11
+ #=== PlugIns
12
+ # => Stuff in Here #
13
+
14
+ #=== include Modules
15
+ include Scribbler::ScribblerElementSetup
16
+
17
+ #== Konstanten
18
+ # => Stuff in Here
19
+
20
+ #== Validation and Callbacks
21
+ #=== Validation
22
+
23
+
24
+ #=== Callbacks
25
+ # after_update :crop_image, :if => :cropping?
26
+
27
+
28
+ # => END
29
+
30
+
31
+ def cropping?
32
+ !crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
33
+ end
34
+
35
+ def crop_image
36
+ self.image.reprocess!
37
+ crop_x = crop_y = crop_w = crop_h = nil
38
+ end
39
+
40
+ def opt_image_width
41
+ self.opt_size.split("x").first
42
+ end
43
+
44
+ def opt_image_height
45
+ self.opt_size.split("x").last
46
+ end
47
+ end
@@ -0,0 +1,31 @@
1
+ class ScribblerLink < ActiveRecord::Base
2
+
3
+ #= Configuration
4
+ #== Associations
5
+
6
+
7
+ #== Plugins and modules
8
+ #=== PlugIns
9
+ # => Stuff in Here
10
+
11
+ #=== include Modules
12
+ include Scribbler::ScribblerElementSetup
13
+
14
+ #== Konstanten
15
+ # => Stuff in Here
16
+
17
+ #== Validation and Callbacks
18
+ #=== Validation
19
+
20
+
21
+ #=== Callbacks
22
+ # => Stuff in Here
23
+
24
+
25
+ # => END
26
+
27
+ def url
28
+ self[:url].blank? ? "/" : self[:url]
29
+ end
30
+
31
+ end
@@ -0,0 +1,27 @@
1
+ class ScribblerText < ActiveRecord::Base
2
+
3
+ #= Configuration
4
+ #== Associations
5
+
6
+
7
+ #== Plugins and modules
8
+ #=== PlugIns
9
+ # => Stuff in Here
10
+
11
+ #=== include Modules
12
+ include Scribbler::ScribblerElementSetup
13
+
14
+ #== Konstanten
15
+ # => Stuff in Here
16
+
17
+ #== Validation and Callbacks
18
+ #=== Validation
19
+
20
+
21
+ #=== Callbacks
22
+ # => Stuff in Here
23
+
24
+
25
+ # => END
26
+
27
+ end
@@ -0,0 +1,6 @@
1
+ <div id="scribbler-admin-area" class="cf">
2
+ <div id="scribbler-sidebar">
3
+ <%= render :partial => "/scribbler_admin/scribbler_sidebar" unless request.xhr? %>
4
+ </div>
5
+ <div id="scribbler-edit-area"><%= content %></div>
6
+ </div>
@@ -0,0 +1,13 @@
1
+ <ul>
2
+ <% ScribblerContainer.all.each do |container| %>
3
+ <li class="scribbler-group">
4
+ <%= link_to container.description, scribbler.url_for({:controller => "/scribbler_admin", :action => "container_edit", :id => container.id}) %><br />
5
+ <div class="metainfo small"><%= container.name %></div>
6
+ <ul class="">
7
+ <% container.groups.each do |group| %>
8
+ <li><%= link_to group.name, scribbler.url_for({:controller => "/scribbler_admin", :action => "group_edit", :id => group.id}), default_ajax_link(:update => "scribbler-edit-area") %></li>
9
+ <% end %>
10
+ </ul>
11
+ </li>
12
+ <% end %>
13
+ </ul>
@@ -0,0 +1,18 @@
1
+ <%= scribbler_layout do %>
2
+ <h3><%= @container.name %> bearbeiten</h3>
3
+ <%= form_for @container, :url => {:action => "container_update", :id => @container.id} do |f| %>
4
+ <%= f.text_field :description %><br />
5
+ <div class="field-container-2-cols cf">
6
+ <div class="left"><%= f.submit "Änderungen speichern" %></div>
7
+ <div class="right">
8
+ <% if @container.scaleable %>
9
+ <%= link_to "Neues Element einfügen", {:action => "container_add_item", :id => @container.id}, :class => "icon-plus" %>
10
+ <% end %>
11
+ </div>
12
+ </div>
13
+
14
+ <% end %>
15
+
16
+
17
+
18
+ <% end %>
@@ -0,0 +1,68 @@
1
+ <%= scribbler_layout do %>
2
+
3
+ <p>
4
+ Element in <i>'<%= @group.container.description %>'</i>
5
+ <% if @group.container.element %>
6
+ auf Seite <i>'<%= @group.container.element.page.name %>'</i>
7
+ <% end %>
8
+ </p>
9
+
10
+ <%= form_for @group, :url => scribbler.url_for({:action => "group_update", :id => @group.id}), :html => {:class => "section", :method => :post} do |f| %>
11
+ <table style="min-width: 940px;" cellspacing="5">
12
+ <tr>
13
+ <td>
14
+ <b><%= link_to_function("Aktueller Zustand", "toggleCol('released')") %></b><br />
15
+ <i>Klicken um Bereich ein- bzw auszublenden</i>
16
+ </td>
17
+ <td>
18
+ <b><%= link_to_function("In Bearbeitung", "toggleCol('unreleased')") %></b><br />
19
+ <i>Klicken um Bereich ein- bzw auszublenden</i>
20
+ </td>
21
+ </tr>
22
+ <tr>
23
+ <td id="released" class="">
24
+ <%= f.fields_for :released do |u| %>
25
+ <% @group.released_elements.each do |e| %>
26
+ <div style="margin-bottom: 5px;"><%= scribbler_form_element(e,u) %></div>
27
+ <% end %>
28
+ <% end %>
29
+ </td>
30
+ <td id="unreleased" class="">
31
+ <%= f.fields_for :unreleased do |u| %>
32
+ <% @group.unreleased_elements.each do |e| %>
33
+ <div style="margin-bottom: 5px;"><%= scribbler_form_element(e,u) %></div>
34
+ <% end %>
35
+ <% end %>
36
+ </td>
37
+ </tr>
38
+ </table>
39
+
40
+ <%= f.submit "Änderungen speichern" %>
41
+
42
+ <% if @group.container.scaleable %>
43
+ <%= link_to "Dieses Element löschen", scribbler.url_for({:action => "group_destroy", :id => @group.id}),
44
+ :confirm => "Soll dieses Element gelöscht werden? Dies kann nicht rückgängig gemacht werden.", :class => "icon-minus" %>
45
+ <% end %>
46
+
47
+ <% end %>
48
+
49
+ <% end %>
50
+
51
+ <%= tinymce %>
52
+
53
+ <script type="text/javascript">
54
+
55
+ toggleCol = function(name){
56
+ col = $("#"+name)
57
+ if(col.hasClass("col-visible")){
58
+ $("#"+name+" *").hide();
59
+ col.removeClass("col-visible")
60
+ }else{
61
+ $("#"+name+" *").show();
62
+ col.addClass("col-visible")
63
+ }
64
+ }
65
+
66
+ toggleCol('released')
67
+ </script>
68
+
@@ -0,0 +1,43 @@
1
+ <% content_for(:head) do %>
2
+ <%= stylesheet_link_tag "ext/jquery.Jcrop" %>
3
+ <%= javascript_include_tag "ext/jquery.Jcrop.min" %>
4
+ <script type="text/javascript" charset="utf-8">
5
+ $(function() {
6
+ $('#cropbox').Jcrop({
7
+ onChange: update_crop,
8
+ onSelect: update_crop,
9
+ setSelect: [0, 0, 500, 500],
10
+ aspectRatio: <%= @element.opt_image_width %> / <%= @element.opt_image_height %>
11
+ });
12
+ });
13
+
14
+ function update_crop(coords) {
15
+ var rx = 100/coords.w;
16
+ var ry = 100/coords.h;
17
+ $('#preview').css({
18
+ width: Math.round(rx * <%= @element.opt_image_width %>) + 'px',
19
+ height: Math.round(ry * <%= @element.opt_image_height %>) + 'px',
20
+ marginLeft: '-' + Math.round(rx * coords.x) + 'px',
21
+ marginTop: '-' + Math.round(ry * coords.y) + 'px'
22
+ });
23
+ var ratio = <%= @element.opt_image_width %> / <%= @element.opt_image_height %>;
24
+ $("#crop_x").val(Math.round(coords.x));
25
+ $("#crop_y").val(Math.round(coords.y));
26
+ $("#crop_w").val(Math.round(coords.w));
27
+ $("#crop_h").val(Math.round(coords.h));
28
+ }
29
+ </script>
30
+ <% end %>
31
+
32
+ <%= scribbler_layout do %>
33
+ <h3>Bild bearbeiten</h3>
34
+
35
+ <%= image_tag @element.image.url, :id => "cropbox" %>
36
+
37
+ <%= form_for @element, :url => {:action => "crop_image", :id => @element.id} do |f| %>
38
+ <% for attribute in [:crop_x, :crop_y, :crop_w, :crop_h] %>
39
+ <%= f.hidden_field attribute, :id => attribute %>
40
+ <% end %>
41
+ <p><%= f.submit "Zuschneiden" %></p>
42
+ <% end %>
43
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <%= scribbler_layout do %>
2
+ <h2>Inhalte verwalten</h2>
3
+ <% end %>
@@ -0,0 +1,25 @@
1
+ <%= f.fields_for "#{element.element_type}_#{element.id}" do |e| %>
2
+
3
+
4
+
5
+ <%= e.label :image, "Bilddatei" %><br />
6
+ <%= e.file_field :image %>
7
+
8
+
9
+ <p>Klicken Sie auf das Bild um die Abmessungen anzupassen</p>
10
+ <%= link_to image_tag(element.image.url(:default), :width => "100%"), {:action => "image_cropper", :id => element.id} %>
11
+
12
+ <div style="margin-bottom: 5px;">
13
+ <%= e.label :copyright, "Copyright" %><br />
14
+ <%= e.text_field :copyright, :value => element.copyright %>
15
+ </div>
16
+
17
+ <div style="margin-bottom: 5px;">
18
+ <%= e.label :alt_text, "ALT-Attribut" %><br />
19
+ <%= e.text_field :alt_text, :value => element.alt_text %>
20
+ </div>
21
+
22
+ <%= e.hidden_field :type, :value => element.element_type %>
23
+ <%= e.hidden_field :id, :value => element.id %>
24
+ <% end %>
25
+ <hr />
@@ -0,0 +1,17 @@
1
+ <%= f.fields_for "#{element.element_type}_#{element.id}" do |e| %>
2
+ <div style="margin-bottom: 5px;">
3
+ <%= e.label :title, "Titel des Links" %><br />
4
+ <%= e.text_field :title, :value => element.title %>
5
+ </div>
6
+
7
+ <div style="margin-bottom: 5px;">
8
+ <%= e.label :url, "Adresse (http://.../)" %><br />
9
+ <%= e.text_field :url, :value => element.url %>
10
+ </div>
11
+
12
+ <%= e.check_box :external, :checked => element.external %>
13
+ <%= e.label :external, "Externer Link" %>
14
+ <%= e.hidden_field :type, :value => element.element_type %>
15
+ <%= e.hidden_field :id, :value => element.id %>
16
+ <% end %>
17
+ <hr />
@@ -0,0 +1,7 @@
1
+ <%= f.fields_for "#{element.element_type}_#{element.id}" do |e| %>
2
+ <%= e.label :content, element.name %><br />
3
+ <%= e.text_field :content, :value => element.content %>
4
+ <%= e.hidden_field :type, :value => element.element_type %>
5
+ <%= e.hidden_field :id, :value => element.id %>
6
+ <% end %>
7
+
@@ -0,0 +1,7 @@
1
+ <%= f.fields_for "#{element.element_type}_#{element.id}" do |e| %>
2
+ <%= e.label :content, element.name %>
3
+ <%= e.text_area :content, :class => "tinymce", :value => element.content %>
4
+ <br />
5
+ <%= e.hidden_field :type, :value => element.element_type %>
6
+ <%= e.hidden_field :id, :value => element.id %>
7
+ <% end %>
data/config/routes.rb ADDED
@@ -0,0 +1,15 @@
1
+ Scribbler::Engine.routes.draw do
2
+
3
+ %w( container_edit container_add_item group_edit group_destroy image_cropper).each do |a|
4
+ get "/scribbler_admin/#{a}/(:id)", :controller => "scribbler_admin", :action => a
5
+ end
6
+
7
+ get "/scribbler_admin", :controller => "scribbler_admin", :action => "index", :as => :scribbler_admin
8
+
9
+ %w(container_update group_update crop_image).each do |a|
10
+ post "/scribbler_admin/#{a}/(:id)", :controller => "scribbler_admin", :action => a
11
+ end
12
+
13
+
14
+
15
+ end
@@ -0,0 +1,48 @@
1
+ class CreateScribblers < ActiveRecord::Migration
2
+ def change
3
+ create_table :scribbler_containers, :force => true do |t|
4
+ t.string :name
5
+ t.string :description
6
+ t.boolean :scaleable, :default => false
7
+ t.integer :element_id
8
+ t.timestamps
9
+ end
10
+
11
+ create_table :scribbler_groups, :force => true do |t|
12
+ t.string :name
13
+ t.integer :container_id
14
+ t.timestamps
15
+ end
16
+
17
+ create_table :scribbler_texts, :force => true do |t|
18
+ t.string :name
19
+ t.integer :group_id
20
+ t.text :content
21
+ t.boolean :plain
22
+ t.boolean :released, :default => false
23
+ t.timestamps
24
+ end
25
+
26
+ create_table :scribbler_links, :force => true do |t|
27
+ t.string :name
28
+ t.text :url
29
+ t.string :title, :title => "Link"
30
+ t.boolean :released, :default => false
31
+ t.integer :group_id
32
+ t.boolean :external, :default => false
33
+
34
+ t.timestamps
35
+ end
36
+
37
+ create_table :scribbler_images, :force => true do |t|
38
+ t.string :name
39
+ t.string :group_id
40
+ t.boolean :released, :default => false
41
+ t.string :copyright
42
+ t.string :alt_text
43
+ t.string :opt_size, :default => "128x128"
44
+ t.attachment :image
45
+ t.timestamps
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,23 @@
1
+ module Paperclip
2
+ class Cropper < Thumbnail
3
+ def transformation_command
4
+ if crop_command
5
+ crop_command
6
+ else
7
+ super
8
+ end
9
+ end
10
+
11
+ def crop_command
12
+ target = @attachment.instance
13
+ puts "try Croppper"
14
+ if target.cropping?
15
+ puts "cropper!"
16
+ cmd = [" -crop '#{target.crop_w.to_i}x#{target.crop_h.to_i}+#{target.crop_x.to_i}+#{target.crop_y.to_i}'"]
17
+ cmd << "-auto-orient"
18
+ cmd << "-resize #{target.opt_image_width}x#{target.opt_image_height}"
19
+ end
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,6 @@
1
+ module Scribbler
2
+ class Engine < Rails::Engine
3
+ engine_name "scribbler"
4
+
5
+ end
6
+ end
@@ -0,0 +1,29 @@
1
+ module Scribbler
2
+ module ScribblerElementSetup
3
+
4
+ def self.included(base)
5
+ base.send(:belongs_to, :group, :class_name => "ScribblerGroup", :foreign_key => "group_id", :touch => true)
6
+ base.send(:validates_presence_of, :group_id)
7
+ base.send(:before_save, :check_uniqueness)
8
+ end
9
+
10
+
11
+ def check_uniqueness
12
+ items = self.class.where(:name => self.name, :group_id => self.group_id, :released => self.released)
13
+ items.empty? || items.size == 1
14
+ end
15
+
16
+ def element_type
17
+ if self.is_a?(ScribblerLink)
18
+ return :link
19
+ elsif self.is_a?(ScribblerText) && self.plain
20
+ return :row
21
+ elsif self.is_a?(ScribblerText) && !self.plain
22
+ return :text
23
+ elsif self.is_a?(ScribblerImage)
24
+ return :image
25
+ end
26
+ end
27
+
28
+ end
29
+ end
data/lib/scribbler.rb ADDED
@@ -0,0 +1,5 @@
1
+ module Scribbler
2
+ end
3
+
4
+ require 'scribbler/engine'
5
+ require 'scribbler/scribbler_element_setup'
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: scribble_cms
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1a
5
+ platform: ruby
6
+ authors:
7
+ - Florian Eck
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: friendly_extensions
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.66
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.66
27
+ - !ruby/object:Gem::Dependency
28
+ name: paperclip
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Easy-to-use tool for placing user-editable content in your pages
42
+ email:
43
+ - it-support@friends-systems.de
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - app/assets/javascripts/ext/jquery.Jcrop.min.js
49
+ - app/assets/javascripts/scribbler.js
50
+ - app/assets/stylesheets/ext/jquery.Jcrop.css
51
+ - app/assets/stylesheets/scribbler.css.erb
52
+ - app/assets/stylesheets/scribbler_layout.css.erb
53
+ - app/controllers/scribbler_admin_controller.rb
54
+ - app/helpers/scribbler_admin_helper.rb
55
+ - app/helpers/scribbler_content_helper.rb
56
+ - app/models/scribbler_container.rb
57
+ - app/models/scribbler_group.rb
58
+ - app/models/scribbler_image.rb
59
+ - app/models/scribbler_link.rb
60
+ - app/models/scribbler_text.rb
61
+ - app/views/scribbler_admin/_scribbler_layout.html.erb
62
+ - app/views/scribbler_admin/_scribbler_sidebar.html.erb
63
+ - app/views/scribbler_admin/container_edit.html.erb
64
+ - app/views/scribbler_admin/group_edit.html.erb
65
+ - app/views/scribbler_admin/image_cropper.html.erb
66
+ - app/views/scribbler_admin/index.html.erb
67
+ - app/views/scribbler_content/forms/_image.html.erb
68
+ - app/views/scribbler_content/forms/_link.html.erb
69
+ - app/views/scribbler_content/forms/_row.html.erb
70
+ - app/views/scribbler_content/forms/_text.html.erb
71
+ - config/routes.rb
72
+ - db/migrate/20140313012637_create_scribblers.rb
73
+ - lib/paperclip_processors/cropper.rb
74
+ - lib/scribbler.rb
75
+ - lib/scribbler/engine.rb
76
+ - lib/scribbler/scribbler_element_setup.rb
77
+ homepage: http://www.friends-systems.de
78
+ licenses: []
79
+ metadata: {}
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">"
92
+ - !ruby/object:Gem::Version
93
+ version: 1.3.1
94
+ requirements: []
95
+ rubyforge_project:
96
+ rubygems_version: 2.2.1
97
+ signing_key:
98
+ specification_version: 4
99
+ summary: Easy-to-use tool for placing user-editable content in your pages
100
+ test_files: []
101
+ has_rdoc: