Merge branch '7.0.0' of https://github.com/umbraco/Umbraco-CMS into 7.0.0

This commit is contained in:
Shannon
2013-11-20 08:55:38 +11:00
57 changed files with 930 additions and 291 deletions
+4 -1
View File
@@ -1,6 +1,6 @@
@ECHO OFF
SET release=7.0.0
SET comment=RC
SET comment=
SET version=%release%
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
@@ -20,6 +20,9 @@ echo This file is only here so that the containing folder will be included in th
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\Views\Partials\dummy.txt
echo This file is only here so that the containing folder will be included in the NuGet package, it is safe to delete. > .\_BuildOutput\WebApp\Views\MacroPartials\dummy.txt
ren .\_BuildOutput\WebApp\MacroScripts\Web.config Web.config.transform
ren .\_BuildOutput\WebApp\Views\Web.config Web.config.transform
..\src\.nuget\NuGet.exe pack NuSpecs\UmbracoCms.Core.nuspec -Version %version%
..\src\.nuget\NuGet.exe pack NuSpecs\UmbracoCms.nuspec -Version %version%
+1 -1
View File
@@ -23,7 +23,7 @@
<file src="..\_BuildOutput\WebApp\bin\x86\**" target="Content\bin\x86" />
<file src="..\_BuildOutput\Configs\**" target="Content\config" exclude="..\_BuildOutput\Configs\Web.config.transform" />
<file src="..\_BuildOutput\WebApp\css\**" target="Content\css" />
<file src="..\_BuildOutput\WebApp\macroScripts\**" target="Content\macroScripts" />
<file src="..\_BuildOutput\WebApp\macroScripts\**" target="Content\macroScripts" exclude="..\_BuildOutput\WebApp\macroScripts\Web.config" />
<file src="..\_BuildOutput\WebApp\masterpages\**" target="Content\masterpages" />
<file src="..\_BuildOutput\WebApp\media\**" target="Content\media" />
<file src="..\_BuildOutput\WebApp\scripts\**" target="Content\scripts" />
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Configuration.UmbracoSettings
set { base["guid"] = value; }
}
[ConfigurationProperty("repositoryurl", DefaultValue = "http://our.umbraco.org")]
[ConfigurationProperty("repositoryurl", DefaultValue = "http://packages.umbraco.org")]
public string RepositoryUrl
{
get { return (string)base["repositoryurl"]; }
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration
/// Gets the version comment (like beta or RC).
/// </summary>
/// <value>The version comment.</value>
public static string CurrentComment { get { return "RC"; } }
public static string CurrentComment { get { return ""; } }
// Get the version of the umbraco.dll by looking at a class in that dll
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

@@ -139,6 +139,7 @@ angular.module("umbraco.directives.html")
$timeout(function () {
var photos = ngModel.$modelValue;
scope.imagesOnly = element.attr('imagesOnly');
scope.baseline = element.attr('baseline') ? parseInt(element.attr('baseline'), 10) : 0;
scope.minWidth = element.attr('min-width') ? parseInt(element.attr('min-width'), 10) : 420;
scope.minHeight = element.attr('min-height') ? parseInt(element.attr('min-height'), 10) : 200;
@@ -60,6 +60,12 @@ function sectionsDirective($timeout, $window, navigationService, treeService, se
}
});
scope.$on("appState.sectionState.changed", function (e, args) {
if (args.key === "currentSection") {
scope.currentSection = args.value;
}
});
//on page resize
window.onresize = calculateHeight;
@@ -13,8 +13,8 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat
scope: {
section: '@',
treealias: '@',
showoptions: '@',
showheader: '@',
hideoptions: '@',
hideheader: '@',
cachekey: '@',
isdialog: '@',
//Custom query string arguments to pass in to the tree as a string, example: "startnodeid=123&something=value"
@@ -24,18 +24,13 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat
compile: function(element, attrs) {
//config
var hideheader = (attrs.showheader === 'false') ? true : false;
var hideoptions = (attrs.showoptions === 'false') ? "hide-options" : "";
var template = '<ul class="umb-tree ' + hideoptions + '">' +
'<li class="root">';
if (!hideheader) {
template += '<div>' +
'<h5><a href="#/{{section}}" ng-click="select(this, tree.root, $event)" on-right-click="altSelect(this, tree.root, $event)" class="root-link">{{tree.name}}</a></h5>' +
'<a href class="umb-options" ng-hide="tree.root.isContainer || !tree.root.menuUrl" ng-click="options(this, tree.root, $event)" ng-swipe-right="options(this, tree.root, $event)"><i></i><i></i><i></i></a>' +
'</div>';
}
//var showheader = (attrs.showheader !== 'false');
var hideoptions = (attrs.hideoptions === 'true') ? "hide-options" : "";
var template = '<ul class="umb-tree ' + hideoptions + '"><li class="root">';
template += '<div ng-hide="hideheader">' +
'<h5><a href="#/{{section}}" ng-click="select(this, tree.root, $event)" on-right-click="altSelect(this, tree.root, $event)" class="root-link">{{tree.name}}</a></h5>' +
'<a href class="umb-options" ng-hide="tree.root.isContainer || !tree.root.menuUrl" ng-click="options(this, tree.root, $event)" ng-swipe-right="options(this, tree.root, $event)"><i></i><i></i><i></i></a>' +
'</div>';
template += '<ul>' +
'<umb-tree-item ng-repeat="child in tree.root.children" eventhandler="eventhandler" node="child" current-node="currentNode" tree="child" section="{{section}}" ng-animate="animation()"></umb-tree-item>' +
'</ul>' +
@@ -36,17 +36,21 @@ angular.module('umbraco.directives')
})
.directive('onRightClick',function(){
document.oncontextmenu = function (e) {
if(e.target.hasAttribute('on-right-click')) {
e.preventDefault();
e.stopPropagation();
return false;
}
};
return function(scope,el,attrs){
el.bind('contextmenu',function(e){
e.preventDefault();
e.stopPropagation();
scope.$apply(attrs.onRightClick);
}) ;
return false;
});
};
});
@@ -565,10 +565,57 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
return saveContentItem(content, "publish" + (isNew ? "New" : ""), files);
},
/**
* @ngdoc method
* @name umbraco.resources.contentResource#sendToPublish
* @methodOf umbraco.resources.contentResource
*
* @description
* Saves changes made to a content item, and notifies any subscribers about a pending publication
*
* ##usage
* <pre>
* contentResource.getById(1234)
* .then(function(content) {
* content.name = "I want a new name, and be published!";
* contentResource.sendToPublish(content, false)
* .then(function(content){
* alert("Retrieved, updated and notication send off");
* });
* });
* </pre>
*
* @param {Object} content The content item object with changes applied
* @param {Bool} isNew set to true to create a new item or to update an existing
* @param {Array} files collection of files for the document
* @returns {Promise} resourcePromise object containing the saved content item.
*
*/
sendToPublish: function (content, isNew, files) {
return saveContentItem(content, "sendPublish" + (isNew ? "New" : ""), files);
},
/**
* @ngdoc method
* @name umbraco.resources.contentResource#publishByid
* @methodOf umbraco.resources.contentResource
*
* @description
* Publishes a content item with a given ID
*
* ##usage
* <pre>
* contentResource.publishById(1234)
* .then(function(content) {
* alert("published");
* });
* </pre>
*
* @param {Int} id The ID of the conten to publish
* @returns {Promise} resourcePromise object containing the published content item.
*
*/
publishById: function(id){
if (!id) {
@@ -7,7 +7,25 @@ function contentTypeResource($q, $http, umbRequestHelper) {
return {
//return a content type with a given ID
/**
* @ngdoc method
* @name umbraco.resources.contentTypeResource#getContentType
* @methodOf umbraco.resources.contentTypeResource
*
* @description
* Returns a content type with a given ID
*
* ##usage
* <pre>
* contentTypeResource.getContentType(1234)
* .then(function(type) {
* $scope.type = type;
* });
* </pre>
* @param {Int} id id of the content type to retrieve
* @returns {Promise} resourcePromise object.
*
*/
getContentType: function (id) {
var deferred = $q.defer();
@@ -22,7 +40,25 @@ function contentTypeResource($q, $http, umbRequestHelper) {
return deferred.promise;
},
//return all types allowed under given document
/**
* @ngdoc method
* @name umbraco.resources.contentTypeResource#getAllowedTypes
* @methodOf umbraco.resources.contentTypeResource
*
* @description
* Returns a list of allowed content types underneath a content item with a given ID
*
* ##usage
* <pre>
* contentTypeResource.getAllowedTypes(1234)
* .then(function(array) {
* $scope.type = type;
* });
* </pre>
* @param {Int} contentId id of the content item to retrive allowed child types for
* @returns {Promise} resourcePromise object.
*
*/
getAllowedTypes: function (contentId) {
return umbRequestHelper.resourcePromise(
@@ -6,6 +6,19 @@
function dashboardResource($q, $http, umbRequestHelper) {
//the factory object returned
return {
/**
* @ngdoc method
* @name umbraco.resources.dashboardResource#getDashboard
* @methodOf umbraco.resources.dashboardResource
*
* @description
* Retrieves the dashboard configuration for a given section
*
* @param {string} section Alias of section to retrieve dashboard configuraton for
* @returns {Promise} resourcePromise object containing the user array.
*
*/
getDashboard: function (section) {
return umbRequestHelper.resourcePromise(
@@ -7,7 +7,28 @@ function dataTypeResource($q, $http, umbDataFormatter, umbRequestHelper) {
return {
getPreValues: function (editorId, dataTypeId) {
/**
* @ngdoc method
* @name umbraco.resources.dataTypeResource#getPreValues
* @methodOf umbraco.resources.dataTypeResource
*
* @description
* Retrieves available prevalues for a given data type + editor
*
* ##usage
* <pre>
* dataTypeResource.getPrevalyes("Umbraco.MediaPicker", 1234)
* .then(function(prevalues) {
* alert('its gone!');
* });
* </pre>
*
* @param {String} editorAlias string alias of editor type to retrive prevalues configuration for
* @param {Int} id id of datatype to retrieve prevalues for
* @returns {Promise} resourcePromise object.
*
*/
getPreValues: function (editorAlias, dataTypeId) {
if (!dataTypeId) {
dataTypeId = -1;
@@ -18,10 +39,30 @@ function dataTypeResource($q, $http, umbDataFormatter, umbRequestHelper) {
umbRequestHelper.getApiUrl(
"dataTypeApiBaseUrl",
"GetPreValues",
[{ editorAlias: editorId }, { dataTypeId: dataTypeId }])),
[{ editorAlias: editorAlias }, { dataTypeId: dataTypeId }])),
'Failed to retreive pre values for editor id ' + editorId);
},
/**
* @ngdoc method
* @name umbraco.resources.dataTypeResource#getById
* @methodOf umbraco.resources.dataTypeResource
*
* @description
* Gets a data type item with a given id
*
* ##usage
* <pre>
* dataTypeResource.getById(1234)
* .then(function() {
* alert('its gone!');
* });
* </pre>
*
* @param {Int} id id of data type to retrieve
* @returns {Promise} resourcePromise object.
*
*/
getById: function (id) {
return umbRequestHelper.resourcePromise(
@@ -39,21 +80,45 @@ function dataTypeResource($q, $http, umbDataFormatter, umbRequestHelper) {
$http.get(
umbRequestHelper.getApiUrl(
"dataTypeApiBaseUrl",
"GetAll",
[{ id: id }])),
'Failed to retreive data for data type id ' + id);
"GetAll")),
'Failed to retreive data');
},
/** 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 */
getScaffold: function (parentId, alias) {
/**
* @ngdoc method
* @name umbraco.resources.contentResource#getScaffold
* @methodOf umbraco.resources.contentResource
*
* @description
* Returns a scaffold of an empty data type item
*
* The scaffold is used to build editors for data types that has not yet been populated with data.
*
* ##usage
* <pre>
* dataTypeResource.getScaffold()
* .then(function(scaffold) {
* var myType = scaffold;
* myType.name = "My new data type";
*
* dataTypeResource.save(myType, myType.preValues, true)
* .then(function(type){
* alert("Retrieved, updated and saved again");
* });
* });
* </pre>
*
* @returns {Promise} resourcePromise object containing the data type scaffold.
*
*/
getScaffold: function () {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"dataTypeApiBaseUrl",
"GetEmpty")),
'Failed to retreive data for empty datatype ' + alias);
'Failed to retreive data for empty datatype');
},
/**
* @ngdoc method
@@ -61,7 +126,7 @@ function dataTypeResource($q, $http, umbDataFormatter, umbRequestHelper) {
* @methodOf umbraco.resources.dataTypeResource
*
* @description
* Deletes a content item with a given id
* Deletes a data type with a given id
*
* ##usage
* <pre>
@@ -84,7 +149,33 @@ function dataTypeResource($q, $http, umbDataFormatter, umbRequestHelper) {
[{ id: id }])),
'Failed to delete item ' + id);
},
/** saves or updates a data type object */
/**
* @ngdoc method
* @name umbraco.resources.dataTypeResource#deleteById
* @methodOf umbraco.resources.dataTypeResource
*
* @description
* Saves or update a data typw
*
* ##usage
* <pre>
* dataTypeResource.getById(1234)
* .then(function(type) {
* type.name ="hibba";
*
* dataTypeResource.save(type, type.preValues, false).then(function(type){
* alert('its done!');
* }):
* });
* </pre>
*
* @param {Object} dataType data type object to create/update
* @param {Array} preValues collection of prevalues on the datatype
* @param {Bool} isNew set to true if type should be create instead of updated
* @returns {Promise} resourcePromise object.
*
*/
save: function (dataType, preValues, isNew) {
var saveModel = umbDataFormatter.formatDataTypePostData(dataType, preValues, "save" + (isNew ? "New" : ""));
@@ -264,6 +264,28 @@ function entityResource($q, $http, umbRequestHelper) {
'Failed to retreive entity data for query ' + query);
},
/**
* @ngdoc method
* @name umbraco.resources.entityResource#searchAll
* @methodOf umbraco.resources.entityResource
*
* @description
* Gets an array of entities from all available search indexes, given a lucene query
*
* ##usage
* <pre>
* entityResource.searchAll("bob")
* .then(function(array) {
* var myDoc = array;
* alert('they are here!');
* });
* </pre>
*
* @param {String} Query search query
* @returns {Promise} resourcePromise object containing the entity array.
*
*/
searchAll: function (query) {
return umbRequestHelper.resourcePromise(
@@ -329,12 +329,59 @@ function mediaResource($q, $http, umbDataFormatter, umbRequestHelper) {
'Failed to retreive children for media item ' + parentId);
},
/** saves or updates a media object */
/**
* @ngdoc method
* @name umbraco.resources.mediaResource#save
* @methodOf umbraco.resources.mediaResource
*
* @description
* Saves changes made to a media item, if the media item is new, the isNew paramater must be passed to force creation
* if the media item needs to have files attached, they must be provided as the files param and passed seperately
*
*
* ##usage
* <pre>
* mediaResource.getById(1234)
* .then(function(media) {
* media.name = "I want a new name!";
* mediaResource.save(media, false)
* .then(function(media){
* alert("Retrieved, updated and saved again");
* });
* });
* </pre>
*
* @param {Object} media The media item object with changes applied
* @param {Bool} isNew set to true to create a new item or to update an existing
* @param {Array} files collection of files for the media item
* @returns {Promise} resourcePromise object containing the saved media item.
*
*/
save: function (media, isNew, files) {
return saveMediaItem(media, "save" + (isNew ? "New" : ""), files);
},
//** shorthand for creating a new folder under a given parent **/
/**
* @ngdoc method
* @name umbraco.resources.mediaResource#addFolder
* @methodOf umbraco.resources.mediaResource
*
* @description
* Shorthand for adding a media item of the type "Folder" under a given parent ID
*
* ##usage
* <pre>
* mediaResource.addFolder("My gallery", 1234)
* .then(function(folder) {
* alert('New folder');
* });
* </pre>
*
* @param {string} name Name of the folder to create
* @param {int} parentId Id of the media item to create the folder underneath
* @returns {Promise} resourcePromise object.
*
*/
addFolder: function(name, parentId){
return umbRequestHelper.resourcePromise(
$http.post(umbRequestHelper
@@ -7,16 +7,34 @@ function mediaTypeResource($q, $http, umbRequestHelper) {
return {
//return all types allowed under given document
getAllowedTypes: function (contentId) {
/**
* @ngdoc method
* @name umbraco.resources.mediaTypeResource#getAllowedTypes
* @methodOf umbraco.resources.mediaTypeResource
*
* @description
* Returns a list of allowed media types underneath a media item with a given ID
*
* ##usage
* <pre>
* mediaTypeResource.getAllowedTypes(1234)
* .then(function(array) {
* $scope.type = type;
* });
* </pre>
* @param {Int} mediaId id of the media item to retrive allowed child types for
* @returns {Promise} resourcePromise object.
*
*/
getAllowedTypes: function (mediaId) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"mediaTypeApiBaseUrl",
"GetAllowedChildren",
[{ contentId: contentId }])),
'Failed to retreive data for media id ' + contentId);
[{ contentId: mediaId }])),
'Failed to retreive data for media id ' + mediaId);
}
};
@@ -138,7 +138,34 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
},
/** saves or updates a member object */
/**
* @ngdoc method
* @name umbraco.resources.memberResource#save
* @methodOf umbraco.resources.memberResource
*
* @description
* Saves changes made to a member, if the member is new, the isNew paramater must be passed to force creation
* if the member needs to have files attached, they must be provided as the files param and passed seperately
*
*
* ##usage
* <pre>
* memberResource.getBykey("23234-sd8djsd-3h8d3j-sdh8d")
* .then(function(member) {
* member.name = "Bob";
* memberResource.save(member, false)
* .then(function(member){
* alert("Retrieved, updated and saved again");
* });
* });
* </pre>
*
* @param {Object} media The member item object with changes applied
* @param {Bool} isNew set to true to create a new item or to update an existing
* @param {Array} files collection of files for the media item
* @returns {Promise} resourcePromise object containing the saved media item.
*
*/
save: function (member, isNew, files) {
return saveMember(member, "save" + (isNew ? "New" : ""), files);
}
@@ -38,24 +38,61 @@ function stylesheetResource($q, $http, umbRequestHelper) {
'Failed to retreive stylesheets ');
},
/**
* @ngdoc method
* @name umbraco.resources.stylesheetResource#getRules
* @methodOf umbraco.resources.stylesheetResource
*
* @description
* Returns all defined child rules for a stylesheet with a given ID
*
* ##usage
* <pre>
* stylesheetResource.getRules(2345)
* .then(function(rules) {
* alert('its here!');
* });
* </pre>
*
* @returns {Promise} resourcePromise object containing the rules.
*
*/
getRules: function (id) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"stylesheetApiBaseUrl",
"GetRules",
[{ id: id }]
)),
[{ id: id }]) +"&rnd=" + Math.floor(Math.random()*1001), {cache: false}),
'Failed to retreive stylesheets ');
},
/**
* @ngdoc method
* @name umbraco.resources.stylesheetResource#getRulesByName
* @methodOf umbraco.resources.stylesheetResource
*
* @description
* Returns all defined child rules for a stylesheet with a given name
*
* ##usage
* <pre>
* stylesheetResource.getRulesByName("ie7stylesheet")
* .then(function(rules) {
* alert('its here!');
* });
* </pre>
*
* @returns {Promise} resourcePromise object containing the rules.
*
*/
getRulesByName: function (name) {
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"stylesheetApiBaseUrl",
"GetRulesByName",
[{ name: name }])),
[{ name: name }]) +"&rnd=" + Math.floor(Math.random()*1001), {cache: false}),
'Failed to retreive stylesheets ');
}
};
@@ -5,6 +5,32 @@
*
* @description
* Tracks the various application state variables when working in the back office, raises events when state changes.
*
* ##Samples
*
* ####Subscribe to global state changes:
*
* <pre>
* scope.showTree = appState.getGlobalState("showNavigation");
*
* scope.$on("appState.globalState.changed", function (e, args) {
* if (args.key === "showNavigation") {
* scope.showTree = args.value;
* }
* });
* </pre>
*
* ####Subscribe to section-state changes
*
* <pre>
* scope.currentSection = appState.getSectionState("currentSection");
*
* scope.$on("appState.sectionState.changed", function (e, args) {
* if (args.key === "currentSection") {
* scope.currentSection = args.value;
* }
* });
* </pre>
*/
function appState($rootScope) {
@@ -75,7 +101,7 @@ function appState($rootScope) {
* @function
*
* @description
* Returns the current global state value by key - we do not return an object here - we do NOT want this
* Returns the current global state value by key - we do not return an object reference here - we do NOT want this
* to be publicly mutable and allow setting arbitrary values
*
*/
@@ -203,13 +229,52 @@ angular.module('umbraco.services').factory("editorState", function() {
var current = null;
var state = {
/**
* @ngdoc function
* @name umbraco.services.angularHelper#set
* @methodOf umbraco.services.editorState
* @function
*
* @description
* Sets the current entity object for the currently active editor
* This is only used when implementing an editor with a complex model
* like the content editor, where the model is modified by several
* child controllers.
*/
set: function (entity) {
current = entity;
},
/**
* @ngdoc function
* @name umbraco.services.angularHelper#reset
* @methodOf umbraco.services.editorState
* @function
*
* @description
* Since the editorstate entity is read-only, you cannot set it to null
* only through the reset() method
*/
reset: function() {
current = null;
}
/**
* @ngdoc function
* @name umbraco.services.angularHelper#current
* @methodOf umbraco.services.editorState
* @function
*
* @description
* Returns an object reference to the current editor entity.
* the entity is the root object of the editor.
* EditorState is used by property/parameter editors that need
* access to the entire entity being edited, not just the property/parameter
*
* editorState.current can not be overwritten, you should only read values from it
* since modifying individual properties should be handled by the property editors
*/
};
//create a get/set property but don't allow setting
@@ -1,3 +1,25 @@
/**
* @ngdoc service
* @name umbraco.services.searchService
*
*
* @description
* Service for handling the main application search, can currently search content, media and members
*
* ##usage
* To use, simply inject the searchService into any controller that needs it, and make
* sure the umbraco.services module is accesible - which it should be by default.
*
* <pre>
* searchService.searchMembers({term: 'bob'}).then(function(results){
* angular.forEach(results, function(result){
* //returns:
* {name: "name", id: 1234, menuUrl: "url", editorPath: "url", metaData: {}, subtitle: "/path/etc" }
* })
* var result =
* })
* </pre>
*/
angular.module('umbraco.services')
.factory('searchService', function ($q, $log, entityResource, contentResource, umbRequestHelper) {
@@ -23,6 +45,18 @@ angular.module('umbraco.services')
}
return {
/**
* @ngdoc method
* @name umbraco.services.searchService#searchMembers
* @methodOf umbraco.services.searchService
*
* @description
* Searches the default member search index
* @param {Object} args argument object
* @param {String} args.term seach term
* @returns {Promise} returns promise containing all matching members
*/
searchMembers: function(args) {
if (!args.term) {
@@ -36,6 +70,18 @@ angular.module('umbraco.services')
return data;
});
},
/**
* @ngdoc method
* @name umbraco.services.searchService#searchContent
* @methodOf umbraco.services.searchService
*
* @description
* Searches the default internal content search index
* @param {Object} args argument object
* @param {String} args.term seach term
* @returns {Promise} returns promise containing all matching content items
*/
searchContent: function(args) {
if (!args.term) {
@@ -49,6 +95,18 @@ angular.module('umbraco.services')
return data;
});
},
/**
* @ngdoc method
* @name umbraco.services.searchService#searchMedia
* @methodOf umbraco.services.searchService
*
* @description
* Searches the default media search index
* @param {Object} args argument object
* @param {String} args.term seach term
* @returns {Promise} returns promise containing all matching media items
*/
searchMedia: function(args) {
if (!args.term) {
@@ -62,6 +120,18 @@ angular.module('umbraco.services')
return data;
});
},
/**
* @ngdoc method
* @name umbraco.services.searchService#searchAll
* @methodOf umbraco.services.searchService
*
* @description
* Searches all available indexes and returns all results in one collection
* @param {Object} args argument object
* @param {String} args.term seach term
* @returns {Promise} returns promise containing all matching items
*/
searchAll: function (args) {
if (!args.term) {
@@ -86,6 +86,7 @@ function tinyMceService(dialogService, $log, imageHelper, $http, $timeout, macro
tooltip: 'Media Picker',
onclick: function () {
dialogService.mediaPicker({
onlyImages: true,
scope: $scope, callback: function (img) {
if (img) {
@@ -121,7 +121,20 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
return undefined;
},
/** clears the tree cache - with optional cacheKey, optional section or optional filter */
/**
* @ngdoc method
* @name umbraco.services.treeService#clearCache
* @methodOf umbraco.services.treeService
* @function
*
* @description
* Clears the tree cache - with optional cacheKey, optional section or optional filter.
*
* @param {Object} args arguments
* @param {String} args.cacheKey optional cachekey - this is used to clear specific trees in dialogs
* @param {String} args.section optional section alias - clear tree for a given section
* @param {String} args.childrenOf optional parent ID - only clear the cache below a specific node
*/
clearCache: function (args) {
//clear all if not specified
if (!args) {
@@ -252,7 +265,16 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
},
/** Removes a given tree node from the tree */
/**
* @ngdoc method
* @name umbraco.services.treeService#removeNode
* @methodOf umbraco.services.treeService
* @function
*
* @description
* Removes a given node from the tree
* @param {object} treeNode the node to remove
*/
removeNode: function(treeNode) {
if (treeNode.parent() == null) {
throw "Cannot remove a node that doesn't have a parent";
@@ -261,14 +283,33 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
treeNode.parent().children.splice(treeNode.parent().children.indexOf(treeNode), 1);
},
/** Removes all child nodes from a given tree node */
/**
* @ngdoc method
* @name umbraco.services.treeService#removeChildNodes
* @methodOf umbraco.services.treeService
* @function
*
* @description
* Removes all child nodes from a given tree node
* @param {object} treeNode the node to remove children from
*/
removeChildNodes : function(treeNode) {
treeNode.expanded = false;
treeNode.children = [];
treeNode.hasChildren = false;
},
/** Gets a child node by id */
/**
* @ngdoc method
* @name umbraco.services.treeService#getChildNode
* @methodOf umbraco.services.treeService
* @function
*
* @description
* Gets a child node with a given ID, from a specific treeNode
* @param {object} treeNode to retrive child node from
* @param {int} id id of child node
*/
getChildNode: function (treeNode, id) {
if (!treeNode.children) {
return null;
@@ -279,7 +320,18 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
return found === undefined ? null : found;
},
/** Gets a descendant node by id */
/**
* @ngdoc method
* @name umbraco.services.treeService#getDescendantNode
* @methodOf umbraco.services.treeService
* @function
*
* @description
* Gets a descendant node by id
* @param {object} treeNode to retrive descendant node from
* @param {int} id id of descendant node
* @param {string} treeAlias - optional tree alias, if fetching descendant node from a child of a listview document
*/
getDescendantNode: function(treeNode, id, treeAlias) {
//validate if it is a section container since we'll need a treeAlias if it is one
@@ -332,7 +384,16 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
return found === undefined ? null : found;
},
/** Gets the root node of the current tree type for a given tree node */
/**
* @ngdoc method
* @name umbraco.services.treeService#getTreeRoot
* @methodOf umbraco.services.treeService
* @function
*
* @description
* Gets the root node of the current tree type for a given tree node
* @param {object} treeNode to retrive tree root node from
*/
getTreeRoot: function (treeNode) {
if (!treeNode) {
throw "treeNode cannot be null";
@@ -354,6 +415,16 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
},
/** Gets the node's tree alias, this is done by looking up the meta-data of the current node's root node */
/**
* @ngdoc method
* @name umbraco.services.treeService#getTreeAlias
* @methodOf umbraco.services.treeService
* @function
*
* @description
* Gets the node's tree alias, this is done by looking up the meta-data of the current node's root node
* @param {object} treeNode to retrive tree alias from
*/
getTreeAlias : function(treeNode) {
var root = this.getTreeRoot(treeNode);
if (root) {
@@ -362,7 +433,18 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
return "";
},
/** gets the tree, returns a promise */
/**
* @ngdoc method
* @name umbraco.services.treeService#getTree
* @methodOf umbraco.services.treeService
* @function
*
* @description
* gets the tree, returns a promise
* @param {object} args Arguments
* @param {string} args.section Section alias
* @param {string} args.cacheKey Optional cachekey
*/
getTree: function (args) {
var deferred = $q.defer();
@@ -409,6 +491,17 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
return deferred.promise;
},
/**
* @ngdoc method
* @name umbraco.services.treeService#getMenu
* @methodOf umbraco.services.treeService
* @function
*
* @description
* Returns available menu actions for a given tree node
* @param {object} args Arguments
* @param {string} args.treeNode tree node object to retrieve the menu for
*/
getMenu: function (args) {
if (!args) {
@@ -428,7 +521,18 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
});
},
/** Gets the children from the server for a given node */
/**
* @ngdoc method
* @name umbraco.services.treeService#getChildren
* @methodOf umbraco.services.treeService
* @function
*
* @description
* Gets the children from the server for a given node
* @param {object} args Arguments
* @param {object} args.node tree node object to retrieve the children for
* @param {string} args.section current section alias
*/
getChildren: function (args) {
if (!args) {
@@ -451,7 +555,16 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
});
},
/** This re-loads the single node from the server */
/**
* @ngdoc method
* @name umbraco.services.treeService#reloadNode
* @methodOf umbraco.services.treeService
* @function
*
* @description
* Re-loads the single node from the server
* @param {object} node Tree node to reload
*/
reloadNode: function(node) {
if (!node) {
throw "node cannot be null";
@@ -495,7 +608,16 @@ function treeService($q, treeResource, iconHelper, notificationsService, $rootSc
return deferred.promise;
},
/** This will return the current node's path by walking up the tree */
/**
* @ngdoc method
* @name umbraco.services.treeService#getPath
* @methodOf umbraco.services.treeService
* @function
*
* @description
* This will return the current node's path by walking up the tree
* @param {object} node Tree node to retrieve path for
*/
getPath: function(node) {
if (!node) {
throw "node cannot be null";
@@ -165,41 +165,53 @@ function imageHelper() {
if (!options && !options.imageModel) {
throw "The options objet does not contain the required parameters: imageModel";
}
if (options.imageModel.contentTypeAlias.toLowerCase() === "image") {
//combine all props, TODO: we really need a better way then this
var props = [];
if(options.imageModel.properties){
props = options.imageModel.properties;
}else{
$(options.imageModel.tabs).each(function(i, tab){
props = props.concat(tab.properties);
});
}
var imageProp = _.find(props, function (item) {
return item.alias === 'umbracoFile';
});
if (!imageProp) {
return "";
}
var imageVal;
//our default images might store one or many images (as csv)
var split = imageProp.value.split(',');
var self = this;
imageVal = _.map(split, function(item) {
return { file: item, isImage: self.detectIfImageByExtension(item) };
});
//for now we'll just return the first image in the collection.
//TODO: we should enable returning many to be displayed in the picker if the uploader supports many.
if (imageVal.length && imageVal.length > 0 && imageVal[0].isImage) {
return imageVal[0].file;
}
//combine all props, TODO: we really need a better way then this
var props = [];
if(options.imageModel.properties){
props = options.imageModel.properties;
}else{
$(options.imageModel.tabs).each(function(i, tab){
props = props.concat(tab.properties);
});
}
var mediaRoot = Umbraco.Sys.ServerVariables.umbracoSettings.mediaPath;
var imageProp = _.find(props, function (item) {
if(item.alias === "umbracoFile")
{
return true;
}
//this performs a simple check to see if we have a media file as value
//it doesnt catch everything, but better then nothing
if(item.value.indexOf(mediaRoot) === 0){
return true;
}
return false;
});
if (!imageProp) {
return "";
}
var imageVal;
//our default images might store one or many images (as csv)
var split = imageProp.value.split(',');
var self = this;
imageVal = _.map(split, function(item) {
return { file: item, isImage: self.detectIfImageByExtension(item) };
});
//for now we'll just return the first image in the collection.
//TODO: we should enable returning many to be displayed in the picker if the uploader supports many.
if (imageVal.length && imageVal.length > 0 && imageVal[0].isImage) {
return imageVal[0].file;
}
return "";
},
/** formats the display model used to display the content to the model used to save the content */
@@ -26,7 +26,7 @@
overflow: auto;
}
.umb-panel-body.no-header {
top: 0px;
top: 20px;
}
.umb-panel-body.with-footer {
@@ -148,7 +148,6 @@ ul.color-picker li a {
margin: 0;
padding: 0;
display: block;
width: 520px;
}
@@ -159,6 +158,7 @@ ul.color-picker li a {
background: white;
margin: 5px;
position: relative;
text-align: center
}
.umb-sortable-thumbnails li:hover a{
@@ -167,10 +167,20 @@ ul.color-picker li a {
.umb-sortable-thumbnails li img
{
max-width:100%;
max-height:100%;
margin:auto;
display:block;
max-width:100%;
max-height:100%;
margin:auto;
display:block;
}
.umb-sortable-thumbnails .icon-holder .icon{
font-size: 60px;
line-height: 70px;
}
.umb-sortable-thumbnails .icon-holder *
{
color: @grayLight;
display: block
}
@@ -221,14 +231,16 @@ display:block;
.umb-photo-folder .picrow{
overflow-y: hidden;
position: relative;
}
.umb-photo-folder .picrow a, .umb-photo-preview{
.umb-photo-folder .picrow div, .umb-photo-preview{
margin: 0px;
padding: 0px;
border: none;
display: inline-block;
vertical-align: top;
position: relative;
}
.umb-photo-folder a:hover{text-decoration: none}
@@ -241,6 +253,21 @@ display:block;
text-decoration: none;
}
//this is a temp hack, to provide selectors in the dialog:
.umb-dialogs-mediapicker .umb-photo-folder .pic:hover .selector-overlay{
position: absolute;
bottom: 0px;
left: 0px;
right: 0px;
padding: 5px;
background: black;
z-index: 100;
display: block;
text-align: center;
color: white;
opacity: 0.4;
}
.umb-photo-folder .umb-non-thumbnail i{
color: @grayLight;
font-size: 70px;
@@ -257,6 +284,7 @@ display:block;
.umb-photo-folder .selected:before{
content: "\e165";
font-family: Icomoon;
position: absolute;
bottom: 10px;
right: 10px;
@@ -275,6 +303,7 @@ display:block;
width: 32px;
overflow: hidden;
display: block;
z-index: 100;
}
@@ -38,8 +38,7 @@
<div ng-hide="showSearch">
<umb-tree
section="content"
showheader="true"
showoptions="false"
hideoptions="true"
isdialog="true"
eventhandler="dialogTreeEventHandler">
</umb-tree>
@@ -21,7 +21,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.LinkPickerController",
}
contentResource.getNiceUrl($scope.target.id).then(function(url){
$scope.target.url = angular.fromJson(url);
$scope.target.url = url;
});
}
}
@@ -53,7 +53,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.LinkPickerController",
$scope.target.url = "/";
} else {
contentResource.getNiceUrl(args.node.id).then(function (url) {
$scope.target.url = angular.fromJson(url);
$scope.target.url = url;
});
}
} else {
@@ -22,8 +22,8 @@
<umb-tree
section="content"
showheader="true"
showoptions="false"
hideheader="false"
hideoptions="true"
eventhandler="dialogTreeEventHandler">
</umb-tree>
</div>
@@ -4,6 +4,8 @@ angular.module("umbraco")
function($scope, mediaResource, umbRequestHelper, entityResource, $log, imageHelper, eventsService, treeService) {
var dialogOptions = $scope.$parent.dialogOptions;
$scope.onlyImages = dialogOptions.onlyImages;
$scope.options = {
url: umbRequestHelper.getApiUrl("mediaApiBaseUrl", "PostAddFile"),
autoUpload: true,
@@ -27,15 +29,19 @@ angular.module("umbraco")
childrenOf: data.parentId //clear the children of the parent
});
$scope.gotoFolder(data.id);
$scope.gotoFolder(data);
});
}
};
$scope.gotoFolder = function(folderId) {
$scope.gotoFolder = function(folder) {
if (folderId > 0) {
entityResource.getAncestors(folderId, "media")
if(!folder){
folder = {id: -1, name: "Media", icon: "icon-folder"};
}
if (folder.id > 0) {
entityResource.getAncestors(folder.id, "media")
.then(function(anc) {
// anc.splice(0,1);
$scope.path = anc;
@@ -44,25 +50,33 @@ angular.module("umbraco")
else {
$scope.path = [];
}
//mediaResource.rootMedia()
mediaResource.getChildren(folderId)
mediaResource.getChildren(folder.id)
.then(function(data) {
$scope.images = [];
$scope.searchTerm = "";
$scope.images = data.items;
//update the thumbnail property
_.each($scope.images, function(img) {
img.thumbnail = imageHelper.getThumbnail({ imageModel: img, scope: $scope });
});
//reject all images that have an empty thumbnail - this can occur if there's an image item
// that doesn't have an uploaded image.
$scope.images = _.reject($scope.images, function(item) {
return item.contentTypeAlias.toLowerCase() !== "folder" && item.thumbnail === "";
});
if($scope.onlyImages){
$scope.images = _.reject($scope.images, function(item) {
return item.contentTypeAlias.toLowerCase() !== "folder" && item.thumbnail === "";
});
}
});
$scope.options.formData.currentFolder = folderId;
$scope.options.formData.currentFolder = folder.id;
$scope.currentFolder = folder;
};
@@ -70,14 +84,11 @@ angular.module("umbraco")
$scope.gotoFolder($scope.options.formData.currentFolder);
});
$scope.clickHandler = function(image, ev) {
if (image.contentTypeAlias.toLowerCase() == 'folder') {
$scope.options.formData.currentFolder = image.id;
$scope.gotoFolder(image.id);
}
else if (image.contentTypeAlias.toLowerCase() == 'image') {
$scope.clickHandler = function(image, ev, select) {
if (image.contentTypeAlias.toLowerCase() == 'folder' && !select) {
$scope.gotoFolder(image);
}else{
eventsService.publish("Umbraco.Dialogs.MediaPickerController.Select", image);
if (dialogOptions && dialogOptions.multiPicker) {
@@ -92,13 +103,19 @@ angular.module("umbraco")
ev.preventDefault();
};
$scope.selectFolder= function(folder) {
if (dialogOptions && dialogOptions.multiPicker) {
$scope.select(folder);
}
else {
$scope.submit(folder);
}
};
$scope.selectMediaItem = function(image) {
if (image.contentTypeAlias.toLowerCase() == 'folder') {
$scope.options.formData.currentFolder = image.id;
$scope.gotoFolder(image.id);
}
else if (image.contentTypeAlias.toLowerCase() == 'image') {
$scope.gotoFolder(image);
}else{
eventsService.publish("Umbraco.Dialogs.MediaPickerController.Select", image);
if (dialogOptions && dialogOptions.multiPicker) {
@@ -110,5 +127,6 @@ angular.module("umbraco")
}
};
$scope.gotoFolder(-1);
//default root item
$scope.gotoFolder();
});
@@ -1,7 +1,7 @@
<form ng-controller="Umbraco.Dialogs.MediaPickerController" id="fileupload" method="POST" enctype="multipart/form-data"
data-file-upload="options" data-file-upload-progress="" data-ng-class="{'fileupload-processing': processing() || loadingFiles}">
<div class="umb-panel">
<div class="umb-panel umb-dialogs-mediapicker">
<div class="umb-panel-header">
<div class="umb-el-wrap umb-panel-buttons">
@@ -26,10 +26,10 @@ data-file-upload="options" data-file-upload-progress="" data-ng-class="{'fileupl
<div class="row">
<ul class="breadcrumb span12">
<li><a href ng-click="gotoFolder(-1)" prevent-default>Media</a> / </li>
<li><a href ng-click="gotoFolder()" prevent-default>Media</a> / </li>
<li ng-repeat="item in path">
<a href ng-click="gotoFolder(item.id)" prevent-default>{{item.name}}</a> /
<a href ng-click="gotoFolder(item)" prevent-default>{{item.name}}</a> /
</li>
<li>
@@ -48,7 +48,7 @@ data-file-upload="options" data-file-upload-progress="" data-ng-class="{'fileupl
</div>
</div>
<div class="umb-panel-body umb-scrollable" auto-scale="70">
<div class="umb-panel-body with-footer">
<div style="height: 10px; margin: 10px 0px 10px 0px" class="umb-loader"
ng-hide="active() == 0"></div>
@@ -57,9 +57,8 @@ data-file-upload="options" data-file-upload-progress="" data-ng-class="{'fileupl
min-width="220"
on-click="clickHandler"
ng-model="images"
filter-by="searchTerm"
/>
</div>
filter-by="searchTerm"/>
</div>
<div class="umb-panel-footer" >
<div class="umb-el-wrap umb-panel-buttons">
@@ -7,8 +7,8 @@
<umb-tree
section="member"
treealias="memberGroup"
showheader="false"
showoptions="false"
hideheader="true"
hideoptions="true"
isdialog="true"
eventhandler="dialogTreeEventHandler">
</umb-tree>
@@ -39,8 +39,8 @@
<umb-tree
section="member"
treealias="member"
showheader="false"
showoptions="false"
hideheader="true"
hideoptions="true"
isdialog="true"
eventhandler="dialogTreeEventHandler">
</umb-tree>
@@ -7,13 +7,12 @@ angular.module("umbraco").controller("Umbraco.Dialogs.TreePickerController",
$scope.section = dialogOptions.section;
$scope.treeAlias = dialogOptions.treeAlias;
$scope.multiPicker = dialogOptions.multiPicker;
$scope.startNodeId = dialogOptions.startNodeId;
$scope.hideHeader = dialogOptions.startNodeId ? true : false;
$scope.startNodeId = dialogOptions.startNodeId ? dialogOptions.startNodeId : -1;
//create the custom query string param for this tree
$scope.customTreeParams = "startNodeId=" + dialogOptions.startNodeId;
if (dialogOptions.customTreeParams) {
$scope.customTreeParams += "&" + dialogOptions.customTreeParams;
}
$scope.customTreeParams = dialogOptions.startNodeId ? "startNodeId=" + dialogOptions.startNodeId : "";
$scope.customTreeParams += dialogOptions.customTreeParams ? "&" + dialogOptions.customTreeParams : "";
//search defaults
$scope.searcher = searchService.searchContent;
@@ -37,8 +37,8 @@
<umb-tree
section="{{section}}"
treealias="{{treeAlias}}"
showheader="true"
showoptions="false"
hideheader="{{hideHeader}}"
hideoptions="true"
isdialog="true"
customtreeparams="{{customTreeParams}}"
eventhandler="dialogTreeEventHandler">
@@ -21,8 +21,8 @@
<div ng-hide="success">
<umb-tree
section="content"
showheader="true"
showoptions="false"
hideheader="false"
hideoptions="true"
isdialog="true"
eventhandler="dialogTreeEventHandler">
</umb-tree>
@@ -21,8 +21,8 @@
<div ng-hide="success">
<umb-tree
section="content"
showheader="true"
showoptions="false"
hideheader="false"
hideoptions="true"
isdialog="true"
eventhandler="dialogTreeEventHandler">
</umb-tree>
@@ -46,7 +46,7 @@ function DataTypeEditController($scope, $routeParams, $location, appState, navig
if ($routeParams.create) {
//we are creating so get an empty data type item
dataTypeResource.getScaffold($routeParams.id)
dataTypeResource.getScaffold()
.then(function(data) {
$scope.loaded = true;
$scope.preValuesLoaded = true;
@@ -44,7 +44,6 @@
<div>{{content.selectedEditor}}</div>
</umb-property>
<hr />
<umb-property
property="preValue"
@@ -1,28 +1,30 @@
<div class="umb-photo-folder">
<div class="picrow" ng-repeat="row in rows">
<a
href="#media/media/edit/{{img.id}}"
ng-click="clickHandler(img, $event)"
ng-switch="img.thumbnail"
ng-repeat="img in row.photos"
style="margin: 0px; padding: 0px; border: none; display: inline-block"
ng-class="img.cssclass"
title="{{img.name}}">
<div ng-style="img.style" class="umb-non-thumbnail" ng-switch-when="none">
<i class="icon large icon-folder"></i>
{{img.name}}
</div>
<img class="umb-photo"
ng-switch-default
ng-src="{{img.thumbnail}}"
ng-style="img.style"
alt="{{img.name}}"/>
</a>
<div class="pic" ng-class="img.cssclass" style="margin: 0px; padding: 0px; border: none; display: inline-block; overflow: hidden" ng-style="img.style" ng-repeat="img in row.photos">
<a
href="#media/media/edit/{{img.id}}"
ng-click="clickHandler(img, $event, false)"
ng-switch="img.thumbnail"
title="{{img.name}}">
<div ng-style="img.style" class="umb-non-thumbnail" ng-switch-when="none">
<i class="icon large {{img.icon}}"></i>
{{img.name}}
</div>
<img class="umb-photo"
ng-switch-default
ng-src="{{img.thumbnail}}"
ng-style="img.style"
alt="{{img.name}}"/>
</a>
<a href ng-click="clickHandler(img, $event, true)" ng-show="img.contentTypeAlias === 'Folder'" class="selector-overlay">
Select
</a>
<div>
</div>
</div>
</div>
@@ -21,8 +21,8 @@
<div ng-hide="success">
<umb-tree
section="media"
showheader="true"
showoptions="false"
hideheader="false"
hideoptions="true"
eventhandler="dialogTreeEventHandler">
</umb-tree>
</div>
@@ -16,10 +16,9 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
mediaResource.getByIds($scope.ids).then(function (medias) {
//img.media = media;
_.each(medias, function (media, i) {
var img = {};
img.src = imageHelper.getImagePropertyValue({ imageModel: media });
img.thumbnail = imageHelper.getThumbnailFromPath(img.src);
$scope.images.push(img);
media.src = imageHelper.getImagePropertyValue({ imageModel: media });
media.thumbnail = imageHelper.getThumbnailFromPath(media.src);
$scope.images.push(media);
});
});
}
@@ -44,13 +43,11 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl
}
_.each(data, function(media, i) {
var img = {};
img.id = media.id;
img.src = imageHelper.getImagePropertyValue({ imageModel: media });
img.thumbnail = imageHelper.getThumbnailFromPath(img.src);
media.src = imageHelper.getImagePropertyValue({ imageModel: media });
media.thumbnail = imageHelper.getThumbnailFromPath(media.src);
$scope.images.push(img);
$scope.ids.push(img.id);
$scope.images.push(media);
$scope.ids.push(media.id);
});
$scope.sync();
@@ -2,14 +2,20 @@
<ul ui-sortable="sortableOptions" ng-model="images" class="umb-sortable-thumbnails">
<li style="width: 120px; height: 100px; overflow: hidden;" ng-repeat="image in images">
<img ng-src="{{image.src}}" alt="">
<img ng-src="{{image.thumbnail}}" alt="" ng-show="image.src">
<span class="icon-holder" ng-hide="image.src">
<i class="icon {{image.icon}} large" ></i>
<small>{{image.name}}</small>
</span>
<a href class="picked-image" ng-click="remove($index)"><i class="icon icon-delete"></i></a>
</li>
</ul>
<ul class="umb-sortable-thumbnails" ng-if="showAdd()">
<li>
<li style="border: none">
<a href="#" class="add-link" ng-click="add()" prevent-default>
<i class="icon icon-add large"></i>
</a>
@@ -1,6 +1,6 @@
angular.module("umbraco")
.controller("Umbraco.PropertyEditors.RTEController",
function ($rootScope, $element, $scope, dialogService, $log, imageHelper, assetsService, $timeout, tinyMceService, angularHelper, stylesheetResource) {
function ($rootScope, $element, $scope, $q, dialogService, $log, imageHelper, assetsService, $timeout, tinyMceService, angularHelper, stylesheetResource) {
tinyMceService.configuration().then(function(tinyMceConfig){
@@ -27,11 +27,16 @@ angular.module("umbraco")
var toolbar = editorConfig.toolbar.join(" | ");
var stylesheets = [];
var styleFormats = [];
var await = [];
//queue file loading
await.push(assetsService.loadJs("lib/tinymce/tinymce.min.js", $scope));
//queue rules loading
angular.forEach(editorConfig.stylesheets, function(val, key){
stylesheets.push("/css/" + val + ".css");
stylesheets.push("/css/" + val + ".css?" + new Date().getTime());
stylesheetResource.getRulesByName(val).then(function(rules) {
await.push(stylesheetResource.getRulesByName(val).then(function(rules) {
angular.forEach(rules, function(rule) {
var r = {};
r.title = rule.name;
@@ -49,11 +54,12 @@ angular.module("umbraco")
styleFormats.push(r);
});
});
}));
});
assetsService.loadJs("lib/tinymce/tinymce.min.js", $scope).then(function () {
//wait for queue to end
$q.all(await).then(function () {
/** Loads in the editor */
function loadTinyMce() {
@@ -126,7 +132,7 @@ angular.module("umbraco")
tinyMceService.createInsertMacro(editor, $scope);
}
});
}, 1);
}, 500);
}
loadTinyMce();
@@ -39,7 +39,7 @@ module.exports = function(karma) {
'src/common/mocks/**/*.js',
'src/views/**/*.controller.js',
'test/unit/**/*.spec.js',
{pattern: 'lib/umbraco/namespacemanager.js', watched: true, served: true}
{pattern: 'lib/**/*.js', watched: true, served: true, included: false}
],
// list of files to exclude
@@ -65,7 +65,7 @@ module.exports = function(karma) {
// level of logging
// possible values: karma.LOG_DISABLE || karma.LOG_ERROR || karma.LOG_WARN || karma.LOG_INFO || karma.LOG_DEBUG
// CLI --log-level debug
logLevel: karma.LOG_DEBUG,
logLevel: karma.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
// CLI --auto-watch --no-auto-watch
+9 -3
View File
@@ -656,8 +656,10 @@
<None Include="Config\404handlers.Release.config">
<DependentUpon>404handlers.config</DependentUpon>
</None>
<Content Include="Config\appSettings.config" />
<None Include="Config\appSettings.Release.config">
<SubType>Designer</SubType>
<DependentUpon>appSettings.config</DependentUpon>
</None>
<None Include="Config\ClientDependency.Release.config">
<DependentUpon>ClientDependency.config</DependentUpon>
@@ -669,7 +671,10 @@
<None Include="Config\BaseRestExtensions.Release.config">
<DependentUpon>BaseRestExtensions.config</DependentUpon>
</None>
<None Include="Config\connectionStrings.Release.config" />
<Content Include="Config\connectionStrings.config" />
<None Include="Config\connectionStrings.Release.config">
<DependentUpon>connectionStrings.config</DependentUpon>
</None>
<None Include="Config\log4net.Release.config">
<DependentUpon>log4net.config</DependentUpon>
</None>
@@ -713,7 +718,9 @@
<DependentUpon>Dashboard.config</DependentUpon>
<SubType>Designer</SubType>
</None>
<Content Include="MacroScripts\Web.config" />
<Content Include="MacroScripts\Web.config">
<SubType>Designer</SubType>
</Content>
<None Include="packages.config">
<SubType>Designer</SubType>
</None>
@@ -2193,7 +2200,6 @@
<Content Include="Web.config">
<SubType>Designer</SubType>
</Content>
<Content Include="Views\Web.config.transform" />
<None Include="Web.Debug.config.transformed" />
<None Include="web.Template.Debug.config">
<DependentUpon>Web.Template.config</DependentUpon>
+5 -5
View File
@@ -7,7 +7,7 @@
<section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
</sectionGroup>
</configSections>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
@@ -16,10 +16,10 @@
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="Umbraco.Web" />
<add namespace="Umbraco.Core" />
<add namespace="Umbraco.Core.Models" />
<add namespace="Umbraco.Web.Mvc" />
<add namespace="Umbraco.Web" />
<add namespace="Umbraco.Core" />
<add namespace="Umbraco.Core.Models" />
<add namespace="Umbraco.Web.Mvc" />
<add namespace="Microsoft.Web.Helpers" />
<add namespace="umbraco" />
<add namespace="Examine" />
@@ -1,55 +0,0 @@
<?xml version="1.0"?>
<configuration>
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="Umbraco.Web" />
<add namespace="Umbraco.Core" />
<add namespace="Umbraco.Core.Models" />
<add namespace="Umbraco.Web.Mvc" />
</namespaces>
</pages>
</system.web.webPages.razor>
<appSettings>
<add key="webpages:Enabled" value="false" />
</appSettings>
<system.web>
<httpHandlers>
<add path="*" verb="*" type="System.Web.HttpNotFoundHandler"/>
</httpHandlers>
<!--
Enabling request validation in view pages would cause validation to occur
after the input has already been processed by the controller. By default
MVC performs request validation before a controller processes the input.
To change this behavior apply the ValidateInputAttribute to a
controller or action.
-->
<pages
validateRequest="false"
pageParserFilterType="System.Web.Mvc.ViewTypeParserFilter, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
pageBaseType="System.Web.Mvc.ViewPage, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"
userControlBaseType="System.Web.Mvc.ViewUserControl, System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<controls>
<add assembly="System.Web.Mvc, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" namespace="System.Web.Mvc" tagPrefix="mvc" />
</controls>
</pages>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<handlers>
<remove name="BlockViewHandler"/>
<add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
</handlers>
</system.webServer>
</configuration>
@@ -38,21 +38,20 @@ namespace Umbraco.Web.UI.Install.Steps
get { return DatabaseType.SelectedValue != ""; }
}
/// <summary>
/// Returns whether the selected database is an embedded database.
/// </summary>
protected bool HasEmbeddedDatabaseFiles
protected bool IsNewInstall
{
get
{
// check if sql ce is present
if (
!File.Exists(IOHelper.MapPath(Path.Combine(IOHelper.ResolveUrl(SystemDirectories.Bin), "System.Data.SqlServerCe.dll"))) ||
!File.Exists(IOHelper.MapPath(Path.Combine(IOHelper.ResolveUrl(SystemDirectories.Bin), "SQLCE4Umbraco.dll")))
)
return false;
else
var databaseSettings = ConfigurationManager.ConnectionStrings[GlobalSettings.UmbracoConnectionName];
if (databaseSettings != null && (
databaseSettings.ConnectionString.Trim() == string.Empty
&& databaseSettings.ProviderName.Trim() == string.Empty
&& GlobalSettings.ConfigurationStatus == string.Empty))
{
return true;
}
return false;
}
}
@@ -167,8 +166,7 @@ namespace Umbraco.Web.UI.Install.Steps
toggleVisible(DatabasePasswordItem, !ManualConnectionString && !IsEmbeddedDatabase);
toggleVisible(DatabaseNameItem, !ManualConnectionString && !IsEmbeddedDatabase);
if (IsEmbeddedDatabase)
if (IsNewInstall || IsEmbeddedDatabase)
dbinit.Text = "$('#databaseOptionEmbedded').click();$('#databaseOptionEmbedded').change();";
else if (ManualConnectionString)
dbinit.Text = "$('#databaseOptionAdvanced').click();$('#databaseOptionAdvanced').change();";
+7 -14
View File
@@ -26,13 +26,13 @@
<ul>
<li>
<input type="radio" id="databaseOptionBlank" name="database" value="blank" />
<label for="databaseOptionBlank">I already have a blank SQL Server, SQL Azure or MySQL database</label>
<input type="radio" id="databaseOptionEmbedded" name="database" value="embedded" />
<label for="databaseOptionEmbedded">I want to use SQL CE 4, a free, quick-and-simple embedded database</label>
</li>
<li>
<input type="radio" id="databaseOptionEmbedded" name="database" value="embedded" />
<label for="databaseOptionEmbedded">I want to use SQL CE 4, a free, quick-and-simple embedded database</label>
<input type="radio" id="databaseOptionBlank" name="database" value="blank" />
<label for="databaseOptionBlank">I already have a blank SQL Server, SQL Azure or MySQL database</label>
</li>
<li>
@@ -253,7 +253,6 @@
</div>
</div>
<script type="text/javascript">
var hasEmbeddedDlls = <%= HasEmbeddedDatabaseFiles.ToString().ToLower() %>;
var currentVersion = '<%=UmbracoVersion.Current.ToString(3)%> <%=UmbracoVersion.CurrentComment%> ';
var configured = <%= IsConfigured.ToString().ToLower() %>;
@@ -278,15 +277,9 @@
$(".database-option").hide();
$("#database-embedded").show();
if (!hasEmbeddedDlls) {
$('.embeddedError').show();
$(".installbtn").hide();
}
else {
$('.embedded').show();
$(".installbtn").show();
}
$('.embedded').show();
$(".installbtn").show();
break;
case "advanced":
$(".database-option").hide();
@@ -71,6 +71,7 @@
<area alias="buttons">
<key alias="select">Select</key>
<key alias="selectCurrentFolder">Select current folder</key>
<key alias="somethingElse">Do something else</key>
<key alias="bold">Bold</key>
@@ -167,6 +167,7 @@ namespace Umbraco.Web.Editors
"umbracoSettings", new Dictionary<string, object>
{
{"umbracoPath", GlobalSettings.Path},
{"mediaPath", IOHelper.ResolveUrl(SystemDirectories.Media).TrimEnd('/')},
{"appPluginsPath", IOHelper.ResolveUrl(SystemDirectories.AppPlugins).TrimEnd('/')},
{
"imageFileTypes",
@@ -526,7 +526,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
//loop through remaining values that haven't been applied
foreach (var i in valueDictionary.Where(x => !_keysAdded.Contains(x.Key)))
{
IPublishedProperty property;
IPublishedProperty property = null;
// must ignore that one
if (i.Key == "version") continue;
@@ -540,7 +540,9 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
{
// use property type to ensure proper conversion
var propertyType = _contentType.GetPropertyType(i.Key);
property = new XmlPublishedProperty(propertyType, false, i.Value); // false :: never preview a media
if (propertyType != null)
property = new XmlPublishedProperty(propertyType, false, i.Value); // false :: never preview a media
}
_properties.Add(property);
@@ -76,10 +76,14 @@ namespace Umbraco.Web.Trees
if (id == Constants.System.Root.ToInvariantString() && UserStartNode == Constants.System.Root)
{
var nodes = new TreeNodeCollection();
var altStartId = string.Empty;
if(queryStrings.HasKey(TreeQueryStringParameters.StartNodeId))
altStartId = queryStrings.GetValue<string>(TreeQueryStringParameters.StartNodeId);
//check if a request has been made to render from a specific start node
if (queryStrings.HasKey(TreeQueryStringParameters.StartNodeId)
&& queryStrings.GetValue<string>(TreeQueryStringParameters.StartNodeId) != Constants.System.Root.ToString(CultureInfo.InvariantCulture))
if (!string.IsNullOrEmpty(altStartId) && altStartId != "undefined" && altStartId != Constants.System.Root.ToString(CultureInfo.InvariantCulture))
{
id = queryStrings.GetValue<string>(TreeQueryStringParameters.StartNodeId);
@@ -81,11 +81,26 @@ namespace umbraco.cms.presentation.Trees
}
}
FileInfo[] fileInfo = dirInfo.GetFiles(FileSearchPattern);
//this is a hack to enable file system tree to support multiple file extension look-up
//so the pattern both support *.* *.xml and xml,js,vb for lookups
string[] allowedExtensions = new string[0];
bool filterByMultipleExtensions = FileSearchPattern.Contains(",");
FileInfo[] fileInfo;
if (filterByMultipleExtensions){
fileInfo = dirInfo.GetFiles();
allowedExtensions = FileSearchPattern.ToLower().Split(',');
}else
fileInfo = dirInfo.GetFiles(FileSearchPattern);
foreach (FileInfo file in fileInfo)
{
if ((file.Attributes & FileAttributes.Hidden) == 0)
{
if (filterByMultipleExtensions && Array.IndexOf<string>(allowedExtensions, file.Extension.ToLower().Trim('.')) < 0)
continue;
XmlTreeNode xFileNode = XmlTreeNode.Create(this);
xFileNode.NodeID = orgPath + file.Name;
xFileNode.Text = file.Name;
@@ -63,11 +63,13 @@ namespace umbraco
protected override string FileSearchPattern
{
get { return "*.*"; }
get { return UmbracoSettings.ScriptFileTypes; }
}
protected override void OnRenderFolderNode(ref XmlTreeNode xNode)
{
xNode.Menu = new List<IAction>(new IAction[] { ActionDelete.Instance, ContextMenuSeperator.Instance, ActionNew.Instance, ContextMenuSeperator.Instance, ActionRefresh.Instance });
xNode.NodeType = "scriptsFolder";
}
@@ -49,7 +49,7 @@ namespace umbraco.presentation.developer.packages {
iframeGen.Text =
string.Format(
"<iframe id=\"repoFrame\" frameborder=\"1\" style=\"border: none; display: block\" src=\"{0}/repo/?repoGuid={1}{2}&callback={3}:{4}{5}/developer/packages/proxy.htm?/{6}/developer/packages/installer.aspx?repoGuid={7}&version=v45&fullVersion={8}.{9}.{10}&useLegacySchema={11}&dotnetVersion={12}&trustLevel={13}\"></iframe>",
"<iframe id=\"repoFrame\" frameborder=\"1\" style=\"border: none; display: block\" src=\"{0}?repoGuid={1}{2}&callback={3}:{4}{5}/developer/packages/proxy.htm?/{6}/developer/packages/installer.aspx?repoGuid={7}&version=v45&fullVersion={8}.{9}.{10}&useLegacySchema={11}&dotnetVersion={12}&trustLevel={13}\"></iframe>",
url, repoGuid, category, Request.ServerVariables["SERVER_NAME"],
Request.ServerVariables["SERVER_PORT"], IOHelper.ResolveUrl(SystemDirectories.Umbraco),
IOHelper.ResolveUrl(SystemDirectories.Umbraco).Trim('/'), repoGuid,
@@ -7,9 +7,10 @@ namespace umbraco.editorControls.imagecropper
public class DataTypeData : umbraco.cms.businesslogic.datatype.DefaultData
{
public DataTypeData(umbraco.cms.businesslogic.datatype.BaseDataType DataType) : base(DataType) { }
/*
public override XmlNode ToXMl(XmlDocument data)
{
if (Value != null && Value.ToString() != "")
{
var xd = new XmlDocument();
@@ -18,6 +19,6 @@ namespace umbraco.editorControls.imagecropper
}
return base.ToXMl(data);
}
}*/
}
}