Fixed JS build issues.

This commit is contained in:
Shannon
2013-06-10 13:16:13 -02:00
parent 10facc24fa
commit e88c28c486
17 changed files with 982 additions and 646 deletions
+152 -152
View File
@@ -1,152 +1,152 @@
<!doctype html>
<html lang="en">
<head>
<base href="/belle/" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Umbraco</title>
<link rel="stylesheet" href="assets/css/umbraco.css" />
</head>
<body ng-controller="MainController" id="umbracoMainPageBody">
<div ng-show="authenticated" ng-cloak ng-animate="'fade'" id="layout" class="clearfix" ng-click="closeDialogs($event)">
<div id="leftcolumn" ng-controller="NavigationController" ng-mouseleave="hideTree()">
<div id="applications" ng-class="{faded:ui.stickyNavigation}">
<ul class="sections">
<li class="avatar">
<a href="#" title="{{user.name}}">
<img ng-src="{{user.avatar}}" />
</a>
</li>
<li ng-repeat="section in sections">
<a href="#/{{section.alias}}"
ng-click="changeSection(section.alias)"
ng-mouseenter="showTree(section.alias)"
prevent-default>
<i class="{{section.cssclass}}"></i><span>{{section.name}}</span>
</a>
</li>
<li class="help">
<a class="help" href="#/help">
<img src="assets/img/applicationIcons/help.svg" style="height: 30px; width: 30px;" />
<span>Help</span>
</a>
</li>
</ul>
</div>
<!-- navigation container -->
<div id="navigation" class="fill shadow umb-panel umb-modalcolumn"
ng-show="ui.showNavigation"
ng-animate="'slide'">
<!-- the search -->
<div id="search-form" ng-animate="'slide'">
<div class="umb-panel-header">
<form class="form-search" ng-controller="SearchController">
<i class="icon-search"></i>
<input type="text"
ng-model="ui.searchTerm"
class="umb-search-field search-query"
placeholder="{{localization.app.search.typeToSearch}}"
on-blur="deActivateSearch()"
on-keyup="performSearch(ui.searchTerm)">
</form>
</div>
</div>
<!-- Search results -->
<div id="search-results" class="umb-scrollable umb-panel" auto-scale="0"
ng-show="ui.showSearchResults" ng-animate="'slide'">
<h5>Search results</h5>
<ul class="searchResults" ng-repeat="resultGroup in ui.searchResults" >
<li class="umb-icon-item" ng-class="{selected:$index==ui.selectedSearchResult}" ng-repeat="result in resultGroup.matches">
<i class="icon umb-tree-icon sprTree {{result.icon}}" ng-show="$first"></i>
<a ng-href="#{{result.view}}">
{{result.name}}
<small>{{result.path}}</small>
</a>
<i class="umb-options" ng-click="showMenu(result, $event)"><i></i><i></i><i></i></i>
</li>
</ul>
</div>
<!-- the tree -->
<div id="tree" class="span5 umb-scrollable umb-panel" auto-scale="0" ng-animate="'slide'">
<umb-tree section="{{ui.currentTree}}" ></umb-tree>
</div>
<!-- The context menu -->
<div id='contextMenu' class="umb-modalcolumn fill shadow umb-panel"
ng-show="ui.showContextMenu" ng-animate="'slide'">
<div class='umb-panel-header'>
<h1>{{ui.dialogTitle}}</h1>
</div>
<div class='umb-panel-body'>
<ul class="umb-actions" >
<li class="action" ng-class="{sep:action.seperator}" ng-repeat="action in ui.actions">
<a prevent-default
ng-click="openDialog(currentNode,action,currentSection)">
<i class="icon icon-{{action.cssclass}}"></i>
<span class="menu-label">{{action.name}}</span>
</a>
</li>
</ul>
</div>
</div>
<!-- Tree dialogs -->
<div id="dialog" class='umb-modalcolumn fill shadow umb-panel'
ng-show="ui.showContextMenuDialog" ng-animate="'slide'">
<div class='umb-panel-header'>
<h1>{{ui.dialogTitle}}</h1>
</div>
<div class='umb-panel-body'>
</div>
</div>
</div>
</div>
<section id="contentwrapper">
<div id="contentcolumn">
{{ui | json}}
<div ng-view></div></div>
</section>
</div>
<!-- Login screen -->
<div id="login" ng-show="!authenticated" ng-animate="'slide'" ng-cloak>
<div class="form" ng-cloak>
<h1>Happy {{today}}!, log in below</h1>
<div class="control-group"><input type="text" ng-model="login" class="input-xlarge" placeholder="Enter your username"/></div>
<div class="control-group"><input type="password" ng-model="password" class="input-xlarge" placeholder="Enter your password"/></div>
<input type="button" ng-click="signin()" class="btn" value="Login" />
</div>
</div>
<!-- notifications -->
<div id='speechbubble' class='umb-notification' ng-cloak>
<ul>
<li ng-repeat="notification in notifications" class="alert alert-block alert-{{notification.type}}">
<strong>{{notification.headline}}:</strong>{{notification.message}}<a class='close' ng-click="removeNotification($index)" prevent-default href='#'>&times;</a>
</li>
</ul>
</div>
<script data-main="js/main" src="lib/require/require-2.1.0.js"></script>
</body>
</html>
<!doctype html>
<html lang="en">
<head>
<base href="/belle/" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Umbraco</title>
<link rel="stylesheet" href="assets/css/umbraco.css" />
</head>
<body ng-controller="MainController" id="umbracoMainPageBody">
<div ng-show="authenticated" ng-cloak ng-animate="'fade'" id="layout" class="clearfix" ng-click="closeDialogs($event)">
<div id="leftcolumn" ng-controller="NavigationController" ng-mouseleave="hideTree()">
<div id="applications" ng-class="{faded:ui.stickyNavigation}">
<ul class="sections">
<li class="avatar">
<a href="#" title="{{user.name}}">
<img ng-src="{{user.avatar}}" />
</a>
</li>
<li ng-repeat="section in sections">
<a href="#/{{section.alias}}"
ng-click="changeSection(section.alias)"
ng-mouseenter="showTree(section.alias)"
prevent-default>
<i class="{{section.cssclass}}"></i><span>{{section.name}}</span>
</a>
</li>
<li class="help">
<a class="help" href="#/help">
<img src="assets/img/applicationIcons/help.svg" style="height: 30px; width: 30px;" />
<span>Help</span>
</a>
</li>
</ul>
</div>
<!-- navigation container -->
<div id="navigation" class="fill shadow umb-panel umb-modalcolumn"
ng-show="ui.showNavigation"
ng-animate="'slide'">
<!-- the search -->
<div id="search-form" ng-animate="'slide'">
<div class="umb-panel-header">
<form class="form-search" ng-controller="SearchController">
<i class="icon-search"></i>
<input type="text"
ng-model="ui.searchTerm"
class="umb-search-field search-query"
placeholder="{{localization.app.search.typeToSearch}}"
on-blur="deActivateSearch()"
on-keyup="performSearch(ui.searchTerm)">
</form>
</div>
</div>
<!-- Search results -->
<div id="search-results" class="umb-scrollable umb-panel" auto-scale="0"
ng-show="ui.showSearchResults" ng-animate="'slide'">
<h5>Search results</h5>
<ul class="searchResults" ng-repeat="resultGroup in ui.searchResults" >
<li class="umb-icon-item" ng-class="{selected:$index==ui.selectedSearchResult}" ng-repeat="result in resultGroup.matches">
<i class="icon umb-tree-icon sprTree {{result.icon}}" ng-show="$first"></i>
<a ng-href="#{{result.view}}">
{{result.name}}
<small>{{result.path}}</small>
</a>
<i class="umb-options" ng-click="showMenu(result, $event)"><i></i><i></i><i></i></i>
</li>
</ul>
</div>
<!-- the tree -->
<div id="tree" class="span5 umb-scrollable umb-panel" auto-scale="0" ng-animate="'slide'">
<umb-tree section="{{ui.currentTree}}" ></umb-tree>
</div>
<!-- The context menu -->
<div id='contextMenu' class="umb-modalcolumn fill shadow umb-panel"
ng-show="ui.showContextMenu" ng-animate="'slide'">
<div class='umb-panel-header'>
<h1>{{ui.dialogTitle}}</h1>
</div>
<div class='umb-panel-body'>
<ul class="umb-actions" >
<li class="action" ng-class="{sep:action.seperator}" ng-repeat="action in ui.actions">
<a prevent-default
ng-click="openDialog(currentNode,action,currentSection)">
<i class="icon icon-{{action.cssclass}}"></i>
<span class="menu-label">{{action.name}}</span>
</a>
</li>
</ul>
</div>
</div>
<!-- Tree dialogs -->
<div id="dialog" class='umb-modalcolumn fill shadow umb-panel'
ng-show="ui.showContextMenuDialog" ng-animate="'slide'">
<div class='umb-panel-header'>
<h1>{{ui.dialogTitle}}</h1>
</div>
<div class='umb-panel-body'>
</div>
</div>
</div>
</div>
<section id="contentwrapper">
<div id="contentcolumn">
{{ui | json}}
<div ng-view></div></div>
</section>
</div>
<!-- Login screen -->
<div id="login" ng-show="!authenticated" ng-animate="'slide'" ng-cloak>
<div class="form" ng-cloak>
<h1>Happy {{today}}!, log in below</h1>
<div class="control-group"><input type="text" ng-model="login" class="input-xlarge" placeholder="Enter your username"/></div>
<div class="control-group"><input type="password" ng-model="password" class="input-xlarge" placeholder="Enter your password"/></div>
<input type="button" ng-click="signin()" class="btn" value="Login" />
</div>
</div>
<!-- notifications -->
<div id='speechbubble' class='umb-notification' ng-cloak>
<ul>
<li ng-repeat="notification in notifications" class="alert alert-block alert-{{notification.type}}">
<strong>{{notification.headline}}:</strong>{{notification.message}}<a class='close' ng-click="removeNotification($index)" prevent-default href='#'>&times;</a>
</li>
</ul>
</div>
<script data-main="js/main" src="lib/require/require-2.1.0.js"></script>
</body>
</html>
+10 -10
View File
@@ -1,16 +1,16 @@
/*! umbraco - v0.0.1-SNAPSHOT - 2013-06-10
* http://umbraco.github.io/Belle
* Copyright (c) 2013 Per Ploug, Anders Stenteberg & Shannon Deminick;
* Licensed MIT
*/
'use strict';
define(['angular'], function (angular) {
/*! umbraco - v0.0.1-SNAPSHOT - 2013-06-10
* http://umbraco.github.io/Belle
* Copyright (c) 2013 Per Ploug, Anders Stenteberg & Shannon Deminick;
* Licensed MIT
*/
'use strict';
define(['angular'], function (angular) {
var app = angular.module('umbraco', [
'umbraco.filters',
'umbraco.directives',
'umbraco.mocks.resources',
'umbraco.services'
]);
return app;
]);
return app;
});
@@ -1,11 +1,11 @@
'use strict';
/*! umbraco - v0.0.1-SNAPSHOT - 2013-06-10
* http://umbraco.github.io/Belle
* Copyright (c) 2013 Per Ploug, Anders Stenteberg & Shannon Deminick;
* Licensed MIT
*/
define(['app', 'angular'], function (app, angular) {
'use strict';
/*! umbraco - v0.0.1-SNAPSHOT - 2013-06-10
* http://umbraco.github.io/Belle
* Copyright (c) 2013 Per Ploug, Anders Stenteberg & Shannon Deminick;
* Licensed MIT
*/
define(['app', 'angular'], function (app, angular) {
//Handles the section area of the app
angular.module('umbraco').controller("NavigationController",
function ($scope, navigationService) {
@@ -129,7 +129,7 @@ angular.module('umbraco').controller("MainController",
$scope.signin();
}
});
//used for the media picker dialog
angular.module("umbraco").controller("Umbraco.Dialogs.ContentPickerController",
function ($scope) {
@@ -139,7 +139,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.ContentPickerController",
$(args.event.target.parentElement).find("i.umb-tree-icon").attr("class", "icon umb-tree-icon sprTree icon-check blue");
$scope.select(args.node);
});
});
});
//used for the macro picker dialog
angular.module("umbraco").controller("Umbraco.Dialogs.MacroPickerController", function ($scope, macroFactory) {
$scope.macros = macroFactory.all(true);
@@ -149,22 +149,38 @@ angular.module("umbraco").controller("Umbraco.Dialogs.MacroPickerController", fu
$scope.dialogMode = "configure";
$scope.dialogData.macro = macroFactory.getMacro(macro.alias);
};
});
});
//used for the media picker dialog
angular.module("umbraco")
.controller("Umbraco.Dialogs.MediaPickerController",
function ($scope, mediaResource) {
$scope.images = mediaResource.rootMedia();
});
angular.module("umbraco")
.controller("Umbraco.Dialogs.MediaPickerController",
function($scope, mediaResource) {
mediaResource.rootMedia()
.then(function(data) {
$scope.images = data;
});
$scope.selectMediaItem = function(image) {
if (image.contentTypeAlias.toLowerCase() == 'folder') {
mediaResource.getChildren(image.id)
.then(function(data) {
$scope.images = data;
});
} else if (image.contentTypeAlias.toLowerCase() == 'image') {
$scope.select(image);
}
};
});
angular.module("umbraco").controller("Umbraco.Common.LegacyController",
function($scope, $routeParams){
$scope.legacyPath = decodeURI($routeParams.p);
});
});
angular.module('umbraco')
.controller("Umbraco.Editors.ContentCreateController",
function ($scope, $routeParams,contentTypeResource) {
$scope.allowedTypes = contentTypeResource.getAllowedTypes($scope.currentNode.id);
});
});
angular.module("umbraco")
.controller("Umbraco.Editors.ContentEditController",
function ($scope, $routeParams, contentResource, notificationsService) {
@@ -186,7 +202,7 @@ angular.module("umbraco")
contentResource.saveContent(cnt);
notificationsService.success("Saved", "Content has been saved");
};
});
});
angular.module("umbraco").controller("Umbraco.Editors.CodeMirrorController", function ($scope, $rootScope) {
require(
[
@@ -210,7 +226,7 @@ angular.module("umbraco").controller("Umbraco.Editors.CodeMirrorController", fun
});
});
});
});
//this controller simply tells the dialogs service to open a mediaPicker window
//with a specified callback, this callback will receive an object with a selection on it
angular.module('umbraco')
@@ -223,7 +239,7 @@ angular.module('umbraco')
function populate(data){
$scope.model.value = data.selection;
}
});
});
angular.module("umbraco").controller("Umbraco.Editors.DatepickerController",
function ($scope, notificationsService) {
require(
@@ -248,7 +264,7 @@ angular.module("umbraco").controller("Umbraco.Editors.DatepickerController",
}
);
});
angular.module("umbraco")
.controller("Umbraco.Editors.GoogleMapsController",
function ($rootScope, $scope, notificationsService, $timeout) {
@@ -295,7 +311,7 @@ angular.module("umbraco")
}
);
});
});
'use strict';
//this controller simply tells the dialogs service to open a mediaPicker window
//with a specified callback, this callback will receive an object with a selection on it
@@ -347,7 +363,7 @@ angular.module("umbraco").controller("Umbraco.Editors.GridController",
$scope.propertyDialog();
});
})
});
});
angular.module("umbraco")
.controller("Umbraco.Editors.ListViewController",
function ($rootScope, $scope, contentResource, contentTypeResource) {
@@ -412,7 +428,7 @@ angular.module("umbraco")
};
$scope.reloadView();
});
});
//this controller simply tells the dialogs service to open a mediaPicker window
//with a specified callback, this callback will receive an object with a selection on it
angular.module('umbraco').controller("Umbraco.Editors.MediaPickerController",
@@ -425,7 +441,7 @@ angular.module('umbraco').controller("Umbraco.Editors.MediaPickerController",
$log.log(data.selection);
$scope.model.value = data.selection;
}
});
});
angular.module("umbraco")
.controller("Umbraco.Editors.RTEController",
function($rootScope, $scope, dialogService, $log){
@@ -445,11 +461,11 @@ angular.module("umbraco")
toolbar: "bold italic | styleselect | alignleft aligncenter alignright | bullist numlist | outdent indent | link image mediapicker",
setup : function(editor) {
editor.on('blur', function(e) {
$scope.$apply(function(){
//$scope.model.value = e.getBody().innerHTML;
$scope.model.value = editor.getContent();
})
editor.on('blur', function(e) {
$scope.$apply(function() {
//$scope.model.value = e.getBody().innerHTML;
$scope.model.value = editor.getContent();
});
});
editor.addButton('mediapicker', {
@@ -459,12 +475,17 @@ angular.module("umbraco")
dialogService.mediaPicker({scope: $scope, callback: function(data){
//really simple example on how to intergrate a service with tinyMCE
$(data.selection).each(function(i,img){
var data = {
src: img.thumbnail,
style: 'width: 100px; height: 100px',
id : '__mcenew'
};
$(data.selection).each(function (i, img) {
var imageProperty = _.find(img.properties, function(item) {
return item.alias == 'umbracoFile';
});
var data = {
src: imageProperty != null ? imageProperty.value : "nothing.jpg",
style: 'width: 100px; height: 100px',
id: '__mcenew'
};
editor.insertContent(editor.dom.createHTML('img', data));
var imgElm = editor.dom.get('__mcenew');
@@ -486,11 +507,11 @@ angular.module("umbraco")
};
function bindValue(inst){
$log.log("woot");
$scope.$apply(function(){
$scope.model.value = inst.getBody().innerHTML;
})
$log.log("woot");
$scope.$apply(function() {
$scope.model.value = inst.getBody().innerHTML;
});
}
function myHandleEvent(e){
@@ -502,7 +523,7 @@ angular.module("umbraco")
}
});
});
});
angular.module("umbraco")
.controller("Umbraco.Editors.TagsController",
function($rootScope, $scope, $log, tagsResource) {
@@ -525,7 +546,7 @@ angular.module("umbraco")
});
});
}
);
);
//this controller simply tells the dialogs service to open a mediaPicker window
//with a specified callback, this callback will receive an object with a selection on it
angular.module('umbraco').controller("Umbraco.Editors.EmbeddedContentController",
@@ -552,7 +573,7 @@ angular.module('umbraco').controller("Umbraco.Editors.EmbeddedContentController"
$scope.model.value.push(angular.copy($scope.fakeData));
$scope.fakeData = [];
};
});
return angular;
});
return angular;
});
@@ -1,11 +1,11 @@
/*! umbraco - v0.0.1-SNAPSHOT - 2013-06-10
* http://umbraco.github.io/Belle
* Copyright (c) 2013 Per Ploug, Anders Stenteberg & Shannon Deminick;
* Licensed MIT
*/
'use strict';
define(['app','angular','underscore'], function (app, angular,_) {
angular.module("umbraco.directives", []);
/*! umbraco - v0.0.1-SNAPSHOT - 2013-06-10
* http://umbraco.github.io/Belle
* Copyright (c) 2013 Per Ploug, Anders Stenteberg & Shannon Deminick;
* Licensed MIT
*/
'use strict';
define(['app','angular','underscore'], function (app, angular,_) {
angular.module("umbraco.directives", []);
angular.module("umbraco.directives")
.directive('autoScale', function ($window) {
return function (scope, el, attrs) {
@@ -26,7 +26,7 @@ angular.module("umbraco.directives")
});
};
});
});
/**
* @ngdoc directive
* @name umbraco.directive:umbFileUpload
@@ -45,7 +45,7 @@ function umbFileUpload() {
};
}
angular.module('umbraco.directives').directive("umbFileUpload", umbFileUpload);
angular.module('umbraco.directives').directive("umbFileUpload", umbFileUpload);
angular.module("umbraco.directives")
.directive('umbHeader', function($parse, $timeout){
return {
@@ -99,7 +99,7 @@ angular.module("umbraco.directives")
});
}
};
});
});
angular.module("umbraco.directives")
.directive('headline', function ($window) {
return function (scope, el, attrs) {
@@ -126,7 +126,7 @@ angular.module("umbraco.directives")
el.show().focus();
});
};
});
});
/**
* @ngdoc directive
* @name umbraco.directive:leftColumn
@@ -145,7 +145,7 @@ function leftColumnDirective() {
}
angular.module('umbraco.directives').directive("umbLeftColumn", leftColumnDirective);
/**
* @ngdoc directive
* @name umbraco.directive:login
@@ -164,7 +164,7 @@ function loginDirective() {
}
angular.module('umbraco.directives').directive("umbLogin", loginDirective);
/**
* @ngdoc directive
* @name umbraco.directive:notifications
@@ -182,7 +182,7 @@ function notificationDirective() {
};
}
angular.module('umbraco.directives').directive("umbNotifications", notificationDirective);
angular.module('umbraco.directives').directive("umbNotifications", notificationDirective);
angular.module("umbraco.directives")
.directive('umbPanel', function(){
return {
@@ -191,7 +191,7 @@ angular.module("umbraco.directives")
transclude: 'true',
templateUrl: 'views/directives/umb-panel.html'
};
});
});
angular.module("umbraco.directives")
.directive('preventDefault', function () {
return function (scope, element, attrs) {
@@ -199,7 +199,7 @@ angular.module("umbraco.directives")
event.preventDefault();
});
};
});
});
angular.module("umbraco.directives")
.directive('umbProperty', function(){
return {
@@ -237,7 +237,7 @@ angular.module("umbraco.directives")
}
}
};
});
});
angular.module("umbraco.directives")
.directive('umbTab', function(){
return {
@@ -246,7 +246,7 @@ angular.module("umbraco.directives")
transclude: 'true',
templateUrl: 'views/directives/umb-tab.html'
};
});
});
angular.module("umbraco.directives")
.directive('umbTabView', function(){
return {
@@ -255,7 +255,7 @@ angular.module("umbraco.directives")
transclude: 'true',
templateUrl: 'views/directives/umb-tab-view.html'
};
});
});
angular.module("umbraco.directives")
.directive('umbTree', function ($compile, $log, $q, treeService) {
@@ -329,7 +329,7 @@ angular.module("umbraco.directives")
};
}
};
});
});
angular.module("umbraco.directives")
.directive('umbTreeItem', function($compile, $http, $templateCache, $interpolate, $log, treeService) {
return {
@@ -344,7 +344,7 @@ angular.module("umbraco.directives")
template: '<li><div ng-style="setTreePadding(node)">' +
'<ins ng-class="{\'icon-caret-right\': !node.expanded, \'icon-caret-down\': node.expanded}" ng-click="load(node)"></ins>' +
'<i class="icon umb-tree-icon sprTree {{node.icon}}"></i>' +
'<i class="{{node | umbTreeIconClass:\'icon umb-tree-icon sprTree\'}}" style="{{node | umbTreeIconStyle}}"></i>' +
'<a ng-click="select(this, node, $event)" ng-href="#{{node.view}}">{{node.name}}</a>' +
'<i class="umb-options" ng-click="options(this, node, $event)"><i></i><i></i><i></i></i>' +
'</div>'+
@@ -387,7 +387,7 @@ angular.module("umbraco.directives")
element.append(newElement);
}
};
});
});
/**
* @description Utillity directives for key and field events
**/
@@ -423,7 +423,7 @@ angular.module('umbraco.directives')
scope.$apply(attrs.onFocus);
});
};
});
});
/**
* @ngdoc directive
* @name umbraco.directive:valBubble
@@ -463,7 +463,228 @@ function valBubble(umbFormHelper) {
}
};
}
angular.module('umbraco.directives').directive("valBubble", valBubble);
return angular;
angular.module('umbraco.directives').directive("valBubble", valBubble);
/**
* @ngdoc directive
* @name umbraco.directive:valRegex
* @restrict A
* @description A custom directive to allow for matching a value against a regex string.
* NOTE: there's already an ng-pattern but this requires that a regex expression is set, not a regex string
**/
function valRegex() {
return {
require: 'ngModel',
restrict: "A",
link: function (scope, elm, attrs, ctrl) {
var regex = new RegExp(scope.$eval(attrs.valRegex));
var patternValidator = function (viewValue) {
//NOTE: we don't validate on empty values, use required validator for that
if (!viewValue || regex.test(viewValue)) {
// it is valid
ctrl.$setValidity('valRegex', true);
//assign a message to the validator
ctrl.errorMsg = "";
return viewValue;
}
else {
// it is invalid, return undefined (no model update)
ctrl.$setValidity('valRegex', false);
//assign a message to the validator
ctrl.errorMsg = "Value is invalid, it does not match the correct pattern";
return undefined;
}
};
ctrl.$formatters.push(patternValidator);
ctrl.$parsers.push(patternValidator);
}
};
}
angular.module('umbraco.directives').directive("valRegex", valRegex);
/**
* @ngdoc directive
* @name umbraco.directive:valServer
* @restrict A
* @description This directive is used to associate a field with a server-side validation response
* so that the validators in angular are updated based on server-side feedback.
**/
function valServer() {
return {
require: 'ngModel',
restrict: "A",
link: function (scope, element, attr, ctrl) {
if (!scope.model || !scope.model.alias){
throw "valServer can only be used in the scope of a content property object";
}
var parentErrors = scope.$parent.serverErrors;
if (!parentErrors) {
return;
}
var fieldName = scope.$eval(attr.valServer);
//subscribe to the changed event of the element. This is required because when we
// have a server error we actually invalidate the form which means it cannot be
// resubmitted. So once a field is changed that has a server error assigned to it
// we need to re-validate it for the server side validator so the user can resubmit
// the form. Of course normal client-side validators will continue to execute.
element.keydown(function () {
if (ctrl.$invalid) {
ctrl.$setValidity('valServer', true);
}
});
element.change(function () {
if (ctrl.$invalid) {
ctrl.$setValidity('valServer', true);
}
});
//TODO: DO we need to watch for other changes on the element ?
//subscribe to the server validation changes
parentErrors.subscribe(scope.model, fieldName, function (isValid, propertyErrors, allErrors) {
if (!isValid) {
ctrl.$setValidity('valServer', false);
//assign an error msg property to the current validator
ctrl.errorMsg = propertyErrors[0].errorMsg;
}
else {
ctrl.$setValidity('valServer', true);
//reset the error message
ctrl.errorMsg = "";
}
}, true);
}
};
}
angular.module('umbraco.directives').directive("valServer", valServer);
/**
* @ngdoc directive
* @name umbraco.directive:valSummary
* @restrict E
* @description This directive will display a validation summary for the current form based on the
content properties of the current content item.
**/
function valSummary() {
return {
scope: true, // create a new scope for this directive
replace: true, // replace the html element with the template
restrict: "E", // restrict to an element
template: '<ul class="validation-summary"><li ng-repeat="model in validationSummary">{{model}}</li></ul>',
link: function (scope, element, attr, ctrl) {
//create properties on our custom scope so we can use it in our template
scope.validationSummary = [];
//create a flag for us to be able to reference in the below closures for watching.
var showValidation = false;
//add a watch to update our waitingOnValidation flag for use in the below closures
scope.$watch("$parent.ui.waitingOnValidation", function (isWaiting, oldValue) {
showValidation = isWaiting;
if (scope.validationSummary.length > 0 && showValidation) {
element.show();
}
else {
element.hide();
}
});
//if we are to show field property based errors.
//this requires listening for bubbled events from valBubble directive.
scope.$parent.$on("valBubble", function (evt, args) {
var msg = "The value assigned for the property " + args.scope.model.label + " is invalid";
var exists = _.contains(scope.validationSummary, msg);
//we need to check if the entire property is valid, even though the args says this field is valid there
// may be multiple values attached to a content property. The easiest way to do this is check the DOM
// just like we are doing for the property level validation message.
var propertyHasErrors = args.element.closest(".content-property").find(".ng-invalid").length > 0;
if (args.isValid && exists && !propertyHasErrors) {
//it is valid but we have a val msg for it so we'll need to remove the message
scope.validationSummary = _.reject(scope.validationSummary, function (item) {
return item === msg;
});
}
else if (!args.isValid && !exists) {
//it is invalid and we don't have a msg for it already
scope.validationSummary.push(msg);
}
//show the summary if there are errors and the form has been submitted
if (showValidation && scope.validationSummary.length > 0) {
element.show();
}
});
//listen for form invalidation so we know when to hide it
scope.$watch("contentForm.$error", function (errors) {
//check if there is an error and hide the summary if not
var hasError = _.find(errors, function (err) {
return (err.length && err.length > 0);
});
if (!hasError) {
element.hide();
}
}, true);
}
};
}
angular.module('umbraco.directives').directive("valSummary", valSummary);
/**
* @ngdoc directive
* @name umbraco.directive:valToggleMsg
* @restrict A
* @description This directive will show/hide an error based on: is the value + the given validator invalid? AND, has the form been submitted ?
**/
function valToggleMsg(umbFormHelper) {
return {
restrict: "A",
link: function (scope, element, attr, ctrl) {
if (!attr.valToggleMsg){
throw "valToggleMsg requires that a reference to a validator is specified";
}
if (!attr.valMsgFor){
throw "valToggleMsg requires that the attribute valMsgFor exists on the element";
}
//create a flag for us to be able to reference in the below closures for watching.
var showValidation = false;
var hasError = false;
var currentForm = umbFormHelper.getCurrentForm(scope);
if (!currentForm || !currentForm.$name){
throw "valToggleMsg requires that a name is assigned to the ng-form containing the validated input";
}
//add a watch to the validator for the value (i.e. $parent.myForm.value.$error.required )
scope.$watch(currentForm.$name + "." + attr.valMsgFor + ".$error." + attr.valToggleMsg, function (isInvalid, oldValue) {
hasError = isInvalid;
if (hasError && showValidation) {
element.show();
}
else {
element.hide();
}
});
//add a watch to update our waitingOnValidation flag for use in the above closure
scope.$watch("$parent.ui.waitingOnValidation", function (isWaiting, oldValue) {
showValidation = isWaiting;
if (hasError && showValidation) {
element.show();
}
else {
element.hide();
}
});
}
};
}
angular.module('umbraco.directives').directive("valToggleMsg", valToggleMsg);
return angular;
});
@@ -1,11 +1,11 @@
/*! umbraco - v0.0.1-SNAPSHOT - 2013-06-10
* http://umbraco.github.io/Belle
* Copyright (c) 2013 Per Ploug, Anders Stenteberg & Shannon Deminick;
* Licensed MIT
*/
'use strict';
define([ 'app','angular'], function (app,angular) {
angular.module('umbraco.filters', []);
/*! umbraco - v0.0.1-SNAPSHOT - 2013-06-10
* http://umbraco.github.io/Belle
* Copyright (c) 2013 Per Ploug, Anders Stenteberg & Shannon Deminick;
* Licensed MIT
*/
'use strict';
define([ 'app','angular'], function (app,angular) {
angular.module('umbraco.filters', []);
/**
* @ngdoc filter
* @name umbraco.filters:propertyEditor
@@ -30,7 +30,7 @@ function propertyEditorFilter($log) {
};
}
angular.module("umbraco.filters").filter('propertyEditor', propertyEditorFilter);
angular.module("umbraco.filters").filter('propertyEditor', propertyEditorFilter);
/**
* @ngdoc filter
* @name umbraco.filters:umbTreeIconClass
@@ -46,7 +46,7 @@ function treeIconClassFilter() {
return standardClasses;
};
}
angular.module('umbraco.filters').filter("umbTreeIconClass", treeIconClassFilter);
angular.module('umbraco.filters').filter("umbTreeIconClass", treeIconClassFilter);
/**
* @ngdoc filter
* @name umbraco.filters:umbTreeIconImage
@@ -63,7 +63,7 @@ function treeIconImageFilter() {
};
}
//angular.module('umbraco.filters').filter("umbTreeIconImage", treeIconImageFilter);
return app;
//angular.module('umbraco.filters').filter("umbTreeIconImage", treeIconImageFilter);
return app;
});
@@ -1,11 +1,11 @@
/*! umbraco - v0.0.1-SNAPSHOT - 2013-06-10
* http://umbraco.github.io/Belle
* Copyright (c) 2013 Per Ploug, Anders Stenteberg & Shannon Deminick;
* Licensed MIT
*/
'use strict';
define(['app', 'angular'], function (app, angular) {
angular.module("umbraco.mocks.resources", []);
/*! umbraco - v0.0.1-SNAPSHOT - 2013-06-10
* http://umbraco.github.io/Belle
* Copyright (c) 2013 Per Ploug, Anders Stenteberg & Shannon Deminick;
* Licensed MIT
*/
'use strict';
define(['app', 'angular'], function (app, angular) {
angular.module("umbraco.mocks.resources", []);
angular.module('umbraco.mocks.resources')
.factory('contentResource', function () {
@@ -166,7 +166,7 @@ angular.module('umbraco.mocks.resources')
return factory;
});
angular.module('umbraco.mocks.resources')
.factory('contentTypeResource', function () {
return {
@@ -207,7 +207,7 @@ angular.module('umbraco.mocks.resources')
}
};
});
});
angular.module('umbraco.mocks.resources')
.factory('localizationResource', function () {
var localizationArray = [];
@@ -246,7 +246,7 @@ angular.module('umbraco.mocks.resources')
}
};
return factory;
});
});
angular.module('umbraco.mocks.resources')
.factory('mediaResource', function () {
var mediaArray = [];
@@ -259,7 +259,7 @@ angular.module('umbraco.mocks.resources')
];
}
};
});
});
angular.module('umbraco.mocks.resources')
.factory('tagsResource', function () {
return {
@@ -273,7 +273,7 @@ angular.module('umbraco.mocks.resources')
return g;
}
};
});
});
/**
* @ngdoc factory
* @name umbraco.resources.treeResource
@@ -404,7 +404,7 @@ function treeResource($q) {
};
}
angular.module('umbraco.mocks.resources').factory('treeResource', treeResource);
angular.module('umbraco.mocks.resources').factory('treeResource', treeResource);
angular.module('umbraco.mocks.resources')
.factory('userResource', function () {
@@ -447,7 +447,7 @@ angular.module('umbraco.mocks.resources')
};
});
return angular;
return angular;
});
@@ -1,279 +1,291 @@
/*! umbraco - v0.0.1-SNAPSHOT - 2013-06-10
* http://umbraco.github.io/Belle
* Copyright (c) 2013 Per Ploug, Anders Stenteberg & Shannon Deminick;
* Licensed MIT
*/
'use strict';
define(['app', 'angular'], function (app, angular) {
angular.module("umbraco.resources", []);
/**
* @ngdoc factory
* @name umbraco.resources.contentResource
* @description Loads/saves in data for content
**/
function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
/** internal method to get the api url */
function getContentUrl(contentId) {
return Umbraco.Sys.ServerVariables.contentEditorApiBaseUrl + "GetContent?id=" + contentId;
}
/** internal method to get the api url for publishing */
function getSaveUrl() {
return Umbraco.Sys.ServerVariables.contentEditorApiBaseUrl + "PostSaveContent";
}
/** internal method process the saving of data and post processing the result */
function saveContentItem(content, action) {
var deferred = $q.defer();
//save the active tab id so we can set it when the data is returned.
var activeTab = _.find(content.tabs, function (item) {
return item.active;
});
var activeTabIndex = (activeTab === undefined ? 0 : _.indexOf(content.tabs, activeTab));
//save the data
umbRequestHelper.postMultiPartRequest(
getSaveUrl(content.id),
{ key: "contentItem", value: umbDataFormatter.formatContentPostData(content, action) },
function (data) {
//TODO: transform the request callback and add the files associated with the request
},
function (data, status, headers, config) {
//success callback
//reset the tabs and set the active one
_.each(data.tabs, function (item) {
item.active = false;
});
data.tabs[activeTabIndex].active = true;
//the data returned is the up-to-date data so the UI will refresh
deferred.resolve(data);
},
function (data, status, headers, config) {
//failure callback
deferred.reject('Failed to publish data for content id ' + content.id);
});
return deferred.promise;
}
return {
getContent: function (id) {
var deferred = $q.defer();
//go and get the data
$http.get(getContentUrl(id)).
success(function (data, status, headers, config) {
//set the first tab to active
_.each(data.tabs, function (item) {
item.active = false;
});
if (data.tabs.length > 0){
data.tabs[0].active = true;
}
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
deferred.reject('Failed to retreive data for content id ' + id);
});
return deferred.promise;
//var content = {
// 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",
// properties: [
// { alias: "list", label: "List", view: "umbraco.listview", value: "", hideLabel: true }
// ]
// },
// {
// label: "Content",
// alias: "tab01",
// 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",
// properties: [
// { alias: "sampleProperty", label: "Sample 1", view: "umbraco.sample", value: "Hello World" },
// { alias: "samplePropertyTwo", label: "Sample 2", view: "umbraco.sampletwo", value: 1234, config: { rows: 7 } },
// { alias: "datepicker", label: "Datepicker", view: "umbraco.datepicker", config: { rows: 7 } },
// { alias: "tags", label: "Tags", view: "umbraco.tags", value: "" }
// ]
// },
// {
// label: "Grid",
// alias: "tab03",
// properties: [
// { alias: "grid", label: "Grid", view: "umbraco.grid", controller: "umbraco.grid", value: "test", hideLabel: true }
// ]
// }
// ]
//};
// return undefined;
},
/** returns an empty content object which can be persistent on the content service
requires the parent id and the alias of the content type to base the scaffold on */
getContentScaffold: function (parentId, alias) {
//use temp storage for now...
var c = this.getContent(parentId);
c.name = "empty name";
$.each(c.tabs, function (index, tab) {
$.each(tab.properties, function (index, property) {
property.value = "";
});
});
return c;
},
getChildren: function (parentId, options) {
if (options === undefined) {
options = {
take: 10,
offset: 0,
filter: ''
};
}
var collection = { take: 10, total: 68, pages: 7, currentPage: options.offset, filter: options.filter };
collection.total = 56 - (options.filter.length);
collection.pages = Math.round(collection.total / collection.take);
collection.resultSet = [];
if (collection.total < options.take) {
collection.take = collection.total;
} else {
collection.take = options.take;
}
var _id = 0;
for (var i = 0; i < collection.take; i++) {
_id = (parentId + i) * options.offset;
var cnt = this.getContent(_id);
//here we fake filtering
if (options.filter !== '') {
cnt.name = options.filter + cnt.name;
}
collection.resultSet.push(cnt);
}
return collection;
},
/** saves or updates a content object */
saveContent: function (content) {
return saveContentItem(content, "save");
},
/** saves and publishes a content object */
publishContent: function (content) {
return saveContentItem(content, "publish");
}
};
}
angular.module('umbraco.resources').factory('contentResource', contentResource);
/**
* @ngdoc factory
* @name umbraco.resources.contentTypeResource
* @description Loads in data for content types
**/
function contentTypeResource($q, $http) {
/** internal method to get the api url */
function getChildContentTypesUrl(contentId) {
return Umbraco.Sys.ServerVariables.contentTypeApiBaseUrl + "GetAllowedChildrenForContent?contentId=" + contentId;
}
return {
//return a content type with a given ID
getContentType: function (id) {
return {
name: "News Article",
alias: "newsArticle",
id: id,
tabs: []
};
},
//return all available types
all: function () {
return [];
},
//return children inheriting a given type
children: function (id) {
return [];
},
//return all content types a type inherits from
parents: function (id) {
return [];
},
//return all types allowed under given document
getAllowedTypes: function (contentId) {
var deferred = $q.defer();
//go and get the tree data
$http.get(getChildContentTypesUrl(contentId)).
success(function (data, status, headers, config) {
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
deferred.reject('Failed to retreive data for content id ' + contentId);
});
return deferred.promise;
}
};
}
angular.module('umbraco.resources').factory('contentTypeResource', contentTypeResource);
/*! umbraco - v0.0.1-SNAPSHOT - 2013-06-10
* http://umbraco.github.io/Belle
* Copyright (c) 2013 Per Ploug, Anders Stenteberg & Shannon Deminick;
* Licensed MIT
*/
'use strict';
define(['app', 'angular'], function (app, angular) {
angular.module("umbraco.resources", []);
/**
* @ngdoc factory
* @name umbraco.resources.treeResource
* @description Loads in data for trees
**/
* @ngdoc factory
* @name umbraco.resources.contentResource
* @description Loads/saves in data for content
**/
function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
/** internal method to get the api url */
function getContentUrl(contentId) {
return Umbraco.Sys.ServerVariables.contentApiBaseUrl + "GetContent?id=" + contentId;
}
/** internal method to get the api url */
function getEmptyContentUrl(contentTypeAlias, parentId) {
return Umbraco.Sys.ServerVariables.contentApiBaseUrl + "GetEmptyContent?contentTypeAlias=" + contentTypeAlias + "&parentId=" + parentId;
}
/** internal method to get the api url for publishing */
function getSaveUrl() {
return Umbraco.Sys.ServerVariables.contentApiBaseUrl + "PostSave";
}
/** internal method process the saving of data and post processing the result */
function saveContentItem(content, action) {
var deferred = $q.defer();
//save the active tab id so we can set it when the data is returned.
var activeTab = _.find(content.tabs, function(item) {
return item.active;
});
var activeTabIndex = (activeTab === undefined ? 0 : _.indexOf(content.tabs, activeTab));
//save the data
umbRequestHelper.postMultiPartRequest(
getSaveUrl(content.id),
{ key: "contentItem", value: umbDataFormatter.formatContentPostData(content, action) },
function (data) {
//TODO: transform the request callback and add the files associated with the request
},
function (data, status, headers, config) {
//success callback
//reset the tabs and set the active one
_.each(data.tabs, function (item) {
item.active = false;
});
data.tabs[activeTabIndex].active = true;
//the data returned is the up-to-date data so the UI will refresh
deferred.resolve(data);
},
function (data, status, headers, config) {
//failure callback
deferred.reject('Failed to publish data for content id ' + content.id);
});
return deferred.promise;
}
return {
getContent: function (id) {
var deferred = $q.defer();
//go and get the data
$http.get(getContentUrl(id)).
success(function (data, status, headers, config) {
//set the first tab to active
_.each(data.tabs, function (item) {
item.active = false;
});
if (data.tabs.length > 0){
data.tabs[0].active = true;
}
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
deferred.reject('Failed to retreive data for content id ' + id);
});
return deferred.promise;
},
/** returns an empty content object which can be persistent on the content service
requires the parent id and the alias of the content type to base the scaffold on */
getContentScaffold: function (parentId, alias) {
var deferred = $q.defer();
//go and get the data
$http.get(getEmptyContentUrl(alias, parentId)).
success(function (data, status, headers, config) {
//set the first tab to active
_.each(data.tabs, function (item) {
item.active = false;
});
if (data.tabs.length > 0){
data.tabs[0].active = true;
}
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
deferred.reject('Failed to retreive data for empty content item type ' + alias);
});
return deferred.promise;
},
getChildren: function (parentId, options) {
if (options === undefined) {
options = {
take: 10,
offset: 0,
filter: ''
};
}
var collection = { take: 10, total: 68, pages: 7, currentPage: options.offset, filter: options.filter };
collection.total = 56 - (options.filter.length);
collection.pages = Math.round(collection.total / collection.take);
collection.resultSet = [];
if (collection.total < options.take) {
collection.take = collection.total;
} else {
collection.take = options.take;
}
var _id = 0;
for (var i = 0; i < collection.take; i++) {
_id = (parentId + i) * options.offset;
var cnt = this.getContent(_id);
//here we fake filtering
if (options.filter !== '') {
cnt.name = options.filter + cnt.name;
}
collection.resultSet.push(cnt);
}
return collection;
},
/** saves or updates a content object */
saveContent: function (content, isNew) {
return saveContentItem(content, "save" + (isNew ? "New" : ""));
},
/** saves and publishes a content object */
publishContent: function (content, isNew) {
return saveContentItem(content, "publish" + (isNew ? "New" : ""));
}
};
}
angular.module('umbraco.resources').factory('contentResource', contentResource);
/**
* @ngdoc factory
* @name umbraco.resources.contentTypeResource
* @description Loads in data for content types
**/
function contentTypeResource($q, $http) {
/** internal method to get the api url */
function getChildContentTypesUrl(contentId) {
return Umbraco.Sys.ServerVariables.contentTypeApiBaseUrl + "GetAllowedChildrenForContent?contentId=" + contentId;
}
return {
//return a content type with a given ID
getContentType: function (id) {
return {
name: "News Article",
alias: "newsArticle",
id: id,
tabs: []
};
},
//return all available types
all: function () {
return [];
},
//return children inheriting a given type
children: function (id) {
return [];
},
//return all content types a type inherits from
parents: function (id) {
return [];
},
//return all types allowed under given document
getAllowedTypes: function (contentId) {
var deferred = $q.defer();
//go and get the tree data
$http.get(getChildContentTypesUrl(contentId)).
success(function (data, status, headers, config) {
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
deferred.reject('Failed to retreive data for content id ' + contentId);
});
return deferred.promise;
}
};
}
angular.module('umbraco.resources').factory('contentTypeResource', contentTypeResource);
/**
* @ngdoc factory
* @name umbraco.resources.treeResource
* @description Loads in data for trees
**/
function mediaResource($q, $http) {
/** internal method to get the api url */
function getRootMediaUrl() {
return Umbraco.Sys.ServerVariables.mediaApiBaseUrl + "GetRootMedia";
}
/** internal method to get the api url */
function getChildrenMediaUrl(parentId) {
return Umbraco.Sys.ServerVariables.mediaApiBaseUrl + "GetChildren?parentId=" + parentId;
}
return {
rootMedia: function () {
var deferred = $q.defer();
//go and get the tree data
$http.get(getRootMediaUrl()).
success(function (data, status, headers, config) {
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
deferred.reject('Failed to retreive data for application tree ' + section);
});
return deferred.promise;
},
getChildren: function (parentId) {
var deferred = $q.defer();
//go and get the tree data
$http.get(getChildrenMediaUrl(parentId)).
success(function (data, status, headers, config) {
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
deferred.reject('Failed to retreive data for application tree ' + section);
});
return deferred.promise;
}
};
}
angular.module('umbraco.resources').factory('mediaResource', mediaResource);
/**
* @ngdoc factory
* @name umbraco.resources.treeResource
* @description Loads in data for trees
**/
function treeResource($q, $http) {
/** internal method to get the tree app url */
@@ -285,19 +297,18 @@ function treeResource($q, $http) {
if (!node.childNodesUrl){
throw "No childNodesUrl property found on the tree node, cannot load child nodes";
}
return node.childNodesUrl;
}
//the factory object returned
return {
/** Loads in the data to display the nodes for an application */
loadApplication: function (options) {
loadApplication: function (section) {
var deferred = $q.defer();
//go and get the tree data
$http.get(getTreeAppUrl(options.section)).
$http.get(getTreeAppUrl(section)).
success(function (data, status, headers, config) {
deferred.resolve(data);
}).
@@ -327,7 +338,7 @@ function treeResource($q, $http) {
};
}
angular.module('umbraco.resources').factory('treeResource', treeResource);
return angular;
angular.module('umbraco.resources').factory('treeResource', treeResource);
return angular;
});
@@ -1,6 +1,6 @@
'use strict';
define(['app','angular'], function (app, angular) {
angular.module("umbraco.services", []);
'use strict';
define(['app','angular'], function (app, angular) {
angular.module("umbraco.services", []);
angular.module('umbraco.services')
.factory('dialogService', ['$rootScope', '$compile', '$http', '$timeout', '$q', '$templateCache',
function($rootScope, $compile, $http, $timeout, $q, $templateCache) {
@@ -140,7 +140,7 @@ return{
});
}
};
}]);
}]);
angular.module('umbraco.services')
.factory('navigationService', function ($rootScope, $routeParams, $log, dialogService, treeService) {
@@ -301,7 +301,7 @@ angular.module('umbraco.services')
}
};
});
});
angular.module('umbraco.services')
.factory('notificationsService', function ($rootScope, $timeout) {
@@ -345,8 +345,8 @@ angular.module('umbraco.services')
return nArray;
}
};
});
//script loader wrapping around 3rd party loader
});
//script loader wrapping around 3rd party loader
angular.module('umbraco.services')
.factory('searchService', function () {
return {
@@ -389,7 +389,7 @@ angular.module('umbraco.services')
currentSection = sectionAlias;
}
};
});
});
angular.module('umbraco.services')
.factory('treeService', function ($q, treeResource) {
//implement this in local storage
@@ -539,7 +539,7 @@ angular.module('umbraco.services')
return deferred.promise;
}
};
});
});
angular.module('umbraco.services')
.factory('userService', function () {
@@ -582,7 +582,7 @@ angular.module('umbraco.services')
};
});
/*Contains multiple services for various helper tasks */
/**
@@ -762,7 +762,7 @@ function treeIconHelper() {
}
};
}
angular.module('umbraco.services').factory('treeIconHelper', treeIconHelper);
return angular;
angular.module('umbraco.services').factory('treeIconHelper', treeIconHelper);
return angular;
});
@@ -1,6 +1,22 @@
//used for the media picker dialog
angular.module("umbraco")
.controller("Umbraco.Dialogs.MediaPickerController",
function ($scope, mediaResource) {
$scope.images = mediaResource.rootMedia();
});
angular.module("umbraco")
.controller("Umbraco.Dialogs.MediaPickerController",
function($scope, mediaResource) {
mediaResource.rootMedia()
.then(function(data) {
$scope.images = data;
});
$scope.selectMediaItem = function(image) {
if (image.contentTypeAlias.toLowerCase() == 'folder') {
mediaResource.getChildren(image.id)
.then(function(data) {
$scope.images = data;
});
} else if (image.contentTypeAlias.toLowerCase() == 'image') {
$scope.select(image);
}
};
});
@@ -1,49 +1,49 @@
<div class="umb-panel" ng-controller="Umbraco.Dialogs.MediaPickerController">
<div class="umb-panel-header">
<div class="umb-el-wrap umb-panel-buttons">
<div class="pull-right umb-btn-toolbar">
<button class="btn">Create <i class="icon-upload"></i></button>
<button type="button" ng-click="submit(dialogData)" class="btn btn-primary">Select (x)</button>
</div>
</div>
</div>
<div class="umb-panel-body umb-scrollable" auto-scale="1">
<div class="umb-panel">
<div class="umb-control-group">
<ul class="breadcrumb">
<li><strong>You are here:</strong></li>
<li><a href="#">Media</a></li>
</ul>
<div id="search-form" ng-animate="'slide'">
<form class="form-search" ng-controller="SearchController">
<i class="icon-search"></i>
<input type="text"
ng-model="ui.searchTerm"
class="umb-search-field search-query"
placeholder="Type to search...">
</form>
</div>
</ul>
<ul class="thumbnails">
<li class="span2 folder">
<a href="#">
<i class="icon-folder-close"></i>
Codegarden
</a>
</li>
<li class="span2" ng-repeat="image in images">
<a href="#" class="thumbnail" ng-class="{selected: dialogData.selection.indexOf(image) > -1}" ng-click="select(image)" prevent-default>
<img ng-src="{{image.thumbnail}}" />
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="umb-panel" ng-controller="Umbraco.Dialogs.MediaPickerController">
<div class="umb-panel-header">
<div class="umb-el-wrap umb-panel-buttons">
<div class="pull-right umb-btn-toolbar">
<button class="btn">Create <i class="icon-upload"></i></button>
<button type="button" ng-click="submit(dialogData)" class="btn btn-primary">Select (x)</button>
</div>
</div>
</div>
<div class="umb-panel-body umb-scrollable" auto-scale="1">
<div class="umb-panel">
<div class="umb-control-group">
<ul class="breadcrumb">
<li><strong>You are here:</strong></li>
<li><a href="#">Media</a></li>
</ul>
<div id="search-form" ng-animate="'slide'">
<form class="form-search" ng-controller="SearchController">
<i class="icon-search"></i>
<input type="text"
ng-model="ui.searchTerm"
class="umb-search-field search-query"
placeholder="{{localization.app.search.typeToSearch}}"
on-blur="deActivateSearch()"
on-keyup="performSearch(ui.searchTerm)">
</form>
</div>
</ul>
<ul class="thumbnails">
<li class="span2" ng-repeat="image in images">
<a href="#" class="thumbnail" ng-class="{selected: dialogData.selection.indexOf(image) > -1}"
ng-click="selectMediaItem(image)"
prevent-default>
<img ng-src="{{image.thumbnail}}" />
<span style="color:white;">{{image.name}}</span>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
@@ -17,11 +17,11 @@ angular.module("umbraco")
toolbar: "bold italic | styleselect | alignleft aligncenter alignright | bullist numlist | outdent indent | link image mediapicker",
setup : function(editor) {
editor.on('blur', function(e) {
$scope.$apply(function(){
//$scope.model.value = e.getBody().innerHTML;
$scope.model.value = editor.getContent();
})
editor.on('blur', function(e) {
$scope.$apply(function() {
//$scope.model.value = e.getBody().innerHTML;
$scope.model.value = editor.getContent();
});
});
editor.addButton('mediapicker', {
@@ -31,12 +31,17 @@ angular.module("umbraco")
dialogService.mediaPicker({scope: $scope, callback: function(data){
//really simple example on how to intergrate a service with tinyMCE
$(data.selection).each(function(i,img){
var data = {
src: img.thumbnail,
style: 'width: 100px; height: 100px',
id : '__mcenew'
};
$(data.selection).each(function (i, img) {
var imageProperty = _.find(img.properties, function(item) {
return item.alias == 'umbracoFile';
});
var data = {
src: imageProperty != null ? imageProperty.value : "nothing.jpg",
style: 'width: 100px; height: 100px',
id: '__mcenew'
};
editor.insertContent(editor.dom.createHTML('img', data));
var imgElm = editor.dom.get('__mcenew');
@@ -58,11 +63,11 @@ angular.module("umbraco")
};
function bindValue(inst){
$log.log("woot");
$scope.$apply(function(){
$scope.model.value = inst.getBody().innerHTML;
})
$log.log("woot");
$scope.$apply(function() {
$scope.model.value = inst.getBody().innerHTML;
});
}
function myHandleEvent(e){
@@ -10,10 +10,13 @@ function valServer() {
require: 'ngModel',
restrict: "A",
link: function (scope, element, attr, ctrl) {
if (!scope.model || !scope.model.alias)
if (!scope.model || !scope.model.alias){
throw "valServer can only be used in the scope of a content property object";
}
var parentErrors = scope.$parent.serverErrors;
if (!parentErrors) return;
if (!parentErrors) {
return;
}
var fieldName = scope.$eval(attr.valServer);
@@ -45,7 +45,7 @@ function valSummary() {
if (args.isValid && exists && !propertyHasErrors) {
//it is valid but we have a val msg for it so we'll need to remove the message
scope.validationSummary = _.reject(scope.validationSummary, function (item) {
return item == msg;
return item === msg;
});
}
else if (!args.isValid && !exists) {
@@ -70,5 +70,5 @@ function valSummary() {
}, true);
}
};
}
}
angular.module('umbraco.directives').directive("valSummary", valSummary);
@@ -9,18 +9,21 @@ function valToggleMsg(umbFormHelper) {
restrict: "A",
link: function (scope, element, attr, ctrl) {
if (!attr.valToggleMsg)
if (!attr.valToggleMsg){
throw "valToggleMsg requires that a reference to a validator is specified";
if (!attr.valMsgFor)
}
if (!attr.valMsgFor){
throw "valToggleMsg requires that the attribute valMsgFor exists on the element";
}
//create a flag for us to be able to reference in the below closures for watching.
var showValidation = false;
var hasError = false;
var currentForm = umbFormHelper.getCurrentForm(scope);
if (!currentForm || !currentForm.$name)
if (!currentForm || !currentForm.$name){
throw "valToggleMsg requires that a name is assigned to the ng-form containing the validated input";
}
//add a watch to the validator for the value (i.e. $parent.myForm.value.$error.required )
scope.$watch(currentForm.$name + "." + attr.valMsgFor + ".$error." + attr.valToggleMsg, function (isInvalid, oldValue) {
@@ -22,10 +22,10 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
var deferred = $q.defer();
//save the active tab id so we can set it when the data is returned.
var activeTab = _.find(content.tabs, function (item) {
return item.active
})
var activeTabIndex = (activeTab == undefined ? 0 : _.indexOf(content.tabs, activeTab));
var activeTab = _.find(content.tabs, function(item) {
return item.active;
});
var activeTabIndex = (activeTab === undefined ? 0 : _.indexOf(content.tabs, activeTab));
//save the data
umbRequestHelper.postMultiPartRequest(
@@ -67,8 +67,9 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
_.each(data.tabs, function (item) {
item.active = false;
});
if (data.tabs.length > 0)
if (data.tabs.length > 0){
data.tabs[0].active = true;
}
deferred.resolve(data);
}).
@@ -92,8 +93,9 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
_.each(data.tabs, function (item) {
item.active = false;
});
if (data.tabs.length > 0)
if (data.tabs.length > 0){
data.tabs[0].active = true;
}
deferred.resolve(data);
}).
@@ -153,6 +155,6 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
}
};
}
angular.module('umbraco.resources').factory('contentResource', contentResource);
}
angular.module('umbraco.resources').factory('contentResource', contentResource);
@@ -0,0 +1,53 @@
/**
* @ngdoc factory
* @name umbraco.resources.treeResource
* @description Loads in data for trees
**/
function mediaResource($q, $http) {
/** internal method to get the api url */
function getRootMediaUrl() {
return Umbraco.Sys.ServerVariables.mediaApiBaseUrl + "GetRootMedia";
}
/** internal method to get the api url */
function getChildrenMediaUrl(parentId) {
return Umbraco.Sys.ServerVariables.mediaApiBaseUrl + "GetChildren?parentId=" + parentId;
}
return {
rootMedia: function () {
var deferred = $q.defer();
//go and get the tree data
$http.get(getRootMediaUrl()).
success(function (data, status, headers, config) {
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
deferred.reject('Failed to retreive data for application tree ' + section);
});
return deferred.promise;
},
getChildren: function (parentId) {
var deferred = $q.defer();
//go and get the tree data
$http.get(getChildrenMediaUrl(parentId)).
success(function (data, status, headers, config) {
deferred.resolve(data);
}).
error(function (data, status, headers, config) {
deferred.reject('Failed to retreive data for application tree ' + section);
});
return deferred.promise;
}
};
}
angular.module('umbraco.resources').factory('mediaResource', mediaResource);
@@ -11,8 +11,9 @@ function treeResource($q, $http) {
}
/** internal method to get the tree node's children url */
function getTreeNodesUrl(node) {
if (!node.childNodesUrl)
if (!node.childNodesUrl){
throw "No childNodesUrl property found on the tree node, cannot load child nodes";
}
return node.childNodesUrl;
}