merge
This commit is contained in:
@@ -43,7 +43,8 @@ function valToggleMsg(serverValidationManager) {
|
||||
}
|
||||
});
|
||||
|
||||
scope.$on("saving", function(ev, args) {
|
||||
//listen for the saving event (the result is a callback method which is called to unsubscribe)
|
||||
var unsubscribeSaving = scope.$on("saving", function (ev, args) {
|
||||
showValidation = true;
|
||||
if (formCtrl[attr.valMsgFor].$error[attr.valToggleMsg]) {
|
||||
element.show();
|
||||
@@ -57,11 +58,20 @@ function valToggleMsg(serverValidationManager) {
|
||||
}
|
||||
});
|
||||
|
||||
scope.$on("saved", function (ev, args) {
|
||||
//listen for the saved event (the result is a callback method which is called to unsubscribe)
|
||||
var unsubscribeSaved = scope.$on("saved", function (ev, args) {
|
||||
showValidation = false;
|
||||
element.hide();
|
||||
});
|
||||
|
||||
//when the element is disposed we need to unsubscribe!
|
||||
// NOTE: this is very important otherwise if this directive is part of a modal, the listener still exists because the dom
|
||||
// element might still be there even after the modal has been hidden.
|
||||
element.bind('$destroy', function () {
|
||||
unsubscribeSaving();
|
||||
unsubscribeSaved();
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -128,16 +128,29 @@ function entityResource($q, $http, umbRequestHelper) {
|
||||
* </pre>
|
||||
*
|
||||
* @param {string} type Object type name
|
||||
* @param {string} postFilter optional filter expression which will execute a dynamic where clause on the server
|
||||
* @param {string} postFilterParams optional parameters for the postFilter expression
|
||||
* @returns {Promise} resourcePromise object containing the entity.
|
||||
*
|
||||
*/
|
||||
getAll: function (type) {
|
||||
getAll: function (type, postFilter, postFilterParams) {
|
||||
|
||||
//need to build the query string manually
|
||||
var query = "type=" + type + "&postFilter=" + (postFilter ? postFilter : "");
|
||||
if (postFilter && postFilterParams) {
|
||||
var counter = 0;
|
||||
_.each(postFilterParams, function(val, key) {
|
||||
query += "&postFilterParams[" + counter + "].key=" + key + "&postFilterParams[" + counter + "].value=" + val;
|
||||
counter++;
|
||||
});
|
||||
}
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"entityApiBaseUrl",
|
||||
"GetAll",
|
||||
[{type: type }])),
|
||||
query)),
|
||||
'Failed to retreive entity data for type ' + type);
|
||||
},
|
||||
|
||||
|
||||
@@ -40,15 +40,27 @@ function macroResource($q, $http, umbRequestHelper) {
|
||||
*
|
||||
* @param {int} macroId The macro id to get parameters for
|
||||
* @param {int} pageId The current page id
|
||||
* @param {Array} macroParamDictionary A dictionary of macro parameters
|
||||
*
|
||||
*/
|
||||
getMacroResultAsHtmlForEditor: function (macroAlias, pageId) {
|
||||
getMacroResultAsHtmlForEditor: function (macroAlias, pageId, macroParamDictionary) {
|
||||
|
||||
//need to format the query string for the custom dictionary
|
||||
var query = "macroAlias=" + macroAlias + "&pageId=" + pageId;
|
||||
if (macroParamDictionary) {
|
||||
var counter = 0;
|
||||
_.each(macroParamDictionary, function(val, key) {
|
||||
query += "¯oParams[" + counter + "].key=" + key + "¯oParams[" + counter + "].value=" + val;
|
||||
counter++;
|
||||
});
|
||||
}
|
||||
|
||||
return umbRequestHelper.resourcePromise(
|
||||
$http.get(
|
||||
umbRequestHelper.getApiUrl(
|
||||
"macroApiBaseUrl",
|
||||
"GetMacroResultAsHtmlForEditor",
|
||||
[{ macroAlias: macroAlias }, { pageId: pageId }])),
|
||||
query)),
|
||||
'Failed to retreive macro result for macro with alias ' + macroAlias);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,11 +26,11 @@ function macroService() {
|
||||
var paramExpression = new RegExp("(\\w+?)=['\"](.*?)['\"]", "g");
|
||||
var paramMatch;
|
||||
var returnVal = {
|
||||
alias: alias,
|
||||
params: []
|
||||
macroAlias: alias,
|
||||
marcoParamsDictionary: {}
|
||||
};
|
||||
while (paramMatch = paramExpression.exec(paramsChunk)) {
|
||||
returnVal.params.push({ alias: paramMatch[1], value: paramMatch[2] });
|
||||
returnVal.marcoParamsDictionary[paramMatch[1]] = paramMatch[2];
|
||||
}
|
||||
return returnVal;
|
||||
},
|
||||
@@ -52,12 +52,13 @@ function macroService() {
|
||||
|
||||
var macroString = '<?UMBRACO_MACRO macroAlias=\"' + args.macroAlias + "\" ";
|
||||
|
||||
if (args.macroParams) {
|
||||
for (var i = 0; i < args.macroParams.length; i++) {
|
||||
if (args.marcoParamsDictionary) {
|
||||
|
||||
var keyVal = args.macroParams[i].alias + "=\"" + (args.macroParams[i].value ? args.macroParams[i].value : "") + "\" ";
|
||||
_.each(args.marcoParamsDictionary, function (val, key) {
|
||||
var keyVal = key + "=\"" + (val ? val : "") + "\" ";
|
||||
macroString += keyVal;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
macroString += "/>";
|
||||
@@ -80,12 +81,13 @@ function macroService() {
|
||||
|
||||
var macroString = '<umbraco:Macro ';
|
||||
|
||||
if (args.macroParams) {
|
||||
for (var i = 0; i < args.macroParams.length; i++) {
|
||||
|
||||
var keyVal = args.macroParams[i].alias + "=\"" + (args.macroParams[i].value ? args.macroParams[i].value : "") + "\" ";
|
||||
if (args.marcoParamsDictionary) {
|
||||
|
||||
_.each(args.marcoParamsDictionary, function (val, key) {
|
||||
var keyVal = key + "=\"" + (val ? val : "") + "\" ";
|
||||
macroString += keyVal;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
macroString += "Alias=\"" + args.macroAlias + "\" runat=\"server\"></umbraco:Macro>";
|
||||
@@ -108,19 +110,28 @@ function macroService() {
|
||||
|
||||
var macroString = "@Umbraco.RenderMacro(\"" + args.macroAlias + "\"";
|
||||
|
||||
if (args.macroParams && args.macroParams.length > 0) {
|
||||
macroString += ", new {";
|
||||
for (var i = 0; i < args.macroParams.length; i++) {
|
||||
|
||||
var keyVal = args.macroParams[i].alias + "=\"" + (args.macroParams[i].value ? args.macroParams[i].value : "") + "\"";
|
||||
var hasParams = false;
|
||||
var paramString;
|
||||
if (args.marcoParamsDictionary) {
|
||||
|
||||
paramString = ", new {";
|
||||
|
||||
macroString += keyVal;
|
||||
_.each(args.marcoParamsDictionary, function(val, key) {
|
||||
|
||||
hasParams = true;
|
||||
|
||||
if (i < args.macroParams.length - 1) {
|
||||
macroString += ", ";
|
||||
}
|
||||
}
|
||||
macroString += "}";
|
||||
var keyVal = key + "=\"" + (val ? val : "") + "\", ";
|
||||
|
||||
paramString += keyVal;
|
||||
});
|
||||
|
||||
//remove the last ,
|
||||
paramString = paramString.trimEnd(", ");
|
||||
|
||||
paramString += "}";
|
||||
}
|
||||
if (hasParams) {
|
||||
macroString += paramString;
|
||||
}
|
||||
|
||||
macroString += ")";
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
* @description
|
||||
* A service containing all logic for all of the Umbraco TinyMCE plugins
|
||||
*/
|
||||
function tinyMceService(dialogService, $log, imageHelper, assetsService, $timeout, macroResource, macroService) {
|
||||
function tinyMceService(dialogService, $log, imageHelper, assetsService, $timeout, macroResource, macroService, $routeParams) {
|
||||
return {
|
||||
|
||||
/**
|
||||
@@ -22,7 +22,7 @@ function tinyMceService(dialogService, $log, imageHelper, assetsService, $timeou
|
||||
*/
|
||||
createInsertEmbeddedMedia: function (editor, $scope) {
|
||||
editor.addButton('umbembeddialog', {
|
||||
icon: 'media',
|
||||
icon: 'custom icon-tv',
|
||||
tooltip: 'Embed',
|
||||
onclick: function () {
|
||||
dialogService.embedDialog({
|
||||
@@ -162,6 +162,41 @@ function tinyMceService(dialogService, $log, imageHelper, assetsService, $timeou
|
||||
return null;
|
||||
}
|
||||
|
||||
/** loads in the macro content async from the server */
|
||||
function loadMacroContent($macroDiv, macroData) {
|
||||
|
||||
//if we don't have the macroData, then we'll need to parse it from the macro div
|
||||
if (!macroData) {
|
||||
var contents = $macroDiv.contents();
|
||||
var comment = _.find(contents, function (item) {
|
||||
return item.nodeType === 8;
|
||||
});
|
||||
if (!comment) {
|
||||
throw "Cannot parse the current macro, the syntax in the editor is invalid";
|
||||
}
|
||||
var syntax = comment.textContent.trim();
|
||||
var parsed = macroService.parseMacroSyntax(syntax);
|
||||
macroData = parsed;
|
||||
}
|
||||
|
||||
var $ins = $macroDiv.find("ins");
|
||||
|
||||
//show the throbber
|
||||
$macroDiv.addClass("loading");
|
||||
|
||||
var contentId = $routeParams.id;
|
||||
|
||||
macroResource.getMacroResultAsHtmlForEditor(macroData.macroAlias, contentId, macroData.marcoParamsDictionary)
|
||||
.then(function (htmlResult) {
|
||||
|
||||
$macroDiv.removeClass("loading");
|
||||
htmlResult = htmlResult.trim();
|
||||
if (htmlResult !== "") {
|
||||
$ins.html(htmlResult);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** Adds the button instance */
|
||||
editor.addButton('umbmacro', {
|
||||
icon: 'custom icon-settings-alt',
|
||||
@@ -171,6 +206,57 @@ function tinyMceService(dialogService, $log, imageHelper, assetsService, $timeou
|
||||
var ctrl = this;
|
||||
var isOnMacroElement = false;
|
||||
|
||||
/**
|
||||
if the selection comes from a different element that is not the macro's
|
||||
we need to check if the selection includes part of the macro, if so we'll force the selection
|
||||
to clear to the next element since if people can select part of the macro markup they can then modify it.
|
||||
*/
|
||||
function handleSelectionChange() {
|
||||
|
||||
if (!editor.selection.isCollapsed()) {
|
||||
var endSelection = tinymce.activeEditor.selection.getEnd();
|
||||
var startSelection = tinymce.activeEditor.selection.getStart();
|
||||
//don't proceed if it's an entire element selected
|
||||
if (endSelection !== startSelection) {
|
||||
|
||||
//if the end selection is a macro then move the cursor
|
||||
//NOTE: we don't have to handle when the selection comes from a previous parent because
|
||||
// that is automatically taken care of with the normal onNodeChanged logic since the
|
||||
// evt.element will be the macro once it becomes part of the selection.
|
||||
var $testForMacro = $(endSelection).closest(".umb-macro-holder");
|
||||
if ($testForMacro.length > 0) {
|
||||
|
||||
//it came from before so move after, if there is no after then select ourselves
|
||||
var next = $testForMacro.next();
|
||||
if (next.length > 0) {
|
||||
editor.selection.setCursorLocation($testForMacro.next().get(0));
|
||||
}
|
||||
else {
|
||||
selectMacroElement($testForMacro.get(0));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** helper method to select the macro element */
|
||||
function selectMacroElement(macroElement) {
|
||||
// move selection to top element to ensure we can't edit this
|
||||
editor.selection.select(macroElement);
|
||||
|
||||
// check if the current selection *is* the element (ie bug)
|
||||
var currentSelection = editor.selection.getStart();
|
||||
if (tinymce.isIE) {
|
||||
if (!editor.dom.hasClass(currentSelection, 'umb-macro-holder')) {
|
||||
while (!editor.dom.hasClass(currentSelection, 'umb-macro-holder') && currentSelection.parentNode) {
|
||||
currentSelection = currentSelection.parentNode;
|
||||
}
|
||||
editor.selection.select(currentSelection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a node change handler, test if we're editing a macro and select the whole thing, then set our isOnMacroElement flag.
|
||||
* If we change the selection inside this method, then we end up in an infinite loop, so we have to remove ourselves
|
||||
@@ -181,7 +267,10 @@ function tinyMceService(dialogService, $log, imageHelper, assetsService, $timeou
|
||||
|
||||
//set our macro button active when on a node of class umb-macro-holder
|
||||
var $macroElement = $(evt.element).closest(".umb-macro-holder");
|
||||
|
||||
handleSelectionChange();
|
||||
|
||||
//set the button active
|
||||
ctrl.active($macroElement.length !== 0);
|
||||
|
||||
if ($macroElement.length > 0) {
|
||||
@@ -189,20 +278,8 @@ function tinyMceService(dialogService, $log, imageHelper, assetsService, $timeou
|
||||
|
||||
//remove the event listener before re-selecting
|
||||
editor.off('NodeChange', onNodeChanged);
|
||||
|
||||
// move selection to top element to ensure we can't edit this
|
||||
editor.selection.select(macroElement);
|
||||
|
||||
// check if the current selection *is* the element (ie bug)
|
||||
var currentSelection = editor.selection.getStart();
|
||||
if (tinymce.isIE) {
|
||||
if (!editor.dom.hasClass(currentSelection, 'umb-macro-holder')) {
|
||||
while (!editor.dom.hasClass(currentSelection, 'umb-macro-holder') && currentSelection.parentNode) {
|
||||
currentSelection = currentSelection.parentNode;
|
||||
}
|
||||
editor.selection.select(currentSelection);
|
||||
}
|
||||
}
|
||||
selectMacroElement(macroElement);
|
||||
|
||||
//set the flag
|
||||
isOnMacroElement = true;
|
||||
@@ -216,6 +293,16 @@ function tinyMceService(dialogService, $log, imageHelper, assetsService, $timeou
|
||||
|
||||
}
|
||||
|
||||
/** when the contents load we need to find any macros declared and load in their content */
|
||||
editor.on("LoadContent", function (o) {
|
||||
|
||||
//get all macro divs and load their content
|
||||
$(editor.dom.select(".umb-macro-holder.mceNonEditable")).each(function() {
|
||||
loadMacroContent($(this));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
/** This prevents any other commands from executing when the current element is the macro so the content cannot be edited */
|
||||
editor.on('BeforeExecCommand', function (o) {
|
||||
if (isOnMacroElement) {
|
||||
@@ -310,7 +397,10 @@ function tinyMceService(dialogService, $log, imageHelper, assetsService, $timeou
|
||||
/** The insert macro button click event handler */
|
||||
onclick: function () {
|
||||
|
||||
var dialogData;
|
||||
var dialogData = {
|
||||
//flag for use in rte so we only show macros flagged for the editor
|
||||
richTextEditor: true
|
||||
};
|
||||
|
||||
//when we click we could have a macro already selected and in that case we'll want to edit the current parameters
|
||||
//so we'll need to extract them and submit them to the dialog.
|
||||
@@ -352,20 +442,9 @@ function tinyMceService(dialogService, $log, imageHelper, assetsService, $timeou
|
||||
editor.selection.setNode(macroDiv);
|
||||
|
||||
var $macroDiv = $(editor.dom.select("div.umb-macro-holder." + uniqueId));
|
||||
var $ins = $macroDiv.find("ins");
|
||||
|
||||
//show the throbber
|
||||
$macroDiv.addClass("loading");
|
||||
|
||||
macroResource.getMacroResultAsHtmlForEditor(data.macroAlias, 1234)
|
||||
.then(function (htmlResult) {
|
||||
|
||||
$macroDiv.removeClass("loading");
|
||||
htmlResult = htmlResult.trim();
|
||||
if (htmlResult !== "") {
|
||||
$ins.html(htmlResult);
|
||||
}
|
||||
});
|
||||
//async load the macro content
|
||||
loadMacroContent($macroDiv, data);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -25,13 +25,13 @@ function InsertMacroController($scope, entityResource, macroResource, umbPropEdi
|
||||
$scope.macroParams = data;
|
||||
|
||||
//fill in the data if we are editing this macro
|
||||
if ($scope.dialogData && $scope.dialogData.macroData && $scope.dialogData.macroData.params) {
|
||||
_.each($scope.dialogData.macroData.params, function(p) {
|
||||
if ($scope.dialogData && $scope.dialogData.macroData && $scope.dialogData.macroData.marcoParamsDictionary) {
|
||||
_.each($scope.dialogData.macroData.marcoParamsDictionary, function (val, key) {
|
||||
var prop = _.find($scope.macroParams, function (item) {
|
||||
return item.alias == p.alias;
|
||||
return item.alias == key;
|
||||
});
|
||||
if (prop) {
|
||||
prop.value = p.value;
|
||||
prop.value = val;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -44,10 +44,13 @@ function InsertMacroController($scope, entityResource, macroResource, umbPropEdi
|
||||
function submitForm() {
|
||||
|
||||
//collect the value data, close the dialog and send the data back to the caller
|
||||
var vals = _.map($scope.macroParams, function (item) {
|
||||
return { value: item.value, alias: item.alias };
|
||||
});
|
||||
|
||||
//create a dictionary for the macro params
|
||||
var paramDictionary = {};
|
||||
_.each($scope.macroParams, function (item) {
|
||||
paramDictionary[item.alias] = item.value;
|
||||
});
|
||||
|
||||
//need to find the macro alias for the selected id
|
||||
var macroAlias = $scope.selectedMacro.alias;
|
||||
|
||||
@@ -58,16 +61,16 @@ function InsertMacroController($scope, entityResource, macroResource, umbPropEdi
|
||||
//get the syntax based on the rendering engine
|
||||
var syntax;
|
||||
if ($scope.dialogData.renderingEngine && $scope.dialogData.renderingEngine === "WebForms") {
|
||||
syntax = macroService.generateWebFormsSyntax({ macroAlias: macroAlias, macroParams: vals });
|
||||
syntax = macroService.generateWebFormsSyntax({ macroAlias: macroAlias, marcoParamsDictionary: paramDictionary });
|
||||
}
|
||||
else if ($scope.dialogData.renderingEngine && $scope.dialogData.renderingEngine === "Mvc") {
|
||||
syntax = macroService.generateMvcSyntax({ macroAlias: macroAlias, macroParams: vals });
|
||||
syntax = macroService.generateMvcSyntax({ macroAlias: macroAlias, marcoParamsDictionary: paramDictionary });
|
||||
}
|
||||
else {
|
||||
syntax = macroService.generateMacroSyntax({ macroAlias: macroAlias, macroParams: vals });
|
||||
syntax = macroService.generateMacroSyntax({ macroAlias: macroAlias, marcoParamsDictionary: paramDictionary });
|
||||
}
|
||||
|
||||
$scope.submit({syntax : syntax, macroAlias: macroAlias, macroParams: vals });
|
||||
$scope.submit({ syntax: syntax, macroAlias: macroAlias, marcoParamsDictionary: paramDictionary });
|
||||
}
|
||||
|
||||
$scope.macros = [];
|
||||
@@ -103,16 +106,16 @@ function InsertMacroController($scope, entityResource, macroResource, umbPropEdi
|
||||
$scope.wizardStep = "paramSelect";
|
||||
}
|
||||
|
||||
//get the macro list
|
||||
entityResource.getAll("Macro")
|
||||
//get the macro list - pass in a filter if it is only for rte
|
||||
entityResource.getAll("Macro", ($scope.dialogData && $scope.dialogData.richTextEditor && $scope.dialogData.richTextEditor === true) ? "UseInEditor=true" : null)
|
||||
.then(function (data) {
|
||||
|
||||
$scope.macros = data;
|
||||
|
||||
//check if there's a pre-selected macro and if it exists
|
||||
if ($scope.dialogData && $scope.dialogData.macroData && $scope.dialogData.macroData.alias) {
|
||||
if ($scope.dialogData && $scope.dialogData.macroData && $scope.dialogData.macroData.macroAlias) {
|
||||
var found = _.find(data, function (item) {
|
||||
return item.alias === $scope.dialogData.macroData.alias;
|
||||
return item.alias === $scope.dialogData.macroData.macroAlias;
|
||||
});
|
||||
if (found) {
|
||||
//select the macro and go to next screen
|
||||
|
||||
@@ -1,32 +1,39 @@
|
||||
<div class="umb-panel" ng-controller="Umbraco.Dialogs.RteEmbedController">
|
||||
<form ng-controller="Umbraco.Dialogs.RteEmbedController">
|
||||
|
||||
<div class="umb-panel" val-show-validation>
|
||||
|
||||
<div class="umb-panel-header">
|
||||
<div class="umb-el-wrap umb-panel-buttons">
|
||||
<div class="btn-toolbar umb-btn-toolbar">
|
||||
<input type="button" ng-click="insert()" class="btn btn-primary" value="Insert" ng-disabled="!success" />
|
||||
<div class="umb-panel-header">
|
||||
<div class="umb-el-wrap umb-panel-buttons">
|
||||
<div class="btn-toolbar umb-btn-toolbar">
|
||||
<button type="button" class="btn" ng-click="close()">Cancel</button>
|
||||
|
||||
<input type="button" ng-click="insert()" class="btn btn-primary" value="Ok" ng-disabled="!success" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="umb-panel-body umb-scrollable" auto-scale="1">
|
||||
<div class="umb-panel">
|
||||
<div class="umb-control-group">
|
||||
|
||||
<label for="url">Url</label>
|
||||
<input id="url" type="text" ng-model="url" ng-change="showPreview()"/>
|
||||
|
||||
<div ng-show="supportsDimensions">
|
||||
<label>Size:</label>
|
||||
<input type="text" ng-model="width" on-blur="changeSize('width')"/> x <input type="text" ng-model="height" on-blur="changeSize('height')"/>
|
||||
<label for="constrain">Constrain:</label>
|
||||
<input id="constrain" type="checkbox" ng-model="constrain"/>
|
||||
<div class="umb-panel-body umb-scrollable" auto-scale="1">
|
||||
|
||||
<div class="umb-control-group">
|
||||
|
||||
<div class="umb-pane">
|
||||
<label for="url">Url:</label>
|
||||
<input id="url" type="text" ng-model="url" ng-change="showPreview()" required/>
|
||||
</div>
|
||||
<div class="umb-pane" ng-show="supportsDimensions">
|
||||
<label>Size:</label>
|
||||
<input type="text" ng-model="width" on-blur="changeSize('width')" style="width:50px"/> x <input type="text" ng-model="height" on-blur="changeSize('height')" style="width:50px"/>
|
||||
<label for="constrain" style="display:inline">Constrain:</label>
|
||||
<input id="constrain" type="checkbox" ng-model="constrain" style="margin-bottom: 10px;"/>
|
||||
</div>
|
||||
<div class="umb-pane">
|
||||
<p ng-bind="info"></p>
|
||||
<div ng-bind-html-unsafe="preview">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p ng-bind="info"></p>
|
||||
<div ng-bind-html-unsafe="preview">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
angular.module("umbraco")
|
||||
.controller("Umbraco.Editors.RTEController",
|
||||
function ($rootScope, $scope, dialogService, $log, imageHelper, assetsService, $timeout, tinyMceService) {
|
||||
function ($rootScope, $element, $scope, dialogService, $log, imageHelper, assetsService, $timeout, tinyMceService, angularHelper) {
|
||||
|
||||
//TODO: This should be configurable (i.e. from the config file we have and/or from pre-values)
|
||||
var validElements = "@[id|class|style|title|dir<ltr?rtl|lang|xml::lang|onclick|ondblclick|"
|
||||
@@ -23,7 +23,7 @@ angular.module("umbraco")
|
||||
+ "input[accept|alt|checked|disabled|maxlength|name|readonly|size|src|type|value],"
|
||||
+ "kbd,label[for],legend,noscript,optgroup[label|disabled],option[disabled|label|selected|value],"
|
||||
+ "q[cite],samp,select[disabled|multiple|name|size],small,"
|
||||
+ "textarea[cols|rows|disabled|name|readonly],tt,var,big";
|
||||
+ "textarea[cols|rows|disabled|name|readonly],tt,var,big,iframe[*]";
|
||||
|
||||
//TODO: This should be configurable (i.e. from the config file we have and/or from pre-values)
|
||||
var toolbar = "code | bold italic | styleselect | alignleft aligncenter alignright | bullist numlist | outdent indent | link image umbmediapicker umbiconpicker umbembeddialog umbmacro";
|
||||
@@ -47,11 +47,36 @@ angular.module("umbraco")
|
||||
height: 340,
|
||||
toolbar: toolbar,
|
||||
setup: function (editor) {
|
||||
|
||||
//We need to listen on multiple things here because of the nature of tinymce, it doesn't
|
||||
//fire events when you think!
|
||||
//The change event doesn't fire when content changes, only when cursor points are changed and undo points
|
||||
//are created. the blur event doesn't fire if you insert content into the editor with a button and then
|
||||
//press save.
|
||||
//We have a couple of options, one is to do a set timeout and check for isDirty on the editor, or we can
|
||||
//listen to both change and blur and also on our own 'saving' event. I think this will be best because a
|
||||
//timer might end up using unwanted cpu and we'd still have to listen to our saving event in case they clicked
|
||||
//save before the timeout elapsed.
|
||||
editor.on('change', function (e) {
|
||||
angularHelper.safeApply($scope, function() {
|
||||
$scope.model.value = editor.getContent();
|
||||
});
|
||||
});
|
||||
editor.on('blur', function (e) {
|
||||
$scope.$apply(function () {
|
||||
angularHelper.safeApply($scope, function () {
|
||||
$scope.model.value = editor.getContent();
|
||||
});
|
||||
});
|
||||
var unsubscribe = $scope.$on("saving", function() {
|
||||
$scope.model.value = editor.getContent();
|
||||
});
|
||||
|
||||
//when the element is disposed we need to unsubscribe!
|
||||
// NOTE: this is very important otherwise if this is part of a modal, the listener still exists because the dom
|
||||
// element might still be there even after the modal has been hidden.
|
||||
$element.bind('$destroy', function () {
|
||||
unsubscribe();
|
||||
});
|
||||
|
||||
//Create the insert media plugin
|
||||
tinyMceService.createMediaPicker(editor, $scope);
|
||||
|
||||
@@ -14,12 +14,11 @@ describe('macro service tests', function () {
|
||||
var result = macroService.parseMacroSyntax("<?UMBRACO_MACRO macroAlias='Map' test1=\"asdf\" test2='hello' />");
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result.alias).toBe("Map");
|
||||
expect(result.params.length).toBe(2);
|
||||
expect(result.params[0].alias).toBe("test1");
|
||||
expect(result.params[0].value).toBe("asdf");
|
||||
expect(result.params[1].alias).toBe("test2");
|
||||
expect(result.params[1].value).toBe("hello");
|
||||
expect(result.macroAlias).toBe("Map");
|
||||
expect(result.marcoParamsDictionary.test1).not.toBeUndefined();
|
||||
expect(result.marcoParamsDictionary.test1).toBe("asdf");
|
||||
expect(result.marcoParamsDictionary.test2).not.toBeUndefined();
|
||||
expect(result.marcoParamsDictionary.test2).toBe("hello");
|
||||
|
||||
|
||||
});
|
||||
@@ -29,12 +28,11 @@ describe('macro service tests', function () {
|
||||
var result = macroService.parseMacroSyntax("<?UMBRACO_MACRO macroAlias='Map' test1=\"asdf\" test2='hello' ><img src='blah.jpg'/></?UMBRACO_MACRO>");
|
||||
|
||||
expect(result).not.toBeNull();
|
||||
expect(result.alias).toBe("Map");
|
||||
expect(result.params.length).toBe(2);
|
||||
expect(result.params[0].alias).toBe("test1");
|
||||
expect(result.params[0].value).toBe("asdf");
|
||||
expect(result.params[1].alias).toBe("test2");
|
||||
expect(result.params[1].value).toBe("hello");
|
||||
expect(result.macroAlias).toBe("Map");
|
||||
expect(result.marcoParamsDictionary.test1).not.toBeUndefined();
|
||||
expect(result.marcoParamsDictionary.test1).toBe("asdf");
|
||||
expect(result.marcoParamsDictionary.test2).not.toBeUndefined();
|
||||
expect(result.marcoParamsDictionary.test2).toBe("hello");
|
||||
|
||||
|
||||
});
|
||||
@@ -47,11 +45,11 @@ describe('macro service tests', function () {
|
||||
|
||||
var syntax = macroService.generateMacroSyntax({
|
||||
macroAlias: "myMacro",
|
||||
macroParams: [
|
||||
{ alias: "param1", value: "value1" },
|
||||
{ alias: "param2", value: "value2" },
|
||||
{ alias: "param3", value: "value3" }
|
||||
]
|
||||
marcoParamsDictionary: {
|
||||
param1: "value1",
|
||||
param2: "value2",
|
||||
param3: "value3"
|
||||
}
|
||||
});
|
||||
|
||||
expect(syntax).
|
||||
@@ -63,7 +61,7 @@ describe('macro service tests', function () {
|
||||
|
||||
var syntax = macroService.generateMacroSyntax({
|
||||
macroAlias: "myMacro",
|
||||
macroParams: []
|
||||
marcoParamsDictionary: {}
|
||||
});
|
||||
|
||||
expect(syntax).
|
||||
@@ -75,11 +73,11 @@ describe('macro service tests', function () {
|
||||
|
||||
var syntax = macroService.generateWebFormsSyntax({
|
||||
macroAlias: "myMacro",
|
||||
macroParams: [
|
||||
{ alias: "param1", value: "value1" },
|
||||
{ alias: "param2", value: "value2" },
|
||||
{ alias: "param3", value: "value3" }
|
||||
]
|
||||
marcoParamsDictionary: {
|
||||
param1: "value1",
|
||||
param2: "value2",
|
||||
param3: "value3"
|
||||
}
|
||||
});
|
||||
|
||||
expect(syntax).
|
||||
@@ -91,7 +89,7 @@ describe('macro service tests', function () {
|
||||
|
||||
var syntax = macroService.generateWebFormsSyntax({
|
||||
macroAlias: "myMacro",
|
||||
macroParams: []
|
||||
marcoParamsDictionary: {}
|
||||
});
|
||||
|
||||
expect(syntax).
|
||||
@@ -103,11 +101,11 @@ describe('macro service tests', function () {
|
||||
|
||||
var syntax = macroService.generateMvcSyntax({
|
||||
macroAlias: "myMacro",
|
||||
macroParams: [
|
||||
{ alias: "param1", value: "value1" },
|
||||
{ alias: "param2", value: "value2" },
|
||||
{ alias: "param3", value: "value3" }
|
||||
]
|
||||
marcoParamsDictionary: {
|
||||
param1: "value1",
|
||||
param2: "value2",
|
||||
param3: "value3"
|
||||
}
|
||||
});
|
||||
|
||||
expect(syntax).
|
||||
@@ -116,11 +114,11 @@ describe('macro service tests', function () {
|
||||
|
||||
});
|
||||
|
||||
it('can generate syntax for webforms with no params', function () {
|
||||
it('can generate syntax for MVC with no params', function () {
|
||||
|
||||
var syntax = macroService.generateMvcSyntax({
|
||||
macroAlias: "myMacro",
|
||||
macroParams: []
|
||||
marcoParamsDictionary: {}
|
||||
});
|
||||
|
||||
expect(syntax).
|
||||
|
||||
Reference in New Issue
Block a user