Replaces require.js with jepnope

Gets rid of the AMD pattern, adds scriptLoader service, work on security
service started
This commit is contained in:
Per Ploug
2013-06-18 10:51:26 +02:00
parent a2e4b6b698
commit 4b68d1950c
36 changed files with 681 additions and 385 deletions

3
.gitignore vendored
View File

@@ -76,7 +76,8 @@ src/Umbraco.Web.UI/umbraco/[V]iews/**/*.css
src/Umbraco.Web.UI/umbraco/[V]iews/**/*.html src/Umbraco.Web.UI/umbraco/[V]iews/**/*.html
src/Umbraco.Web.UI/umbraco/assets/* src/Umbraco.Web.UI/umbraco/assets/*
src/Umbraco.Web.UI.Client/build/* src/Umbraco.Web.UI.Client/build/*
src/Umbraco.Web.UI.Client/build/* src/Umbraco.Web.UI.Client/build/**/*.*
src/Umbraco.Web.UI.Client/build/belle/ src/Umbraco.Web.UI.Client/build/belle/
src/Umbraco.Web.UI/UserControls/ src/Umbraco.Web.UI/UserControls/
build/_BuildOutput/ build/_BuildOutput/
build/belle/

View File

@@ -105,8 +105,8 @@ module.exports = function (grunt) {
}, },
app: { app: {
files: [ files: [
{ dest: '<%= distdir %>/js', src : 'main.js', expand: true, cwd: 'src/' }, { dest: '<%= distdir %>/js', src : '*.js', expand: true, cwd: 'src/' }
{ dest: '<%= distdir %>/js', src : 'routes.js', expand: true, cwd: 'src/' }] ]
}, },
media: { media: {
files: [{ dest: 'build/media', src : '*.*', expand: true, cwd: 'media/' }] files: [{ dest: 'build/media', src : '*.*', expand: true, cwd: 'media/' }]
@@ -130,65 +130,37 @@ module.exports = function (grunt) {
process: true process: true
} }
}, },
app: {
src: ['src/app.js'],
dest: '<%= distdir %>/js/app.js',
options:{
banner: "<%= banner %>'use strict';\ndefine(['angular'], function (angular) {\n",
footer: "\n\nreturn app;\n});"
}
},
angular: { angular: {
src:['vendor/angular/angular.min.js'], src:['vendor/angular/angular.min.js'],
dest: '<%= distdir %>/lib/angular/angular.min.js' dest: '<%= distdir %>/lib/angular/angular.min.js'
}, },
controllers: { controllers: {
src:['src/views/**/*.controller.js'], src:['src/views/**/*.controller.js'],
dest: '<%= distdir %>/js/umbraco.controllers.js', dest: '<%= distdir %>/js/umbraco.controllers.js'
options:{
banner: "'use strict';\n<%= banner %>\ndefine(['app', 'angular'], function (app, angular) {\n",
footer: "\n\nreturn angular;\n});"
}
}, },
services: { services: {
src:['src/common/services/*.js'], src:['src/common/services/*.js'],
dest: '<%= distdir %>/js/umbraco.services.js', dest: '<%= distdir %>/js/umbraco.services.js'
options:{ },
banner: "'use strict';\ndefine(['app','angular'], function (app, angular) {\n", security: {
footer: "\n\nreturn angular;\n});" src:['src/common/security/*.js'],
} dest: '<%= distdir %>/js/umbraco.security.js'
}, },
resources: { resources: {
src:['src/common/resources/*.js'], src:['src/common/resources/*.js'],
dest: '<%= distdir %>/js/umbraco.resources.js', dest: '<%= distdir %>/js/umbraco.resources.js'
options:{
banner: "<%= banner %>'use strict';\ndefine(['app', 'angular'], function (app, angular) {\n",
footer: "\n\nreturn angular;\n});"
}
}, },
mocks: { mocks: {
src:['src/common/mocks/**/*.js'], src:['src/common/mocks/**/*.js'],
dest: '<%= distdir %>/js/umbraco.mocks.js', dest: '<%= distdir %>/js/umbraco.mocks.js'
options:{
banner: "<%= banner %>'use strict';\ndefine(['app', 'angular'], function (app, angular) {\n",
footer: "\n\nreturn angular;\n});"
}
}, },
directives: { directives: {
src:['src/common/directives/*.js'], src:['src/common/directives/*.js'],
dest: '<%= distdir %>/js/umbraco.directives.js', dest: '<%= distdir %>/js/umbraco.directives.js'
options:{
banner: "<%= banner %>'use strict';\ndefine(['app','angular','underscore'], function (app, angular,_) {\n",
footer: "\n\nreturn angular;\n});"
}
}, },
filters: { filters: {
src:['src/common/filters/*.js'], src:['src/common/filters/*.js'],
dest: '<%= distdir %>/js/umbraco.filters.js', dest: '<%= distdir %>/js/umbraco.filters.js'
options:{
banner: "<%= banner %>'use strict';\ndefine([ 'app','angular'], function (app,angular) {\n",
footer: "\n\nreturn app;\n});"
}
} }
}, },

View File

@@ -0,0 +1,2 @@
/*yepnope1.5.x|WTFPL*/
(function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f<d;f++)g=a[f].split("="),(e=z[g.shift()])&&(c=e(c,g));for(f=0;f<b;f++)c=x[f](c);return c}function g(a,e,f,g,h){var i=b(a),j=i.autoCallback;i.url.split(".").pop().split("?").shift(),i.bypass||(e&&(e=d(e)?e:e[a]||e[g]||e[a.split("/").pop().split("?")[0]]),i.instead?i.instead(a,e,f,g,h):(y[i.url]?i.noexec=!0:y[i.url]=1,f.load(i.url,i.forceCSS||!i.forceJS&&"css"==i.url.split(".").pop().split("?").shift()?"c":c,i.noexec,i.attrs,i.timeout),(d(e)||d(j))&&f.load(function(){k(),e&&e(i.origUrl,h,g),j&&j(i.origUrl,h,g),y[i.url]=2})))}function h(a,b){function c(a,c){if(a){if(e(a))c||(j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}),g(a,j,b,0,h);else if(Object(a)===a)for(n in m=function(){var b=0,c;for(c in a)a.hasOwnProperty(c)&&b++;return b}(),a)a.hasOwnProperty(n)&&(!c&&!--m&&(d(j)?j=function(){var a=[].slice.call(arguments);k.apply(this,a),l()}:j[n]=function(a){return function(){var b=[].slice.call(arguments);a&&a.apply(this,b),l()}}(k[n])),g(a[n],j,b,n,h))}else!c&&l()}var h=!!a.test,i=a.load||a.both,j=a.callback||f,k=j,l=a.complete||f,m,n;c(h?a.yep:a.nope,!!i),i&&c(i)}var i,j,l=this.yepnope.loader;if(e(a))g(a,0,l,0);else if(w(a))for(i=0;i<a.length;i++)j=a[i],e(j)?g(j,0,l,0):w(j)?B(j):Object(j)===j&&h(j,l);else Object(a)===a&&h(a,l)},B.addPrefix=function(a,b){z[a]=b},B.addFilter=function(a){x.push(a)},B.errorTimeout=1e4,null==b.readyState&&b.addEventListener&&(b.readyState="loading",b.addEventListener("DOMContentLoaded",A=function(){b.removeEventListener("DOMContentLoaded",A,0),b.readyState="complete"},0)),a.yepnope=k(),a.yepnope.executeStack=h,a.yepnope.injectJs=function(a,c,d,e,i,j){var k=b.createElement("script"),l,o,e=e||B.errorTimeout;k.src=a;for(o in d)k.setAttribute(o,d[o]);c=j?h:c||f,k.onreadystatechange=k.onload=function(){!l&&g(k.readyState)&&(l=1,c(),k.onload=k.onreadystatechange=null)},m(function(){l||(l=1,c(1))},e),i?k.onload():n.parentNode.insertBefore(k,n)},a.yepnope.injectCss=function(a,c,d,e,g,i){var e=b.createElement("link"),j,c=i?h:c||f;e.href=a,e.rel="stylesheet",e.type="text/css";for(j in d)e.setAttribute(j,d[j]);g||(n.parentNode.insertBefore(e,n),m(c,0))}})(this,document);

View File

@@ -1,6 +1,7 @@
var app = angular.module('umbraco', [ var app = angular.module('umbraco', [
'umbraco.filters', 'umbraco.filters',
'umbraco.directives', 'umbraco.directives',
'umbraco.resources', 'umbraco.resources',
'umbraco.services' 'umbraco.services',
'umbraco.security'
]); ]);

View File

@@ -1,6 +1,7 @@
var app = angular.module('umbraco', [ var app = angular.module('umbraco', [
'umbraco.filters', 'umbraco.filters',
'umbraco.directives', 'umbraco.directives',
'umbraco.mocks.resources', 'umbraco.mocks.resources',
'umbraco.services' 'umbraco.services',
'umbraco.security'
]); ]);

View File

@@ -5,7 +5,7 @@
**/ **/
function treeIconClassFilter(treeIconHelper) { function treeIconClassFilter(treeIconHelper) {
return function (treeNode, standardClasses) { return function (treeNode, standardClasses) {
if (treeNode.iconIsClass) { if (treeNode.iconIsClass !== false) {
return standardClasses + " " + treeIconHelper.convertFromLegacy(treeNode); return standardClasses + " " + treeIconHelper.convertFromLegacy(treeNode);
} }
//we need an 'icon-' class in there for certain styles to work so if it is image based we'll add this //we need an 'icon-' class in there for certain styles to work so if it is image based we'll add this

View File

@@ -1,91 +1,91 @@
function _getNode(id){
return {
name: "My content with id: " + id,
updateDate: new Date(),
publishDate: new Date(),
id: id,
parentId: 1234,
icon: "icon-file-alt",
owner: {name: "Administrator", id: 0},
updater: {name: "Per Ploug Krogslund", id: 1},
tabs: [
{
label: "Child documents",
alias: "tab00",
id: 0,
active: true,
properties: [
{ alias: "list", label: "List", view: "umbraco.listview", value: "", hideLabel: true }
]
},
{
label: "Content",
alias: "tab01",
id: 1,
properties: [
{ alias: "bodyText", label: "Body Text", description:"Here you enter the primary article contents", view: "umbraco.rte", value: "<p>askjdkasj lasjd</p>" },
{ alias: "textarea", label: "textarea", view: "umbraco.textarea", value: "ajsdka sdjkds", config: { rows: 4 } },
{ alias: "map", label: "Map", view: "umbraco.googlemaps", value: "37.4419,-122.1419", config: { mapType: "ROADMAP", zoom: 4 } },
{ alias: "media", label: "Media picker", view: "umbraco.mediapicker", value: "" },
{ alias: "content", label: "Content picker", view: "umbraco.contentpicker", value: "" }
]
},
{
label: "Sample Editor",
alias: "tab02",
id: 2,
properties: [
{ alias: "datepicker", label: "Datepicker", view: "umbraco.datepicker", config: { rows: 7 } },
{ alias: "tags", label: "Tags", view: "umbraco.tags", value: ""}
]
},
{
label: "Grid",
alias: "tab03",
id: 3,
properties: [
{ alias: "grid", label: "Grid", view: "umbraco.grid", controller: "umbraco.grid", value: "test", hideLabel: true }
]
},{
label: "WIP",
alias: "tab04",
id: 4,
properties: [
{ alias: "tes", label: "Stuff", view: "umbraco.test", controller: "umbraco.embeddedcontent", value: "",
config: {
fields: [
{ alias: "embedded", label: "Embbeded", view: "umbraco.textstring", value: ""},
{ alias: "embedded2", label: "Embbeded 2", view: "umbraco.contentpicker", value: ""},
{ alias: "embedded3", label: "Embbeded 3", view: "umbraco.textarea", value: ""},
{ alias: "embedded4", label: "Embbeded 4", view: "umbraco.datepicker", value: ""}
]
}
}
]
}
]
};
}
angular.module('umbraco.mocks.resources') angular.module('umbraco.mocks.resources')
.factory('contentResource', function () { .factory('contentResource', function ($q) {
var contentArray = []; var contentArray = [];
var factory = { var factory = {
_cachedItems: contentArray, getById: function (id) {
getContent: function (id) { var deferred = $q.defer();
if (contentArray[id] !== undefined){ if (contentArray[id] !== undefined){
return contentArray[id]; deferred.resolve(contentArray[id]);
}else{
deferred.resolve(_getNode(id));
} }
var content = { return deferred.promise;
name: "My content with id: " + id,
updateDate: new Date(),
publishDate: new Date(),
id: id,
parentId: 1234,
icon: "icon-file-alt",
owner: {name: "Administrator", id: 0},
updater: {name: "Per Ploug Krogslund", id: 1},
tabs: [
{
label: "Child documents",
alias: "tab00",
id: 0,
active: true,
properties: [
{ alias: "list", label: "List", view: "umbraco.listview", value: "", hideLabel: true }
]
},
{
label: "Content",
alias: "tab01",
id: 1,
properties: [
{ alias: "bodyText", label: "Body Text", description:"Here you enter the primary article contents", view: "umbraco.rte", value: "<p>askjdkasj lasjd</p>" },
{ alias: "textarea", label: "textarea", view: "umbraco.textarea", value: "ajsdka sdjkds", config: { rows: 4 } },
{ alias: "map", label: "Map", view: "umbraco.googlemaps", value: "37.4419,-122.1419", config: { mapType: "ROADMAP", zoom: 4 } },
{ alias: "media", label: "Media picker", view: "umbraco.mediapicker", value: "" },
{ alias: "content", label: "Content picker", view: "umbraco.contentpicker", value: "" }
]
},
{
label: "Sample Editor",
alias: "tab02",
id: 2,
properties: [
{ alias: "datepicker", label: "Datepicker", view: "umbraco.datepicker", config: { rows: 7 } },
{ alias: "tags", label: "Tags", view: "umbraco.tags", value: ""}
]
},
{
label: "Grid",
alias: "tab03",
id: 3,
properties: [
{ alias: "grid", label: "Grid", view: "umbraco.grid", controller: "umbraco.grid", value: "test", hideLabel: true }
]
},{
label: "WIP",
alias: "tab04",
id: 4,
properties: [
{ alias: "tes", label: "Stuff", view: "umbraco.test", controller: "umbraco.embeddedcontent", value: "",
config: {
fields: [
{ alias: "embedded", label: "Embbeded", view: "umbraco.textstring", value: ""},
{ alias: "embedded2", label: "Embbeded 2", view: "umbraco.contentpicker", value: ""},
{ alias: "embedded3", label: "Embbeded 3", view: "umbraco.textarea", value: ""},
{ alias: "embedded4", label: "Embbeded 4", view: "umbraco.datepicker", value: ""}
]
}
}
]
}
]
};
// return undefined;
return content;
}, },
//returns an empty content object which can be persistent on the content service //returns an empty content object which can be persistent on the content service
@@ -131,7 +131,7 @@ angular.module('umbraco.mocks.resources')
var _id = 0; var _id = 0;
for (var i = 0; i < collection.take; i++) { for (var i = 0; i < collection.take; i++) {
_id = (parentId + i) * options.offset; _id = (parentId + i) * options.offset;
var cnt = this.getContent(_id); var cnt = this.getById(_id);
//here we fake filtering //here we fake filtering
if(options.filter !== ''){ if(options.filter !== ''){

View File

@@ -1,13 +1,19 @@
angular.module('umbraco.mocks.resources') angular.module('umbraco.mocks.resources')
.factory('mediaResource', function () { .factory('mediaResource', function ($q) {
var mediaArray = []; var mediaArray = [];
return { return {
rootMedia: function(){ rootMedia: function(){
return [
{id: 1234, src: "/Media/boston.jpg", thumbnail: "/Media/boston.jpg" }, var deferred = $q.defer();
{src: "/Media/bird.jpg", thumbnail: "/Media/bird.jpg" },
{src: "/Media/frog.jpg", thumbnail: "/Media/frog.jpg" } deferred.resolve(
]; [
{id: 1234, src: "/Media/boston.jpg", thumbnail: "/Media/boston.jpg" },
{src: "/Media/bird.jpg", thumbnail: "/Media/bird.jpg" },
{src: "/Media/frog.jpg", thumbnail: "/Media/frog.jpg" }
]);
return deferred.promise;
} }
}; };
}); });

View File

@@ -21,10 +21,10 @@ function treeResource($q) {
} }
return [ return [
{ name: "child-of-" + treeItem.name, id: iLevel + "" + 1234, icon: "icon-file-alt", view: section + "/edit/" + iLevel + "" + 1234, children: [], expanded: false, level: iLevel, defaultAction: action }, { name: "child-of-" + treeItem.name, id: iLevel + "" + 1234, icon: "icon-file-alt", view: section + "/edit/" + iLevel + "" + 1234, children: [], expanded: false, hasChildren: true, level: iLevel, defaultAction: action },
{ name: "random-name-" + section, id: iLevel + "" + 1235, icon: "icon-file-alt", view: section + "/edit/" + iLevel + "" + 1235, children: [], expanded: false, level: iLevel, defaultAction: action }, { name: "random-name-" + section, id: iLevel + "" + 1235, icon: "icon-file-alt", view: section + "/edit/" + iLevel + "" + 1235, children: [], expanded: false, hasChildren: true, level: iLevel, defaultAction: action },
{ name: "random-name-" + section, id: iLevel + "" + 1236, icon: "icon-file-alt", view: section + "/edit/" + iLevel + "" + 1236, children: [], expanded: false, level: iLevel, defaultAction: action }, { name: "random-name-" + section, id: iLevel + "" + 1236, icon: "icon-file-alt", view: section + "/edit/" + iLevel + "" + 1236, children: [], expanded: false, hasChildren: true, level: iLevel, defaultAction: action },
{ name: "random-name-" + section, id: iLevel + "" + 1237, icon: "icon-file-alt", view: "common/legacy/1237?p=" + encodeURI("developer/contentType.aspx?idequal1234"), children: [], expanded: false, level: iLevel, defaultAction: action } { name: "random-name-" + section, id: iLevel + "" + 1237, icon: "icon-file-alt", view: "common/legacy/1237?p=" + encodeURI("developer/contentType.aspx?idequal1234"), children: [], expanded: false, hasChildren: true, level: iLevel, defaultAction: action }
]; ];
} }
@@ -36,7 +36,7 @@ function treeResource($q) {
var section = options.section || 'content'; var section = options.section || 'content';
var cacheKey = options.cachekey || ''; var cacheKey = options.cachekey || '';
cacheKey += "_" + section; cacheKey += "_" + section;
if (treeArray[cacheKey] !== undefined){ if (treeArray[cacheKey] !== undefined){
return treeArray[cacheKey]; return treeArray[cacheKey];
@@ -46,59 +46,39 @@ function treeResource($q) {
switch(section){ switch(section){
case "content": case "content":
t = { t = [
name: section, { name: "My website", id: 1234, icon: "icon-home", view: section + "/edit/" + 1234, children: [], expanded: false, hasChildren: true, level: 1, defaultAction: "create" },
alias: section, { name: "Components", id: 1235, icon: "icon-cogs", view: section + "/edit/" + 1235, children: [], expanded: false, hasChildren: true, level: 1, defaultAction: "create" },
{ name: "Archieve", id: 1236, icon: "icon-folder-close", view: section + "/edit/" + 1236, children: [], expanded: false, hasChildren: true, level: 1, defaultAction: "create" },
children: [ { name: "Recycle Bin", id: 1237, icon: "icon-trash", view: section + "/trash/view/", children: [], expanded: false, hasChildren: true, level: 1, defaultAction: "create" }
{ name: "My website", id: 1234, icon: "icon-home", view: section + "/edit/" + 1234, children: [], expanded: false, level: 1, defaultAction: "create" }, ];
{ name: "Components", id: 1235, icon: "icon-cogs", view: section + "/edit/" + 1235, children: [], expanded: false, level: 1, defaultAction: "create" },
{ name: "Archieve", id: 1236, icon: "icon-folder-close", view: section + "/edit/" + 1236, children: [], expanded: false, level: 1, defaultAction: "create" },
{ name: "Recycle Bin", id: 1237, icon: "icon-trash", view: section + "/trash/view/", children: [], expanded: false, level: 1, defaultAction: "create" }
]
};
break; break;
case "developer": case "developer":
t = { t = [
name: section, { name: "Data types", id: 1234, icon: "icon-folder-close", view: section + "/edit/" + 1234, children: [], expanded: false, hasChildren: true, level: 1 },
alias: section, { name: "Macros", id: 1235, icon: "icon-folder-close", view: section + "/edit/" + 1235, children: [], expanded: false, hasChildren: true, level: 1 },
{ name: "Pacakges", id: 1236, icon: "icon-folder-close", view: section + "/edit/" + 1236, children: [], expanded: false, hasChildren: true, level: 1 },
children: [ { name: "XSLT Files", id: 1237, icon: "icon-folder-close", view: section + "/edit/" + 1237, children: [], expanded: false, hasChildren: true, level: 1 },
{ name: "Data types", id: 1234, icon: "icon-folder-close", view: section + "/edit/" + 1234, children: [], expanded: false, level: 1 }, { name: "Razor Files", id: 1237, icon: "icon-folder-close", view: section + "/edit/" + 1237, children: [], expanded: false, hasChildren: true, level: 1 }
{ name: "Macros", id: 1235, icon: "icon-folder-close", view: section + "/edit/" + 1235, children: [], expanded: false, level: 1 }, ];
{ name: "Pacakges", id: 1236, icon: "icon-folder-close", view: section + "/edit/" + 1236, children: [], expanded: false, level: 1 },
{ name: "XSLT Files", id: 1237, icon: "icon-folder-close", view: section + "/edit/" + 1237, children: [], expanded: false, level: 1 },
{ name: "Razor Files", id: 1237, icon: "icon-folder-close", view: section + "/edit/" + 1237, children: [], expanded: false, level: 1 }
]
};
break; break;
case "settings": case "settings":
t = { t = [
name: section, { name: "Stylesheets", id: 1234, icon: "icon-folder-close", view: section + "/edit/" + 1234, children: [], expanded: false, hasChildren: true, level: 1 },
alias: section, { name: "Templates", id: 1235, icon: "icon-folder-close", view: section + "/edit/" + 1235, children: [], expanded: false, hasChildren: true, level: 1 },
{ name: "Dictionary", id: 1236, icon: "icon-folder-close", view: section + "/edit/" + 1236, children: [], expanded: false, hasChildren: true, level: 1 },
children: [ { name: "Media types", id: 1237, icon: "icon-folder-close", view: section + "/edit/" + 1237, children: [], expanded: false, hasChildren: true, level: 1 },
{ name: "Stylesheets", id: 1234, icon: "icon-folder-close", view: section + "/edit/" + 1234, children: [], expanded: false, level: 1 }, { name: "Document types", id: 1237, icon: "icon-folder-close", view: section + "/edit/" + 1237, children: [], expanded: false, hasChildren: true, level: 1 }
{ name: "Templates", id: 1235, icon: "icon-folder-close", view: section + "/edit/" + 1235, children: [], expanded: false, level: 1 }, ];
{ name: "Dictionary", id: 1236, icon: "icon-folder-close", view: section + "/edit/" + 1236, children: [], expanded: false, level: 1 },
{ name: "Media types", id: 1237, icon: "icon-folder-close", view: section + "/edit/" + 1237, children: [], expanded: false, level: 1 },
{ name: "Document types", id: 1237, icon: "icon-folder-close", view: section + "/edit/" + 1237, children: [], expanded: false, level: 1 }
]
};
break; break;
default: default:
t = { t = [
name: section, { name: "random-name-" + section, id: 1234, icon: "icon-home", defaultAction: "create", view: section + "/edit/" + 1234, children: [], expanded: false, hasChildren: true, level: 1 },
alias: section, { name: "random-name-" + section, id: 1235, icon: "icon-folder-close", defaultAction: "create", view: section + "/edit/" + 1235, children: [], expanded: false, hasChildren: true, level: 1 },
{ name: "random-name-" + section, id: 1236, icon: "icon-folder-close", defaultAction: "create", view: section + "/edit/" + 1236, children: [], expanded: false, hasChildren: true, level: 1 },
children: [ { name: "random-name-" + section, id: 1237, icon: "icon-folder-close", defaultAction: "create", view: section + "/edit/" + 1237, children: [], expanded: false, hasChildren: true, level: 1 }
{ name: "random-name-" + section, id: 1234, icon: "icon-home", defaultAction: "create", view: section + "/edit/" + 1234, children: [], expanded: false, level: 1 }, ];
{ name: "random-name-" + section, id: 1235, icon: "icon-folder-close", defaultAction: "create", view: section + "/edit/" + 1235, children: [], expanded: false, level: 1 },
{ name: "random-name-" + section, id: 1236, icon: "icon-folder-close", defaultAction: "create", view: section + "/edit/" + 1236, children: [], expanded: false, level: 1 },
{ name: "random-name-" + section, id: 1237, icon: "icon-folder-close", defaultAction: "create", view: section + "/edit/" + 1237, children: [], expanded: false, level: 1 }
]
};
break; break;
} }
@@ -121,7 +101,6 @@ function treeResource($q) {
var deferred = $q.defer(); var deferred = $q.defer();
var data = _getChildren(options); var data = _getChildren(options);
deferred.resolve(data); deferred.resolve(data);
return deferred.promise; return deferred.promise;
} }

View File

@@ -52,7 +52,7 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
deferred.reject('Failed to retreive data for content id ' + id); deferred.reject('Failed to retreive data for content id ' + id);
}); });
return deferred.promise; return deferred.promise;
}, },
getByIds: function (ids) { getByIds: function (ids) {

View File

@@ -121,7 +121,7 @@ function mediaResource($q, $http, umbDataFormatter, umbRequestHelper) {
/** saves or updates a media object */ /** saves or updates a media object */
saveMedia: function (media, isNew, files) { saveMedia: function (media, isNew, files) {
return saveMediaItem(media, "save" + (isNew ? "New" : ""), files); return saveMediaItem(media, "save" + (isNew ? "New" : ""), files);
}, }
}; };
} }

View File

@@ -0,0 +1,4 @@
// Based loosely around work by Witold Szczerba - https://github.com/witoldsz/angular-http-auth
angular.module('umbraco.security', [
'umbraco.security.service',
'umbraco.security.interceptor']);

View File

@@ -0,0 +1,23 @@
angular.module('umbraco.security.interceptor', ['umbraco.security.retryQueue'])
// This http interceptor listens for authentication failures
.factory('securityInterceptor', ['$injector', 'securityRetryQueue', function($injector, queue) {
return function(promise) {
// Intercept failed requests
return promise.then(null, function(originalResponse) {
if(originalResponse.status === 401) {
// The request bounced because it was not authorized - add a new request to the retry queue
promise = queue.pushRetryFn('unauthorized-server', function retryRequest() {
// We must use $injector to get the $http service to prevent circular dependency
return $injector.get('$http')(originalResponse.config);
});
}
return promise;
});
};
}])
// We have to add the interceptor to the queue as a string because the interceptor depends upon service instances that are not available in the config block.
.config(['$httpProvider', function($httpProvider) {
$httpProvider.responseInterceptors.push('securityInterceptor');
}]);

View File

@@ -0,0 +1,68 @@
angular.module('umbraco.security.retryQueue', [])
// This is a generic retry queue for security failures. Each item is expected to expose two functions: retry and cancel.
.factory('securityRetryQueue', ['$q', '$log', function($q, $log) {
var retryQueue = [];
var service = {
// The security service puts its own handler in here!
onItemAddedCallbacks: [],
hasMore: function() {
return retryQueue.length > 0;
},
push: function(retryItem) {
retryQueue.push(retryItem);
// Call all the onItemAdded callbacks
angular.forEach(service.onItemAddedCallbacks, function(cb) {
try {
cb(retryItem);
} catch(e) {
$log.error('securityRetryQueue.push(retryItem): callback threw an error' + e);
}
});
},
pushRetryFn: function(reason, retryFn) {
// The reason parameter is optional
if ( arguments.length === 1) {
retryFn = reason;
reason = undefined;
}
// The deferred object that will be resolved or rejected by calling retry or cancel
var deferred = $q.defer();
var retryItem = {
reason: reason,
retry: function() {
// Wrap the result of the retryFn into a promise if it is not already
$q.when(retryFn()).then(function(value) {
// If it was successful then resolve our deferred
deferred.resolve(value);
}, function(value) {
// Othewise reject it
deferred.reject(value);
});
},
cancel: function() {
// Give up on retrying and reject our deferred
deferred.reject();
}
};
service.push(retryItem);
return deferred.promise;
},
retryReason: function() {
return service.hasMore() && retryQueue[0].reason;
},
cancelAll: function() {
while(service.hasMore()) {
retryQueue.shift().cancel();
}
},
retryAll: function() {
while(service.hasMore()) {
retryQueue.shift().retry();
}
}
};
return service;
}]);

View File

@@ -0,0 +1,114 @@
// Based loosely around work by Witold Szczerba - https://github.com/witoldsz/angular-http-auth
angular.module('umbraco.security.service', [
'umbraco.security.retryQueue', // Keeps track of failed requests that need to be retried once the user logs in
'umbraco.services'
])
.factory('security', ['$http', '$q', '$location', 'securityRetryQueue', 'dialogService', function($http, $q, $location, queue, $dialog) {
// Redirect to the given url (defaults to '/')
function redirect(url) {
url = url || '/';
$location.path(url);
}
// Login form dialog stuff
var loginDialog = null;
function openLoginDialog() {
if ( loginDialog ) {
throw new Error('Trying to open a dialog that is already open!');
}
//loginDialog = $dialog.dialog();
//loginDialog.open('security/login/form.tpl.html', 'LoginFormController').then(onLoginDialogClose);
}
function closeLoginDialog(success) {
if (loginDialog) {
loginDialog.close(success);
}
}
function onLoginDialogClose(success) {
loginDialog = null;
if ( success ) {
queue.retryAll();
} else {
queue.cancelAll();
redirect();
}
}
// Register a handler for when an item is added to the retry queue
queue.onItemAddedCallbacks.push(function(retryItem) {
if ( queue.hasMore() ) {
service.showLogin();
}
});
// The public API of the service
var service = {
// Get the first reason for needing a login
getLoginReason: function() {
return queue.retryReason();
},
// Show the modal login dialog
showLogin: function() {
openLoginDialog();
},
// Attempt to authenticate a user by the given email and password
login: function(email, password) {
var request = $http.post('/login', {email: email, password: password});
return request.then(function(response) {
service.currentUser = response.data.user;
if ( service.isAuthenticated() ) {
closeLoginDialog(true);
}
});
},
// Give up trying to login and clear the retry queue
cancelLogin: function() {
closeLoginDialog(false);
redirect();
},
// Logout the current user and redirect
logout: function(redirectTo) {
$http.post('/logout').then(function() {
service.currentUser = null;
redirect(redirectTo);
});
},
// Ask the backend to see if a user is already authenticated - this may be from a previous session.
requestCurrentUser: function() {
if ( service.isAuthenticated() ) {
return $q.when(service.currentUser);
} else {
return $http.get('/current-user').then(function(response) {
service.currentUser = response.data.user;
return service.currentUser;
});
}
},
// Information about the current user
currentUser: null,
// Is the current user authenticated?
isAuthenticated: function(){
return !!service.currentUser;
},
// Is the current user an adminstrator?
isAdmin: function() {
return !!(service.currentUser && service.currentUser.admin);
}
};
return service;
}]);

View File

@@ -0,0 +1,19 @@
//script loader wrapping around 3rd party loader
angular.module('umbraco.services')
.factory('scriptLoader', function ($q) {
return {
load: function (pathArray) {
var deferred = $q.defer();
yepnope({
load: pathArray,
complete: function () {
deferred.resolve(true);
}
});
return deferred.promise;
}
};
});

View File

@@ -1 +0,0 @@
//script loader wrapping around 3rd party loader

View File

@@ -12,9 +12,9 @@ function umbImageHelper() {
if (!options && !options.imageModel && !options.scope) { if (!options && !options.imageModel && !options.scope) {
throw "The options objet does not contain the required parameters: imageModel, scope"; throw "The options objet does not contain the required parameters: imageModel, scope";
} }
if (options.imageModel.contentTypeAlias.toLowerCase() == "image") { if (options.imageModel.contentTypeAlias.toLowerCase() === "image") {
var imageProp = _.find(options.imageModel.properties, function (item) { var imageProp = _.find(options.imageModel.properties, function (item) {
return item.alias == 'umbracoFile'; return item.alias === 'umbracoFile';
}); });
var imageVal; var imageVal;
//Legacy images will be saved as a string, not an array so we will convert the legacy values //Legacy images will be saved as a string, not an array so we will convert the legacy values
@@ -40,7 +40,7 @@ function umbImageHelper() {
} }
var imagePropVal = this.getImagePropertyVaue(options); var imagePropVal = this.getImagePropertyVaue(options);
if (imagePropVal != "") { if (imagePropVal !== "") {
return this.getThumbnailFromPath(imagePropVal); return this.getThumbnailFromPath(imagePropVal);
} }
return ""; return "";

View File

@@ -146,7 +146,12 @@
</ul> </ul>
</div> </div>
<!--
<script data-main="js/main" src="lib/require/require-2.1.0.js"></script> <script data-main="js/main" src="lib/require/require-2.1.0.js"></script>
-->
<script src="lib/yepnope/yepnope.min.js"></script>
<script src="js/loader.js"></script>
</body> </body>
</html> </html>

View File

@@ -0,0 +1,28 @@
yepnope({
load: [
'lib/jquery/jquery-1.8.2.min.js',
'lib/jquery/jquery.cookie.js',
'lib/angular/angular.min.js',
'lib/bootstrap/js/bootstrap.js',
'lib/underscore/underscore.js',
'lib/umbraco/Extensions.js',
'js/app_dev.js',
'js/umbraco.mocks.js',
'js/umbraco.directives.js',
'js/umbraco.filters.js',
'js/umbraco.services.js',
'js/umbraco.security.js',
'js/umbraco.controllers.js',
'js/routes.js'
],
complete: function () {
jQuery(document).ready(function () {
angular.bootstrap(document, ['umbraco']);
});
}
});

View File

@@ -9,6 +9,8 @@ require.config({
angular: '../lib/angular/angular.min', angular: '../lib/angular/angular.min',
angularResource: '../lib/angular/angular-resource', angularResource: '../lib/angular/angular-resource',
app: 'app_dev',
codemirror: '../lib/codemirror/js/lib/codemirror', codemirror: '../lib/codemirror/js/lib/codemirror',
codemirrorJs: '../lib/codemirror/js/mode/javascript/javascript', codemirrorJs: '../lib/codemirror/js/mode/javascript/javascript',
codemirrorCss: '../lib/codemirror/js/mode/css/css', codemirrorCss: '../lib/codemirror/js/mode/css/css',
@@ -47,7 +49,7 @@ require.config({
require( [ require( [
'angular', 'angular',
'app_dev', 'app',
'jquery', 'jquery',
'jqueryCookie', 'jqueryCookie',
'bootstrap', 'bootstrap',
@@ -56,6 +58,7 @@ require( [
'umbraco.directives', 'umbraco.directives',
'umbraco.filters', 'umbraco.filters',
'umbraco.services', 'umbraco.services',
'umbraco.security',
'umbraco.controllers', 'umbraco.controllers',
'routes' 'routes'
], function(angular, app, jQuery) { ], function(angular, app, jQuery) {
@@ -67,4 +70,5 @@ require( [
jQuery(document).ready(function () { jQuery(document).ready(function () {
angular.bootstrap(document, ['umbraco']); angular.bootstrap(document, ['umbraco']);
}); });
}); });

View File

@@ -1,8 +1,4 @@
define([ app.config(function ($routeProvider) {
'app'
], function(app) {
return app.config(function ($routeProvider) {
$routeProvider $routeProvider
.when('/:section', { .when('/:section', {
templateUrl: "views/common/dashboard.html" templateUrl: "views/common/dashboard.html"
@@ -27,6 +23,4 @@ define([
}).config(function ($locationProvider) { }).config(function ($locationProvider) {
//$locationProvider.html5Mode(false).hashPrefix('!'); //turn html5 mode off //$locationProvider.html5Mode(false).hashPrefix('!'); //turn html5 mode off
// $locationProvider.html5Mode(true); //turn html5 mode on // $locationProvider.html5Mode(true); //turn html5 mode on
}); });
});

View File

@@ -67,8 +67,30 @@ angular.module('umbraco').controller("SearchController", function ($scope, searc
}); });
angular.module('umbraco').controller("DashboardController", function ($scope, $routeParams) { angular.module('umbraco').controller("DashboardController", function ($scope, $routeParams, scriptLoader) {
$scope.name = $routeParams.section; $scope.name = $routeParams.section;
scriptLoader.load(['http://www.google.com/jsapi'])
.then(function(){
google.load("maps", "3",
{
callback: function () {
//Google maps is available and all components are ready to use.
var mapOptions = {
zoom: 8,
center: new google.maps.LatLng(-34.397, 150.644),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var mapDiv = document.getElementById('test_map');
var map = new google.maps.Map(mapDiv, mapOptions);
},
other_params: "sensor=false"
});
});
}); });

View File

@@ -9,7 +9,7 @@
<div class="umb-panel-body umb-scrollable" auto-scale="1"> <div class="umb-panel-body umb-scrollable" auto-scale="1">
<div class="tab-content form-horizontal"> <div class="tab-content form-horizontal">
<div class="" style="height: 400px;" id="test_map"></div>
</div> </div>
</div> </div>

View File

@@ -1,10 +1,10 @@
angular.module("umbraco").controller("Umbraco.Editors.DatepickerController", angular.module("umbraco").controller("Umbraco.Editors.DatepickerController",
function ($scope, notificationsService) { function ($scope, notificationsService, scriptLoader) {
require(
[ scriptLoader.load([
'views/propertyeditors/umbraco/datepicker/bootstrap.datepicker.js', 'views/propertyeditors/umbraco/datepicker/bootstrap.datepicker.js',
'css!/belle/views/propertyeditors/umbraco/datepicker/bootstrap.datepicker.css' 'css!/belle/views/propertyeditors/umbraco/datepicker/bootstrap.datepicker.css'
], ]).then(
function () { function () {
//The Datepicker js and css files are available and all components are ready to use. //The Datepicker js and css files are available and all components are ready to use.
@@ -19,6 +19,5 @@ angular.module("umbraco").controller("Umbraco.Editors.DatepickerController",
// When a date is clicked the date is stored in model.value as a ISO 8601 date // When a date is clicked the date is stored in model.value as a ISO 8601 date
$scope.model.value = e.date.toISOString(); $scope.model.value = e.date.toISOString();
}); });
} });
);
}); });

View File

@@ -1,75 +1,76 @@
angular.module("umbraco") angular.module("umbraco")
.controller("Umbraco.Editors.GoogleMapsController", .controller("Umbraco.Editors.GoogleMapsController",
function ($rootScope, $scope, notificationsService, dialogService, $log, $timeout) { function ($rootScope, $scope, notificationsService, dialogService, scriptLoader, $log, $timeout) {
require(
[ scriptLoader.load(['http://www.google.com/jsapi'])
'async!http://maps.google.com/maps/api/js?sensor=false' .then(function(){
], google.load("maps", "3",
function () { {
//Google maps is available and all components are ready to use. callback: initMap,
var valueArray = $scope.model.value.split(','); other_params: "sensor=false"
var latLng = new google.maps.LatLng(valueArray[0], valueArray[1]); });
});
var mapDiv = document.getElementById($scope.model.alias + '_map');
var mapOptions = {
zoom: $scope.model.config.zoom,
center: latLng,
mapTypeId: google.maps.MapTypeId[$scope.model.config.mapType]
};
var geocoder = new google.maps.Geocoder();
var map = new google.maps.Map(mapDiv, mapOptions);
var marker = new google.maps.Marker({ function initMap(){
map: map, //Google maps is available and all components are ready to use.
position: latLng, var valueArray = $scope.model.value.split(',');
draggable: true var latLng = new google.maps.LatLng(valueArray[0], valueArray[1]);
var mapDiv = document.getElementById($scope.model.alias + '_map');
var mapOptions = {
zoom: $scope.model.config.zoom,
center: latLng,
mapTypeId: google.maps.MapTypeId[$scope.model.config.mapType]
};
var geocoder = new google.maps.Geocoder();
var map = new google.maps.Map(mapDiv, mapOptions);
var marker = new google.maps.Marker({
map: map,
position: latLng,
draggable: true
});
google.maps.event.addListener(map, 'click', function(event) {
dialogService.mediaPicker({scope: $scope, callback: function(data){
var image = data.selection[0].src;
var latLng = event.latLng;
var marker = new google.maps.Marker({
map: map,
icon: image,
position: latLng,
draggable: true
});
google.maps.event.addListener(marker, "dragend", function(e){
var newLat = marker.getPosition().lat();
var newLng = marker.getPosition().lng();
codeLatLng(marker.getPosition(), geocoder);
//set the model value
$scope.model.value = newLat + "," + newLng;
});
}});
});
$('a[data-toggle="tab"]').on('shown', function (e) {
google.maps.event.trigger(map, 'resize');
});
}
function codeLatLng(latLng, geocoder) {
geocoder.geocode({'latLng': latLng},
function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var location = results[0].formatted_address;
$rootScope.$apply(function () {
notificationsService.success("Peter just went to: ", location);
});
}
}); });
}
google.maps.event.addListener(map, 'click', function(event) {
dialogService.mediaPicker({scope: $scope, callback: function(data){
var image = data.selection[0].src;
var latLng = event.latLng;
var marker = new google.maps.Marker({
map: map,
icon: image,
position: latLng,
draggable: true
});
google.maps.event.addListener(marker, "dragend", function(e){
var newLat = marker.getPosition().lat();
var newLng = marker.getPosition().lng();
codeLatLng(marker.getPosition());
//set the model value
$scope.model.value = newLat + "," + newLng;
});
}});
});
function codeLatLng(latLng) {
geocoder.geocode({'latLng': latLng},
function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var location = results[0].formatted_address;
$rootScope.$apply(function () {
notificationsService.success("Peter just went to: ", location);
});
}
});
}
//hack to hook into tab switching for map resizing
$('a[data-toggle="tab"]').on('shown', function (e) {
google.maps.event.trigger(map, 'resize');
});
}
);
}); });

View File

@@ -1,82 +1,65 @@
angular.module("umbraco") angular.module("umbraco")
.controller("Umbraco.Editors.RTEController", .controller("Umbraco.Editors.RTEController",
function($rootScope, $scope, dialogService, $log, umbImageHelper){ function($rootScope, $scope, dialogService, $log, umbImageHelper, scriptLoader){
require(
[
'tinymce'
],
function (tinymce) {
tinymce.DOM.events.domLoaded = true; scriptLoader.load(["lib/tinymce/tinymce.min.js"]).then(function(){
tinymce.init({
selector: "#" + $scope.model.alias + "_rte", tinymce.DOM.events.domLoaded = true;
skin: "umbraco", tinymce.init({
menubar : false, selector: "#" + $scope.model.alias + "_rte",
statusbar: false, skin: "umbraco",
height: 340, menubar : false,
toolbar: "bold italic | styleselect | alignleft aligncenter alignright | bullist numlist | outdent indent | link image mediapicker", statusbar: false,
setup : function(editor) { height: 340,
toolbar: "bold italic | styleselect | alignleft aligncenter alignright | bullist numlist | outdent indent | link image mediapicker",
editor.on('blur', function(e) { setup : function(editor) {
$scope.$apply(function() {
//$scope.model.value = e.getBody().innerHTML; editor.on('blur', function(e) {
$scope.model.value = editor.getContent(); $scope.$apply(function() {
}); //$scope.model.value = e.getBody().innerHTML;
$scope.model.value = editor.getContent();
}); });
});
editor.addButton('mediapicker', { editor.addButton('mediapicker', {
icon: 'media', icon: 'media',
tooltip: 'Media Picker', tooltip: 'Media Picker',
onclick: function(){ onclick: function(){
dialogService.mediaPicker({scope: $scope, callback: function(data){ dialogService.mediaPicker({scope: $scope, callback: function(data){
//really simple example on how to intergrate a service with tinyMCE //really simple example on how to intergrate a service with tinyMCE
$(data.selection).each(function (i, img) { $(data.selection).each(function (i, img) {
var imagePropVal = umbImageHelper.getImagePropertyVaue({imageModel: img, scope: $scope});
var data = {
src: (imagePropVal != null && imagePropVal != "")
? imagePropVal
: "nothing.jpg",
style: 'width: 100px; height: 100px',
id: '__mcenew'
};
editor.insertContent(editor.dom.createHTML('img', data));
var imgElm = editor.dom.get('__mcenew');
editor.dom.setAttrib(imgElm, 'id', null);
});
}}); var imagePropVal = umbImageHelper.getImagePropertyVaue({imageModel: img, scope: $scope});
}
});
var data = {
} src: (imagePropVal != null && imagePropVal != "")
}); ? imagePropVal
: "nothing.jpg",
style: 'width: 100px; height: 100px',
$scope.openMediaPicker =function(value){ id: '__mcenew'
var d = dialog.mediaPicker({scope: $scope, callback: populate}); };
};
editor.insertContent(editor.dom.createHTML('img', data));
function bindValue(inst){ var imgElm = editor.dom.get('__mcenew');
$log.log("woot"); editor.dom.setAttrib(imgElm, 'id', null);
});
$scope.$apply(function() {
$scope.model.value = inst.getBody().innerHTML;
});
}
function myHandleEvent(e){
$log.log(e);
}
function populate(data){
$scope.model.value = data.selection;
}
}});
}
});
}
}); });
$scope.openMediaPicker =function(value){
var d = dialog.mediaPicker({scope: $scope, callback: populate});
};
function populate(data){
$scope.model.value = data.selection;
}
});
}); });

View File

@@ -1,11 +1,12 @@
angular.module("umbraco") angular.module("umbraco")
.controller("Umbraco.Editors.TagsController", .controller("Umbraco.Editors.TagsController",
function($rootScope, $scope, $log, tagsResource) { function($rootScope, $scope, $log, tagsResource, scriptLoader) {
require(
scriptLoader.load(
[ [
'/belle/views/propertyeditors/umbraco/tags/bootstrap-tags.custom.js', 'views/propertyeditors/umbraco/tags/bootstrap-tags.custom.js',
'css!/belle/views/propertyeditors/umbraco/tags/bootstrap-tags.custom.css' 'css!views/propertyeditors/umbraco/tags/bootstrap-tags.custom.css'
],function(){ ]).then(function(){
// Get data from tagsFactory // Get data from tagsFactory
$scope.tags = tagsResource.getTags("group"); $scope.tags = tagsResource.getTags("group");

View File

@@ -9,8 +9,12 @@ files = [
'lib/jquery/jquery-1.8.2.min.js', 'lib/jquery/jquery-1.8.2.min.js',
'lib/angular/angular.min.js', 'lib/angular/angular.min.js',
'test/lib/angular/angular-mocks.js', 'test/lib/angular/angular-mocks.js',
'src/app.js', 'src/app_dev.js',
'src/common/**/*.js', 'src/common/directives/*.js',
'src/common/filters/*.js',
'src/common/services/*.js',
'src/common/security/*.js',
'src/common/mocks/**/*.js',
'src/views/**/*.controller.js', 'src/views/**/*.controller.js',
'test/unit/**/*.spec.js' 'test/unit/**/*.spec.js'
]; ];

View File

@@ -11,10 +11,10 @@ describe('content factory tests', function () {
describe('global content factory crud', function () { describe('global content factory crud', function () {
it('should return a content object, given an id', function () { it('should return a content object, given an id', function () {
var doc1 = contentFactory.getContent(1234); var doc1 = contentFactory.getById(1234).then(function(doc1){
expect(doc1).toNotBe(undefined);
expect(doc1).toNotBe(undefined); expect(doc1.id).toBe(1234);
expect(doc1.id).toBe(1234); });
}); });
it('should return a content children collection given an id', function () { it('should return a content children collection given an id', function () {

View File

@@ -2,7 +2,7 @@ define(['app', 'angular'], function (app, angular) {
angular.module("umbraco") angular.module("umbraco")
.controller("Umbraco.Editors.GoogleMapsController", .controller("Umbraco.Editors.GoogleMapsController",
function ($rootScope, $scope, notificationsService, dialogService, $log, $timeout) { function ($rootScope, $scope, notificationsService, dialogService) {
require( require(
[ [
@@ -10,25 +10,29 @@ angular.module("umbraco")
], ],
function () { function () {
//Google maps is available and all components are ready to use.
//var valueArray = $scope.model.value.split(',');
var latLng = new google.maps.LatLng(-34.397, 150.644);
//Google maps is available and all components are ready to use.
var geocoder = new google.maps.Geocoder();
var latLng = new google.maps.LatLng(-34.397, 150.644);
var mapDiv = document.getElementById($scope.model.alias + '_map'); var mapDiv = document.getElementById($scope.model.alias + '_map');
var mapOptions = { var mapOptions = {
zoom: 4, zoom: 2,
center: latLng, center: latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP mapTypeId: google.maps.MapTypeId.ROADMAP
}; };
var geocoder = new google.maps.Geocoder(); //lets load the map
var map = new google.maps.Map(mapDiv, mapOptions); var map = new google.maps.Map(mapDiv, mapOptions);
//lets add a picture on click
google.maps.event.addListener(map, 'click', function(event) { google.maps.event.addListener(map, 'click', function(event) {
//opens the media dialog
dialogService.mediaPicker({scope: $scope, callback: function(data){ dialogService.mediaPicker({scope: $scope, callback: function(data){
var image = data.selection[0].src; var image = data.selection[0].thumbnail;
var latLng = event.latLng; var latLng = event.latLng;
var marker = new google.maps.Marker({ var marker = new google.maps.Marker({
map: map, map: map,
@@ -41,34 +45,39 @@ angular.module("umbraco")
var newLat = marker.getPosition().lat(); var newLat = marker.getPosition().lat();
var newLng = marker.getPosition().lng(); var newLng = marker.getPosition().lng();
//find the location
codeLatLng(marker.getPosition()); codeLatLng(marker.getPosition());
//set the model value //set the model value
$scope.model.value = newLat + "," + newLng; $scope.model.value = newLat + "," + newLng;
}); });
}}); }});
}); });
function codeLatLng(latLng) { function codeLatLng(latLng) {
geocoder.geocode({'latLng': latLng}, geocoder.geocode({'latLng': latLng},
function(results, status) { function(results, status) {
if (status == google.maps.GeocoderStatus.OK) { if (status == google.maps.GeocoderStatus.OK) {
var location = results[0].formatted_address; var location = results[0].formatted_address;
$rootScope.$apply(function () { $rootScope.$apply(function () {
notificationsService.success("Peter just went to: ", location);
//alert(location);
notificationsService.success("Pete just went to: ", location);
}); });
} }
}); });
} }
//hack to hook into tab switching for map resizing
$('a[data-toggle="tab"]').on('shown', function (e) { $('a[data-toggle="tab"]').on('shown', function (e) {
google.maps.event.trigger(map, 'resize'); google.maps.event.trigger(map, 'resize');
}); });
} }
); );
}); });

View File

@@ -0,0 +1,29 @@
<div class="searchPreview" ng-controller="Umbraco.Editors.SimpleEditorController">
<h3><a href="#">{{content.name}}</a></h3>
<a href="#">http://localhost/{{content.name}}</a>
<p>{{tab.properties[1].value}}</p>
</div>
<style>
.searchPreview h3{
font-size: 16px !Important;
line-height: 16px !Important;
padding: 0px; margin: 0px;
}
.searchPreview h3 a{
color: #12c; text-decoration: underline;}
.searchPreview a{
color: #009933;
font-size: 14px;
}
.searchPreview p{
color: #444;
font-size: 13px;
}
</style>

View File

@@ -0,0 +1,10 @@
define(['app', 'angular'], function (app, angular) {
angular.module("umbraco")
.controller("Umbraco.Editors.SimpleEditorController",
function ($rootScope, $scope, notificationsService, dialogService) {
alert("wat");
});
return angular;
});

View File

@@ -0,0 +1,19 @@
{
propertyEditors: [
{
id: "0BA0F832-D759-4526-9B3E-95BBFC98F82E",
name: "My Simple Editor",
editor: {
view: "~/App_Plugins/SimpleEditor/PropertyEditors/Views/simpleeditor.html"
}
}
],
config: {
paths: {
'simpleController': '~/App_Plugins/SimpleEditor/PropertyEditors/Js/SimpleEditor'
}
},
init: [
'simpleController'
]
}

View File

@@ -63,7 +63,6 @@
</section> </section>
</div> </div>
<umb-login></umb-login>
<umb-notifications></umb-notifications> <umb-notifications></umb-notifications>
<script src="lib/require/require.min.js" type="text/javascript"></script> <script src="lib/require/require.min.js" type="text/javascript"></script>