diff --git a/DependencyInjection/CmfTreeBrowserExtension.php b/DependencyInjection/CmfTreeBrowserExtension.php index 13eb9ca..b32abba 100644 --- a/DependencyInjection/CmfTreeBrowserExtension.php +++ b/DependencyInjection/CmfTreeBrowserExtension.php @@ -11,8 +11,10 @@ namespace Symfony\Cmf\Bundle\TreeBrowserBundle\DependencyInjection; +use Symfony\Component\Config\FileLocator; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface; +use Symfony\Component\DependencyInjection\Loader\XmlFileLoader; use Symfony\Component\HttpKernel\DependencyInjection\Extension; class CmfTreeBrowserExtension extends Extension implements PrependExtensionInterface @@ -40,5 +42,10 @@ public function prepend(ContainerBuilder $container) */ public function load(array $configs, ContainerBuilder $container) { + $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); + $loader->load('services.xml'); + + $config = $this->processConfiguration(new Configuration(), $configs); + $container->setParameter('cmf_tree_browser.description.icon_map', $config['icons']); } } diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php new file mode 100644 index 0000000..ea63a7d --- /dev/null +++ b/DependencyInjection/Configuration.php @@ -0,0 +1,36 @@ +root('cmf_tree_browser'); + + $rootNode + ->children() + ->arrayNode('icons') + ->useAttributeAsKey('class') + ->prototype('scalar')->end() + ->info('A mapping of classes/interfaces and icon classes or icon URLs used by the tree browser.') + ->end() + ->end() + ; + + return $treeBuilder; + } +} diff --git a/Description/IconEnhancer.php b/Description/IconEnhancer.php new file mode 100644 index 0000000..49122a8 --- /dev/null +++ b/Description/IconEnhancer.php @@ -0,0 +1,67 @@ + + */ +class IconEnhancer implements DescriptionEnhancerInterface +{ + private $iconMap; + private $classMap = []; + + public function __construct(array $iconMap) + { + $this->iconMap = $iconMap; + } + + public function enhance(Description $description) + { + $class = get_class($description->getResource()->getPayload()); + if (isset($this->classMap[$class])) { + $class = $this->classMap[$class]; + } + + $description->set('icon', $this->iconMap[$class]); + } + + public function supports(PuliResource $resource) + { + if (!$resource instanceof CmfResource) { + return false; + } + + $payload = $resource->getPayload(); + $payloadClass = get_class($payload); + + if (isset($this->iconMap[$payloadClass]) || isset($this->classMap[$payloadClass])) { + return true; + } + + foreach (array_keys($this->iconMap) as $class) { + if (is_a($payload, $class) || is_subclass_of($payload, $class)) { + $this->classMap[$payloadClass] = $class; + + return true; + } + } + + return false; + } +} diff --git a/Resources/assets/js/adapter/fancytree.js b/Resources/assets/js/adapter/fancytree.js index 6fe4214..f320b33 100644 --- a/Resources/assets/js/adapter/fancytree.js +++ b/Resources/assets/js/adapter/fancytree.js @@ -71,7 +71,6 @@ export class FancytreeAdapter { this.$tree = $elem; var actions = this.actions; - var requestNode = this.requestNode; var requestNodeToFancytreeNode = (requestNode) => { if (requestNode.length === 0) { return; @@ -92,6 +91,10 @@ export class FancytreeAdapter { this.pathKeyMap[fancytreeNode.refPath] = key; + if (requestNode.descriptors.hasOwnProperty('icon')) { + fancytreeNode.icon = requestNode.descriptors.icon; + } + for (let actionName in actions) { var action = actions[actionName]; var url = action.url; diff --git a/Resources/config/services.xml b/Resources/config/services.xml new file mode 100644 index 0000000..ad25f04 --- /dev/null +++ b/Resources/config/services.xml @@ -0,0 +1,16 @@ + + + + + + %cmf_tree_browser.description.icon_map% + + + + + + diff --git a/Resources/public/js/cmf_tree_browser.fancytree.js b/Resources/public/js/cmf_tree_browser.fancytree.js index 9d780b5..e1287f5 100644 --- a/Resources/public/js/cmf_tree_browser.fancytree.js +++ b/Resources/public/js/cmf_tree_browser.fancytree.js @@ -1,3 +1,3 @@ !function(e){function t(i){if(n[i])return n[i].exports;var r=n[i]={exports:{},id:i,loaded:!1};return e[i].call(r.exports,r,r.exports,t),r.loaded=!0,r.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){"use strict";function i(e){return e&&e.__esModule?e:{default:e}}var r=n(27),o=i(r),s=n(29);o.default.fn.cmfTree=function(e){e=o.default.extend({adapter:null,request:{load:null},actions:{}},e);var t=(0,o.default)(this),n=function(e){if("string"==typeof e)return(0,o.default)(e);if(e instanceof o.default)return e;throw"Cannot handle selector "+e+". You may want to pass a jQuery object or a jQuery selector."};if(!e.request.load)throw"cmfTree needs an AJAX URL to lazy load the tree, pass it using the `request.load` option.";e.adapter||(e.adapter=new s.FancytreeAdapter(e));var i=e.adapter;if(!i.bindToElement)throw"cmfTree adapters must have a bindToElement() method to specify the output element of the tree.";for(var r in e.actions)if(e.actions.hasOwnProperty(r)){if(!i.addAction)throw"The configured cmfTree adapter does not support actions, implement the addAction() method or use another adapter.";var a=e.actions[r];if(!a.url)throw'actions should have a url defined, "'+r+'" does not.';i.addAction(r,a.url,a.icon)}if(i.bindToElement(t),e.path_output){if(!i.bindToInput)throw"The configured cmfTree adapter does not support binding to an input field, implement the bindToInput() method or use another adapter.";i.bindToInput(n(e.path_output))}return i}},function(e,t,n){var i=n(43)("wks"),r=n(15),o=n(2).Symbol;e.exports=function(e){return i[e]||(i[e]=o&&o[e]||(o||r)("Symbol."+e))}},function(e,t){var n=e.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(e,t,n){var i=n(4),r=n(23);e.exports=n(10)?function(e,t,n){return i.setDesc(e,t,r(1,n))}:function(e,t,n){return e[t]=n,e}},function(e,t){var n=Object;e.exports={create:n.create,getProto:n.getPrototypeOf,isEnum:{}.propertyIsEnumerable,getDesc:n.getOwnPropertyDescriptor,setDesc:n.defineProperty,setDescs:n.defineProperties,getKeys:n.keys,getNames:n.getOwnPropertyNames,getSymbols:n.getOwnPropertySymbols,each:[].forEach}},function(e,t){e.exports={}},function(e,t,n){var i=n(2),r=n(3),o=n(15)("src"),s="toString",a=Function[s],l=(""+a).split(s);n(7).inspectSource=function(e){return a.call(e)},(e.exports=function(e,t,n,s){"function"==typeof n&&(n.hasOwnProperty(o)||r(n,o,e[t]?""+e[t]:l.join(String(t))),n.hasOwnProperty("name")||r(n,"name",t)),e===i?e[t]=n:(s||delete e[t],r(e,t,n))})(Function.prototype,s,function(){return"function"==typeof this&&this[o]||a.call(this)})},function(e,t){var n=e.exports={version:"1.2.6"};"number"==typeof __e&&(__e=n)},function(e,t,n){var i=n(32);e.exports=function(e,t,n){if(i(e),void 0===t)return e;switch(n){case 1:return function(n){return e.call(t,n)};case 2:return function(n,i){return e.call(t,n,i)};case 3:return function(n,i,r){return e.call(t,n,i,r)}}return function(){return e.apply(t,arguments)}}},function(e,t){e.exports=function(e){if(void 0==e)throw TypeError("Can't call method on "+e);return e}},function(e,t,n){e.exports=!n(20)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(e,t){var n={}.hasOwnProperty;e.exports=function(e,t){return n.call(e,t)}},function(e,t){e.exports=function(e){return"object"==typeof e?null!==e:"function"==typeof e}},function(e,t,n){"use strict";var i=n(41),r=n(19),o=n(6),s=n(3),a=n(11),l=n(5),c=n(39),d=n(14),u=n(4).getProto,h=n(1)("iterator"),f=!([].keys&&"next"in[].keys()),p="@@iterator",v="keys",y="values",g=function(){return this};e.exports=function(e,t,n,b,m,x,_){c(n,t,b);var k,N,w=function(e){if(!f&&e in E)return E[e];switch(e){case v:return function(){return new n(this,e)};case y:return function(){return new n(this,e)}}return function(){return new n(this,e)}},C=t+" Iterator",S=m==y,T=!1,E=e.prototype,P=E[h]||E[p]||m&&E[m],A=P||w(m);if(P){var F=u(A.call(new e));d(F,C,!0),!i&&a(E,p)&&s(F,h,g),S&&P.name!==y&&(T=!0,A=function(){return P.call(this)})}if(i&&!_||!f&&!T&&E[h]||s(E,h,A),l[t]=A,l[C]=g,m)if(k={values:S?A:w(y),keys:x?A:w(v),entries:S?w("entries"):A},_)for(N in k)N in E||o(E,N,k[N]);else r(r.P+r.F*(f||T),t,k);return k}},function(e,t,n){var i=n(4).setDesc,r=n(11),o=n(1)("toStringTag");e.exports=function(e,t,n){e&&!r(e=n?e:e.prototype,o)&&i(e,o,{configurable:!0,value:t})}},function(e,t){var n=0,i=Math.random();e.exports=function(e){return"Symbol(".concat(void 0===e?"":e,")_",(++n+i).toString(36))}},function(e,t,n){var i=n(12);e.exports=function(e){if(!i(e))throw TypeError(e+" is not an object!");return e}},function(e,t,n){var i=n(18),r=n(1)("toStringTag"),o="Arguments"==i(function(){return arguments}());e.exports=function(e){var t,n,s;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(n=(t=Object(e))[r])?n:o?i(t):"Object"==(s=i(t))&&"function"==typeof t.callee?"Arguments":s}},function(e,t){var n={}.toString;e.exports=function(e){return n.call(e).slice(8,-1)}},function(e,t,n){var i=n(2),r=n(7),o=n(3),s=n(6),a=n(8),l="prototype",c=function(e,t,n){var d,u,h,f,p=e&c.F,v=e&c.G,y=e&c.S,g=e&c.P,b=e&c.B,m=v?i:y?i[t]||(i[t]={}):(i[t]||{})[l],x=v?r:r[t]||(r[t]={}),_=x[l]||(x[l]={});v&&(n=t);for(d in n)u=!p&&m&&d in m,h=(u?m:n)[d],f=b&&u?a(h,i):g&&"function"==typeof h?a(Function.call,h):h,m&&!u&&s(m,d,h),x[d]!=h&&o(x,d,f),g&&_[d]!=h&&(_[d]=h)};i.core=r,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,e.exports=c},function(e,t){e.exports=function(e){try{return!!e()}catch(e){return!0}}},function(e,t,n){var i=n(8),r=n(38),o=n(37),s=n(16),a=n(46),l=n(47);e.exports=function(e,t,n,c){var d,u,h,f=l(e),p=i(n,c,t?2:1),v=0;if("function"!=typeof f)throw TypeError(e+" is not iterable!");if(o(f))for(d=a(e.length);d>v;v++)t?p(s(u=e[v])[0],u[1]):p(e[v]);else for(h=f.call(e);!(u=h.next()).done;)r(h,p,u.value,t)}},function(e,t){e.exports=function(e,t){return{value:t,done:!!e}}},function(e,t){e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},function(e,t,n){var i=n(6);e.exports=function(e,t){for(var n in t)i(e,n,t[n]);return e}},function(e,t){e.exports=function(e,t,n){if(!(e instanceof t))throw TypeError(n+": use the 'new' operator!");return e}},function(e,t){var n=Math.ceil,i=Math.floor;e.exports=function(e){return isNaN(e=+e)?0:(e>0?i:n)(e)}},function(e,t){e.exports=jQuery},function(e,t){!function(e,t,n,i){"use strict";function r(t,n){t||(n=n?": "+n:"",e.error("Fancytree assertion failed"+n))}function o(e,n){var i,r,o=t.console?t.console[e]:null;if(o)try{o.apply(t.console,n)}catch(e){for(r="",i=0;ia;return!0}function l(e,t,n,i,r){var o=function(){var n=t[e],o=i[e],s=t.ext[r],a=function(){return n.apply(t,arguments)},l=function(e){return n.apply(t,e)};return function(){var e=t._local,n=t._super,i=t._superApply;try{return t._local=s,t._super=a,t._superApply=l,o.apply(t,arguments)}finally{t._local=e,t._super=n,t._superApply=i}}}();return o}function c(t,n,i,r){for(var o in i)"function"==typeof i[o]?"function"==typeof t[o]?t[o]=l(o,t,n,i,r):"_"===o.charAt(0)?t.ext[r][o]=l(o,t,n,i,r):e.error("Could not override tree."+o+". Use prefix '_' to create tree."+r+"._"+o):"options"!==o&&(t.ext[r][o]=i[o])}function d(t,n){return t===i?e.Deferred(function(){this.resolve()}).promise():e.Deferred(function(){this.resolveWith(t,n)}).promise()}function u(t,n){return t===i?e.Deferred(function(){this.reject()}).promise():e.Deferred(function(){this.rejectWith(t,n)}).promise()}function h(e,t){return function(){e.resolveWith(t)}}function f(t){var n=e.extend({},t.data()),i=n.json;return delete n.fancytree,delete n.uiFancytree,i&&(delete n.json,n=e.extend(n,i)),n}function p(e){return(""+e).replace(w,function(e){return T[e]})}function v(e){return(""+e).replace(C,function(e){return T[e]})}function y(e){return e=e.toLowerCase(),function(t){return t.title.toLowerCase().indexOf(e)>=0}}function g(e){var t=new RegExp("^"+e,"i");return function(e){return t.test(e.title)}}function b(t,n){var i,o,s,a;for(this.parent=t,this.tree=t.tree,this.ul=null,this.li=null,this.statusNodeType=null,this._isLoading=!1,this._error=null,this.data={},i=0,o=j.length;iul.fancytree-container").remove();var n,r={tree:this};this.rootNode=new b(r,{title:"root",key:"root_"+this._id,children:null,expanded:!0}),this.rootNode.parent=null,n=e("