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 ";
+ }else{
+ resultStr+="/>";
+ }
+
+ return resultStr;
+ }
+
+ function endTag(jsonObj,elementName) {
+ return ""+ (jsonObj.__prefix!==null? (jsonObj.__prefix+":"):"")+elementName+">";
+ }
+
+ 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("")===0) {
+ xmlDocStr = xmlDocStr.substr( 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