diff --git a/src/Umbraco.Web.UI.Client/.jshintignore b/src/Umbraco.Web.UI.Client/.jshintignore new file mode 100644 index 0000000000..97620d1820 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/.jshintignore @@ -0,0 +1 @@ +src/common/services/util.service.js \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/gruntFile.js b/src/Umbraco.Web.UI.Client/gruntFile.js index 73661c158a..384c02f92e 100644 --- a/src/Umbraco.Web.UI.Client/gruntFile.js +++ b/src/Umbraco.Web.UI.Client/gruntFile.js @@ -303,6 +303,7 @@ module.exports = function (grunt) { smarttabs: true, globalstrict:true, globals:{$:false, jQuery:false,define:false,require:false,window:false} + } } } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/umbtreeitem.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/umbtreeitem.directive.js index 68d26dd316..337de3d15a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/umbtreeitem.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/umbtreeitem.directive.js @@ -34,8 +34,8 @@ angular.module("umbraco.directives") '' + '' + '' + - '{{node.name}}' + - '' + + '{{node.name}}' + + '' + '
' + '' + '', diff --git a/src/Umbraco.Web.UI.Client/src/common/services/events.service.js b/src/Umbraco.Web.UI.Client/src/common/services/events.service.js new file mode 100644 index 0000000000..23bc61da32 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/services/events.service.js @@ -0,0 +1,48 @@ +/* pubsub - based on https://github.com/phiggins42/bloody-jquery-plugins/blob/master/pubsub.js*/ +function eventsService($q) { + var cache = {}; + + return { + publish: function(){ + + var args = [].splice.call(arguments,0); + var topic = args[0]; + var deferred = $q.defer(); + args.splice(0,1); + + if(cache[topic]){ + $.each(cache[topic], function() { + this.apply(null, args || []); + }); + deferred.resolve.apply(null, args); + }else{ + deferred.resolve.apply(null, args); + } + + return deferred.promise; + }, + + subscribe: function(topic, callback) { + if(!cache[topic]) { + cache[topic] = []; + } + cache[topic].push(callback); + return [topic, callback]; + }, + + unsubscribe: function(handle) { + var t = handle[0]; + + if(cache[t]){ + $.each(cache[t], function(idx){ + if(this === handle[1]){ + cache[t].splice(idx, 1); + } + }); + } + } + + }; +} + +angular.module('umbraco.services').factory('eventsService', eventsService); \ 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 e5393069c9..00c12af11b 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 @@ -20,6 +20,7 @@ function legacyJsLoader(assetsService, umbRequestHelper) { } angular.module('umbraco.services').factory('legacyJsLoader', legacyJsLoader); + /** * @ngdoc service * @name umbraco.services.angularHelper @@ -461,4 +462,386 @@ function iconHelper() { } }; } -angular.module('umbraco.services').factory('iconHelper', iconHelper); \ No newline at end of file +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() { + /* + 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; + } + }; +} +angular.module('umbraco.services').factory('xmlhelper', xmlhelper); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/index.html b/src/Umbraco.Web.UI.Client/src/index.html index e2f69746f6..eab3f8163c 100644 --- a/src/Umbraco.Web.UI.Client/src/index.html +++ b/src/Umbraco.Web.UI.Client/src/index.html @@ -11,15 +11,12 @@
- -
-
diff --git a/src/Umbraco.Web.UI.Client/src/packages/property editors/relatedlinks/relatedlinks.html b/src/Umbraco.Web.UI.Client/src/packages/property editors/relatedlinks/relatedlinks.html index e69de29bb2..87180e4324 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property editors/relatedlinks/relatedlinks.html +++ b/src/Umbraco.Web.UI.Client/src/packages/property editors/relatedlinks/relatedlinks.html @@ -0,0 +1 @@ +{{model | json}} \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/packages/property editors/relatedlinks/relatedlinks.js b/src/Umbraco.Web.UI.Client/src/packages/property editors/relatedlinks/relatedlinks.js index e69de29bb2..c8a6f62e5e 100644 --- a/src/Umbraco.Web.UI.Client/src/packages/property editors/relatedlinks/relatedlinks.js +++ b/src/Umbraco.Web.UI.Client/src/packages/property editors/relatedlinks/relatedlinks.js @@ -0,0 +1 @@ +alert("bong"); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/contentpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/contentpicker.controller.js index 95f99b87d8..f843d9e370 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/contentpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/contentpicker.controller.js @@ -1,13 +1,15 @@ //used for the media picker dialog angular.module("umbraco").controller("Umbraco.Dialogs.ContentPickerController", - function ($scope) { + function ($scope, eventsService) { $scope.dialogTreeEventHandler = $({}); $scope.dialogTreeEventHandler.bind("treeNodeSelect", function(ev, args){ args.event.preventDefault(); args.event.stopPropagation(); - - $(args.event.target.parentElement).find("i.umb-tree-icon").attr("class", "icon umb-tree-icon sprTree icon-check blue"); - $scope.select(args.node); + + eventsService.publish("Umbraco.Dialogs.ContentPickerController.Select", args, "hello").then(function(args){ + $(args.event.target.parentElement).find("i.umb-tree-icon").attr("class", "icon umb-tree-icon sprTree icon-check blue"); + $scope.select(args.node); + }); }); }); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js index 3dab0da431..c538771e7e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js @@ -66,5 +66,14 @@ function MainController($scope, $routeParams, $rootScope, $timeout, notification }); } + //register it angular.module('umbraco').controller("Umbraco.MainController", MainController); + +/* +angular.module("umbraco").run(function(eventsService){ + eventsService.subscribe("Umbraco.Dialogs.ContentPickerController.Select", function(a, b){ + a.node.name = "wat"; + }); +}); +*/ \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/navigation.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/navigation.controller.js index a883c3291f..b3a873a658 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/navigation.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/navigation.controller.js @@ -49,6 +49,9 @@ function NavigationController($scope,$rootScope, $location, $log, navigationServ //this reacts to tree items themselves being clicked //the tree directive should not contain any handling, simply just bubble events $scope.treeEventHandler.bind("treeNodeSelect", function (ev, args) { + ev.stopPropagation(); + ev.preventDefault(); + var n = args.node; //here we need to check for some legacy tree code