Add WebCms

This commit is contained in:
2016-11-07 12:56:17 -05:00
parent dfe92218f4
commit 15911f33c0
2750 changed files with 365672 additions and 133 deletions
+83
View File
@@ -0,0 +1,83 @@
// Umbraco SpeechBubble Javascript
// Dependency Loader Constructor
function UmbracoSpeechBubble(id) {
this.id = id;
this.ie = document.all ? true : false;
this.GenerateSpeechBubble();
}
UmbracoSpeechBubble.prototype.GenerateSpeechBubble = function() {
theBody = document.getElementsByTagName('BODY')[0];
sbHtml = document.createElement('div');
sbHtml.id = this.id + 'Container';
sbHtml.innerHTML = '' +
'<div id="' + this.id + '" style="z-index: 10; filter: Alpha(Opacity=0); background-image: url(/umbraco/images/speechbubble/speechbubble.gif); visibility: hidden; width: 231px; position: absolute; height: 84px">' +
'<div id="' + this.id + 'Icon" style="left: 10px; position: absolute; top: 16px">' +
'<img src="/umbraco/images/speechBubble/info.gif" alt="Info" width="30" height="30" id="' + this.id + 'IconSrc"></div>' +
' <div id="speechClose" style="left: 208px; position: absolute; top: 6px">' +
' <a href="javascript:UmbSpeechBubble.Hide(100)">' +
' <img src="/umbraco/images/speechbubble/speechBubble_close.gif" width="18" height="18" border="0" alt="Close"' +
' onmouseover="this.src = \'/umbraco/images/speechbubble/speechBubble_close_over.gif\';" onmouseout="this.src=\'images/speechbubble/speechBubble_close.gif\';"></a></div>' +
' <div id="' + this.id + 'Header" style="font-family: Segoe UI; lucida sans; sans serif; font-size: 16px; font-weight: 100; color: #0033aa; left: 50px;' +
' position: absolute; top: 6px">' +
' Data gemt!</div>' +
' <div id="' + this.id + 'Message" style="font-size: 11px; font-weight: normal; color: #000; text-align: left; left: 50px; width: 180px; position: absolute;' +
' top: 28px">' +
' Default Text Container!</div>' +
' </div>';
theBody.appendChild(sbHtml);
}
UmbracoSpeechBubble.prototype.ShowMessage = function(icon, header, message) {
var speechBubble = document.getElementById(this.id);
document.getElementById(this.id + "Header").innerHTML = header;
document.getElementById(this.id + "Message").innerHTML = message;
document.getElementById(this.id + "IconSrc").src = '/umbraco/images/speechBubble/' + icon + '.png';
speechBubble.style.right = "20px";
speechBubble.style.bottom = "20px";
speechBubble.style.visibility = 'visible';
this.Show(0);
}
UmbracoSpeechBubble.prototype.Show = function(opacity) {
document.getElementById(this.id).style.filter = 'Alpha(Opacity=' + opacity + ')';
opacity = parseInt(opacity) + 10;
var _self = this;
if (opacity < 101) {
setTimeout(function() {_self.Show(opacity+10);}, 50);
} else {
setTimeout(function() {_self.Hide(100);}, 5000);
}
}
UmbracoSpeechBubble.prototype.Hide = function(opacity) {
document.getElementById(this.id).style.filter = 'Alpha(Opacity=' + opacity + ')';
var _self = this;
opacity = parseInt(opacity) - 10;
if (opacity > 1)
setTimeout(function() {_self.Hide(opacity-10);}, 50);
else {
document.getElementById(this.id).style.visibility = 'hidden';
}
}
// Initialize
var UmbSpeechBubble = null
function InitUmbracoSpeechBubble() {
if (UmbSpeechBubble == null)
UmbSpeechBubble = new UmbracoSpeechBubble("defaultSpeechbubble");
}
//if (typeof(addEvent) !== 'undefined') {
// addEvent(window, "load", InitUmbracoSpeechBubble);
//}else if (Sys != undefined) {
// Sys.Application.add_load(InitUmbracoSpeechBubble);
//}
@@ -0,0 +1,68 @@
// Umbraco SpeechBubble Javascript
// Dependency Loader Constructor
function UmbracoSpeechBubble(id) {
this.id = id;
this.ie = document.all ? true : false;
this.GenerateSpeechBubble();
}
UmbracoSpeechBubble.prototype.GenerateSpeechBubble = function() {
var sbHtml = document.getElementById(this.id);
sbHtml.innerHTML = '' +
'<div class="speechBubbleTop"></div>' +
'<div class="speechBubbleContent">' +
'<img id="' + this.id + 'Icon" style="float: left; margin: 0px 5px 10px 3px;" />' +
' <img class="speechClose" onClick="UmbSpeechBubble.Hide();" id="' + this.id + 'close" src="/umbraco/images/speechBubble/speechBubble_close.gif" width="18" height="18" border="0" alt="Close"' +
' onmouseover="this.src = \'/umbraco/images/speechBubble/speechBubble_close_over.gif\';" onmouseout="this.src=\'images/speechBubble/speechBubble_close.gif\';">' +
' <div style="float: right; width: 186px; margin-right: 10px;"><h3 id="' + this.id + 'Header">The header!</h3>' +
' <p style="width: 185px" id="' + this.id + 'Message">Default Text Container!<br /></p></div><br style="clear: both" />' +
'</div>' +
'<div class="speechBubbleBottom"></div>'
}
UmbracoSpeechBubble.prototype.ShowMessage = function (icon, header, message, dontAutoHide) {
var speechBubble = jQuery("#" + this.id);
jQuery("#" + this.id + "Header").html(header);
jQuery("#" + this.id + "Message").html(message);
jQuery("#" + this.id + "Icon").attr('src', 'images/speechBubble/' + icon + '.png');
if (!this.ie) {
if (!dontAutoHide) {
jQuery("#" + this.id).fadeIn("slow").animate({ opacity: 1.0 }, 5000).fadeOut("fast");
} else {
jQuery(".speechClose").show();
jQuery("#" + this.id).fadeIn("slow");
}
} else {
// this is special for IE as it handles fades with pngs very ugly
jQuery("#" + this.id).show();
if (!dontAutoHide) {
setTimeout('UmbSpeechBubble.Hide();', 5000);
} else {
jQuery(".speechClose").show();
}
}
}
UmbracoSpeechBubble.prototype.Hide = function () {
if (!this.ie) {
jQuery("#" + this.id).fadeOut("slow");
} else {
jQuery("#" + this.id).hide();
}
}
// Initialize
var UmbSpeechBubble = null
function InitUmbracoSpeechBubble() {
if (UmbSpeechBubble == null)
UmbSpeechBubble = new UmbracoSpeechBubble("defaultSpeechbubble");
}
jQuery(document).ready(function() {
InitUmbracoSpeechBubble();
});
@@ -0,0 +1,3 @@
//used by live editing to ensure the speech bubble is initialized after the main js file has been lazy loaded.
//alert("Speech Bubble init: " + InitUmbracoSpeechBubble);
InitUmbracoSpeechBubble();
+61
View File
@@ -0,0 +1,61 @@
var app = angular.module('umbraco', [
'umbraco.filters',
'umbraco.directives',
'umbraco.resources',
'umbraco.services',
'umbraco.packages',
'umbraco.views',
'ngCookies',
'ngSanitize',
'ngMobile',
'tmh.dynamicLocale',
'ngFileUpload',
'LocalStorageModule'
]);
var packages = angular.module("umbraco.packages", []);
//this ensures we can inject our own views into templateCache and clear
//the entire cache before the app runs, due to the module
//order, clearing will always happen before umbraco.views and umbraco
//module is initilized.
angular.module("umbraco.views", ["umbraco.viewcache"]);
angular.module("umbraco.viewcache", [])
.run(function($rootScope, $templateCache) {
/** For debug mode, always clear template cache to cut down on
dev frustration and chrome cache on templates */
if (Umbraco.Sys.ServerVariables.isDebuggingEnabled) {
$templateCache.removeAll();
}
})
.config([
//This ensures that all of our angular views are cache busted, if the path starts with views/ and ends with .html, then
// we will append the cache busting value to it. This way all upgraded sites will not have to worry about browser cache.
"$provide", function($provide) {
return $provide.decorator("$http", [
"$delegate", function($delegate) {
var get = $delegate.get;
$delegate.get = function (url, config) {
if (Umbraco.Sys.ServerVariables.application && url.startsWith("views/") && url.endsWith(".html")) {
var rnd = Umbraco.Sys.ServerVariables.application.version + "." + Umbraco.Sys.ServerVariables.application.cdf;
var _op = (url.indexOf("?") > 0) ? "&" : "?";
url += _op + "umb__rnd=" + rnd;
}
return get(url, config);
};
return $delegate;
}
]);
}
]);
//Call a document callback if defined, this is sort of a dodgy hack to
// be able to configure angular values in the Default.cshtml
// view which is much easier to do that configuring values by injecting them in the back office controller
// to follow through to the js initialization stuff
if (angular.isFunction(document.angularReady)) {
document.angularReady.apply(this, [app]);
}
+313
View File
@@ -0,0 +1,313 @@
/*********************************************************************************************************/
/* Canvasdesigner setting panel config */
/*********************************************************************************************************/
var canvasdesignerConfig = {
configs: [{
name: "Body",
schema: "body",
selector: "body",
editors: [
{
type: "background",
category: "Color",
name: "Background",
},
{
type: "color",
category: "Font",
name: "Font Color (main)",
css: "color",
schema: "body, h1, h2, h3, h4, h5, h6, h7, #nav li a"
},
{
type: "color",
category: "Font",
name: "Font Color (secondary)",
css: "color",
schema: "ul.meta, .byline"
},
{
type: "googlefontpicker",
category: "Font",
name: "Font Family",
css: "color",
schema: "body, h1, h2, h3, h4, h5, h6, h7, .byline, #nav, .button"
}
]
},
{
name: "Nav",
schema: "#nav",
selector: "nav",
editors: [
{
type: "background",
category: "Color",
name: "Background",
},
{
type: "border",
category: "Color",
name: "Border",
},
{
type: "color",
category: "Nav",
name: "Font Color",
css: "color",
schema: "#nav li a"
},
{
type: "color",
category: "Nav",
name: "Font Color (hover / selected)",
css: "color",
schema: "#nav li:hover a"
},
{
type: "color",
category: "Nav",
name: "Background Color (hover)",
css: "background-color",
schema: "#nav li:hover a"
},
{
type: "color",
category: "Nav",
name: "Background Color (selected)",
css: "background-color",
schema: "#nav li.current_page_item a"
},
{
type: "googlefontpicker",
category: "Font",
name: "Font familly",
}
]
},
{
name: "Logo",
schema: "#header .logo div",
selector: "#header .logo div",
editors: [
{
type: "color",
category: "Color",
name: "Border color",
css: "border-top-color",
schema: "#header .logo"
},
{
type: "padding",
category: "Position",
name: "Margin",
enable: ["top", "bottom"],
schema: "#header"
},
]
},
{
name: "h2",
schema: "h2",
selector: "h2 span",
editors: [
{
type: "color",
category: "Color",
name: "Border color",
css: "border-top-color",
schema: "h2.major"
},
{
type: "color",
category: "Font",
name: "Font color",
css: "color",
}
]
},
{
name: "h3",
schema: "h3",
selector: "h3",
editors: [
{
type: "color",
category: "Font",
name: "Font color",
css: "color",
}
]
},
{
name: "Banner Title",
schema: "#banner h2",
selector: "#banner h2",
editors: [
{
type: "color",
category: "Font",
name: "Font color",
css: "color",
},
{
type: "slider",
category: "Font",
name: "Font size",
css: "font-size",
min: 18,
max: 100
},
{
type: "margin",
category: "Position",
name: "Margin",
}
]
},
{
name: "Banner Sub-title",
schema: "#banner .byline",
selector: "#banner .byline",
editors: [
{
type: "color",
category: "Font",
name: "Font color",
css: "color",
},
{
type: "slider",
category: "Font",
name: "Font size",
css: "font-size",
min: 18,
max: 100
},
{
type: "margin",
category: "Position",
name: "Margin",
}
]
},
{
name: "Banner",
schema: "#banner",
selector: "#banner",
editors: [
{
type: "background",
category: "Color",
name: "Background",
css: "color"
}
]
},
{
name: "Banner-wrapper",
schema: "#banner-wrapper",
selector: "#banner-wrapper",
editors: [
{
type: "background",
category: "Color",
name: "Background",
},
{
type: "padding",
category: "Position",
name: "Padding",
enable: ["top", "bottom"]
}
]
},
{
name: "#main-wrapper",
schema: "#main-wrapper",
selector: "#main-wrapper",
editors: [
{
type: "border",
category: "Styling",
name: "Border",
enable: ["top", "bottom"]
}
]
},
{
name: "Image",
schema: ".image,.image img,.image:before",
selector: ".image",
editors: [
{
type: "radius",
category: "Styling",
name: "Radius"
}
]
},
{
name: "Button",
schema: ".button",
selector: ".button",
editors: [
{
type: "color",
category: "Color",
name: "Color",
css: "color"
},
{
type: "color",
category: "Color",
name: "Background",
css: "background"
},
{
type: "color",
category: "Color",
name: "Background Hover",
css: "background",
schema: ".button:hover"
},
{
type: "radius",
category: "Styling",
name: "Radius"
}
]
},
{
name: "Button Alt",
schema: ".button-alt",
selector: ".button-alt",
editors: [
{
type: "color",
category: "Color",
name: "Color",
css: "color"
},
{
type: "color",
category: "Color",
name: "Background",
css: "background"
},
{
type: "color",
category: "Color",
name: "Background Hover",
css: "background",
schema: ".button-alt:hover"
},
]
}
]
};
+297
View File
@@ -0,0 +1,297 @@
/*********************************************************************************************************/
/* Global function and variable for panel/page com */
/*********************************************************************************************************/
var currentTarget = undefined;
var refreshLayout = function (parameters) {
// hide preview badget
$("#umbracoPreviewBadge").hide();
var string = "less.modifyVars({" + parameters.join(",") + "})";
eval(string);
}
/* Fonts loaded in the Canvasdesigner panel need to be loaded independently in
* the content iframe to allow live previewing.
*/
var webFontScriptLoaded = false;
var getFont = function (font) {
if (!webFontScriptLoaded) {
$.getScript('https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js')
.done(function () {
webFontScriptLoaded = true;
// Recursively call once webfont script is available.
getFont(font);
})
.fail(function () {
console.log('error loading webfont');
});
}
else {
WebFont.load({
google: {
families: [font]
},
loading: function () {
//console.log('loading font' + font + ' in iframe');
},
active: function () {
//console.log('loaded font ' + font + ' in iframe');
},
inactive: function () {
//console.log('error loading font ' + font + ' in iframe');
}
});
}
}
var closeIntelCanvasdesigner = function (canvasdesignerModel) {
if (canvasdesignerModel) {
$.each(canvasdesignerModel.configs, function (indexConfig, config) {
if (config.schema) {
$(config.schema).unbind();
$(config.schema).removeAttr("canvasdesigner-over");
}
});
initBodyClickEvent();
}
}
var initBodyClickEvent = function () {
$("body").on("click", function () {
if (parent.iframeBodyClick) {
parent.iframeBodyClick();
}
});
}
var initIntelCanvasdesigner = function (canvasdesignerModel) {
if (canvasdesignerModel) {
// Add canvasdesigner-over attr for each schema from config
$.each(canvasdesignerModel.configs, function (indexConfig, config) {
var schema = config.selector ? config.selector : config.schema;
if (schema) {
$(schema).attr("canvasdesigner-over", config.schema);
$(schema).attr("canvasdesigner-over-name", config.name);
$(schema).css("cursor", "default");
}
});
// Outline canvasdesigner-over
$(document).mousemove(function (e) {
e.stopPropagation();
var target = $(e.target);
while (target.length > 0 && (target.attr('canvasdesigner-over') == undefined || target.attr('canvasdesigner-over') == '')) {
target = target.parent();
}
if (target.attr('canvasdesigner-over') != undefined && target.attr('canvasdesigner-over') != '') {
target.unbind();
outlinePosition(target);
parent.onMouseoverCanvasdesignerItem(target.attr('canvasdesigner-over-name'), target);
target.click(function (e) {
e.stopPropagation();
e.preventDefault();
//console.info(target.attr('canvasdesigner-over'));
currentTarget = target;
outlineSelected();
parent.onClickCanvasdesignerItem(target.attr('canvasdesigner-over'), target);
return false;
});
}
else {
outlinePositionHide();
}
});
}
}
var refreshOutlinePosition = function(schema) {
outlinePosition($(schema));
}
var outlinePosition = function (oTarget) {
var target = oTarget;
if (target.length > 0 && target.attr('canvasdesigner-over') != undefined && target.attr('canvasdesigner-over') != '') {
var localname = target[0].localName;
var height = $(target).outerHeight();
var width = $(target).outerWidth();
var position = $(target).offset();
var posY = position.top ;
//$(window).scrollTop();
var posX = position.left;
//+ $(window).scrollLeft();
$(".canvasdesigner-overlay").css('display', 'block');
$(".canvasdesigner-overlay").css('left', posX);
$(".canvasdesigner-overlay").css('top', posY);
$(".canvasdesigner-overlay").css('width', width + "px");
$(".canvasdesigner-overlay").css('height', height + "px");
//console.info("element select " + localname);
$(".canvasdesigner-overlay span").html(target.attr('canvasdesigner-over-name'));
}
else {
outlinePositionHide();
//console.info("element not found select");
}
}
var refreshOutlineSelected = function (schema) {
outlineSelected($(schema));
}
var outlineSelected = function (oTarget) {
var target = currentTarget;
if (oTarget) {
currentTarget = oTarget;
target = oTarget;
}
if (target && target.length > 0 && target.attr('canvasdesigner-over') != undefined && target.attr('canvasdesigner-over') != '') {
var localname = target[0].localName;
var height = $(target).outerHeight();
var width = $(target).outerWidth();
var position = $(target).offset();
var posY = position.top;
//$(window).scrollTop();
var posX = position.left;
//+ $(window).scrollLeft();
$(".canvasdesigner-overlay-selected").css('display', 'block');
$(".canvasdesigner-overlay-selected").css('left', posX);
$(".canvasdesigner-overlay-selected").css('top', posY);
$(".canvasdesigner-overlay-selected").css('width', width + "px");
$(".canvasdesigner-overlay-selected").css('height', height + "px");
//console.info("element select " + localname);
$(".canvasdesigner-overlay-selected span").html(target.attr('canvasdesigner-over-name'));
}
else {
outlinePositionHide();
//console.info("element not found select");
}
}
var outlinePositionHide = function () {
$(".canvasdesigner-overlay").css('display', "none");
}
var outlineSelectedHide = function () {
currentTarget = undefined;
$(".canvasdesigner-overlay-selected").css('display', "none");
}
var initCanvasdesignerPanel = function () {
$('link[data-title="canvasdesignerCss"]').attr('disabled', 'disabled');
// First load the canvasdesigner config from file
if (!canvasdesignerConfig) {
console.info("canvasdesigner config not found");
}
// Add canvasdesigner from HTML 5 data tags
$("[data-canvasdesigner]").each(function (index, value) {
var tagName = $(value).data("canvasdesigner") ? $(value).data("canvasdesigner") : $(value)[0].nodeName.toLowerCase();
var tagSchema = $(value).data("schema") ? $(value).data("schema") : $(value)[0].nodeName.toLowerCase();
var tagSelector = $(value).data("selector") ? $(value).data("selector") : tagSchema;
var tagEditors = $(value).data("editors"); //JSON.parse(...);
canvasdesignerConfig.configs.splice(canvasdesignerConfig.configs.length, 0, {
name: tagName,
schema: tagSchema,
selector: tagSelector,
editors: tagEditors
});
});
// For each editor config create a composite alias
$.each(canvasdesignerConfig.configs, function (configIndex, config) {
if (config.editors) {
$.each(config.editors, function (editorIndex, editor) {
var clearSchema = config.schema.replace(/[^a-zA-Z0-9]+/g, '').toLowerCase();
var clearEditor = JSON.stringify(editor).replace(/[^a-zA-Z0-9]+/g, '').toLowerCase();
editor.alias = clearSchema + clearEditor;
});
}
});
// Create or update the less file
$.ajax({
url: "/Umbraco/Api/CanvasDesigner/Init",
type: 'POST',
dataType: "json",
error: function (err) {
alert(err.responseText)
},
data: {
config: JSON.stringify(canvasdesignerConfig),
pageId: pageId
},
success: function (data) {
// Add Less link in head
$("head").append("<link>");
css = $("head").children(":last");
css.attr({
rel: "stylesheet/less",
type: "text/css",
href: data
});
//console.info("Less styles are loaded");
// Init Less.js
$.getScript("/Umbraco/lib/Less/less-1.7.0.min.js", function (data, textStatus, jqxhr) {
// Init panel
if (parent.setFrameIsLoaded) {
parent.setFrameIsLoaded(canvasdesignerConfig, canvasdesignerPalette);
}
});
}
});
}
$(function () {
if (parent.setFrameIsLoaded) {
// Overlay background-color: rgba(28, 203, 255, 0.05);
$("body").append("<div class=\"canvasdesigner-overlay\" style=\"display:none; pointer-events: none; position: absolute; z-index: 9999; border: 1px solid #2ebdff; border-radius: 3px; \"><span style=\"position:absolute;background: #2ebdff; font-family: Helvetica, Arial, sans-serif; color: #fff; padding: 0 5px 0 6px; font-size: 10px; line-height: 17px; display: inline-block; border-radius: 0 0 3px 0;\"></span></div>");
$("body").append("<div class=\"canvasdesigner-overlay-selected\" style=\"display:none; pointer-events: none; position: absolute; z-index: 9998; border: 2px solid #2ebdff; border-radius: 3px;\"><span style=\"position:absolute;background: #2ebdff; font-family: Helvetica, Arial, sans-serif; color: #fff; padding: 0 5px; font-size: 10px; line-height: 16px; display: inline-block; border-radius: 0 0 3px 0;\"></span></div>");
// Set event for any body click
initBodyClickEvent()
// Init canvasdesigner panel
initCanvasdesignerPanel();
}
});
@@ -0,0 +1,20 @@
LazyLoad.js([
'../lib/jquery/jquery.min.js',
'../lib/jquery-ui/jquery-ui.min.js',
'../lib/angular/1.1.5/angular.min.js',
'../lib/underscore/underscore-min.js',
'../lib/umbraco/Extensions.js',
'../js/app.js',
'../js/umbraco.resources.js',
'../js/umbraco.services.js',
'../js/umbraco.security.js',
'../ServerVariables',
'../lib/spectrum/spectrum.js',
'../js/canvasdesigner.panel.js',
], function () {
jQuery(document).ready(function () {
angular.bootstrap(document, ['Umbraco.canvasdesigner']);
});
});
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+48
View File
@@ -0,0 +1,48 @@
function dualSelectBoxShift(id) {
var posVal = document.getElementById(id + "_posVals");
var selVal = document.getElementById(id + "_selVals");
// First check the possible items
for (var i=0;i<posVal.options.length;i++) {
if (posVal.options[i].selected) {
var selNew = document.createElement('option');
selNew.text = posVal[i].text;
selNew.value = posVal[i].value;
try {
selVal.add(selNew, null);
}
catch(ex) {
selVal.add(selNew);
}
posVal.remove(i);
i--;
}
}
// do the same with the selected items, to return them
for (var i=0;i<selVal.options.length;i++) {
if (selVal.options[i].selected) {
var selNew = document.createElement('option');
selNew.text = selVal[i].text;
selNew.value = selVal[i].value;
try {
posVal.add(selNew, null);
}
catch(ex) {
posVal.add(selNew);
}
selVal.remove(i);
i--;
}
}
// update hidden value field with all values
var hiddenVal = "";
for (var i=0;i<selVal.options.length;i++) {
hiddenVal += selVal.options[i].value + ",";
}
if (hiddenVal != "")
hiddenVal = hiddenVal.substring(0, hiddenVal.length-1);
document.getElementById(id + "_theValue").value = hiddenVal;
}
+88
View File
@@ -0,0 +1,88 @@
// ---------------------------------------------
// guiFunctions
// ---------------------------------------------
function toggleTree(sender) {
var tree = jQuery("#leftDIV");
var frame = jQuery("#rightDIV");
var disp = tree.css("display")
var link = jQuery(sender);
if (disp == "none") {
tree.show();
link.removeClass();
resizePage();
}
else {
tree.hide();
link.addClass("on");
var clientWidth = jQuery(window).width();
frame.width(clientWidth - 20);
}
}
function resizePage(sender) {
var dashboard = jQuery("#rightDIV");
var dashboardFrame = jQuery("#right");
var tree = jQuery("#leftDIV");
var treeToggle = jQuery("#treeToggle");
var appIcons = jQuery("#PlaceHolderAppIcons");
var uiArea = jQuery("#uiArea");
if (jQuery(window)) {
var clientHeight = jQuery(window).height() - 48;
var clientWidth = jQuery(window).width();
var leftWidth = parseInt(clientWidth * 0.25);
var rightWidth = parseInt(clientWidth - leftWidth - 30);
// check if appdock is present
var treeHeight = parseInt(clientHeight - 5);
// resize leftdiv
tree.width(leftWidth);
if (appIcons != null) {
treeHeight = treeHeight - 135;
resizeGuiWindow("PlaceHolderAppIcons", leftWidth, 140);
}
resizeGuiWindow("treeWindow", leftWidth, treeHeight)
if (tree.css("display") == "none") {
dashboard.width(clientWidth - 24);
} else {
dashboard.width(rightWidth);
}
if (clientHeight > 0) {
dashboard.height(clientHeight);
treeToggle.height(clientHeight);
}
treeToggle.show();
uiArea.show();
}
}
function resizeGuiWindow(windowName, newWidth, newHeight, window) {
//This no longer does anything and shouldn't be used.
}
function resizeGuiWindowWithTabs(windowName, newWidth, newHeight) {
right.document.all[windowName + "ContainerTable"].width = newWidth + 22
right.document.all[windowName + "ContainerTableSpacer"].width = newWidth
right.document.all[windowName + "Bottom"].width = newWidth + 12
right.document.all[windowName + "BottomSpacer"].width = newWidth
right.document.all[windowName].style.width = newWidth
// Der skal forskellig størrelse på højden afhængig af om vinduet har en label i bunden
if (right.document.all[windowName + 'BottomLabel']) {
right.document.all[windowName + "ContainerTable"].height = newHeight - 13;
right.document.all[windowName].style.height = newHeight - 13;
} else {
right.document.all[windowName + "ContainerTable"].height = newHeight + 3;
right.document.all[windowName].style.height = newHeight + 3;
}
}
+70
View File
@@ -0,0 +1,70 @@
/** Executed when the application starts, binds to events and set global state */
app.run(['userService', '$log', '$rootScope', '$location', 'navigationService', 'appState', 'editorState', 'fileManager', 'assetsService', 'eventsService', '$cookies', '$templateCache',
function (userService, $log, $rootScope, $location, navigationService, appState, editorState, fileManager, assetsService, eventsService, $cookies, $templateCache) {
//This sets the default jquery ajax headers to include our csrf token, we
// need to user the beforeSend method because our token changes per user/login so
// it cannot be static
$.ajaxSetup({
beforeSend: function (xhr) {
xhr.setRequestHeader("X-XSRF-TOKEN", $cookies["XSRF-TOKEN"]);
}
});
/** Listens for authentication and checks if our required assets are loaded, if/once they are we'll broadcast a ready event */
eventsService.on("app.authenticated", function(evt, data) {
assetsService._loadInitAssets().then(function() {
appState.setGlobalState("isReady", true);
//send the ready event with the included returnToPath,returnToSearch data
eventsService.emit("app.ready", data);
returnToPath = null, returnToSearch = null;
});
});
/** execute code on each successful route */
$rootScope.$on('$routeChangeSuccess', function(event, current, previous) {
if(current.params.section){
$rootScope.locationTitle = current.params.section + " - " + $location.$$host;
}
else {
$rootScope.locationTitle = "Umbraco - " + $location.$$host;
}
//reset the editorState on each successful route chage
editorState.reset();
//reset the file manager on each route change, the file collection is only relavent
// when working in an editor and submitting data to the server.
//This ensures that memory remains clear of any files and that the editors don't have to manually clear the files.
fileManager.clearFiles();
});
/** When the route change is rejected - based on checkAuth - we'll prevent the rejected route from executing including
wiring up it's controller, etc... and then redirect to the rejected URL. */
$rootScope.$on('$routeChangeError', function(event, current, previous, rejection) {
event.preventDefault();
var returnPath = null;
if (rejection.path == "/login" || rejection.path.startsWith("/login/")) {
//Set the current path before redirecting so we know where to redirect back to
returnPath = encodeURIComponent($location.url());
}
$location.path(rejection.path)
if (returnPath) {
$location.search("returnPath", returnPath);
}
});
/* this will initialize the navigation service once the application has started */
navigationService.init();
//check for touch device, add to global appState
//var touchDevice = ("ontouchstart" in window || window.touch || window.navigator.msMaxTouchPoints === 5 || window.DocumentTouch && document instanceof DocumentTouch);
var touchDevice = /android|webos|iphone|ipad|ipod|blackberry|iemobile|touch/i.test(navigator.userAgent.toLowerCase());
appState.setGlobalState("touchDevice", touchDevice);
}]);
+17
View File
@@ -0,0 +1,17 @@
LazyLoad.js( [
'lib/jquery/jquery.min.js',
/* 1.1.5 */
'lib/angular/1.1.5/angular.min.js',
'lib/angular/1.1.5/angular-cookies.min.js',
'lib/angular/1.1.5/angular-mobile.min.js',
'lib/angular/1.1.5/angular-mocks.js',
'lib/angular/1.1.5/angular-sanitize.min.js',
'lib/underscore/underscore-min.js',
'js/umbraco.installer.js',
'js/umbraco.directives.js'
], function () {
jQuery(document).ready(function () {
angular.bootstrap(document, ['ngSanitize', 'umbraco.install', 'umbraco.directives.validation']);
});
}
);
+1
View File
@@ -0,0 +1 @@
<%@ Page language="c#" Codebehind="language.aspx.cs" AutoEventWireup="True" Inherits="umbraco.js.language" %>
+173
View File
@@ -0,0 +1,173 @@
app.config(function ($routeProvider) {
/** This checks if the user is authenticated for a route and what the isRequired is set to.
Depending on whether isRequired = true, it first check if the user is authenticated and will resolve successfully
otherwise the route will fail and the $routeChangeError event will execute, in that handler we will redirect to the rejected
path that is resolved from this method and prevent default (prevent the route from executing) */
var canRoute = function(isRequired) {
return {
/** Checks that the user is authenticated, then ensures that are requires assets are loaded */
isAuthenticatedAndReady: function ($q, userService, $route, assetsService, appState) {
var deferred = $q.defer();
//don't need to check if we've redirected to login and we've already checked auth
if (!$route.current.params.section
&& ($route.current.params.check === false || $route.current.params.check === "false")) {
deferred.resolve(true);
return deferred.promise;
}
userService.isAuthenticated()
.then(function () {
assetsService._loadInitAssets().then(function() {
//This could be the first time has loaded after the user has logged in, in this case
// we need to broadcast the authenticated event - this will be handled by the startup (init)
// handler to set/broadcast the ready state
var broadcast = appState.getGlobalState("isReady") !== true;
userService.getCurrentUser({ broadcastEvent: broadcast }).then(function (user) {
//is auth, check if we allow or reject
if (isRequired) {
// U4-5430, Benjamin Howarth
// We need to change the current route params if the user only has access to a single section
// To do this we need to grab the current user's allowed sections, then reject the promise with the correct path.
if (user.allowedSections.indexOf($route.current.params.section) > -1) {
//this will resolve successfully so the route will continue
deferred.resolve(true);
} else {
deferred.reject({ path: "/" + user.allowedSections[0] });
}
}
else {
deferred.reject({ path: "/" });
}
});
});
}, function () {
//not auth, check if we allow or reject
if (isRequired) {
//the check=false is checked above so that we don't have to make another http call to check
//if they are logged in since we already know they are not.
deferred.reject({ path: "/login/false" });
}
else {
//this will resolve successfully so the route will continue
deferred.resolve(true);
}
});
return deferred.promise;
}
};
};
/** When this is used to resolve it will attempt to log the current user out */
var doLogout = function() {
return {
isLoggedOut: function ($q, userService) {
var deferred = $q.defer();
userService.logout().then(function () {
//success so continue
deferred.resolve(true);
}, function() {
//logout failed somehow ? we'll reject with the login page i suppose
deferred.reject({ path: "/login/false" });
});
return deferred.promise;
}
}
}
$routeProvider
.when('/login', {
templateUrl: 'views/common/login.html',
//ensure auth is *not* required so it will redirect to /
resolve: canRoute(false)
})
.when('/login/:check', {
templateUrl: 'views/common/login.html',
//ensure auth is *not* required so it will redirect to /
resolve: canRoute(false)
})
.when('/logout', {
redirectTo: '/login/false',
resolve: doLogout()
})
.when('/:section', {
templateUrl: function (rp) {
if (rp.section.toLowerCase() === "default" || rp.section.toLowerCase() === "umbraco" || rp.section === "")
{
rp.section = "content";
}
rp.url = "dashboard.aspx?app=" + rp.section;
return 'views/common/dashboard.html';
},
resolve: canRoute(true)
})
.when('/:section/framed/:url', {
//This occurs when we need to launch some content in an iframe
templateUrl: function (rp) {
if (!rp.url)
throw "A framed resource must have a url route parameter";
return 'views/common/legacy.html';
},
resolve: canRoute(true)
})
.when('/:section/:tree/:method', {
templateUrl: function (rp) {
if (!rp.method)
return "views/common/dashboard.html";
//NOTE: This current isn't utilized by anything but does open up some cool opportunities for
// us since we'll be able to have specialized views for individual sections which is something
// we've never had before. So could utilize this for a new dashboard model when we get native
// angular dashboards working. Perhaps a normal section dashboard would list out the registered
// dashboards (as tabs if we wanted) and each tab could actually be a route link to one of these views?
return ('views/' + rp.tree + '/' + rp.method + '.html');
},
resolve: canRoute(true)
})
.when('/:section/:tree/:method/:id', {
//This allows us to dynamically change the template for this route since you cannot inject services into the templateUrl method.
template: "<div ng-include='templateUrl'></div>",
//This controller will execute for this route, then we replace the template dynamnically based on the current tree.
controller: function ($scope, $route, $routeParams, treeService) {
if (!$routeParams.tree || !$routeParams.method) {
$scope.templateUrl = "views/common/dashboard.html";
}
// Here we need to figure out if this route is for a package tree and if so then we need
// to change it's convention view path to:
// /App_Plugins/{mypackage}/backoffice/{treetype}/{method}.html
// otherwise if it is a core tree we use the core paths:
// views/{treetype}/{method}.html
var packageTreeFolder = treeService.getTreePackageFolder($routeParams.tree);
if (packageTreeFolder) {
$scope.templateUrl = (Umbraco.Sys.ServerVariables.umbracoSettings.appPluginsPath +
"/" + packageTreeFolder +
"/backoffice/" + $routeParams.tree + "/" + $routeParams.method + ".html");
}
else {
$scope.templateUrl = ('views/' + $routeParams.tree + '/' + $routeParams.method + '.html');
}
},
resolve: canRoute(true)
})
.otherwise({ redirectTo: '/login' });
}).config(function ($locationProvider) {
//$locationProvider.html5Mode(false).hashPrefix('!'); //turn html5 mode off
// $locationProvider.html5Mode(true); //turn html5 mode on
});
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+53
View File
@@ -0,0 +1,53 @@
/*! umbraco
* https://github.com/umbraco/umbraco-cms/
* Copyright (c) 2016 Umbraco HQ;
* Licensed
*/
(function() {
angular.module('umbraco.filters', []);
angular.module("umbraco.filters")
.filter('compareArrays', function() {
return function inArray(array, compareArray, compareProperty) {
var result = [];
angular.forEach(array, function(arrayItem){
var exists = false;
angular.forEach(compareArray, function(compareItem){
if( arrayItem[compareProperty] === compareItem[compareProperty]) {
exists = true;
}
});
if(!exists) {
result.push(arrayItem);
}
});
return result;
};
});
angular.module("umbraco.filters").filter('timespan', function() {
return function(input) {
var sec_num = parseInt(input, 10);
var hours = Math.floor(sec_num / 3600);
var minutes = Math.floor((sec_num - (hours * 3600)) / 60);
var seconds = sec_num - (hours * 3600) - (minutes * 60);
if (hours < 10) {hours = "0"+hours;}
if (minutes < 10) {minutes = "0"+minutes;}
if (seconds < 10) {seconds = "0"+seconds;}
var time = hours+':'+minutes+':'+seconds;
return time;
};
});
})();
+31
View File
@@ -0,0 +1,31 @@
var umbracoAppDev = angular.module('umbraco.httpbackend', ['umbraco', 'ngMockE2E', 'umbraco.mocks']);
function initBackEnd($httpBackend, contentMocks, mediaMocks, treeMocks, userMocks, contentTypeMocks, sectionMocks, entityMocks, dataTypeMocks, dashboardMocks, macroMocks, utilMocks, localizationMocks, prevaluesMocks) {
console.log("httpBackend inited");
//Register mocked http responses
contentMocks.register();
mediaMocks.register();
sectionMocks.register();
treeMocks.register();
dataTypeMocks.register();
dashboardMocks.register();
userMocks.register();
macroMocks.register();
contentTypeMocks.register();
utilMocks.register();
localizationMocks.register();
prevaluesMocks.register();
entityMocks.register();
$httpBackend.whenGET(/^..\/config\//).passThrough();
$httpBackend.whenGET(/^views\//).passThrough();
$httpBackend.whenGET(/^js\//).passThrough();
$httpBackend.whenGET(/^lib\//).passThrough();
$httpBackend.whenGET(/^assets\//).passThrough();
}
umbracoAppDev.run(initBackEnd);
+468
View File
@@ -0,0 +1,468 @@
/*! umbraco
* https://github.com/umbraco/umbraco-cms/
* Copyright (c) 2016 Umbraco HQ;
* Licensed
*/
(function() {
angular.module('umbraco.install', []);
angular.module("umbraco.install").controller("Umbraco.InstallerController",
function ($scope, installerService) {
//TODO: Decouple the service from the controller - the controller should be responsible
// for the model (state) and the service should be responsible for helping the controller,
// the controller should be passing the model into it's methods for manipulation and not hold
// state. We should not be assigning properties from a service to a controller's scope.
// see: https://github.com/umbraco/Umbraco-CMS/commit/b86ef0d7ac83f699aee35d807f7f7ebb6dd0ed2c#commitcomment-5721204
$scope.stepIndex = 0;
//comment this out if you just want to see tips
installerService.init();
//uncomment this to see tips
//installerService.switchToFeedback();
$scope.installer = installerService.status;
$scope.forward = function () {
installerService.forward();
};
$scope.backward = function () {
installerService.backward();
};
$scope.install = function () {
installerService.install();
};
$scope.gotoStep = function (step) {
installerService.gotoNamedStep(step);
};
$scope.restart = function () {
installerService.gotoStep(0);
};
});
//this ensure that we start with a clean slate on every install and upgrade
angular.module("umbraco.install").run(function ($templateCache) {
$templateCache.removeAll();
});
angular.module("umbraco.install").factory('installerService', function($rootScope, $q, $timeout, $http, $location, $log){
var _status = {
index: 0,
current: undefined,
steps: undefined,
loading: true,
progress: "100%"
};
var factTimer = undefined;
var _installerModel = {
installId: undefined,
instructions: {
}
};
//add to umbraco installer facts here
var facts = ['Umbraco helped millions of people watch a man jump from the edge of space',
'Over 370 000 websites are currently powered by Umbraco',
"At least 2 people have named their cat 'Umbraco'",
'On an average day, more than 1000 people download Umbraco',
'<a target="_blank" href="http://umbraco.tv">umbraco.tv</a> is the premier source of Umbraco video tutorials to get you started',
'You can find the world\'s friendliest CMS community at <a target="_blank" href="http://our.umbraco.org">our.umbraco.org</a>',
'You can become a certified Umbraco developer by attending one of the official courses',
'Umbraco works really well on tablets',
'You have 100% control over your markup and design when crafting a website in Umbraco',
'Umbraco is the best of both worlds: 100% free and open source, and backed by a professional and profitable company',
"There's a pretty big chance, you've visited a website powered by Umbraco today",
"'Umbraco-spotting' is the game of spotting big brands running Umbraco",
"At least 4 people have the Umbraco logo tattooed on them",
"'Umbraco' is the danish name for an allen key",
"Umbraco has been around since 2005, that's a looong time in IT",
"More than 400 people from all over the world meet each year in Denmark in June for our annual conference <a target='_blank' href='http://codegarden15.com'>CodeGarden</a>",
"While you are installing Umbraco someone else on the other side of the planet is probably doing it too",
"You can extend Umbraco without modifying the source code using either JavaScript or C#",
"Umbraco was installed in more than 165 countries in 2015"
];
/**
Returns the description for the step at a given index based on the order of the serverOrder of steps
Since they don't execute on the server in the order that they are displayed in the UI.
*/
function getDescriptionForStepAtIndex(steps, index) {
var sorted = _.sortBy(steps, "serverOrder");
if (sorted[index]) {
return sorted[index].description;
}
return null;
}
/* Returns the description for the given step name */
function getDescriptionForStepName(steps, name) {
var found = _.find(steps, function(i) {
return i.name == name;
});
return (found) ? found.description : null;
}
//calculates the offset of the progressbar on the installer
function calculateProgress(steps, next) {
var sorted = _.sortBy(steps, "serverOrder");
var pct = "100%";
for (var i = sorted.length - 1; i >= 0; i--) {
if(sorted[i].name == next){
pct = Math.floor((i+1) / steps.length * 100) + "%";
break;
}
}
return pct;
}
//helpful defaults for the view loading
function resolveView(view){
if(view.indexOf(".html") < 0){
view = view + ".html";
}
if(view.indexOf("/") < 0){
view = "views/install/" + view;
}
return view;
}
/** Have put this here because we are not referencing our other modules */
function safeApply (scope, fn) {
if (scope.$$phase || scope.$root.$$phase) {
if (angular.isFunction(fn)) {
fn();
}
}
else {
if (angular.isFunction(fn)) {
scope.$apply(fn);
}
else {
scope.$apply();
}
}
}
var service = {
status : _status,
//loads the needed steps and sets the intial state
init : function(){
service.status.loading = true;
if(!_status.all){
service.getSteps().then(function(response){
service.status.steps = response.data.steps;
service.status.index = 0;
_installerModel.installId = response.data.installId;
service.findNextStep();
$timeout(function(){
service.status.loading = false;
service.status.configuring = true;
}, 2000);
});
}
},
//loads available packages from our.umbraco.org
getPackages : function(){
return $http.get(Umbraco.Sys.ServerVariables.installApiBaseUrl + "GetPackages");
},
getSteps : function(){
return $http.get(Umbraco.Sys.ServerVariables.installApiBaseUrl + "GetSetup");
},
gotoStep : function(index){
var step = service.status.steps[index];
step.view = resolveView(step.view);
if(!step.model){
step.model = {};
}
service.status.index = index;
service.status.current = step;
service.retrieveCurrentStep();
},
gotoNamedStep : function(stepName){
var step = _.find(service.status.steps, function(s, index){
if (s.view && s.name === stepName) {
service.status.index = index;
return true;
}
return false;
});
step.view = resolveView(step.view);
if(!step.model){
step.model = {};
}
service.retrieveCurrentStep();
service.status.current = step;
},
/**
Finds the next step containing a view. If one is found it stores it as the current step
and retreives the step information and returns it, otherwise returns null .
*/
findNextStep : function(){
var step = _.find(service.status.steps, function(s, index){
if(s.view && index >= service.status.index){
service.status.index = index;
return true;
}
return false;
});
if (step) {
if (step.view.indexOf(".html") < 0) {
step.view = step.view + ".html";
}
if (step.view.indexOf("/") < 0) {
step.view = "views/install/" + step.view;
}
if (!step.model) {
step.model = {};
}
service.status.current = step;
service.retrieveCurrentStep();
//returns the next found step
return step;
}
else {
//there are no more steps found containing a view so return null
return null;
}
},
storeCurrentStep : function(){
_installerModel.instructions[service.status.current.name] = service.status.current.model;
},
retrieveCurrentStep : function(){
if(_installerModel.instructions[service.status.current.name]){
service.status.current.model = _installerModel.instructions[service.status.current.name];
}
},
/** Moves the installer forward to the next view, if there are not more views than the installation will commence */
forward : function(){
service.storeCurrentStep();
service.status.index++;
var found = service.findNextStep();
if (!found) {
//no more steps were found so start the installation process
service.install();
}
},
backwards : function(){
service.storeCurrentStep();
service.gotoStep(service.status.index--);
},
install : function(){
service.storeCurrentStep();
service.switchToFeedback();
service.status.feedback = getDescriptionForStepAtIndex(service.status.steps, 0);
service.status.progress = 0;
function processInstallStep() {
$http.post(Umbraco.Sys.ServerVariables.installApiBaseUrl + "PostPerformInstall", _installerModel)
.success(function(data, status, headers, config) {
if (!data.complete) {
//progress feedback
service.status.progress = calculateProgress(service.status.steps, data.nextStep);
if (data.view) {
//set the current view and model to whatever the process returns, the view is responsible for retriggering install();
var v = resolveView(data.view);
service.status.current = { view: v, model: data.model };
//turn off loading bar and feedback
service.switchToConfiguration();
}
else {
var desc = getDescriptionForStepName(service.status.steps, data.nextStep);
if (desc) {
service.status.feedback = desc;
}
processInstallStep();
}
}
else {
service.complete();
}
}).error(function(data, status, headers, config) {
//need to handle 500's separately, this will happen if something goes wrong outside
// of the installer (like app startup events or something) and these will get returned as text/html
// not as json. If this happens we can't actually load in external views since they will YSOD as well!
// so we need to display this in our own internal way
if (status >= 500 && status < 600) {
service.status.current = { view: "ysod", model: null };
var ysod = data;
//we need to manually write the html to the iframe - the html contains full html markup
$timeout(function () {
document.getElementById('ysod').contentDocument.write(ysod);
}, 500);
}
else {
//this is where we handle installer error
var v = data.view ? resolveView(data.view) : resolveView("error");
var model = data.model ? data.model : data;
service.status.current = { view: v, model: model };
}
service.switchToConfiguration();
});
}
processInstallStep();
},
randomFact: function () {
safeApply($rootScope, function() {
service.status.fact = facts[_.random(facts.length - 1)];
});
},
switchToFeedback : function(){
service.status.current = undefined;
service.status.loading = true;
service.status.configuring = false;
//initial fact
service.randomFact();
//timed facts
factTimer = window.setInterval(function(){
service.randomFact();
},6000);
},
switchToConfiguration : function(){
service.status.loading = false;
service.status.configuring = true;
service.status.feedback = undefined;
service.status.fact = undefined;
if(factTimer){
clearInterval(factTimer);
}
},
complete : function(){
service.status.progress = "100%";
service.status.done = true;
service.status.feedback = "Redirecting you to Umbraco, please wait";
service.status.loading = false;
if(factTimer){
clearInterval(factTimer);
}
$timeout(function(){
window.location.href = Umbraco.Sys.ServerVariables.umbracoBaseUrl;
}, 1500);
}
};
return service;
});
angular.module("umbraco.install").controller("Umbraco.Installer.DataBaseController", function($scope, $http, installerService){
$scope.checking = false;
$scope.dbs = [
{name: 'Microsoft SQL Server Compact (SQL CE)', id: 0},
{name: 'Microsoft SQL Server', id: 1},
{ name: 'Microsoft SQL Azure', id: 3 },
{ name: 'MySQL', id: 2 },
{name: 'Custom connection string', id: -1}];
if(installerService.status.current.model.dbType === undefined){
installerService.status.current.model.dbType = 0;
}
$scope.validateAndForward = function(){
if(!$scope.checking && this.myForm.$valid){
$scope.checking = true;
var model = installerService.status.current.model;
$http.post(Umbraco.Sys.ServerVariables.installApiBaseUrl + "PostValidateDatabaseConnection",
model).then(function(response){
if(response.data === "true"){
installerService.forward();
}else{
$scope.invalidDbDns = true;
}
$scope.checking = false;
}, function(){
$scope.invalidDbDns = true;
$scope.checking = false;
});
}
};
});
angular.module("umbraco.install").controller("Umbraco.Installer.PackagesController", function ($scope, installerService) {
installerService.getPackages().then(function (response) {
$scope.packages = response.data;
});
$scope.setPackageAndContinue = function (pckId) {
installerService.status.current.model = pckId;
installerService.forward();
};
});
angular.module("umbraco.install").controller("Umbraco.Install.UserController", function($scope, installerService) {
$scope.passwordPattern = /.*/;
$scope.installer.current.model.subscribeToNewsLetter = true;
if ($scope.installer.current.model.minNonAlphaNumericLength > 0) {
var exp = "";
for (var i = 0; i < $scope.installer.current.model.minNonAlphaNumericLength; i++) {
exp += ".*[\\W].*";
}
//replace duplicates
exp = exp.replace(".*.*", ".*");
$scope.passwordPattern = new RegExp(exp);
}
$scope.validateAndInstall = function(){
installerService.install();
};
$scope.validateAndForward = function(){
if(this.myForm.$valid){
installerService.forward();
}
};
});
})();
File diff suppressed because it is too large Load Diff
+206
View File
@@ -0,0 +1,206 @@
/*! umbraco
* https://github.com/umbraco/umbraco-cms/
* Copyright (c) 2016 Umbraco HQ;
* Licensed
*/
(function() {
//TODO: This is silly and unecessary to have a separate module for this
angular.module('umbraco.security.retryQueue', []);
angular.module('umbraco.security.interceptor', ['umbraco.security.retryQueue']);
angular.module('umbraco.security', ['umbraco.security.retryQueue', 'umbraco.security.interceptor']);
//TODO: This is silly and unecessary to have a separate module for this
angular.module('umbraco.security.retryQueue', [])
// This is a generic retry queue for security failures. Each item is expected to expose two functions: retry and cancel.
.factory('securityRetryQueue', ['$q', '$log', function ($q, $log) {
var retryQueue = [];
var retryUser = null;
var service = {
// The security service puts its own handler in here!
onItemAddedCallbacks: [],
hasMore: function() {
return retryQueue.length > 0;
},
push: function(retryItem) {
retryQueue.push(retryItem);
// Call all the onItemAdded callbacks
angular.forEach(service.onItemAddedCallbacks, function(cb) {
try {
cb(retryItem);
} catch(e) {
$log.error('securityRetryQueue.push(retryItem): callback threw an error' + e);
}
});
},
pushRetryFn: function(reason, userName, retryFn) {
// The reason parameter is optional
if ( arguments.length === 2) {
retryFn = userName;
userName = reason;
reason = undefined;
}
if ((retryUser && retryUser !== userName) || userName === null) {
throw new Error('invalid user');
}
retryUser = userName;
// The deferred object that will be resolved or rejected by calling retry or cancel
var deferred = $q.defer();
var retryItem = {
reason: reason,
retry: function() {
// Wrap the result of the retryFn into a promise if it is not already
$q.when(retryFn()).then(function(value) {
// If it was successful then resolve our deferred
deferred.resolve(value);
}, function(value) {
// Othewise reject it
deferred.reject(value);
});
},
cancel: function() {
// Give up on retrying and reject our deferred
deferred.reject();
}
};
service.push(retryItem);
return deferred.promise;
},
retryReason: function() {
return service.hasMore() && retryQueue[0].reason;
},
cancelAll: function() {
while(service.hasMore()) {
retryQueue.shift().cancel();
}
retryUser = null;
},
retryAll: function (userName) {
if (retryUser == null) {
return;
}
if (retryUser !== userName) {
service.cancelAll();
return;
}
while(service.hasMore()) {
retryQueue.shift().retry();
}
}
};
return service;
}]);
angular.module('umbraco.security.interceptor')
// This http interceptor listens for authentication successes and failures
.factory('securityInterceptor', ['$injector', 'securityRetryQueue', 'notificationsService', 'requestInterceptorFilter', function ($injector, queue, notifications, requestInterceptorFilter) {
return function(promise) {
return promise.then(
function(originalResponse) {
// Intercept successful requests
//Here we'll check if our custom header is in the response which indicates how many seconds the user's session has before it
//expires. Then we'll update the user in the user service accordingly.
var headers = originalResponse.headers();
if (headers["x-umb-user-seconds"]) {
// We must use $injector to get the $http service to prevent circular dependency
var userService = $injector.get('userService');
userService.setUserTimeout(headers["x-umb-user-seconds"]);
}
return promise;
}, function(originalResponse) {
// Intercept failed requests
//Here we'll check if we should ignore the error, this will be based on an original header set
var headers = originalResponse.config ? originalResponse.config.headers : {};
if (headers["x-umb-ignore-error"] === "ignore") {
//exit/ignore
return promise;
}
var filtered = _.find(requestInterceptorFilter(), function(val) {
return originalResponse.config.url.indexOf(val) > 0;
});
if (filtered) {
return promise;
}
//A 401 means that the user is not logged in
if (originalResponse.status === 401) {
var userService = $injector.get('userService'); // see above
//Associate the user name with the retry to ensure we retry for the right user
promise = userService.getCurrentUser()
.then(function (user) {
var userName = user ? user.name : null;
//The request bounced because it was not authorized - add a new request to the retry queue
return queue.pushRetryFn('unauthorized-server', userName, function retryRequest() {
// We must use $injector to get the $http service to prevent circular dependency
return $injector.get('$http')(originalResponse.config);
});
});
}
else if (originalResponse.status === 404) {
//a 404 indicates that the request was not found - this could be due to a non existing url, or it could
//be due to accessing a url with a parameter that doesn't exist, either way we should notifiy the user about it
var errMsg = "The URL returned a 404 (not found): <br/><i>" + originalResponse.config.url.split('?')[0] + "</i>";
if (originalResponse.data && originalResponse.data.ExceptionMessage) {
errMsg += "<br/> with error: <br/><i>" + originalResponse.data.ExceptionMessage + "</i>";
}
if (originalResponse.config.data) {
errMsg += "<br/> with data: <br/><i>" + angular.toJson(originalResponse.config.data) + "</i><br/>Contact your administrator for information.";
}
notifications.error(
"Request error",
errMsg);
}
else if (originalResponse.status === 403) {
//if the status was a 403 it means the user didn't have permission to do what the request was trying to do.
//How do we deal with this now, need to tell the user somehow that they don't have permission to do the thing that was
//requested. We can either deal with this globally here, or we can deal with it globally for individual requests on the umbRequestHelper,
// or completely custom for services calling resources.
//http://issues.umbraco.org/issue/U4-2749
//It was decided to just put these messages into the normal status messages.
var msg = "Unauthorized access to URL: <br/><i>" + originalResponse.config.url.split('?')[0] + "</i>";
if (originalResponse.config.data) {
msg += "<br/> with data: <br/><i>" + angular.toJson(originalResponse.config.data) + "</i><br/>Contact your administrator for information.";
}
notifications.error(
"Authorization error",
msg);
}
return promise;
});
};
}])
.value('requestInterceptorFilter', function() {
return ["www.gravatar.com"];
})
// We have to add the interceptor to the queue as a string because the interceptor depends upon service instances that are not available in the config block.
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.responseInterceptors.push('securityInterceptor');
}]);
})();
@@ -0,0 +1,42 @@
//create the namespace (NOTE: This loads before any dependencies so we don't have a namespace mgr so we just create it manually)
var Umbraco = {};
Umbraco.Sys = {};
//define a global static object
Umbraco.Sys.ServerVariables = {
umbracoUrls: {
"contentApiBaseUrl": "/umbraco/UmbracoApi/Content/",
"mediaApiBaseUrl": "/umbraco/UmbracoApi/Media/",
"dataTypeApiBaseUrl": "/umbraco/UmbracoApi/DataType/",
"sectionApiBaseUrl": "/umbraco/UmbracoApi/Section/",
"treeApplicationApiBaseUrl": "/umbraco/UmbracoTrees/ApplicationTreeApi/",
"contentTypeApiBaseUrl": "/umbraco/Api/ContentType/",
"mediaTypeApiBaseUrl": "/umbraco/Api/MediaType/",
"macroApiBaseUrl": "/umbraco/Api/Macro/",
"authenticationApiBaseUrl": "/umbraco/UmbracoApi/Authentication/",
//For this we'll just provide a file that exists during the mock session since we don't really have legay js tree stuff
"legacyTreeJs": "/belle/lib/lazyload/empty.js",
"serverVarsJs": "/belle/lib/lazyload/empty.js",
"imagesApiBaseUrl": "/umbraco/UmbracoApi/Images/",
"entityApiBaseUrl": "/umbraco/UmbracoApi/Entity/",
"dashboardApiBaseUrl": "/umbraco/UmbracoApi/Dashboard/",
"updateCheckApiBaseUrl": "/umbraco/Api/UpdateCheck/",
"relationApiBaseUrl": "/umbraco/UmbracoApi/Relation/",
"rteApiBaseUrl": "/umbraco/UmbracoApi/RichTextPreValue/"
},
umbracoSettings: {
"umbracoPath": "/umbraco",
"appPluginsPath" : "/App_Plugins",
"imageFileTypes": "jpeg,jpg,gif,bmp,png,tiff,tif",
"keepUserLoggedIn": true
},
umbracoPlugins: {
trees: [
{ alias: "myTree", packageFolder: "MyPackage" }
]
},
isDebuggingEnabled: true,
application: {
assemblyVersion: "1",
version: "7"
}
};
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+102
View File
@@ -0,0 +1,102 @@
var ctrlDown = false;
var shiftDown = false;
var keycode = 0
var currentRichTextDocument = null;
var currentRichTextObject = null;
function umbracoCheckKeysUp(e) {
ctrlDown = e.ctrlKey;
shiftDown = e.shiftKey;
}
function umbracoActivateKeys(ctrl, shift, key) {
ctrlDown = ctrl;
shiftDown = shift;
keycode = key
return runShortCuts();
}
function umbracoActivateKeysUp(ctrl, shift, key) {
ctrlDown = ctrl;
shiftDown = shift;
keycode = key;
}
function umbracoCheckKeys(e) {
ctrlDown = e.ctrlKey;
shiftDown = e.shiftKey;
keycode = e.keyCode;
return runShortCuts();
}
function shortcutCheckKeysPressFirefox(e) {
if (ctrlDown && keycode == 83)
e.preventDefault();
}
function runShortCuts() {
if (currentRichTextObject != undefined && currentRichTextObject != null) {
if (ctrlDown) {
if (!shiftDown && keycode == 9)
functionsFrame.tabSwitch(1);
else
if (shiftDown && keycode == 9) functionsFrame.tabSwitch(-1);
if (keycode == 83) {doSubmit(); return false;}
if (shiftDown && currentRichTextObject) {
if (keycode == 70) {functionsFrame.umbracoInsertForm(myAlias); return false;}
if (keycode == 76) {functionsFrame.umbracoLink(myAlias); return false;}
if (keycode == 77) {functionsFrame.umbracoInsertMacro(myAlias, umbracoPath); return false;}
if (keycode == 80) {functionsFrame.umbracoImage(myAlias); return false;}
if (keycode == 84) {functionsFrame.umbracoInsertTable(myAlias); return false;}
if (keycode == 86) {functionsFrame.umbracoShowStyles(myAlias); return false;}
if (keycode == 85) {functionsFrame.document.getElementById('TabView1_tab01layer_publish').click(); return false;}
}
}
} else
if (isDialog) {
if (keycode == 27) {window.close();} // ESC
if (keycode == 13 && functionsFrame.submitOnEnter != undefined) {
if (!functionsFrame.disableEnterSubmit) {
if (functionsFrame.submitOnEnter) {
// firefox hack
if (window.addEventListener)
e.preventDefault();
doSubmit();
}
}
}
if (ctrlDown) {
if (keycode == 83)
doSubmit();
else if (keycode == 85)
document.getElementById('TabView1_tab01layer_publish').click();
else if (!shiftDown && keycode == 9) {
functionsFrame.tabSwitch(1);
return false;
}
else
if (shiftDown && keycode == 9) {
functionsFrame.tabSwitch(-1);
return false;
}
}
}
return true;
}
if (window.addEventListener) {
document.addEventListener('keyup', umbracoCheckKeysUp, false);
document.addEventListener('keydown', umbracoCheckKeys, false);
document.addEventListener('keypress', shortcutCheckKeysPressFirefox, false);
} else {
document.attachEvent( "onkeyup", umbracoCheckKeysUp);
document.attachEvent("onkeydown", umbracoCheckKeys);
}
@@ -0,0 +1,15 @@
function umbracoCheckUpgrade(result) {
if (result) {
if (result.UpgradeType.toLowerCase() != 'none') {
if (UmbSpeechBubble == null) {
InitUmbracoSpeechBubble();
}
var icon = 'info';
if (result.UpgradeType.toLowerCase() == 'critical') {
icon = 'error';
}
UmbSpeechBubble.ShowMessage(icon, 'Upgrade Available!', '<a style="text-decoration:none" target="_blank" href="' + result.UpgradeUrl + '">' + result.UpgradeComment + '</a>', true);
}
}
}
+77
View File
@@ -0,0 +1,77 @@
var requestRunning = false;
var xmlHttp = null;
var xmlHttpDebug = false;
// Inspired by great work of Webfx in xloadtree
function umbracoStartXmlRequest(scriptUrl, postData, eventFunction) {
// random hack for ie7
day = new Date();
z = day.getTime();
y = (z - (parseInt(z/1000,10) * 1000))/10;
scriptUrl += "&xmlRnd=" + y;
if (xmlHttpDebug)
alert(scriptUrl)
this.requestRunning = true;
this.xmlHttpObject = XmlHttp.create();
if (postData != "") {
if (document.all) {
this.xmlHttpObject.open("POST", scriptUrl, false);
this.xmlHttpObject.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
}
else {
eval(eventFunction);
}
} else
this.xmlHttpObject.open("GET", scriptUrl, true);
this.xmlHttpObject.onreadystatechange = function () {
if (xmlHttp.readyState == 4) {
// Removed the this from this.requestRunning = false; this was causing a bug in the find search box in cms backend.
requestRunning = false;
// debug
if (xmlHttpDebug)
alert(xmlHttp.responseText)
eval(eventFunction);
xmlHttp = null;
}
};
// call in new thread to allow ui to update
window.setTimeout(function () {
this.xmlHttpObject.send(postData);
}, 10);
xmlHttp = this.xmlHttpObject;
return this;
}
umbracoStartXmlRequest.prototype.ResultText =
umbracoStartXmlRequest.prototype.ResultText = function () {
return this.xmlHttpObject.responseText;
}
umbracoStartXmlRequest.prototype.ResultXml =
umbracoStartXmlRequest.prototype.ResultXml = function () {
return this.xmlHttpObject.responseXML;
}
function umbracoXmlRequestResult() {
if (!requestRunning)
return xmlHttp.responseXML
}
function umbracoXmlRequestResultTxt() {
if (!requestRunning)
return xmlHttp.responseText
}
function xmlReturnRandom() {
day = new Date()
z = day.getTime()
y = (z - (parseInt(z/1000,10) * 1000))/10
return y
}
+151
View File
@@ -0,0 +1,151 @@
//<script>
//////////////////
// Helper Stuff //
//////////////////
function HTMLEncode(t) {
return t.toString().replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
}
// used to find the Automation server name
function getDomDocumentPrefix() {
if (getDomDocumentPrefix.prefix)
return getDomDocumentPrefix.prefix;
var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
var o;
for (var i = 0; i < prefixes.length; i++) {
try {
// try to create the objects
o = new ActiveXObject(prefixes[i] + ".DomDocument");
return getDomDocumentPrefix.prefix = prefixes[i];
}
catch (ex) {};
}
throw new Error("Could not find an installed XML parser");
}
function getXmlHttpPrefix() {
if (getXmlHttpPrefix.prefix)
return getXmlHttpPrefix.prefix;
var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];
var o;
for (var i = 0; i < prefixes.length; i++) {
try {
// try to create the objects
o = new ActiveXObject(prefixes[i] + ".XmlHttp");
return getXmlHttpPrefix.prefix = prefixes[i];
}
catch (ex) {};
}
throw new Error("Could not find an installed XML parser");
}
//////////////////////////
// Start the Real stuff //
//////////////////////////
// XmlHttp factory
function XmlHttp() {}
XmlHttp.create = function () {
try {
if (window.XMLHttpRequest) {
var req = new XMLHttpRequest();
// some versions of Moz do not support the readyState property
// and the onreadystate event so we patch it!
if (req.readyState == null) {
req.readyState = 1;
req.addEventListener("load", function () {
req.readyState = 4;
if (typeof req.onreadystatechange == "function")
req.onreadystatechange();
}, false);
}
return req;
}
if (window.ActiveXObject) {
return new ActiveXObject(getXmlHttpPrefix() + ".XmlHttp");
}
}
catch (ex) {}
// fell through
throw new Error("Your browser does not support XmlHttp objects");
};
// XmlDocument factory
function XmlDocument() {}
XmlDocument.create = function () {
try {
// DOM2
if (document.implementation && document.implementation.createDocument) {
var doc = document.implementation.createDocument("", "", null);
// some versions of Moz do not support the readyState property
// and the onreadystate event so we patch it!
if (doc.readyState == null) {
doc.readyState = 1;
doc.addEventListener("load", function () {
doc.readyState = 4;
if (typeof doc.onreadystatechange == "function")
doc.onreadystatechange();
}, false);
}
return doc;
}
if (window.ActiveXObject)
return new ActiveXObject(getDomDocumentPrefix() + ".DomDocument");
}
catch (ex) {}
throw new Error("Your browser does not support XmlDocument objects");
};
// Create the loadXML method and xml getter for Mozilla
if (window.DOMParser &&
window.XMLSerializer &&
window.Node && Node.prototype && Node.prototype.__defineGetter__) {
// XMLDocument did not extend the Document interface in some versions
// of Mozilla. Extend both!
XMLDocument.prototype.loadXML =
Document.prototype.loadXML = function (s) {
// parse the string to a new doc
var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
// remove all initial children
while (this.hasChildNodes())
this.removeChild(this.lastChild);
// insert and import nodes
for (var i = 0; i < doc2.childNodes.length; i++) {
this.appendChild(this.importNode(doc2.childNodes[i], true));
}
};
/*
* xml getter
*
* This serializes the DOM tree to an XML String
*
* Usage: var sXml = oNode.xml
*
*/
// XMLDocument did not extend the Document interface in some versions
// of Mozilla. Extend both!
XMLDocument.prototype.__defineGetter__("xml", function () {
return (new XMLSerializer()).serializeToString(this);
});
Document.prototype.__defineGetter__("xml", function () {
return (new XMLSerializer()).serializeToString(this);
});
}