finally it actually previews

This commit is contained in:
Shannon
2018-09-14 00:14:03 +10:00
parent 647eac2d9b
commit e771e781dd
31 changed files with 250 additions and 352 deletions

View File

@@ -19,7 +19,7 @@ namespace Umbraco.Tests.Web.AngularIntegration
[Test]
public void Parse_Main()
{
var result = JsInitialization.WriteScript(new[] {"[World]", "Hello" });
var result = JsInitialization.WriteScript("[World]", "Hello", "Blah");
Assert.AreEqual(@"LazyLoad.js([World], function () {
//we need to set the legacy UmbClientMgr path
@@ -27,7 +27,7 @@ namespace Umbraco.Tests.Web.AngularIntegration
jQuery(document).ready(function () {
angular.bootstrap(document, ['umbraco']);
angular.bootstrap(document, ['Blah']);
});
});".StripWhitespace(), result.StripWhitespace());

View File

@@ -80,7 +80,7 @@ var sources = {
//js files for backoffie
//processed in the js task
js: {
preview: { files: ["src/canvasdesigner/**/*.js"], out: "umbraco.canvasdesigner.js" },
preview: { files: ["src/preview/**/*.js"], out: "umbraco.preview.js" },
installer: { files: ["src/installer/**/*.js"], out: "umbraco.installer.js" },
controllers: { files: ["src/{views,controllers}/**/*.controller.js"], out: "umbraco.controllers.js" },
directives: { files: ["src/common/directives/**/*.js"], out: "umbraco.directives.js" },

View File

@@ -471,10 +471,10 @@
// Chromes popup blocker will kick in if a window is opened
// without the initial scoped request. This trick will fix that.
//
var previewWindow = $window.open('preview/#?init=true', 'umbpreview');
var previewWindow = $window.open('preview/?init=true', 'umbpreview');
// Build the correct path so both /#/ and #/ work.
var redirect = Umbraco.Sys.ServerVariables.umbracoSettings.umbracoPath + '/preview/#?id=' + content.id;
var redirect = Umbraco.Sys.ServerVariables.umbracoSettings.umbracoPath + '/preview/?id=' + content.id;
//The user cannot save if they don't have access to do that, in which case we just want to preview
//and that's it otherwise they'll get an unauthorized access message

View File

@@ -3,10 +3,10 @@
/* Canvasdesigner panel app and controller */
/*********************************************************************************************************/
var app = angular.module("Umbraco.canvasdesigner", ['umbraco.resources', 'umbraco.services'])
.controller("Umbraco.canvasdesignerController", function ($scope, $http, $window, $timeout, $location, dialogService) {
var app = angular.module("umbraco.preview", ['umbraco.resources', 'umbraco.services'])
.controller("previewController", function ($scope, $http, $window, $timeout, $location, dialogService) {
//gets a real query string value
function getParameterByName(name, url) {
if (!url) url = $window.location.href;
@@ -18,7 +18,28 @@ var app = angular.module("Umbraco.canvasdesigner", ['umbraco.resources', 'umbrac
return decodeURIComponent(results[2].replace(/\+/g, ' '));
}
var isInit = $location.search().init;
function configureSignalR(iframe) {
// signalr hub
var previewHub = $.connection.previewHub;
previewHub.client.refreshed = function (message, sender) {
console.log("Notified by SignalR preview hub (" + message + ").");
if ($scope.pageId != message) {
console.log("Not a notification for us (" + $scope.pageId + ").");
return;
}
var iframeDoc = (iframe.contentWindow || iframe.contentDocument);
iframeDoc.location.reload();
};
$.connection.hub.start()
.done(function () { console.log("Connected to SignalR preview hub (ID=" + $.connection.hub.id + ")"); })
.fail(function () { console.log("Could not connect to SignalR preview hub."); });
}
var isInit = getParameterByName("init");
if (isInit === "true") {
//do not continue, this is the first load of this new window, if this is passed in it means it's been
//initialized by the content editor and then the content editor will actually re-load this window without
@@ -45,6 +66,7 @@ var app = angular.module("Umbraco.canvasdesigner", ['umbraco.resources', 'umbrac
$scope.pageId = pageId;
$scope.pageUrl = "frame?id=" + pageId;
$scope.valueAreLoaded = false;
$scope.devices = [
{ name: "desktop", css: "desktop", icon: "icon-display", title: "Desktop" },
@@ -73,8 +95,9 @@ var app = angular.module("Umbraco.canvasdesigner", ['umbraco.resources', 'umbrac
window.top.location.href = "../endPreview.aspx?redir=%2f" + $scope.pageId;
};
$scope.onFrameLoaded = function () {
$scope.onFrameLoaded = function (iframe) {
$scope.frameLoaded = true;
configureSignalR(iframe);
}
/*****************************************************************************/
@@ -91,54 +114,35 @@ var app = angular.module("Umbraco.canvasdesigner", ['umbraco.resources', 'umbrac
.component('previewIFrame', {
template: "<div><iframe id='resultFrame' ng-src=\"{{ vm.src }}\" frameborder='0'></iframe></div>",
controller: function ($element) {
template: "<div style='width:100%;height:100%;margin:0 auto;overflow:hidden;'><iframe id='resultFrame' src='about:blank' ng-src=\"{{vm.srcDelayed}}\" frameborder='0'></iframe></div>",
controller: function ($element, $scope, angularHelper) {
var vm = this;
vm.$onInit = function () {
////TODO: Move this to the callback on the controller
//// signalr hub
//var previewHub = $.connection.previewHub;
//previewHub.client.refreshed = function (message, sender) {
// console.log("Notified by SignalR preview hub (" + message + ").");
// if ($scope.pageId != message) {
// console.log("Not a notification for us (" + $scope.pageId + ").");
// return;
// }
// var iframe = ($element.context.contentWindow || $element.context.contentDocument);
// iframe.location.reload();
//};
//$.connection.hub.start()
// .done(function () { console.log("Connected to SignalR preview hub (ID=" + $.connection.hub.id + ")"); })
// .fail(function () { console.log("Could not connect to SignalR preview hub."); });
};
vm.$postLink = function () {
$element.find("#resultFrame").on("load", function () {
var iframe = $element.find("#resultFrame").get(0);
hideUmbracoPreviewBadge(iframe);
vm.onLoaded();
scope.$apply();
});
var resultFrame = $element.find("#resultFrame");
resultFrame.on("load", iframeReady);
vm.srcDelayed = vm.src;
};
function iframeReady() {
var iframe = $element.find("#resultFrame").get(0);
hideUmbracoPreviewBadge(iframe);
angularHelper.safeApply($scope, function () {
vm.onLoaded({ iframe: iframe });
});
}
function hideUmbracoPreviewBadge (iframe) {
if (iframe && iframe.document.getElementById("umbracoPreviewBadge")) {
iframe.document.getElementById("umbracoPreviewBadge").style.display = "none";
if (iframe && iframe.contentDocument && iframe.contentDocument.getElementById("umbracoPreviewBadge")) {
iframe.contentDocument.getElementById("umbracoPreviewBadge").style.display = "none";
}
};
},
controllerAs: "vm",
bindings: {
src: "@",
src: "<",
onLoaded: "&"
}

View File

@@ -426,18 +426,7 @@
<Content Include="Views\Partials\Grid\Editors\Base.cshtml" />
<Content Include="Views\Partials\Grid\Bootstrap3-Fluid.cshtml" />
<Content Include="Views\Partials\Grid\Bootstrap2-Fluid.cshtml" />
<Content Include="Umbraco\Views\Preview\Background.cshtml" />
<Content Include="Umbraco\Views\Preview\Border.cshtml" />
<Content Include="Umbraco\Views\Preview\Color.cshtml" />
<Content Include="Umbraco\Views\Preview\Googlefontpicker.cshtml" />
<Content Include="Umbraco\Views\Preview\GridRow.cshtml" />
<Content Include="Umbraco\Views\Preview\Index.cshtml" />
<Content Include="Umbraco\Views\Preview\Layout.cshtml" />
<Content Include="Umbraco\Views\Preview\Margin.cshtml" />
<Content Include="Umbraco\Views\Preview\Padding.cshtml" />
<Content Include="Umbraco\Views\Preview\Radius.cshtml" />
<Content Include="Umbraco\Views\Preview\Shadow.cshtml" />
<Content Include="Umbraco\Views\Preview\Slider.cshtml" />
<Content Include="Umbraco\Views\web.config" />
<None Include="Web.Debug.config.transformed" />
<None Include="web.Template.Debug.config">

View File

@@ -1,57 +0,0 @@
@inherits System.Web.Mvc.WebViewPage
<div ng-controller="Umbraco.canvasdesigner.background">
<div class="box-slider">
<div colorpicker ng-model="item.values.color"></div>
</div>
<div class="box-slider">
<div class="imagePickerPreview" ng-click="open(item.values)" style="background-image:{{ item.values.imageorpattern }}">
<i ng-if="item.values.imageorpattern == ''" class="icon icon-picture"></i>
<i ng-if="item.values.imageorpattern != ''" class="icon icon-delete" ng-click="item.values.imageorpattern = ''"></i>
</div>
</div>
</div>
<script type="text/ng-template" id="mediaPickerModal.html">
<div ng-controller="canvasdesigner.mediaPickerModal">
<div class="modal-header bodyCanvasdesignerImagePicker ng-scope">
<ul class="breadcrumb">
<li ng-if="startNodeId == -1">
<a href="" ng-click="gotoFolder()">Media</a>
</li>
<!-- ngRepeat: item in path -->
<li ng-repeat="item in currentPath" class="ng-scope">
/ <a ng-if="currentFolder.id == item.id" href="" ng-class="{disabled:currentFolder.id == item.id}">{{ item.name }}</a>
<a ng-if="currentFolder.id != item.id" ng-click="gotoFolder(item)">{{ item.name }}</a>
</li>
</ul>
</div>
<div class="modal-body bodyCanvasdesignerImagePicker">
<ul class="canvasdesignerImagePicker">
<li>
<ul class="media-items">
<li ng-repeat="child in currentFolder.children | orderBy:'isFolder':true">
<div ng-if="!child.isFolder" class="media-preview" ng-class="{selected:selectedMedia.id == child.id}" ng-click="selectMedia(child)" style="background-image: url({{ child.thumbnail }})"></div>
<div ng-if="child.isFolder" class="media-preview" ng-click="selectMedia(child)">
<i class="icon icon-folder folder"><p class="folder-name">{{child.name}}</p></i>
</div>
</li>
</ul>
</li>
</ul>
</div>
<div class="right">
<a class="btn" href="#" ng-click="cancelAndClose()">Cancel</a>
<a class="btn btn-success" href="#" ng-click="submitAndClose()">Done</a>
</div>
</div>
</script>

View File

@@ -1,20 +0,0 @@
@inherits System.Web.Mvc.WebViewPage
<div ng-controller="Umbraco.canvasdesigner.border" class="bordereditor">
<div class="box-slider">
<ul class="box-preview">
<li ng-repeat="border in borderList" class="border-{{border}}" ng-class="{selected: selectedBorder.name == border}" ng-click="setselectedBorder(border)"></li>
</ul>
</div>
<div class="box-slider" ng-repeat="border in borderList" ng-show="selectedBorder.name == border">
<div colorpicker ng-model="item.values[(border !== 'all' ? border : '') + 'bordercolor']"></div>
<select class="borderStyleSelect" ng-model="selectedBorder.type" ng-options="bordertype for bordertype in bordertypes"></select>
<!--<i ng-if="selectedBorder.color != ''" ng-click="selectedBorder.color= ''" class="icon icon-delete colorPickerDelete"></i>-->
</div>
<div class="box-slider">
<div ui-slider min="0" max="40" step="1" ng-model="selectedBorder.size"></div>
</div>
</div>

View File

@@ -1,4 +0,0 @@
@inherits System.Web.Mvc.WebViewPage
<div class="box-slider">
<div colorpicker ng-model="item.values.color"></div>
</div>

View File

@@ -1,34 +0,0 @@
@inherits System.Web.Mvc.WebViewPage
<div ng-controller="Umbraco.canvasdesigner.googlefontpicker">
<div class="box-slider">
<div class="fontFamilyPickerPreview" ng-click="open(item.values)" ng-style="setStyleVariant()">
<span>Aa</span>
{{ item.values.fontFamily }}
<i ng-if="item.values.fontFamily != ''" ng-click="item.values.fontFamily = ''" class="icon icon-delete fontPickerDelete"></i>
</div>
</div>
</div>
<script type="text/ng-template" id="googlefontdialog.html">
<div ng-controller="googlefontdialog.controller">
<div class="modal-header canvasdesigner-fontfamilypicker">
<select class="font-list" ng-model="selectedFont" ng-change="showFontPreview(selectedFont)" ng-options="font as font.fontFamily group by font.fontType for font in fonts"></select>
<select class="variant-list" ng-model="selectedFont.variant" ng-change="showFontPreview(selectedFont,selectedFont.variant)" ng-options="variant for variant in selectedFont.variants" />
</div>
<div class="modal-body canvasdesigner-fontfamilypicker">
<span class="show" ng-style="setStyleVariant()">Aa Bb Cc 1 2 3 4&hellip; <br />The quick brown fox jumps over the lazy dog&hellip;</span>
</div>
<div class="right">
<a class="btn" href="#" ng-click="cancelAndClose()">Cancel</a>
<a class="btn btn-success" href="#" ng-click="submitAndClose()">Done</a>
</div>
</div>
</script>

View File

@@ -1,8 +0,0 @@
@inherits System.Web.Mvc.WebViewPage
<div ng-controller="Umbraco.canvasdesigner.gridRow">
<div class="box-slider">
<input type="checkbox" ng-model="item.values.fullsize" /><label>Full size</label>
</div>
</div>

View File

@@ -1,16 +1,30 @@
@using System.Web.Mvc.Html
@inherits System.Web.Mvc.WebViewPage<Umbraco.Web.Models.ContentEditing.BackOfficePreview>
@using Umbraco.Core
@using ClientDependency.Core
@using ClientDependency.Core.Mvc
@using Umbraco.Core.IO
@using Umbraco.Web
@using Umbraco.Core.Configuration
@inherits System.Web.Mvc.WebViewPage<Umbraco.Web.Editors.BackOfficePreviewModel>
@{
var disableDevicePreview = Model.DisableDevicePreview.ToString().ToLowerInvariant();
Html
.RequiresCss("assets/css/canvasdesigner.css", "Umbraco");
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Umbraco Canvas Designer</title>
<link href="../assets/css/canvasdesigner.css" type="text/css" rel="stylesheet" />
<meta charset="utf-8">
<title>Umbraco Preview</title>
<meta name="robots" content="noindex, nofollow">
<meta name="pinterest" content="nopin" />
@Html.RenderCssHere(
new BasicPath("Umbraco", IOHelper.ResolveUrl(SystemDirectories.Umbraco)))
</head>
<body id="canvasdesignerPanel" ng-mouseover="outlinePositionHide()" ng-controller="Umbraco.canvasdesignerController">
<body id="canvasdesignerPanel" ng-mouseover="outlinePositionHide()" ng-controller="previewController">
<div class="wait" ng-show="!frameLoaded"></div>
@if (string.IsNullOrWhiteSpace(Model.PreviewExtendedHeaderView) == false)
@@ -18,8 +32,8 @@
@Html.Partial(Model.PreviewExtendedHeaderView)
}
<div id="demo-iframe-wrapper" ng-if="pageUrl" ng-show="frameLoaded" class="{{previewDevice.css}}">
<preview-i-frame src="{{pageUrl}}" on-loaded="onFrameLoaded()"></preview-i-frame>
<div id="demo-iframe-wrapper" ng-show="frameLoaded && pageUrl" class="{{previewDevice.css}}">
<preview-i-frame src="pageUrl" on-loaded="onFrameLoaded(iframe)"></preview-i-frame>
</div>
<div class="canvasdesigner" ng-init="showDevicesPreview = true; showDevices = !@(disableDevicePreview);" ng-mouseenter="positionSelectedHide()">
<div class="fix-left-menu selected">
@@ -29,17 +43,19 @@
../assets/img/application/logo@3x.png 3x" />
</div>
<ul class="sections" ng-class="{selected: showDevicesPreview && showDevices}">
<li ng-repeat="device in devices" ng-class="{ current:previewDevice==device }" ng-click="updatePreviewDevice(device)">
<a href="#"><i class="icon {{device.icon}}" title="{{device.title}}"></i><span></span></a>
<li ng-repeat="device in devices" ng-class="{ current:previewDevice==device }">
<a href="" ng-click="updatePreviewDevice(device)"><i class="icon {{device.icon}}" title="{{device.title}}"></i><span></span></a>
</li>
<li ng-click="exitPreview()">
<a href="#" title="Exit Preview"><i class="icon icon-wrong"></i><span> </span></a>
<li>
<a href="" ng-click="exitPreview()" title="Exit Preview"><i class="icon icon-wrong"></i><span> </span></a>
</li>
</ul>
</div>
</div>
<script src="../lib/rgrove-lazyload/lazyload.js"></script>
<script src="../js/canvasdesigner.loader.js"></script>
<script src="@Url.GetUrlWithCacheBust("Application", "Preview")"></script>
</body>
</html>

View File

@@ -1,10 +0,0 @@
@inherits System.Web.Mvc.WebViewPage
<div ng-controller="Umbraco.canvasdesigner.layout">
<div class="box-slider">
<input type="radio" ng-model="item.values.layout" value="box"> Box
<input type="radio" ng-model="item.values.layout" value="wide"> Wide
<input type="radio" ng-model="item.values.layout" value="full"> Full
</div>
</div>

View File

@@ -1,14 +0,0 @@
@inherits System.Web.Mvc.WebViewPage
<div ng-controller="Umbraco.canvasdesigner.margin">
<div class="box-slider">
<ul class="box-preview">
<li ng-repeat="margin in marginList" class="border-{{margin}}" ng-class="{selected: selectedmargin.name == margin}" ng-click="setSelectedmargin(margin)"></li>
</ul>
</div>
<div class="box-slider">
<div ui-slider min="0" max="400" step="1" ng-model="selectedmargin.value"></div>
</div>
</div>

View File

@@ -1,14 +0,0 @@
@inherits System.Web.Mvc.WebViewPage
<div ng-controller="Umbraco.canvasdesigner.padding">
<div class="box-slider">
<ul class="box-preview">
<li ng-repeat="padding in paddingList" class="border-{{padding}}" ng-class="{selected: selectedpadding.name == padding}" ng-click="setSelectedpadding(padding)"></li>
</ul>
</div>
<div class="box-slider">
<div ui-slider min="0" max="400" step="1" ng-model="selectedpadding.value"></div>
</div>
</div>

View File

@@ -1,21 +0,0 @@
@inherits System.Web.Mvc.WebViewPage
<div ng-controller="Umbraco.canvasdesigner.radius">
<div class="box-slider">
<ul class="box-preview">
<li ng-repeat="radius in radiusList" ng-class="{selected: selectedradius.name == radius}" ng-click="setSelectedradius(radius)">
<span ng-show="radius == 'topleft' || radius == 'all'" class="radius-top-left"></span>
<span ng-show="radius == 'topright' || radius == 'all'" class="radius-top-right"></span>
<span ng-show="radius == 'bottomleft' || radius == 'all'" class="radius-bottom-left"></span>
<span ng-show="radius == 'bottomright' || radius == 'all'" class="radius-bottom-right"></span>
</li>
</ul>
</div>
<div class="box-slider">
<div ui-slider min="0" max="40" step="1" ng-model="selectedradius.value"></div>
</div>
</div>

View File

@@ -1,8 +0,0 @@
@inherits System.Web.Mvc.WebViewPage
<div ng-controller="Umbraco.canvasdesigner.shadow">
<div class="box-slider">
<div ui-slider min="0" max="100" step="1" ng-model="item.values.shadow"></div>
</div>
</div>

View File

@@ -1,8 +0,0 @@
@inherits System.Web.Mvc.WebViewPage
<div ng-controller="Umbraco.canvasdesigner.slider">
<div class="box-slider">
<div ui-slider min="{{item.min}}" max="{{item.max}}" step="1" ng-model="item.values.slider"></div>
</div>
</div>

View File

@@ -44,7 +44,7 @@ namespace Umbraco.Web.Editors
/// Represents a controller user to render out the default back office view and JS results.
/// </summary>
[UmbracoRequireHttps]
[DisableClientCache]
[DisableBrowserCache]
public class BackOfficeController : UmbracoController
{
private readonly ManifestParser _manifestParser;
@@ -192,7 +192,8 @@ namespace Umbraco.Web.Editors
//get the legacy ActionJs file references to append as well
var legacyActionJsRef = GetLegacyActionJs(LegacyJsActionType.JsUrl);
var result = initJs.GetJavascriptInitialization(HttpContext, JsInitialization.GetDefaultInitialization(), legacyActionJsRef);
var files = initJs.OptimizeBackOfficeScriptFiles(HttpContext, JsInitialization.GetDefaultInitialization(), legacyActionJsRef);
var result = JsInitialization.GetJavascriptInitialization(HttpContext, files, "umbraco");
result += initCss.GetStylesheetInitialization(HttpContext);
return JavaScript(result);
@@ -211,7 +212,7 @@ namespace Umbraco.Web.Editors
var initJs = new JsInitialization(_manifestParser);
var initCss = new CssInitialization(_manifestParser);
var assets = new List<string>();
assets.AddRange(initJs.GetScriptFiles(HttpContext, Enumerable.Empty<string>()));
assets.AddRange(initJs.OptimizeBackOfficeScriptFiles(HttpContext, Enumerable.Empty<string>()));
assets.AddRange(initCss.GetStylesheetFiles(HttpContext));
return new JArray(assets);
}

View File

@@ -3,6 +3,7 @@ using Umbraco.Web.Features;
namespace Umbraco.Web.Editors
{
public class BackOfficeModel
{
public BackOfficeModel(UmbracoFeatures features, IGlobalSettings globalSettings)

View File

@@ -0,0 +1,15 @@
using Umbraco.Core.Configuration;
using Umbraco.Web.Features;
namespace Umbraco.Web.Editors
{
public class BackOfficePreviewModel : BackOfficeModel
{
public BackOfficePreviewModel(UmbracoFeatures features, IGlobalSettings globalSettings) : base(features, globalSettings)
{
}
public bool DisableDevicePreview => Features.Disabled.DisableDevicePreview;
public string PreviewExtendedHeaderView => Features.Enabled.PreviewExtendedView;
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Web.Composing;
@@ -8,6 +9,7 @@ using Umbraco.Web.Features;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Mvc;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.UI.JavaScript;
using Constants = Umbraco.Core.Constants;
namespace Umbraco.Web.Editors
@@ -29,13 +31,10 @@ namespace Umbraco.Web.Editors
}
[UmbracoAuthorize(redirectToUmbracoLogin: true)]
[DisableBrowserCache]
public ActionResult Index()
{
var model = new BackOfficePreview
{
DisableDevicePreview = _features.Disabled.DisableDevicePreview,
PreviewExtendedHeaderView = _features.Enabled.PreviewExtendedView
};
var model = new BackOfficePreviewModel(_features, _globalSettings);
if (model.PreviewExtendedHeaderView.IsNullOrWhiteSpace() == false)
{
@@ -49,6 +48,20 @@ namespace Umbraco.Web.Editors
return View(_globalSettings.Path.EnsureEndsWith('/') + "Views/Preview/" + "Index.cshtml", model);
}
/// <summary>
/// Returns the JavaScript file for preview
/// </summary>
/// <returns></returns>
[MinifyJavaScriptResult(Order = 0)]
[OutputCache(Order = 1, VaryByParam = "none", Location = OutputCacheLocation.Server, Duration = 5000)]
public JavaScriptResult Application()
{
var files = JsInitialization.OptimizeScriptFiles(HttpContext, JsInitialization.GetPreviewInitialization());
var result = JsInitialization.GetJavascriptInitialization(HttpContext, files, "umbraco.preview");
return JavaScript(result);
}
/// <summary>
/// The endpoint that is loaded within the preview iframe
/// </summary>
@@ -68,11 +81,11 @@ namespace Umbraco.Web.Editors
return null;
}
//fixme: not sure we need this anymore since there is no canvas editing - then we can remove that route too
public ActionResult Editors(string editor)
{
if (string.IsNullOrEmpty(editor)) throw new ArgumentNullException(nameof(editor));
return View(_globalSettings.Path.EnsureEndsWith('/') + "Views/Preview/" + editor.Replace(".html", string.Empty) + ".cshtml");
}
////fixme: not sure we need this anymore since there is no canvas editing - then we can remove that route too
//public ActionResult Editors(string editor)
//{
// if (string.IsNullOrEmpty(editor)) throw new ArgumentNullException(nameof(editor));
// return View(_globalSettings.Path.EnsureEndsWith('/') + "Views/Preview/" + editor.Replace(".html", string.Empty) + ".cshtml");
//}
}
}

View File

@@ -1,13 +0,0 @@
namespace Umbraco.Web.Models.ContentEditing
{
/// <summary>
/// The model representing Previewing of a content item from the back office
/// </summary>
public class BackOfficePreview
{
public string PreviewExtendedHeaderView { get; set; }
//TODO: We could potentially have a 'footer' view
public bool DisableDevicePreview { get; set; }
}
}

View File

@@ -9,9 +9,9 @@ namespace Umbraco.Web.Mvc
/// </summary>
public class DisableBrowserCacheAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
base.OnActionExecuted(filterContext);
base.OnResultExecuting(filterContext);
// could happens if exception (but afaik this wouldn't happen in MVC)
if (filterContext.HttpContext == null || filterContext.HttpContext.Response == null ||
@@ -20,6 +20,13 @@ namespace Umbraco.Web.Mvc
return;
}
if (filterContext.IsChildAction)
{
return;
}
filterContext.HttpContext.Response.Cache.SetLastModified(DateTime.Now);
filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetMaxAge(TimeSpan.Zero);
filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);

View File

@@ -1,26 +0,0 @@
using System;
using System.Web;
using System.Web.Mvc;
namespace Umbraco.Web.Mvc
{
/// <summary>
/// Will ensure that client-side cache does not occur by sending the correct response headers
/// </summary>
public class DisableClientCacheAttribute : ActionFilterAttribute
{
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
if (filterContext.IsChildAction) base.OnResultExecuting(filterContext);
filterContext.HttpContext.Response.Cache.SetExpires(DateTime.Now.AddDays(-10));
filterContext.HttpContext.Response.Cache.SetLastModified(DateTime.Now);
filterContext.HttpContext.Response.Cache.SetValidUntilExpires(false);
filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
filterContext.HttpContext.Response.Cache.SetNoStore();
base.OnResultExecuting(filterContext);
}
}
}

View File

@@ -28,7 +28,7 @@ namespace Umbraco.Web.UI.JavaScript
return toParse.Split(new[] { DependencyPathRenderer.Delimiter }, StringSplitOptions.RemoveEmptyEntries);
}
protected IEnumerable<string> OptimizeAssetCollection(IEnumerable<string> assets, ClientDependencyType assetType, HttpContextBase httpContext)
internal static IEnumerable<string> OptimizeAssetCollection(IEnumerable<string> assets, ClientDependencyType assetType, HttpContextBase httpContext)
{
if (httpContext == null) throw new ArgumentNullException(nameof(httpContext));
@@ -41,11 +41,11 @@ namespace Umbraco.Web.UI.JavaScript
// ike lib/blah/blah.js so we need to turn them into absolutes here
if (x.StartsWith("/") == false && Uri.IsWellFormedUriString(x, UriKind.Relative))
{
return (IClientDependencyFile) new BasicFile(assetType) { FilePath = new Uri(requestUrl, x).AbsolutePath };
return new BasicFile(assetType) { FilePath = new Uri(requestUrl, x).AbsolutePath };
}
return assetType == ClientDependencyType.Javascript
? (IClientDependencyFile) new JavascriptFile(x)
? new JavascriptFile(x)
: (IClientDependencyFile) new CssFile(x);
}).ToList();

View File

@@ -33,16 +33,20 @@ namespace Umbraco.Web.UI.JavaScript
private static readonly Regex Token = new Regex("(\"##\\w+?##\")", RegexOptions.Compiled);
/// <summary>
/// Processes all found manifest files and outputs the main.js file containing all plugin manifests
/// Gets the JS initialization script to boot the back office application
/// </summary>
public string GetJavascriptInitialization(HttpContextBase httpContext, IEnumerable<string> umbracoInit, IEnumerable<string> additionalJsFiles = null)
/// <param name="httpContext"></param>
/// <param name="scripts"></param>
/// <param name="angularModule">
/// The angular module name to boot
/// </param>
/// <returns></returns>
public static string GetJavascriptInitialization(HttpContextBase httpContext, IEnumerable<string> scripts, string angularModule)
{
var files = GetScriptFiles(httpContext, umbracoInit, additionalJsFiles);
var jarray = new StringBuilder();
jarray.AppendLine("[");
var first = true;
foreach (var file in files)
foreach (var file in scripts)
{
if (first) first = false;
else jarray.AppendLine(",");
@@ -53,10 +57,22 @@ namespace Umbraco.Web.UI.JavaScript
}
jarray.Append("]");
return WriteScript(jarray.ToString(), IOHelper.ResolveUrl(SystemDirectories.Umbraco));
return WriteScript(jarray.ToString(), IOHelper.ResolveUrl(SystemDirectories.Umbraco), angularModule);
}
public IEnumerable<string> GetScriptFiles(HttpContextBase httpContext, IEnumerable<string> umbracoInit, IEnumerable<string> additionalJsFiles = null)
/// <summary>
/// Returns a list of optimized script paths for the back office
/// </summary>
/// <param name="httpContext"></param>
/// <param name="umbracoInit"></param>
/// <param name="additionalJsFiles"></param>
/// <returns>
/// Cache busted/optimized script paths for the back office including manifest and property editor scripts
/// </returns>
/// <remarks>
/// Used to cache bust and optimize script paths for the back office
/// </remarks>
public IEnumerable<string> OptimizeBackOfficeScriptFiles(HttpContextBase httpContext, IEnumerable<string> umbracoInit, IEnumerable<string> additionalJsFiles = null)
{
var scripts = new HashSet<string>();
foreach (var script in umbracoInit)
@@ -75,6 +91,26 @@ namespace Umbraco.Web.UI.JavaScript
return scripts.ToArray();
}
/// <summary>
/// Returns a list of optimized script paths
/// </summary>
/// <param name="httpContext"></param>
/// <param name="scriptFiles"></param>
/// <returns></returns>
/// <remarks>
/// Used to cache bust and optimize script paths
/// </remarks>
public static IEnumerable<string> OptimizeScriptFiles(HttpContextBase httpContext, IEnumerable<string> scriptFiles)
{
var scripts = new HashSet<string>();
foreach (var script in scriptFiles)
scripts.Add(script);
scripts = new HashSet<string>(OptimizeAssetCollection(scripts, ClientDependencyType.Javascript, httpContext));
return scripts.ToArray();
}
/// <summary>
/// Returns the default config as a JArray
/// </summary>
@@ -85,15 +121,25 @@ namespace Umbraco.Web.UI.JavaScript
return resources.Where(x => x.Type == JTokenType.String).Select(x => x.ToString());
}
/// <summary>
/// Returns the default config as a JArray
/// </summary>
/// <returns></returns>
internal static IEnumerable<string> GetPreviewInitialization()
{
var resources = JsonConvert.DeserializeObject<JArray>(Resources.PreviewInitialize);
return resources.Where(x => x.Type == JTokenType.String).Select(x => x.ToString());
}
/// <summary>
/// Parses the JsResources.Main and replaces the replacement tokens accordingly.
/// </summary>
/// <param name="replacements"></param>
/// <returns></returns>
internal static string WriteScript(params string[] replacements)
internal static string WriteScript(string scripts, string umbracoPath, string angularModule)
{
var count = 0;
var replacements = new[] { scripts, umbracoPath, angularModule };
// replace, catering for the special syntax when we have
// js function() objects contained in the json

View File

@@ -1,10 +1,12 @@
LazyLoad.js("##JsInitialize##", function () {
//we need to set the legacy UmbClientMgr path
UmbClientMgr.setUmbracoPath('"##UmbracoPath##"');
if ((typeof UmbClientMgr) !== "undefined") {
UmbClientMgr.setUmbracoPath('"##UmbracoPath##"');
}
jQuery(document).ready(function () {
angular.bootstrap(document, ['umbraco']);
angular.bootstrap(document, ['"##AngularModule##"']);
});
});
});

View File

@@ -0,0 +1,14 @@
[
'../lib/jquery/jquery.min.js',
'../lib/angular/angular.js',
'../lib/underscore/underscore-min.js',
'../lib/umbraco/Extensions.js',
'../js/app.js',
'../js/umbraco.resources.js',
'../js/umbraco.services.js',
'../js/umbraco.interceptors.js',
'../ServerVariables',
'../lib/signalr/jquery.signalR.js',
'../BackOffice/signalr/hubs',
'../js/umbraco.preview.js'
]

View File

@@ -63,22 +63,22 @@ namespace Umbraco.Web.UI.JavaScript {
/// <summary>
/// Looks up a localized string similar to [
/// &apos;lib/jquery/jquery.min.js&apos;,
/// &apos;lib/angular/1.1.5/angular.min.js&apos;,
/// &apos;lib/jquery-ui/jquery-ui.min.js&apos;,
/// &apos;lib/jquery-ui-touch-punch/jquery.ui.touch-punch.js&apos;,
///
/// &apos;lib/angular/angular.js&apos;,
/// &apos;lib/underscore/underscore-min.js&apos;,
///
/// &apos;lib/moment/moment.min.js&apos;,
///
/// &apos;lib/jquery-ui/jquery-ui.min.js&apos;,
/// &apos;lib/jquery-ui-touch-punch/jquery.ui.touch-punch.js&apos;,
/// &apos;lib/animejs/anime.min.js&apos;,
///
/// &apos;lib/angular/1.1.5/angular-cookies.min.js&apos;,
/// &apos;lib/angular/1.1.5/angular-mobile.js&apos;,
/// &apos;lib/angular/1.1.5/angular-sanitize.min.js&apos;,
///
/// &apos;lib/angular/angular-ui-sortable.js&apos;,
///
/// &apos;lib/angular-dynamic-locale/tmhDynamicLocale.min.js&apos;,
/// &apos;lib [rest of string was truncated]&quot;;.
/// &apos;lib/angular-route/angular-route.js&apos;,
/// &apos;lib/angular-cookies/angular-cookies.js&apos;,
/// &apos;lib/angular-touch/angular-touch.js&apos;,
/// &apos;lib/angular-sanitize/angular-sanitize.js&apos;,
/// &apos;lib/angular-animate/angular-animate.js&apos;,
/// [rest of string was truncated]&quot;;.
/// </summary>
internal static string JsInitialize {
get {
@@ -93,10 +93,11 @@ namespace Umbraco.Web.UI.JavaScript {
///
/// jQuery(document).ready(function () {
///
/// angular.bootstrap(document, [&apos;umbraco&apos;]);
/// angular.bootstrap(document, [&apos;##AngularModule##&apos;]);
///
/// });
///});.
///});
///.
/// </summary>
internal static string Main {
get {
@@ -104,6 +105,29 @@ namespace Umbraco.Web.UI.JavaScript {
}
}
/// <summary>
/// Looks up a localized string similar to [
/// &apos;../lib/jquery/jquery.min.js&apos;,
/// &apos;../lib/angular/angular.js&apos;,
/// &apos;../lib/underscore/underscore-min.js&apos;,
/// &apos;../lib/umbraco/Extensions.js&apos;,
/// &apos;../js/app.js&apos;,
/// &apos;../js/umbraco.resources.js&apos;,
/// &apos;../js/umbraco.services.js&apos;,
/// &apos;../js/umbraco.interceptors.js&apos;,
/// &apos;../ServerVariables&apos;,
/// &apos;../lib/signalr/jquery.signalR.js&apos;,
/// &apos;../BackOffice/signalr/hubs&apos;,
/// &apos;../js/umbraco.canvasdesigner.js&apos;
///]
///.
/// </summary>
internal static string PreviewInitialize {
get {
return ResourceManager.GetString("PreviewInitialize", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to //TODO: This would be nicer as an angular module so it can be injected into stuff... that&apos;d be heaps nicer, but
///// how to do that when this is not a regular JS file, it is a server side JS file and RequireJS seems to only want

View File

@@ -124,6 +124,9 @@
<data name="Main" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Main.js;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
</data>
<data name="PreviewInitialize" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>previewinitialize.js;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="ServerVariables" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>servervariables.js;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>

View File

@@ -111,6 +111,7 @@
<Compile Include="Cache\UserGroupCacheRefresher.cs" />
<Compile Include="Cache\UserGroupPermissionsCacheRefresher.cs" />
<Compile Include="Components\BackOfficeUserAuditEventsComponent.cs" />
<Compile Include="Editors\BackOfficePreviewModel.cs" />
<Compile Include="Media\Exif\BitConverterEx.cs" />
<Compile Include="Media\Exif\ExifBitConverter.cs" />
<Compile Include="Media\Exif\ExifEnums.cs" />
@@ -258,7 +259,6 @@
<Compile Include="Models\BackOfficeTourStep.cs" />
<Compile Include="Models\ContentEditing\AssignedContentPermissions.cs" />
<Compile Include="Models\ContentEditing\AssignedUserGroupPermissions.cs" />
<Compile Include="Models\ContentEditing\BackOfficePreview.cs" />
<Compile Include="Models\ContentEditing\CodeFileDisplay.cs" />
<Compile Include="Models\ContentEditing\ContentApp.cs" />
<Compile Include="Models\ContentEditing\ContentRedirectUrl.cs" />
@@ -637,7 +637,6 @@
<Compile Include="ITagQuery.cs" />
<Compile Include="IUmbracoComponentRenderer.cs" />
<Compile Include="Models\Mapping\RelationMapperProfile.cs" />
<Compile Include="Mvc\DisableClientCacheAttribute.cs" />
<Compile Include="Models\UnLinkLoginModel.cs" />
<Compile Include="Mvc\MvcVersionCheck.cs" />
<Compile Include="Scheduling\ThreadingTaskImmutable.cs" />
@@ -1451,6 +1450,7 @@
<WebReferences Include="Web References\" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="UI\JavaScript\PreviewInitialize.js" />
<Content Include="umbraco.presentation\umbraco\webservices\CheckForUpgrade.asmx" />
<Content Include="umbraco.presentation\umbraco\translation\default.aspx">
<SubType>ASPXCodeBehind</SubType>