From a027e1118556c2b5cea426a1c2cef6caa830cf37 Mon Sep 17 00:00:00 2001 From: David Neukirchen Date: Fri, 30 Dec 2016 12:19:50 +0100 Subject: [PATCH] Basic vue-app-setup (#70) * Basic vue-app-setup * Remove modified api controller * Add npm-debug.log to gitignore * Revert to wrong gitignore and ad npm-debug.log to the correct one * Fix more code style errors --- .gitignore | 1 + administrator/components/com_media/.babelrc | 3 + .../components/com_media/controller.php | 17 ----- .../components/com_media/package.json | 27 +++++++ .../com_media/resources/app/Event.js | 17 +++++ .../com_media/resources/components/app.vue | 76 +++++++++++++++++++ .../resources/components/browser/browser.vue | 45 +++++++++++ .../resources/components/browser/item.vue | 12 +++ .../resources/components/tree/item.vue | 32 ++++++++ .../resources/components/tree/tree.vue | 29 +++++++ .../components/com_media/resources/main.js | 27 +++++++ .../com_media/views/media/tmpl/default.php | 11 +++ .../com_media/views/media/view.html.php | 69 +++++++++++++++++ media/media/js/app.js | 3 + 14 files changed, 352 insertions(+), 17 deletions(-) create mode 100644 administrator/components/com_media/.babelrc create mode 100644 administrator/components/com_media/package.json create mode 100644 administrator/components/com_media/resources/app/Event.js create mode 100644 administrator/components/com_media/resources/components/app.vue create mode 100644 administrator/components/com_media/resources/components/browser/browser.vue create mode 100644 administrator/components/com_media/resources/components/browser/item.vue create mode 100644 administrator/components/com_media/resources/components/tree/item.vue create mode 100644 administrator/components/com_media/resources/components/tree/tree.vue create mode 100644 administrator/components/com_media/resources/main.js create mode 100644 administrator/components/com_media/views/media/tmpl/default.php create mode 100644 administrator/components/com_media/views/media/view.html.php create mode 100644 media/media/js/app.js diff --git a/.gitignore b/.gitignore index f7d136459ad47..32bde8d2915c6 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ # Node modules # node_modules/ +npm-debug.log # phpDocumentor Logs # phpdoc-* diff --git a/administrator/components/com_media/.babelrc b/administrator/components/com_media/.babelrc new file mode 100644 index 0000000000000..af0f0c3d35213 --- /dev/null +++ b/administrator/components/com_media/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015"] +} \ No newline at end of file diff --git a/administrator/components/com_media/controller.php b/administrator/components/com_media/controller.php index 4fa8ea84e478e..3d443443e9490 100644 --- a/administrator/components/com_media/controller.php +++ b/administrator/components/com_media/controller.php @@ -16,21 +16,4 @@ */ class MediaController extends JControllerLegacy { - /** - * Typical view method for MVC based architecture - * - * This function is provide as a default implementation, in most cases - * you will need to override it in your own controllers. - * - * @param boolean $cachable If true, the view output will be cached - * @param array $urlparams An array of safe url parameters and their variable types, for valid values see {@link JFilterInput::clean()}. - * - * @return JControllerLegacy A JControllerLegacy object to support chaining. - * - * @since __DEPLOY_VERSION__ - */ - public function display($cachable = false, $urlparams = false) - { - echo 'Welcome to the new media manager'; - } } diff --git a/administrator/components/com_media/package.json b/administrator/components/com_media/package.json new file mode 100644 index 0000000000000..b3a45aa128e9b --- /dev/null +++ b/administrator/components/com_media/package.json @@ -0,0 +1,27 @@ +{ + "name": "com_media", + "version": "3.0.0", + "description": "Component for managing site media", + "author": "", + "license": "GPL-3.0", + "scripts": { + "build": "browserify ./resources/main.js | uglifyjs -c warnings=false -m > ../../../media/media/js/app.js" + }, + "dependencies": { + "vue": "^2.0.1" + }, + "devDependencies": { + "babel-core": "^6.0.0", + "babel-preset-es2015": "^6.0.0", + "babelify": "^7.2.0", + "browserify": "^13.0.1", + "uglify-js": "^2.5.0", + "vueify": "^9.1.0" + }, + "browserify": { + "transform": [ + "vueify", + "babelify" + ] + } +} diff --git a/administrator/components/com_media/resources/app/Event.js b/administrator/components/com_media/resources/app/Event.js new file mode 100644 index 0000000000000..c1f21e501b03f --- /dev/null +++ b/administrator/components/com_media/resources/app/Event.js @@ -0,0 +1,17 @@ +import Vue from "vue"; + +class Event { + constructor() { + this.vue = new Vue(); + } + + fire(event, data = null) { + this.vue.$emit(event, data); + } + + listen(event, callback) { + this.vue.$on(event, callback); + } +} + +export default Event; \ No newline at end of file diff --git a/administrator/components/com_media/resources/components/app.vue b/administrator/components/com_media/resources/components/app.vue new file mode 100644 index 0000000000000..6d3a859b39f2c --- /dev/null +++ b/administrator/components/com_media/resources/components/app.vue @@ -0,0 +1,76 @@ + + + \ No newline at end of file diff --git a/administrator/components/com_media/resources/components/browser/browser.vue b/administrator/components/com_media/resources/components/browser/browser.vue new file mode 100644 index 0000000000000..f592fe32ed448 --- /dev/null +++ b/administrator/components/com_media/resources/components/browser/browser.vue @@ -0,0 +1,45 @@ + + + \ No newline at end of file diff --git a/administrator/components/com_media/resources/components/browser/item.vue b/administrator/components/com_media/resources/components/browser/item.vue new file mode 100644 index 0000000000000..61adea40186a7 --- /dev/null +++ b/administrator/components/com_media/resources/components/browser/item.vue @@ -0,0 +1,12 @@ + + + \ No newline at end of file diff --git a/administrator/components/com_media/resources/components/tree/item.vue b/administrator/components/com_media/resources/components/tree/item.vue new file mode 100644 index 0000000000000..a5aeb054c2387 --- /dev/null +++ b/administrator/components/com_media/resources/components/tree/item.vue @@ -0,0 +1,32 @@ + + + + + \ No newline at end of file diff --git a/administrator/components/com_media/resources/components/tree/tree.vue b/administrator/components/com_media/resources/components/tree/tree.vue new file mode 100644 index 0000000000000..34362580bae19 --- /dev/null +++ b/administrator/components/com_media/resources/components/tree/tree.vue @@ -0,0 +1,29 @@ + + + \ No newline at end of file diff --git a/administrator/components/com_media/resources/main.js b/administrator/components/com_media/resources/main.js new file mode 100644 index 0000000000000..2d55adaa27eed --- /dev/null +++ b/administrator/components/com_media/resources/main.js @@ -0,0 +1,27 @@ +import Vue from "vue"; +import App from "./components/app.vue"; +import Tree from "./components/tree/tree.vue"; +import TreeItem from "./components/tree/item.vue"; +import Browser from "./components/browser/browser.vue"; +import BrowserItem from "./components/browser/item.vue"; +import Event from "./app/Event"; + +// Media Manager namespace +window.Media = window.Media || {}; + +// Register the Event Bus +window.Media.Event = new Event(); + +// Register the vue components +Vue.component('media-tree', Tree); +Vue.component('media-tree-item', TreeItem); +Vue.component('media-browser', Browser); +Vue.component('media-browser-item', BrowserItem); + +// Create the root Vue instance +document.addEventListener("DOMContentLoaded", + (e) => new Vue({ + el: '#com-media', + render: h => h(App) + }) +) diff --git a/administrator/components/com_media/views/media/tmpl/default.php b/administrator/components/com_media/views/media/tmpl/default.php new file mode 100644 index 0000000000000..ea0af071a5cd8 --- /dev/null +++ b/administrator/components/com_media/views/media/tmpl/default.php @@ -0,0 +1,11 @@ + +
diff --git a/administrator/components/com_media/views/media/view.html.php b/administrator/components/com_media/views/media/view.html.php new file mode 100644 index 0000000000000..51b48088d8ea7 --- /dev/null +++ b/administrator/components/com_media/views/media/view.html.php @@ -0,0 +1,69 @@ +prepareDocument(); + + // Prepare the toolbar + $this->prepareToolbar(); + + parent::display($tpl); + } + + /** + * Prepare the document. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function prepareDocument() + { + $doc = JFactory::getDocument(); + + // Add javascripts + $doc->addScript(JUri::root() . 'media/media/js/app.js'); + + // TODO Add stylesheets + } + + /** + * Prepare the toolbar. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + protected function prepareToolbar() + { + // Set the title + JToolbarHelper::title(JText::_('COM_MEDIA'), 'images mediamanager'); + + // TODO add the toolbar buttons + } +} diff --git a/media/media/js/app.js b/media/media/js/app.js new file mode 100644 index 0000000000000..5090b81e607fc --- /dev/null +++ b/media/media/js/app.js @@ -0,0 +1,3 @@ +!function e(t,n,r){function o(a,s){if(!n[a]){if(!t[a]){var c="function"==typeof require&&require;if(!s&&c)return c(a,!0);if(i)return i(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var l=n[a]={exports:{}};t[a][0].call(l.exports,function(e){var n=t[a][1][e];return o(n?n:e)},l,l.exports,e,t,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;a1)for(var n=1;n-1&&(l="init"),n.compatible=Number(a.version.split(".")[0])>=2,n.compatible?void 0:void console.warn("[HMR] You are using a version of vue-hot-reload-api that is only compatible with Vue.js core ^2.0.0.")},n.createRecord=function(e,t){var n=null;"function"==typeof t&&(n=t,t=n.options),r(e,t),s[e]={Ctor:a.extend(t),instances:[]}},n.rerender=i(function(e,t){var n=s[e];n.Ctor.options.render=t.render,n.Ctor.options.staticRenderFns=t.staticRenderFns,n.instances.slice().forEach(function(e){e.$options.render=t.render,e.$options.staticRenderFns=t.staticRenderFns,e._staticTrees=[],e.$forceUpdate()})}),n.reload=i(function(e,t){r(e,t);var n=s[e];n.Ctor.extendOptions=t;var o=a.extend(t);n.Ctor.options=o.options,n.Ctor.cid=o.cid,o.release&&o.release(),n.instances.slice().forEach(function(e){e.$parent?e.$parent.$forceUpdate():console.warn("Root or manually mounted instance modified. Full reload required.")})})},{}],3:[function(e,t,n){(function(e,n){"use strict";function r(e){return null==e?"":"object"==typeof e?JSON.stringify(e,null,2):String(e)}function o(e){var t=parseFloat(e,10);return t||0===t?t:e}function i(e,t){for(var n=Object.create(null),r=e.split(","),o=0;o-1)return e.splice(n,1)}}function s(e,t){return On.call(e,t)}function c(e){return"string"==typeof e||"number"==typeof e}function u(e){var t=Object.create(null);return function(n){var r=t[n];return r||(t[n]=e(n))}}function l(e,t){function n(n){var r=arguments.length;return r?r>1?e.apply(t,arguments):e.call(t,n):e.call(t)}return n._length=e.length,n}function d(e,t){t=t||0;for(var n=e.length-t,r=new Array(n);n--;)r[n]=e[n+t];return r}function f(e,t){for(var n in t)e[n]=t[n];return e}function p(e){return null!==e&&"object"==typeof e}function v(e){return Dn.call(e)===Sn}function h(e){for(var t={},n=0;nVn._maxUpdateCount)){Wn("You may have an infinite update loop "+(t.user?'in watcher with expression "'+t.expression+'"':"in a component render function."),t.vm);break}}zn&&Vn.devtools&&zn.emit("flush"),K()}function Y(e){var t=e.id;if(null==mr[t]){if(mr[t]=!0,gr){for(var n=hr.length-1;n>=0&&hr[n].id>e.id;)n--;hr.splice(Math.max(n,br)+1,0,e)}else hr.push(e);_r||(_r=!0,Jn(W))}}function Z(e){Or.clear(),G(e,Or)}function G(e,t){var n,r,o=Array.isArray(e);if((o||p(e))&&Object.isExtensible(e)){if(e.__ob__){var i=e.__ob__.dep.id;if(t.has(i))return;t.add(i)}if(o)for(n=e.length;n--;)G(e[n],t);else for(r=Object.keys(e),n=r.length;n--;)G(e[r[n]],t)}}function Q(e){e._watchers=[];var t=e.$options;t.props&&X(e,t.props),t.methods&&re(e,t.methods),t.data?ee(e):A(e._data={},!0),t.computed&&te(e,t.computed),t.watch&&oe(e,t.watch)}function X(t,n){var r=t.$options.propsData||{},o=t.$options._propKeys=Object.keys(n),i=!t.$parent;rr.shouldConvert=i;for(var a=function(i){var a=o[i];"production"!==e.env.NODE_ENV?(Cr[a]&&Wn('"'+a+'" is a reserved attribute and cannot be used as component prop.',t),k(t,a,F(a,n,r,t),function(){t.$parent&&!rr.isSettingProps&&Wn("Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: \""+a+'"',t)})):k(t,a,F(a,n,r,t))},s=0;s1?d(n):n;for(var r=d(arguments,1),o=0,i=n.length;o-1:e.test(t)}function et(t){var n={};n.get=function(){return Vn},"production"!==e.env.NODE_ENV&&(n.set=function(){Wn("Do not replace the Vue.config object, set individual fields instead.")}),Object.defineProperty(t,"config",n),t.util=cr,t.set=D,t.delete=S,t.nextTick=Jn,t.options=Object.create(null),Vn._assetTypes.forEach(function(e){t.options[e+"s"]=Object.create(null)}),t.options._base=t,f(t.options.components,Lr),Ye(t),Ze(t),Ge(t),Qe(t)}function tt(e){for(var t=e.data,n=e,r=e;r.child;)r=r.child._vnode,r.data&&(t=nt(r.data,t));for(;n=n.parent;)n.data&&(t=nt(t,n.data));return rt(t)}function nt(e,t){return{staticClass:ot(e.staticClass,t.staticClass),class:e.class?[e.class,t.class]:t.class}}function rt(e){var t=e.class,n=e.staticClass;return n||t?ot(n,it(t)):""}function ot(e,t){return e?t?e+" "+t:e:t||""}function it(e){var t="";if(!e)return t;if("string"==typeof e)return e;if(Array.isArray(e)){for(var n,r=0,o=e.length;r-1?Qr[e]=t.constructor===window.HTMLUnknownElement||t.constructor===window.HTMLElement:Qr[e]=/HTMLUnknownElement/.test(t.toString())}function ct(t){if("string"==typeof t){var n=t;if(t=document.querySelector(t),!t)return"production"!==e.env.NODE_ENV&&Wn("Cannot find element: "+n),document.createElement("div")}return t}function ut(e,t){var n=document.createElement(e);return"select"!==e?n:(t.data&&t.data.attrs&&"multiple"in t.data.attrs&&n.setAttribute("multiple","multiple"),n)}function lt(e,t){return document.createElementNS(Wr[e],t)}function dt(e){return document.createTextNode(e)}function ft(e){return document.createComment(e)}function pt(e,t,n){e.insertBefore(t,n)}function vt(e,t){e.removeChild(t)}function ht(e,t){e.appendChild(t)}function mt(e){return e.parentNode}function yt(e){return e.nextSibling}function _t(e){return e.tagName}function gt(e,t){e.textContent=t}function bt(e,t,n){e.setAttribute(t,n)}function wt(e,t){var n=e.data.ref;if(n){var r=e.context,o=e.child||e.elm,i=r.$refs;t?Array.isArray(i[n])?a(i[n],o):i[n]===o&&(i[n]=void 0):e.data.refInFor?Array.isArray(i[n])&&i[n].indexOf(o)<0?i[n].push(o):i[n]=[o]:i[n]=o}}function Et(e){return null==e}function xt(e){return null!=e}function Ot(e,t){return e.key===t.key&&e.tag===t.tag&&e.isComment===t.isComment&&!e.data==!t.data}function Ct(e,t,n){var r,o,i={};for(r=t;r<=n;++r)o=e[r].key,xt(o)&&(i[o]=r);return i}function Nt(t){function n(e){return new $r(D.tagName(e).toLowerCase(),{},[],void 0,e)}function o(e,t){function n(){0===--n.listeners&&a(e)}return n.listeners=t,n}function a(e){var t=D.parentNode(e);t&&D.removeChild(t,e)}function s(t,n,r,o,i){if(t.isRootInsert=!i,!u(t,n,r,o)){var a=t.data,s=t.children,c=t.tag;xt(c)?("production"!==e.env.NODE_ENV&&(a&&a.pre&&S++,S||t.ns||Vn.ignoredElements.length&&Vn.ignoredElements.indexOf(c)>-1||!Vn.isUnknownElement(c)||Wn("Unknown custom element: <"+c+'> - did you register the component correctly? For recursive components, make sure to provide the "name" option.',t.context)),t.elm=t.ns?D.createElementNS(t.ns,c):D.createElement(c,t),m(t),f(t,s,n),xt(a)&&v(t,n),d(r,t.elm,o),"production"!==e.env.NODE_ENV&&a&&a.pre&&S--):t.isComment?(t.elm=D.createComment(t.text),d(r,t.elm,o)):(t.elm=D.createTextNode(t.text),d(r,t.elm,o))}}function u(e,t,n,r){var o=e.data;if(xt(o)){var i=xt(e.child)&&o.keepAlive;if(xt(o=o.hook)&&xt(o=o.init)&&o(e,!1,n,r),xt(e.child))return h(e,t),i&&l(e,t,n,r),!0}}function l(e,t,n,r){for(var o,i=e;i.child;)if(i=i.child._vnode,xt(o=i.data)&&xt(o=o.transition)){for(o=0;op?(l=Et(r[m+1])?null:r[m+1].elm,y(t,l,r,f,m,o)):f>m&&g(t,n,d,p)}function E(e,t,n,r){if(e!==t){if(t.isStatic&&e.isStatic&&t.key===e.key&&(t.isCloned||t.isOnce))return t.elm=e.elm,void(t.child=e.child);var o,i=t.data,a=xt(i);a&&xt(o=i.hook)&&xt(o=o.prepatch)&&o(e,t);var s=t.elm=e.elm,c=e.children,u=t.children;if(a&&p(t)){for(o=0;o, or missing . Bailing hydration and performing full client-side render.")}t=n(t)}if(u=t.elm,l=D.parentNode(u),s(r,f,l,D.nextSibling(u)),r.parent){for(var h=r.parent;h;)h.elm=r.elm,h=h.parent;if(p(r))for(var m=0;m-1?t.split(/\s+/).forEach(function(t){return e.classList.add(t)}):e.classList.add(t);else{var n=" "+e.getAttribute("class")+" ";n.indexOf(" "+t+" ")<0&&e.setAttribute("class",(n+t).trim())}}function Kt(e,t){if(t&&t.trim())if(e.classList)t.indexOf(" ")>-1?t.split(/\s+/).forEach(function(t){return e.classList.remove(t)}):e.classList.remove(t);else{for(var n=" "+e.getAttribute("class")+" ",r=" "+t+" ";n.indexOf(r)>=0;)n=n.replace(r," ");e.setAttribute("class",n.trim())}}function Wt(e){Co(function(){Co(e)})}function Yt(e,t){(e._transitionClasses||(e._transitionClasses=[])).push(t),Jt(e,t)}function Zt(e,t){e._transitionClasses&&a(e._transitionClasses,t),Kt(e,t)}function Gt(e,t,n){var r=Qt(e,t),o=r.type,i=r.timeout,a=r.propCount;if(!o)return n();var s=o===go?Eo:Oo,c=0,u=function(){e.removeEventListener(s,l),n()},l=function(t){t.target===e&&++c>=a&&u()};setTimeout(function(){c0&&(n=go,l=a,d=i.length):t===bo?u>0&&(n=bo,l=u,d=c.length):(l=Math.max(a,u),n=l>0?a>u?go:bo:null,d=n?n===go?i.length:c.length:0);var f=n===go&&No.test(r[wo+"Property"]);return{type:n,timeout:l,propCount:d,hasTransform:f}}function Xt(e,t){for(;e.length1,k=n._enterCb=on(function(){$&&Zt(n,E),k.cancelled?($&&Zt(n,w),N&&N(n)):C&&C(n),n._enterCb=null});e.data.show||de(e.data.hook||(e.data.hook={}),"insert",function(){var t=n.parentNode,r=t&&t._pending&&t._pending[e.key];r&&r.context===e.context&&r.tag===e.tag&&r.elm._leaveCb&&r.elm._leaveCb(),O&&O(n,k)},"transition-insert"),x&&x(n),$&&(Yt(n,w),Wt(function(){Zt(n,w),Yt(n,E),k.cancelled||A||Gt(n,i,k)})),e.data.show&&(t&&t(),O&&O(n,k)),$||A||k()}}}function nn(e,t){function n(){m.cancelled||(e.data.show||((r.parentNode._pending||(r.parentNode._pending={}))[e.key]=e),u&&u(r),v&&(Yt(r,s),Wt(function(){Zt(r,s),Yt(r,c),m.cancelled||h||Gt(r,a,m)})),l&&l(r,m),v||h||m())}var r=e.elm;r._enterCb&&(r._enterCb.cancelled=!0,r._enterCb());var o=rn(e.data.transition);if(!o)return t();if(!r._leaveCb&&1===r.nodeType){var i=o.css,a=o.type,s=o.leaveClass,c=o.leaveActiveClass,u=o.beforeLeave,l=o.leave,d=o.afterLeave,f=o.leaveCancelled,p=o.delayLeave,v=i!==!1&&!Un,h=l&&(l._length||l.length)>1,m=r._leaveCb=on(function(){r.parentNode&&r.parentNode._pending&&(r.parentNode._pending[e.key]=null),v&&Zt(r,c),m.cancelled?(v&&Zt(r,s),f&&f(r)):(t(),d&&d(r)),r._leaveCb=null});p?p(n):n()}}function rn(e){if(e){if("object"==typeof e){var t={};return e.css!==!1&&f(t,$o(e.name||"v")),f(t,e),t}return"string"==typeof e?$o(e):void 0}}function on(e){var t=!1;return function(){t||(t=!0,e())}}function an(e,t){t.data.show||tn(t)}function sn(t,n,r){var o=n.value,i=t.multiple;if(i&&!Array.isArray(o))return void("production"!==e.env.NODE_ENV&&Wn('