diff --git a/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js new file mode 100644 index 0000000000..6d83c1b907 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/services/iconhelper.service.js @@ -0,0 +1,218 @@ +/** +* @ngdoc service +* @name umbraco.services.iconHelper +* @description A helper service for dealing with icons, mostly dealing with legacy tree icons +**/ +function iconHelper($q, $timeout) { + + var converter = [ + { oldIcon: ".sprNew", newIcon: "add" }, + { oldIcon: ".sprDelete", newIcon: "remove" }, + { oldIcon: ".sprMove", newIcon: "enter" }, + { oldIcon: ".sprCopy", newIcon: "documents" }, + { oldIcon: ".sprSort", newIcon: "navigation-vertical" }, + { oldIcon: ".sprPublish", newIcon: "globe" }, + { oldIcon: ".sprRollback", newIcon: "undo" }, + { oldIcon: ".sprProtect", newIcon: "lock" }, + { oldIcon: ".sprAudit", newIcon: "time" }, + { oldIcon: ".sprNotify", newIcon: "envelope" }, + { oldIcon: ".sprDomain", newIcon: "home" }, + { oldIcon: ".sprPermission", newIcon: "lock" }, + { oldIcon: ".sprRefresh", newIcon: "refresh" }, + { oldIcon: ".sprBinEmpty", newIcon: "trash" }, + { oldIcon: ".sprExportDocumentType", newIcon: "download-alt" }, + { oldIcon: ".sprImportDocumentType", newIcon: "page-up" }, + { oldIcon: ".sprLiveEdit", newIcon: "edit" }, + { oldIcon: ".sprCreateFolder", newIcon: "add" }, + { oldIcon: ".sprPackage2", newIcon: "box" }, + { oldIcon: ".sprLogout", newIcon: "logout" }, + { oldIcon: ".sprSave", newIcon: "save" }, + { oldIcon: ".sprSendToTranslate", newIcon: "envelope-alt" }, + { oldIcon: ".sprToPublish", newIcon: "mail-forward" }, + { oldIcon: ".sprTranslate", newIcon: "comments" }, + { oldIcon: ".sprUpdate", newIcon: "save" }, + + { oldIcon: ".sprTreeSettingDomain", newIcon: "icon-home" }, + { oldIcon: ".sprTreeDoc", newIcon: "icon-document" }, + { oldIcon: ".sprTreeDoc2", newIcon: "icon-diploma-alt" }, + { oldIcon: ".sprTreeDoc3", newIcon: "icon-notepad" }, + { oldIcon: ".sprTreeDoc4", newIcon: "icon-newspaper-alt" }, + { oldIcon: ".sprTreeDoc5", newIcon: "icon-notepad-alt" }, + + { oldIcon: ".sprTreeDocPic", newIcon: "icon-picture" }, + { oldIcon: ".sprTreeFolder", newIcon: "icon-folder" }, + { oldIcon: ".sprTreeFolder_o", newIcon: "icon-folder" }, + { oldIcon: ".sprTreeMediaFile", newIcon: "icon-music" }, + { oldIcon: ".sprTreeMediaMovie", newIcon: "icon-movie" }, + { oldIcon: ".sprTreeMediaPhoto", newIcon: "icon-picture" }, + + { oldIcon: ".sprTreeMember", newIcon: "icon-user" }, + { oldIcon: ".sprTreeMemberGroup", newIcon: "icon-users" }, + { oldIcon: ".sprTreeMemberType", newIcon: "icon-users" }, + + { oldIcon: ".sprTreeNewsletter", newIcon: "icon-file-text-alt" }, + { oldIcon: ".sprTreePackage", newIcon: "icon-box" }, + { oldIcon: ".sprTreeRepository", newIcon: "icon-server-alt" }, + + { oldIcon: ".sprTreeSettingDataType", newIcon: "icon-autofill" }, + + //TODO: + /* + { oldIcon: ".sprTreeSettingAgent", newIcon: "" }, + { oldIcon: ".sprTreeSettingCss", newIcon: "" }, + { oldIcon: ".sprTreeSettingCssItem", newIcon: "" }, + + { oldIcon: ".sprTreeSettingDataTypeChild", newIcon: "" }, + { oldIcon: ".sprTreeSettingDomain", newIcon: "" }, + { oldIcon: ".sprTreeSettingLanguage", newIcon: "" }, + { oldIcon: ".sprTreeSettingScript", newIcon: "" }, + { oldIcon: ".sprTreeSettingTemplate", newIcon: "" }, + { oldIcon: ".sprTreeSettingXml", newIcon: "" }, + { oldIcon: ".sprTreeStatistik", newIcon: "" }, + { oldIcon: ".sprTreeUser", newIcon: "" }, + { oldIcon: ".sprTreeUserGroup", newIcon: "" }, + { oldIcon: ".sprTreeUserType", newIcon: "" }, + */ + + { oldIcon: "folder.png", newIcon: "icon-folder" }, + { oldIcon: "mediaphoto.gif", newIcon: "icon-picture" }, + { oldIcon: "mediafile.gif", newIcon: "icon-document" }, + + { oldIcon: ".sprTreeDeveloperCacheItem", newIcon: "icon-box" }, + { oldIcon: ".sprTreeDeveloperCacheTypes", newIcon: "icon-box" }, + { oldIcon: ".sprTreeDeveloperMacro", newIcon: "icon-cogs" }, + { oldIcon: ".sprTreeDeveloperRegistry", newIcon: "icon-windows" }, + { oldIcon: ".sprTreeDeveloperPython", newIcon: "icon-linux" } + ]; + + var imageConverter = [ + {oldImage: "contour.png", newIcon: "icon-umb-contour"} + ]; + + var collectedIcons; + + return { + + /** Used by the create dialogs for content/media types to format the data so that the thumbnails are styled properly */ + formatContentTypeThumbnails: function (contentTypes) { + for (var i = 0; i < contentTypes.length; i++) { + + if (contentTypes[i].thumbnailIsClass === undefined || contentTypes[i].thumbnailIsClass) { + contentTypes[i].cssClass = this.convertFromLegacyIcon(contentTypes[i].thumbnail); + }else { + contentTypes[i].style = "background-image: url('" + contentTypes[i].thumbnailFilePath + "');height:36px; background-position:4px 0px; background-repeat: no-repeat;background-size: 35px 35px;"; + //we need an 'icon-' class in there for certain styles to work so if it is image based we'll add this + contentTypes[i].cssClass = "custom-file"; + } + } + return contentTypes; + }, + formatContentTypeIcons: function (contentTypes) { + for (var i = 0; i < contentTypes.length; i++) { + contentTypes[i].icon = this.convertFromLegacyIcon(contentTypes[i].icon); + + //couldnt find replacement + if(contentTypes[i].icon.indexOf(".") > 0){ + contentTypes[i].icon = "icon-document-dashed-line"; + } + } + return contentTypes; + }, + /** If the icon is file based (i.e. it has a file path) */ + isFileBasedIcon: function (icon) { + //if it doesn't start with a '.' but contains one then we'll assume it's file based + if (icon.startsWith('..') || (!icon.startsWith('.') && icon.indexOf('.') > 1)) { + return true; + } + return false; + }, + /** If the icon is legacy */ + isLegacyIcon: function (icon) { + if(icon.startsWith('..')){ + return false; + } + + if (icon.startsWith('.')) { + return true; + } + return false; + }, + /** If the tree node has a legacy icon */ + isLegacyTreeNodeIcon: function(treeNode){ + if (treeNode.iconIsClass) { + return this.isLegacyIcon(treeNode.icon); + } + return false; + }, + + /** Return a list of icons, optionally filter them */ + /** It fetches them directly from the active stylesheets in the browser */ + getIcons: function(){ + var deferred = $q.defer(); + $timeout(function(){ + if(collectedIcons){ + deferred.resolve(collectedIcons); + }else{ + collectedIcons = []; + var c = ".icon-"; + + for (var i = document.styleSheets.length - 1; i >= 0; i--) { + var classes = document.styleSheets[i].rules || document.styleSheets[i].cssRules; + + if (classes !== null) { + for(var x=0;x0){ + s = s.substring(0, hasSpace); + } + var hasPseudo = s.indexOf(":"); + if(hasPseudo>0){ + s = s.substring(0, hasPseudo); + } + + if(collectedIcons.indexOf(s) < 0){ + collectedIcons.push(s); + } + } + } + } + } + deferred.resolve(collectedIcons); + } + }, 100); + + return deferred.promise; + }, + + /** Converts the icon from legacy to a new one if an old one is detected */ + convertFromLegacyIcon: function (icon) { + if (this.isLegacyIcon(icon)) { + //its legacy so convert it if we can + var found = _.find(converter, function (item) { + return item.oldIcon.toLowerCase() === icon.toLowerCase(); + }); + return (found ? found.newIcon : icon); + } + return icon; + }, + + convertFromLegacyImage: function (icon) { + var found = _.find(imageConverter, function (item) { + return item.oldImage.toLowerCase() === icon.toLowerCase(); + }); + return (found ? found.newIcon : undefined); + }, + + /** If we detect that the tree node has legacy icons that can be converted, this will convert them */ + convertFromLegacyTreeNodeIcon: function (treeNode) { + if (this.isLegacyTreeNodeIcon(treeNode)) { + return this.convertFromLegacyIcon(treeNode.icon); + } + return treeNode.icon; + } + }; +} +angular.module('umbraco.services').factory('iconHelper', iconHelper); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/services/imagehelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/imagehelper.service.js new file mode 100644 index 0000000000..2e1e496416 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/services/imagehelper.service.js @@ -0,0 +1,183 @@ +/** +* @ngdoc service +* @name umbraco.services.imageHelper +* @description A helper object used for parsing image paths +**/ +function imageHelper(umbRequestHelper) { + return { + /** + * @ngdoc function + * @name umbraco.services.imageHelper#getImagePropertyValue + * @methodOf umbraco.services.imageHelper + * @function + * + * @description + * Returns the actual image path associated with the image property if there is one + * + * @param {object} options Options object + * @param {object} options.imageModel The media object to retrieve the image path from + */ + getImagePropertyValue: function (options) { + if (!options && !options.imageModel) { + throw "The options objet does not contain the required parameters: imageModel"; + } + + + //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 ""; + }, + /** + * @ngdoc function + * @name umbraco.services.imageHelper#getThumbnail + * @methodOf umbraco.services.imageHelper + * @function + * + * @description + * formats the display model used to display the content to the model used to save the content + * + * @param {object} options Options object + * @param {object} options.imageModel The media object to retrieve the image path from + */ + getThumbnail: function (options) { + + if (!options && !options.imageModel) { + throw "The options objet does not contain the required parameters: imageModel"; + } + + var imagePropVal = this.getImagePropertyValue(options); + if (imagePropVal !== "") { + return this.getThumbnailFromPath(imagePropVal); + } + return ""; + }, + + /** + * @ngdoc function + * @name umbraco.services.imageHelper#scaleToMaxSize + * @methodOf umbraco.services.imageHelper + * @function + * + * @description + * Finds the corrct max width and max height, given maximum dimensions and keeping aspect ratios + * + * @param {number} maxSize Maximum width & height + * @param {number} width Current width + * @param {number} height Current height + */ + scaleToMaxSize: function (maxSize, width, height) { + var retval = { width: width, height: height }; + + var maxWidth = maxSize; // Max width for the image + var maxHeight = maxSize; // Max height for the image + var ratio = 0; // Used for aspect ratio + + // Check if the current width is larger than the max + if (width > maxWidth) { + ratio = maxWidth / width; // get ratio for scaling image + + retval.width = maxWidth; + retval.height = height * ratio; + + height = height * ratio; // Reset height to match scaled image + width = width * ratio; // Reset width to match scaled image + } + + // Check if current height is larger than max + if (height > maxHeight) { + ratio = maxHeight / height; // get ratio for scaling image + + retval.height = maxHeight; + retval.width = width * ratio; + width = width * ratio; // Reset width to match scaled image + } + + return retval; + }, + + /** + * @ngdoc function + * @name umbraco.services.imageHelper#getThumbnailFromPath + * @methodOf umbraco.services.imageHelper + * @function + * + * @description + * Returns the path to the thumbnail version of a given media library image path + * + * @param {string} imagePath Image path, ex: /media/1234/my-image.jpg + */ + getThumbnailFromPath: function (imagePath) { + + //get the proxy url for big thumbnails (this ensures one is always generated) + var thumbnailUrl = umbRequestHelper.getApiUrl( + "imagesApiBaseUrl", + "GetBigThumbnail", + [{ originalImagePath: imagePath }]); + + //var ext = imagePath.substr(imagePath.lastIndexOf('.')); + //return imagePath.substr(0, imagePath.lastIndexOf('.')) + "_big-thumb" + ".jpg"; + + return thumbnailUrl; + }, + + /** + * @ngdoc function + * @name umbraco.services.imageHelper#detectIfImageByExtension + * @methodOf umbraco.services.imageHelper + * @function + * + * @description + * Returns true/false, indicating if the given path has an allowed image extension + * + * @param {string} imagePath Image path, ex: /media/1234/my-image.jpg + */ + detectIfImageByExtension: function (imagePath) { + var lowered = imagePath.toLowerCase(); + var ext = lowered.substr(lowered.lastIndexOf(".") + 1); + return ("," + Umbraco.Sys.ServerVariables.umbracoSettings.imageFileTypes + ",").indexOf("," + ext + ",") !== -1; + } + }; +} +angular.module('umbraco.services').factory('imageHelper', imageHelper); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/services/util.service.js b/src/Umbraco.Web.UI.Client/src/common/services/util.service.js index 9cfc5e831a..5abc1116d6 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/util.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/util.service.js @@ -94,15 +94,16 @@ function umbPhotoFolderHelper($compile, $log, $timeout, $filter, imageHelper, um // which means we'll need to remove one from the row so we can scale up to fill the row if (attemptedRowHeight < minDisplayHeight) { - if (idealImages.length > 2) { + if (idealImages.length > 1) { //we'll generate a new targetHeight that is halfway between the max and the current and recurse, passing in a new targetHeight targetHeight += Math.floor((maxRowHeight - targetHeight) / 2); return this.getRowHeightForImages(imgs, maxRowHeight, minDisplayHeight, maxRowWidth, idealImgPerRow - 1, margin, targetHeight); } - else { - //well this shouldn't happen and we don't want to end up with a row of only one so we're just gonna have to return the - //newHeight which will not actually scale to the row correctly - return { height: minDisplayHeight, imgCount: idealImages.length }; + else { + //this will occur when we only have one image remaining in the row but it's still going to be too wide even when + // using the minimum display height specified. In this case we're going to have to just crop the image in it's center + // using the minimum display height and the full row width + return { height: minDisplayHeight, imgCount: 1 }; } } else { @@ -118,13 +119,18 @@ function umbPhotoFolderHelper($compile, $log, $timeout, $filter, imageHelper, um //we have no more remaining images to fill the space, so we'll just use the calc height return { height: targetHeight, imgCount: idealImages.length }; } - if (idealImages.length === idealImgPerRow && targetHeight < maxRowHeight) { + else if (idealImages.length === 1) { + //this will occur when we only have one image remaining in the row to process but it's not really going to fit ideally + // in the row so we'll just return the minDisplayHeight and it will just get centered on the row + return { height: minDisplayHeight, imgCount: 1 }; + } + else if (idealImages.length === idealImgPerRow && targetHeight < maxRowHeight) { //if we're already dealing with the ideal images per row and it's not quite there, we can scale up a little bit so // long as the targetHeight is currently less than the maxRowHeight. The scale up will be half-way between our current - // target height and the maxRowHeight - - targetHeight += Math.floor((maxRowHeight - targetHeight) / 2); - while (targetHeight < maxRowHeight) { + // target height and the maxRowHeight (we won't loop forever though - if there's a difference of 5 px we'll just quit) + + while (targetHeight < maxRowHeight && (maxRowHeight - targetHeight) > 5) { + targetHeight += Math.floor((maxRowHeight - targetHeight) / 2); attemptedRowHeight = this.performGetRowHeight(idealImages, targetRowWidth, minDisplayHeight, targetHeight); if (attemptedRowHeight != null) { //success! @@ -175,6 +181,19 @@ function umbPhotoFolderHelper($compile, $log, $timeout, $filter, imageHelper, um for (var i = 0; i < imgs.length; i++) { //get the lower width to ensure it always fits var scaledWidth = Math.floor(this.getScaledWidth(imgs[i], imageRowHeight.height)); + + //in this case, a single image will not fit into the row so we need to crop/center + // width the full width and the min display height + if (imgs.length > 1 && imageRowHeight.imgCount === 1) { + sizes.push({ + width: targetWidth, + //ensure that the height is rounded + height: Math.round(minDisplayHeight) + }); + row.images.push(imgs[i]); + break; + } + if (currRowWidth + scaledWidth <= targetWidth) { currRowWidth += scaledWidth; sizes.push({ @@ -183,7 +202,7 @@ function umbPhotoFolderHelper($compile, $log, $timeout, $filter, imageHelper, um height: Math.round(imageRowHeight.height) }); row.images.push(imgs[i]); - } + } else { //the max width has been reached break; @@ -409,181 +428,6 @@ function umbPropEditorHelper() { } angular.module('umbraco.services').factory('umbPropEditorHelper', umbPropEditorHelper); -/** -* @ngdoc service -* @name umbraco.services.imageHelper -* @description A helper object used for parsing image paths -**/ -function imageHelper() { - return { - /** - * @ngdoc function - * @name umbraco.services.imageHelper#getImagePropertyValue - * @methodOf umbraco.services.imageHelper - * @function - * - * @description - * Returns the actual image path associated with the image property if there is one - * - * @param {object} options Options object - * @param {object} options.imageModel The media object to retrieve the image path from - */ - getImagePropertyValue: function(options) { - if (!options && !options.imageModel) { - throw "The options objet does not contain the required parameters: imageModel"; - } - - - //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 ""; - }, - /** - * @ngdoc function - * @name umbraco.services.imageHelper#getThumbnail - * @methodOf umbraco.services.imageHelper - * @function - * - * @description - * formats the display model used to display the content to the model used to save the content - * - * @param {object} options Options object - * @param {object} options.imageModel The media object to retrieve the image path from - */ - getThumbnail: function (options) { - - if (!options && !options.imageModel) { - throw "The options objet does not contain the required parameters: imageModel"; - } - - var imagePropVal = this.getImagePropertyValue(options); - if (imagePropVal !== "") { - return this.getThumbnailFromPath(imagePropVal); - } - return ""; - }, - - /** - * @ngdoc function - * @name umbraco.services.imageHelper#scaleToMaxSize - * @methodOf umbraco.services.imageHelper - * @function - * - * @description - * Finds the corrct max width and max height, given maximum dimensions and keeping aspect ratios - * - * @param {number} maxSize Maximum width & height - * @param {number} width Current width - * @param {number} height Current height - */ - scaleToMaxSize: function(maxSize, width, height){ - var retval = {width: width, height: height}; - - var maxWidth = maxSize; // Max width for the image - var maxHeight = maxSize; // Max height for the image - var ratio = 0; // Used for aspect ratio - - // Check if the current width is larger than the max - if(width > maxWidth){ - ratio = maxWidth / width; // get ratio for scaling image - - retval.width = maxWidth; - retval.height = height * ratio; - - height = height * ratio; // Reset height to match scaled image - width = width * ratio; // Reset width to match scaled image - } - - // Check if current height is larger than max - if(height > maxHeight){ - ratio = maxHeight / height; // get ratio for scaling image - - retval.height = maxHeight; - retval.width = width * ratio; - width = width * ratio; // Reset width to match scaled image - } - - return retval; - }, - - /** - * @ngdoc function - * @name umbraco.services.imageHelper#getThumbnailFromPath - * @methodOf umbraco.services.imageHelper - * @function - * - * @description - * Returns the path to the thumbnail version of a given media library image path - * - * @param {string} imagePath Image path, ex: /media/1234/my-image.jpg - */ - getThumbnailFromPath: function(imagePath) { - var ext = imagePath.substr(imagePath.lastIndexOf('.')); - return imagePath.substr(0, imagePath.lastIndexOf('.')) + "_big-thumb" + ".jpg"; - }, - - /** - * @ngdoc function - * @name umbraco.services.imageHelper#detectIfImageByExtension - * @methodOf umbraco.services.imageHelper - * @function - * - * @description - * Returns true/false, indicating if the given path has an allowed image extension - * - * @param {string} imagePath Image path, ex: /media/1234/my-image.jpg - */ - detectIfImageByExtension: function(imagePath) { - var lowered = imagePath.toLowerCase(); - var ext = lowered.substr(lowered.lastIndexOf(".") + 1); - return ("," + Umbraco.Sys.ServerVariables.umbracoSettings.imageFileTypes + ",").indexOf("," + ext + ",") !== -1; - } - }; -} -angular.module('umbraco.services').factory('imageHelper', imageHelper); /** * @ngdoc service @@ -743,606 +587,4 @@ function umbDataFormatter() { } angular.module('umbraco.services').factory('umbDataFormatter', umbDataFormatter); -/** -* @ngdoc service -* @name umbraco.services.iconHelper -* @description A helper service for dealing with icons, mostly dealing with legacy tree icons -**/ -function iconHelper($q, $timeout) { - var converter = [ - { oldIcon: ".sprNew", newIcon: "add" }, - { oldIcon: ".sprDelete", newIcon: "remove" }, - { oldIcon: ".sprMove", newIcon: "enter" }, - { oldIcon: ".sprCopy", newIcon: "documents" }, - { oldIcon: ".sprSort", newIcon: "navigation-vertical" }, - { oldIcon: ".sprPublish", newIcon: "globe" }, - { oldIcon: ".sprRollback", newIcon: "undo" }, - { oldIcon: ".sprProtect", newIcon: "lock" }, - { oldIcon: ".sprAudit", newIcon: "time" }, - { oldIcon: ".sprNotify", newIcon: "envelope" }, - { oldIcon: ".sprDomain", newIcon: "home" }, - { oldIcon: ".sprPermission", newIcon: "lock" }, - { oldIcon: ".sprRefresh", newIcon: "refresh" }, - { oldIcon: ".sprBinEmpty", newIcon: "trash" }, - { oldIcon: ".sprExportDocumentType", newIcon: "download-alt" }, - { oldIcon: ".sprImportDocumentType", newIcon: "page-up" }, - { oldIcon: ".sprLiveEdit", newIcon: "edit" }, - { oldIcon: ".sprCreateFolder", newIcon: "add" }, - { oldIcon: ".sprPackage2", newIcon: "box" }, - { oldIcon: ".sprLogout", newIcon: "logout" }, - { oldIcon: ".sprSave", newIcon: "save" }, - { oldIcon: ".sprSendToTranslate", newIcon: "envelope-alt" }, - { oldIcon: ".sprToPublish", newIcon: "mail-forward" }, - { oldIcon: ".sprTranslate", newIcon: "comments" }, - { oldIcon: ".sprUpdate", newIcon: "save" }, - - { oldIcon: ".sprTreeSettingDomain", newIcon: "icon-home" }, - { oldIcon: ".sprTreeDoc", newIcon: "icon-document" }, - { oldIcon: ".sprTreeDoc2", newIcon: "icon-diploma-alt" }, - { oldIcon: ".sprTreeDoc3", newIcon: "icon-notepad" }, - { oldIcon: ".sprTreeDoc4", newIcon: "icon-newspaper-alt" }, - { oldIcon: ".sprTreeDoc5", newIcon: "icon-notepad-alt" }, - - { oldIcon: ".sprTreeDocPic", newIcon: "icon-picture" }, - { oldIcon: ".sprTreeFolder", newIcon: "icon-folder" }, - { oldIcon: ".sprTreeFolder_o", newIcon: "icon-folder" }, - { oldIcon: ".sprTreeMediaFile", newIcon: "icon-music" }, - { oldIcon: ".sprTreeMediaMovie", newIcon: "icon-movie" }, - { oldIcon: ".sprTreeMediaPhoto", newIcon: "icon-picture" }, - - { oldIcon: ".sprTreeMember", newIcon: "icon-user" }, - { oldIcon: ".sprTreeMemberGroup", newIcon: "icon-users" }, - { oldIcon: ".sprTreeMemberType", newIcon: "icon-users" }, - - { oldIcon: ".sprTreeNewsletter", newIcon: "icon-file-text-alt" }, - { oldIcon: ".sprTreePackage", newIcon: "icon-box" }, - { oldIcon: ".sprTreeRepository", newIcon: "icon-server-alt" }, - - { oldIcon: ".sprTreeSettingDataType", newIcon: "icon-autofill" }, - - //TODO: - /* - { oldIcon: ".sprTreeSettingAgent", newIcon: "" }, - { oldIcon: ".sprTreeSettingCss", newIcon: "" }, - { oldIcon: ".sprTreeSettingCssItem", newIcon: "" }, - - { oldIcon: ".sprTreeSettingDataTypeChild", newIcon: "" }, - { oldIcon: ".sprTreeSettingDomain", newIcon: "" }, - { oldIcon: ".sprTreeSettingLanguage", newIcon: "" }, - { oldIcon: ".sprTreeSettingScript", newIcon: "" }, - { oldIcon: ".sprTreeSettingTemplate", newIcon: "" }, - { oldIcon: ".sprTreeSettingXml", newIcon: "" }, - { oldIcon: ".sprTreeStatistik", newIcon: "" }, - { oldIcon: ".sprTreeUser", newIcon: "" }, - { oldIcon: ".sprTreeUserGroup", newIcon: "" }, - { oldIcon: ".sprTreeUserType", newIcon: "" }, - */ - - { oldIcon: "folder.png", newIcon: "icon-folder" }, - { oldIcon: "mediaphoto.gif", newIcon: "icon-picture" }, - { oldIcon: "mediafile.gif", newIcon: "icon-document" }, - - { oldIcon: ".sprTreeDeveloperCacheItem", newIcon: "icon-box" }, - { oldIcon: ".sprTreeDeveloperCacheTypes", newIcon: "icon-box" }, - { oldIcon: ".sprTreeDeveloperMacro", newIcon: "icon-cogs" }, - { oldIcon: ".sprTreeDeveloperRegistry", newIcon: "icon-windows" }, - { oldIcon: ".sprTreeDeveloperPython", newIcon: "icon-linux" } - ]; - - var imageConverter = [ - {oldImage: "contour.png", newIcon: "icon-umb-contour"} - ]; - - var collectedIcons; - - return { - - /** Used by the create dialogs for content/media types to format the data so that the thumbnails are styled properly */ - formatContentTypeThumbnails: function (contentTypes) { - for (var i = 0; i < contentTypes.length; i++) { - - if (contentTypes[i].thumbnailIsClass === undefined || contentTypes[i].thumbnailIsClass) { - contentTypes[i].cssClass = this.convertFromLegacyIcon(contentTypes[i].thumbnail); - }else { - contentTypes[i].style = "background-image: url('" + contentTypes[i].thumbnailFilePath + "');height:36px; background-position:4px 0px; background-repeat: no-repeat;background-size: 35px 35px;"; - //we need an 'icon-' class in there for certain styles to work so if it is image based we'll add this - contentTypes[i].cssClass = "custom-file"; - } - } - return contentTypes; - }, - formatContentTypeIcons: function (contentTypes) { - for (var i = 0; i < contentTypes.length; i++) { - contentTypes[i].icon = this.convertFromLegacyIcon(contentTypes[i].icon); - - //couldnt find replacement - if(contentTypes[i].icon.indexOf(".") > 0){ - contentTypes[i].icon = "icon-document-dashed-line"; - } - } - return contentTypes; - }, - /** If the icon is file based (i.e. it has a file path) */ - isFileBasedIcon: function (icon) { - //if it doesn't start with a '.' but contains one then we'll assume it's file based - if (icon.startsWith('..') || (!icon.startsWith('.') && icon.indexOf('.') > 1)) { - return true; - } - return false; - }, - /** If the icon is legacy */ - isLegacyIcon: function (icon) { - if(icon.startsWith('..')){ - return false; - } - - if (icon.startsWith('.')) { - return true; - } - return false; - }, - /** If the tree node has a legacy icon */ - isLegacyTreeNodeIcon: function(treeNode){ - if (treeNode.iconIsClass) { - return this.isLegacyIcon(treeNode.icon); - } - return false; - }, - - /** Return a list of icons, optionally filter them */ - /** It fetches them directly from the active stylesheets in the browser */ - getIcons: function(){ - var deferred = $q.defer(); - $timeout(function(){ - if(collectedIcons){ - deferred.resolve(collectedIcons); - }else{ - collectedIcons = []; - var c = ".icon-"; - - for (var i = document.styleSheets.length - 1; i >= 0; i--) { - var classes = document.styleSheets[i].rules || document.styleSheets[i].cssRules; - - if (classes !== null) { - for(var x=0;x0){ - s = s.substring(0, hasSpace); - } - var hasPseudo = s.indexOf(":"); - if(hasPseudo>0){ - s = s.substring(0, hasPseudo); - } - - if(collectedIcons.indexOf(s) < 0){ - collectedIcons.push(s); - } - } - } - } - } - deferred.resolve(collectedIcons); - } - }, 100); - - return deferred.promise; - }, - - /** Converts the icon from legacy to a new one if an old one is detected */ - convertFromLegacyIcon: function (icon) { - if (this.isLegacyIcon(icon)) { - //its legacy so convert it if we can - var found = _.find(converter, function (item) { - return item.oldIcon.toLowerCase() === icon.toLowerCase(); - }); - return (found ? found.newIcon : icon); - } - return icon; - }, - - convertFromLegacyImage: function (icon) { - var found = _.find(imageConverter, function (item) { - return item.oldImage.toLowerCase() === icon.toLowerCase(); - }); - return (found ? found.newIcon : undefined); - }, - - /** If we detect that the tree node has legacy icons that can be converted, this will convert them */ - convertFromLegacyTreeNodeIcon: function (treeNode) { - if (this.isLegacyTreeNodeIcon(treeNode)) { - return this.convertFromLegacyIcon(treeNode.icon); - } - return treeNode.icon; - } - }; -} -angular.module('umbraco.services').factory('iconHelper', iconHelper); - - - - -/** - * @ngdoc service - * @name umbraco.services.xmlhelper - * @function - * - * @description - * Used to convert legacy xml data to json and back again - */ -function xmlhelper($http) { - /* - Copyright 2011 Abdulla Abdurakhmanov - Original sources are available at https://code.google.com/p/x2js/ - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - - function X2JS() { - var VERSION = "1.0.11"; - var escapeMode = false; - - var DOMNodeTypes = { - ELEMENT_NODE : 1, - TEXT_NODE : 3, - CDATA_SECTION_NODE : 4, - DOCUMENT_NODE : 9 - }; - - function getNodeLocalName( node ) { - var nodeLocalName = node.localName; - if(nodeLocalName == null){ - nodeLocalName = node.baseName; - } // Yeah, this is IE!! - - if(nodeLocalName === null || nodeLocalName===""){ - nodeLocalName = node.nodeName; - } // =="" is IE too - - return nodeLocalName; - } - - function getNodePrefix(node) { - return node.prefix; - } - - function escapeXmlChars(str) { - if(typeof(str) === "string"){ - return str.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g, '/'); - }else{ - return str; - } - } - - function unescapeXmlChars(str) { - return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, "'").replace(///g, '\/'); - } - - function parseDOMChildren( node ) { - var result,child, childName; - - if(node.nodeType === DOMNodeTypes.DOCUMENT_NODE) { - result = {}; - child = node.firstChild; - childName = getNodeLocalName(child); - result[childName] = parseDOMChildren(child); - return result; - } - else{ - - if(node.nodeType === DOMNodeTypes.ELEMENT_NODE) { - result = {}; - result.__cnt=0; - var nodeChildren = node.childNodes; - - // Children nodes - for(var cidx=0; cidx "; - } - - function endsWith(str, suffix) { - return str.indexOf(suffix, str.length - suffix.length) !== -1; - } - - function jsonXmlSpecialElem ( jsonObj, jsonObjField ) { - if(endsWith(jsonObjField.toString(),("_asArray")) || jsonObjField.toString().indexOf("_")===0 || (jsonObj[jsonObjField] instanceof Function) ){ - return true; - }else{ - return false; - } - } - - function jsonXmlElemCount ( jsonObj ) { - var elementsCnt = 0; - if(jsonObj instanceof Object ) { - for( var it in jsonObj ) { - if(jsonXmlSpecialElem ( jsonObj, it) ){ - continue; - } - elementsCnt++; - } - } - return elementsCnt; - } - - function parseJSONAttributes ( jsonObj ) { - var attrList = []; - if(jsonObj instanceof Object ) { - for( var ait in jsonObj ) { - if(ait.toString().indexOf("__")=== -1 && ait.toString().indexOf("_")===0) { - attrList.push(ait); - } - } - } - - return attrList; - } - - function parseJSONTextAttrs ( jsonTxtObj ) { - var result =""; - - if(jsonTxtObj.__cdata!=null) { - result+=""; - } - - if(jsonTxtObj.__text!=null) { - if(escapeMode){ - result+=escapeXmlChars(jsonTxtObj.__text); - }else{ - result+=jsonTxtObj.__text; - } - } - return result; - } - - function parseJSONTextObject ( jsonTxtObj ) { - var result =""; - - if( jsonTxtObj instanceof Object ) { - result+=parseJSONTextAttrs ( jsonTxtObj ); - } - else{ - if(jsonTxtObj!=null) { - if(escapeMode){ - result+=escapeXmlChars(jsonTxtObj); - }else{ - result+=jsonTxtObj; - } - } - } - - - return result; - } - - function parseJSONArray ( jsonArrRoot, jsonArrObj, attrList ) { - var result = ""; - if(jsonArrRoot.length === 0) { - result+=startTag(jsonArrRoot, jsonArrObj, attrList, true); - } - else { - for(var arIdx = 0; arIdx < jsonArrRoot.length; arIdx++) { - result+=startTag(jsonArrRoot[arIdx], jsonArrObj, parseJSONAttributes(jsonArrRoot[arIdx]), false); - result+=parseJSONObject(jsonArrRoot[arIdx]); - result+=endTag(jsonArrRoot[arIdx],jsonArrObj); - } - } - return result; - } - - function parseJSONObject ( jsonObj ) { - var result = ""; - - var elementsCnt = jsonXmlElemCount ( jsonObj ); - - if(elementsCnt > 0) { - for( var it in jsonObj ) { - if(jsonXmlSpecialElem ( jsonObj, it) ){ - continue; - } - - var subObj = jsonObj[it]; - var attrList = parseJSONAttributes( subObj ); - - if(subObj === null || subObj === undefined) { - result+=startTag(subObj, it, attrList, true); - }else{ - if(subObj instanceof Object) { - - if(subObj instanceof Array) { - result+=parseJSONArray( subObj, it, attrList ); - }else { - var subObjElementsCnt = jsonXmlElemCount ( subObj ); - if(subObjElementsCnt > 0 || subObj.__text!==null || subObj.__cdata!==null) { - result+=startTag(subObj, it, attrList, false); - result+=parseJSONObject(subObj); - result+=endTag(subObj,it); - }else{ - result+=startTag(subObj, it, attrList, true); - } - } - - }else { - result+=startTag(subObj, it, attrList, false); - result+=parseJSONTextObject(subObj); - result+=endTag(subObj,it); - } - } - } - } - result+=parseJSONTextObject(jsonObj); - - return result; - } - - this.parseXmlString = function(xmlDocStr) { - var xmlDoc; - if (window.DOMParser) { - var parser=new window.DOMParser(); - xmlDoc = parser.parseFromString( xmlDocStr, "text/xml" ); - } - else { - // IE :( - if(xmlDocStr.indexOf("") + 2 ); - } - xmlDoc=new ActiveXObject("Microsoft.XMLDOM"); - xmlDoc.async="false"; - xmlDoc.loadXML(xmlDocStr); - } - return xmlDoc; - }; - - this.xml2json = function (xmlDoc) { - return parseDOMChildren ( xmlDoc ); - }; - - this.xml_str2json = function (xmlDocStr) { - var xmlDoc = this.parseXmlString(xmlDocStr); - return this.xml2json(xmlDoc); - }; - - this.json2xml_str = function (jsonObj) { - return parseJSONObject ( jsonObj ); - }; - - this.json2xml = function (jsonObj) { - var xmlDocStr = this.json2xml_str (jsonObj); - return this.parseXmlString(xmlDocStr); - }; - - this.getVersion = function () { - return VERSION; - }; - - this.escapeMode = function(enabled) { - escapeMode = enabled; - }; - } - - var x2js = new X2JS(); - return { - /** Called to load in the legacy tree js which is required on startup if a user is logged in or - after login, but cannot be called until they are authenticated which is why it needs to be lazy loaded. */ - toJson: function(xml) { - var json = x2js.xml_str2json( xml ); - return json; - }, - fromJson: function(json) { - var xml = x2js.json2xml_str( json ); - return xml; - }, - parseFeed: function (url) { - return $http.jsonp('//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=50&callback=JSON_CALLBACK&q=' + encodeURIComponent(url)); - } - }; -} -angular.module('umbraco.services').factory('xmlhelper', xmlhelper); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/xmlhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/xmlhelper.service.js new file mode 100644 index 0000000000..03f1f6cbbe --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/services/xmlhelper.service.js @@ -0,0 +1,381 @@ +/** + * @ngdoc service + * @name umbraco.services.xmlhelper + * @function + * + * @description + * Used to convert legacy xml data to json and back again + */ +function xmlhelper($http) { + /* + Copyright 2011 Abdulla Abdurakhmanov + Original sources are available at https://code.google.com/p/x2js/ + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + + function X2JS() { + var VERSION = "1.0.11"; + var escapeMode = false; + + var DOMNodeTypes = { + ELEMENT_NODE: 1, + TEXT_NODE: 3, + CDATA_SECTION_NODE: 4, + DOCUMENT_NODE: 9 + }; + + function getNodeLocalName(node) { + var nodeLocalName = node.localName; + if (nodeLocalName == null) { + nodeLocalName = node.baseName; + } // Yeah, this is IE!! + + if (nodeLocalName === null || nodeLocalName === "") { + nodeLocalName = node.nodeName; + } // =="" is IE too + + return nodeLocalName; + } + + function getNodePrefix(node) { + return node.prefix; + } + + function escapeXmlChars(str) { + if (typeof (str) === "string") { + return str.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''').replace(/\//g, '/'); + } else { + return str; + } + } + + function unescapeXmlChars(str) { + return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, "'").replace(///g, '\/'); + } + + function parseDOMChildren(node) { + var result, child, childName; + + if (node.nodeType === DOMNodeTypes.DOCUMENT_NODE) { + result = {}; + child = node.firstChild; + childName = getNodeLocalName(child); + result[childName] = parseDOMChildren(child); + return result; + } + else { + + if (node.nodeType === DOMNodeTypes.ELEMENT_NODE) { + result = {}; + result.__cnt = 0; + var nodeChildren = node.childNodes; + + // Children nodes + for (var cidx = 0; cidx < nodeChildren.length; cidx++) { + child = nodeChildren.item(cidx); // nodeChildren[cidx]; + childName = getNodeLocalName(child); + + result.__cnt++; + if (result[childName] === null) { + result[childName] = parseDOMChildren(child); + result[childName + "_asArray"] = new Array(1); + result[childName + "_asArray"][0] = result[childName]; + } + else { + if (result[childName] !== null) { + if (!(result[childName] instanceof Array)) { + var tmpObj = result[childName]; + result[childName] = []; + result[childName][0] = tmpObj; + + result[childName + "_asArray"] = result[childName]; + } + } + var aridx = 0; + while (result[childName][aridx] !== null) { + aridx++; + } + + (result[childName])[aridx] = parseDOMChildren(child); + } + } + + // Attributes + for (var aidx = 0; aidx < node.attributes.length; aidx++) { + var attr = node.attributes.item(aidx); // [aidx]; + result.__cnt++; + result["_" + attr.name] = attr.value; + } + + // Node namespace prefix + var nodePrefix = getNodePrefix(node); + if (nodePrefix !== null && nodePrefix !== "") { + result.__cnt++; + result.__prefix = nodePrefix; + } + + if (result.__cnt === 1 && result["#text"] !== null) { + result = result["#text"]; + } + + if (result["#text"] !== null) { + result.__text = result["#text"]; + if (escapeMode) { + result.__text = unescapeXmlChars(result.__text); + } + + delete result["#text"]; + delete result["#text_asArray"]; + } + if (result["#cdata-section"] != null) { + result.__cdata = result["#cdata-section"]; + delete result["#cdata-section"]; + delete result["#cdata-section_asArray"]; + } + + if (result.__text != null || result.__cdata != null) { + result.toString = function () { + return (this.__text != null ? this.__text : '') + (this.__cdata != null ? this.__cdata : ''); + }; + } + return result; + } + else { + if (node.nodeType === DOMNodeTypes.TEXT_NODE || node.nodeType === DOMNodeTypes.CDATA_SECTION_NODE) { + return node.nodeValue; + } + } + } + } + + function startTag(jsonObj, element, attrList, closed) { + var resultStr = "<" + ((jsonObj != null && jsonObj.__prefix != null) ? (jsonObj.__prefix + ":") : "") + element; + if (attrList != null) { + for (var aidx = 0; aidx < attrList.length; aidx++) { + var attrName = attrList[aidx]; + var attrVal = jsonObj[attrName]; + resultStr += " " + attrName.substr(1) + "='" + attrVal + "'"; + } + } + if (!closed) { + resultStr += ">"; + } else { + resultStr += "/>"; + } + + return resultStr; + } + + function endTag(jsonObj, elementName) { + return ""; + } + + function endsWith(str, suffix) { + return str.indexOf(suffix, str.length - suffix.length) !== -1; + } + + function jsonXmlSpecialElem(jsonObj, jsonObjField) { + if (endsWith(jsonObjField.toString(), ("_asArray")) || jsonObjField.toString().indexOf("_") === 0 || (jsonObj[jsonObjField] instanceof Function)) { + return true; + } else { + return false; + } + } + + function jsonXmlElemCount(jsonObj) { + var elementsCnt = 0; + if (jsonObj instanceof Object) { + for (var it in jsonObj) { + if (jsonXmlSpecialElem(jsonObj, it)) { + continue; + } + elementsCnt++; + } + } + return elementsCnt; + } + + function parseJSONAttributes(jsonObj) { + var attrList = []; + if (jsonObj instanceof Object) { + for (var ait in jsonObj) { + if (ait.toString().indexOf("__") === -1 && ait.toString().indexOf("_") === 0) { + attrList.push(ait); + } + } + } + + return attrList; + } + + function parseJSONTextAttrs(jsonTxtObj) { + var result = ""; + + if (jsonTxtObj.__cdata != null) { + result += ""; + } + + if (jsonTxtObj.__text != null) { + if (escapeMode) { + result += escapeXmlChars(jsonTxtObj.__text); + } else { + result += jsonTxtObj.__text; + } + } + return result; + } + + function parseJSONTextObject(jsonTxtObj) { + var result = ""; + + if (jsonTxtObj instanceof Object) { + result += parseJSONTextAttrs(jsonTxtObj); + } + else { + if (jsonTxtObj != null) { + if (escapeMode) { + result += escapeXmlChars(jsonTxtObj); + } else { + result += jsonTxtObj; + } + } + } + + + return result; + } + + function parseJSONArray(jsonArrRoot, jsonArrObj, attrList) { + var result = ""; + if (jsonArrRoot.length === 0) { + result += startTag(jsonArrRoot, jsonArrObj, attrList, true); + } + else { + for (var arIdx = 0; arIdx < jsonArrRoot.length; arIdx++) { + result += startTag(jsonArrRoot[arIdx], jsonArrObj, parseJSONAttributes(jsonArrRoot[arIdx]), false); + result += parseJSONObject(jsonArrRoot[arIdx]); + result += endTag(jsonArrRoot[arIdx], jsonArrObj); + } + } + return result; + } + + function parseJSONObject(jsonObj) { + var result = ""; + + var elementsCnt = jsonXmlElemCount(jsonObj); + + if (elementsCnt > 0) { + for (var it in jsonObj) { + if (jsonXmlSpecialElem(jsonObj, it)) { + continue; + } + + var subObj = jsonObj[it]; + var attrList = parseJSONAttributes(subObj); + + if (subObj === null || subObj === undefined) { + result += startTag(subObj, it, attrList, true); + } else { + if (subObj instanceof Object) { + + if (subObj instanceof Array) { + result += parseJSONArray(subObj, it, attrList); + } else { + var subObjElementsCnt = jsonXmlElemCount(subObj); + if (subObjElementsCnt > 0 || subObj.__text !== null || subObj.__cdata !== null) { + result += startTag(subObj, it, attrList, false); + result += parseJSONObject(subObj); + result += endTag(subObj, it); + } else { + result += startTag(subObj, it, attrList, true); + } + } + + } else { + result += startTag(subObj, it, attrList, false); + result += parseJSONTextObject(subObj); + result += endTag(subObj, it); + } + } + } + } + result += parseJSONTextObject(jsonObj); + + return result; + } + + this.parseXmlString = function (xmlDocStr) { + var xmlDoc; + if (window.DOMParser) { + var parser = new window.DOMParser(); + xmlDoc = parser.parseFromString(xmlDocStr, "text/xml"); + } + else { + // IE :( + if (xmlDocStr.indexOf("") + 2); + } + xmlDoc = new ActiveXObject("Microsoft.XMLDOM"); + xmlDoc.async = "false"; + xmlDoc.loadXML(xmlDocStr); + } + return xmlDoc; + }; + + this.xml2json = function (xmlDoc) { + return parseDOMChildren(xmlDoc); + }; + + this.xml_str2json = function (xmlDocStr) { + var xmlDoc = this.parseXmlString(xmlDocStr); + return this.xml2json(xmlDoc); + }; + + this.json2xml_str = function (jsonObj) { + return parseJSONObject(jsonObj); + }; + + this.json2xml = function (jsonObj) { + var xmlDocStr = this.json2xml_str(jsonObj); + return this.parseXmlString(xmlDocStr); + }; + + this.getVersion = function () { + return VERSION; + }; + + this.escapeMode = function (enabled) { + escapeMode = enabled; + }; + } + + var x2js = new X2JS(); + return { + /** Called to load in the legacy tree js which is required on startup if a user is logged in or + after login, but cannot be called until they are authenticated which is why it needs to be lazy loaded. */ + toJson: function (xml) { + var json = x2js.xml_str2json(xml); + return json; + }, + fromJson: function (json) { + var xml = x2js.json2xml_str(json); + return xml; + }, + parseFeed: function (url) { + return $http.jsonp('//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=50&callback=JSON_CALLBACK&q=' + encodeURIComponent(url)); + } + }; +} +angular.module('umbraco.services').factory('xmlhelper', xmlhelper); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.html index 01b42b2752..7b6307ec2f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/mediapicker.html @@ -53,8 +53,10 @@ data-file-upload="options" data-file-upload-progress="" data-ng-class="{'fileupl ng-hide="active() == 0"> diff --git a/src/Umbraco.Web.UI.Client/test/unit/common/services/umb-image-helper.spec.js b/src/Umbraco.Web.UI.Client/test/unit/common/services/umb-image-helper.spec.js index 886ebbd0c9..c457638483 100644 --- a/src/Umbraco.Web.UI.Client/test/unit/common/services/umb-image-helper.spec.js +++ b/src/Umbraco.Web.UI.Client/test/unit/common/services/umb-image-helper.spec.js @@ -23,16 +23,5 @@ describe('image helper tests', function () { expect(umbImageHelper.detectIfImageByExtension(doc1)).toBe(false); }); - it('gets a thumbnail path', function () { - - var image1 = "a-jpeg.jpg"; - var image2 = "a-png.png"; - var image3 = "thisisagif.blah.gif"; - - expect(umbImageHelper.getThumbnailFromPath(image1)).toBe("a-jpeg_big-thumb.jpg"); - expect(umbImageHelper.getThumbnailFromPath(image2)).toBe("a-png_big-thumb.jpg"); - expect(umbImageHelper.getThumbnailFromPath(image3)).toBe("thisisagif.blah_big-thumb.jpg"); - }); - }); }); \ No newline at end of file