From 3e7031290f49dbe2bef16df6453ade3df5ffc1dc Mon Sep 17 00:00:00 2001
From: simoncroak <97484717+simoncroak@users.noreply.github.com>
Date: Mon, 30 May 2022 11:42:27 -0700
Subject: [PATCH 01/99] Update Wait-RemoteSitecoreJob.ps1
Update Wait-RemoteSitecoreJob.ps1 to support multiple jobs, job status will be output until all jobs have completed.
---
Modules/SPE/Wait-RemoteSitecoreJob.ps1 | 30 +++++++++++++++-----------
1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/Modules/SPE/Wait-RemoteSitecoreJob.ps1 b/Modules/SPE/Wait-RemoteSitecoreJob.ps1
index 4933b345f..fe1cff604 100644
--- a/Modules/SPE/Wait-RemoteSitecoreJob.ps1
+++ b/Modules/SPE/Wait-RemoteSitecoreJob.ps1
@@ -45,7 +45,7 @@
[pscustomobject]$Session,
[ValidateNotNull()]
- [string]$Id,
+ [string[]]$Ids,
[int]$Delay = 1
)
@@ -77,17 +77,23 @@
}
}
- $keepRunning = $true
- while($keepRunning) {
- $response = Invoke-RemoteScript -Session $session -ScriptBlock $doneScript
- if($response -and $response.IsDone) {
- $keepRunning = $false
- Write-Verbose "Polling job $($response.Name). Status : $($response.Status)."
- Write-Verbose "Finished polling job $($id)."
- Invoke-RemoteScript -Session $session -ScriptBlock $finishScript
- } else {
- Write-Verbose "Polling job $($response.Name). Status : $($response.Status)."
+ $keepRunning = 0
+ while($keepRunning -ne $Ids.Count) {
+ foreach ($id in $Ids)
+ {
+ $response = Invoke-RemoteScript -Session $session -ScriptBlock $doneScript
+ if($response -and $response.IsDone) {
+ $keepRunning++
+ Write-Verbose "Polling job $($response.Name). Status : $($response.Status)."
+ Write-Verbose "Finished polling job $($id)."
+ } else {
+ Write-Verbose "Polling job $($response.Name). Status : $($response.Status)."
+ Start-Sleep -Seconds $Delay
+ }
+ }
+ if ($keepRunning -ne $Ids.Count) # Only sleep if we're not 'done' waiting for jobs
+ {
Start-Sleep -Seconds $Delay
}
}
-}
\ No newline at end of file
+}
From ff052af01dfe2dee2151fa510357371a14571184 Mon Sep 17 00:00:00 2001
From: simoncroak <97484717+simoncroak@users.noreply.github.com>
Date: Mon, 30 May 2022 11:45:06 -0700
Subject: [PATCH 02/99] Update Wait-RemoteSitecoreJob.ps1
Removed additional Start-Sleep
---
Modules/SPE/Wait-RemoteSitecoreJob.ps1 | 1 -
1 file changed, 1 deletion(-)
diff --git a/Modules/SPE/Wait-RemoteSitecoreJob.ps1 b/Modules/SPE/Wait-RemoteSitecoreJob.ps1
index fe1cff604..d6b3bf6c8 100644
--- a/Modules/SPE/Wait-RemoteSitecoreJob.ps1
+++ b/Modules/SPE/Wait-RemoteSitecoreJob.ps1
@@ -88,7 +88,6 @@
Write-Verbose "Finished polling job $($id)."
} else {
Write-Verbose "Polling job $($response.Name). Status : $($response.Status)."
- Start-Sleep -Seconds $Delay
}
}
if ($keepRunning -ne $Ids.Count) # Only sleep if we're not 'done' waiting for jobs
From 474b844c21903634af25aa7c57bf58bb45c46366 Mon Sep 17 00:00:00 2001
From: Adam Najmanowicz
Date: Fri, 3 May 2024 02:08:37 +0200
Subject: [PATCH 03/99] #1326 It is not possible to search for scripts in the
"Open" dropdown in ISE.
---
.gitignore | 3 +++
src/Spe/Client/Controls/MruGallery.cs | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
index bdfa2aaf9..24833d3ad 100644
--- a/.gitignore
+++ b/.gitignore
@@ -72,3 +72,6 @@ node_modules/
# Ephemeral index caches used by serialization, do not commit
*.scindex
+
+# Jetbrains Rider
+.idea
\ No newline at end of file
diff --git a/src/Spe/Client/Controls/MruGallery.cs b/src/Spe/Client/Controls/MruGallery.cs
index a556d1ece..74182e52d 100644
--- a/src/Spe/Client/Controls/MruGallery.cs
+++ b/src/Spe/Client/Controls/MruGallery.cs
@@ -260,7 +260,7 @@ private bool SearchDatabase(string indexName, string phrase)
{
var scriptsFound = false;
// get all items in medialibrary
- var rootID = ApplicationSettings.ScriptLibraryRoot.ID.ToShortID().ToString();
+ var rootID = ApplicationSettings.ScriptLibraryRoot.ID.ToShortID().ToString().ToLower();
var query =
context.GetQueryable()
.Where(
From 24deb25071c93f38a8ca983b681b10b39c1baac4 Mon Sep 17 00:00:00 2001
From: Adam Najmanowicz
Date: Fri, 3 May 2024 04:19:45 +0200
Subject: [PATCH 04/99] #1327 : ISE Plugin "Scripts Containing" does not work
most of the time
---
.../Include/Spe/Spe.Serialization.config | 2 +-
.../Internal/ISE Plugins/Scripts containing.yml | 16 ++++++++++------
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/src/Spe/App_Config/Include/Spe/Spe.Serialization.config b/src/Spe/App_Config/Include/Spe/Spe.Serialization.config
index ae7e285a1..70dc92307 100644
--- a/src/Spe/App_Config/Include/Spe/Spe.Serialization.config
+++ b/src/Spe/App_Config/Include/Spe/Spe.Serialization.config
@@ -1,6 +1,6 @@
-
+
diff --git a/unicorn/SPE/Scripts/SPE/SPE/Core/Platform/Internal/ISE Plugins/Scripts containing.yml b/unicorn/SPE/Scripts/SPE/SPE/Core/Platform/Internal/ISE Plugins/Scripts containing.yml
index 1847a6acc..eb6611b61 100644
--- a/unicorn/SPE/Scripts/SPE/SPE/Core/Platform/Internal/ISE Plugins/Scripts containing.yml
+++ b/unicorn/SPE/Scripts/SPE/SPE/Core/Platform/Internal/ISE Plugins/Scripts containing.yml
@@ -16,13 +16,17 @@ SharedFields:
exit
}
+ class ScriptSearchResultItem : SearchResultItem
+ {
+ [Sitecore.ContentSearch.IndexField("script")]
+ [string]$Script;
+ }
+
$searchProps = @{
Index = "sitecore_master_index"
- Criteria = @(
- @{ Filter = "StartsWith"; Field = "_fullpath"; Value = "/sitecore/system/modules/PowerShell/" },
- @{ Filter = "Equals"; Field = "_templatename"; Value = "PowerShell Script" },
- @{ Filter = "Contains"; Field = "script"; Value = "$selectionText"; CaseSensitive = $true }
- )
+ Where = "Paths.Contains(@0) and Script.Contains(@1) and Language== `"en`""
+ WhereValues = [Spe.Core.Settings.ApplicationSettings]::ScriptLibraryRoot.ID, $selectionText
+ QueryType = [ScriptSearchResultItem]
}
$reportProps = @{
@@ -91,4 +95,4 @@ Languages:
Value: 20150625T211456Z
- ID: "8cdc337e-a112-42fb-bbb4-4143751e123f"
Hint: __Revision
- Value: "f7b824f0-4bfe-426a-bae8-9d69e361696e"
+ Value: "cab138dc-42f8-4987-98ff-7df638b178e9"
From 3ced607a6400b19bee5b254a0972daa7a290e91d Mon Sep 17 00:00:00 2001
From: Adam Najmanowicz
Date: Fri, 3 May 2024 18:16:36 +0200
Subject: [PATCH 05/99] #1329 : Script execution results should be less
in-the-way
---
.../PowerShell/Scripts/ise.js | 25 +++++++++++++------
.../PowerShell/Styles/ise.css | 16 +++++-------
.../Shell/PowerShell/PowerShellIse.xml | 5 +++-
3 files changed, 27 insertions(+), 19 deletions(-)
diff --git a/src/Spe/sitecore modules/PowerShell/Scripts/ise.js b/src/Spe/sitecore modules/PowerShell/Scripts/ise.js
index 98e22b727..e029293ce 100644
--- a/src/Spe/sitecore modules/PowerShell/Scripts/ise.js
+++ b/src/Spe/sitecore modules/PowerShell/Scripts/ise.js
@@ -29,6 +29,7 @@
var debugMarkers = [];
var resultsBottomOffset = 10;
var typingTimer;
+ var resultsVisibilityIntent = true;
var editor = $($("#Editor")[0]);
editor.hide();
@@ -465,6 +466,9 @@
spe.preventCloseWhenRunning(false);
}
clearVariablesCache();
+ if(!resultsVisibilityIntent){
+ setTimeout(spe.closeResults, 2000);
+ }
};
spe.clearBreakpoints = function() {
@@ -510,7 +514,6 @@
$("#Result").height(resultsHeight);
$("#Result").width($(window).width() - $("#Result").offset().left * 2);
$("#ProgressOverlay").css("top",($("#Result").offset().top+4)+"px");
- $("#ResultsClose").css("top", ($("#Result").offset().top + 4) + "px");
};
function isEmpty(val) {
@@ -536,7 +539,8 @@
spe.restoreResults = function() {
$("#ResultsSplitter").show();
$("#ResultsRow").show();
- codeeditor.resize();
+ spe.resizeEditor();
+ $("#ResultsStatusBarAction").removeClass("status-bar-results-hidden")
};
spe.closeResults = function() {
@@ -544,6 +548,7 @@
$("#ResultsRow").hide("slow", function() {
codeeditor.resize();
});
+ $("#ResultsStatusBarAction").addClass("status-bar-results-hidden")
};
function getCachedVariableValue(storageKey, variableName) {
@@ -677,13 +682,17 @@
});
- $("#ResultsClose").click(function() {
- $("#ResultsSplitter").hide();
- $("#ResultsRow").hide("slow", function() {
- codeeditor.resize(); /* do something cool here? */
- });
+
+ $("#ShowHideResults").click(function() {
+ if ($("#ResultsRow").is(":visible")) {
+ resultsVisibilityIntent = false;
+ spe.closeResults();
+ } else {
+ resultsVisibilityIntent = true;
+ spe.restoreResults();
+ }
});
-
+
function _getCommandHelp(str) {
getPowerShellResponse({ "guid": guid, "command": str }, "GetHelpForCommand",
function(json) {
diff --git a/src/Spe/sitecore modules/PowerShell/Styles/ise.css b/src/Spe/sitecore modules/PowerShell/Styles/ise.css
index 04e87d70e..0d092dc54 100644
--- a/src/Spe/sitecore modules/PowerShell/Styles/ise.css
+++ b/src/Spe/sitecore modules/PowerShell/Styles/ise.css
@@ -146,7 +146,7 @@ a.ps-link {
text-transform: uppercase;
}
-#HelpClose, #ResultsClose {
+#HelpClose {
-moz-border-radius-bottomleft: 9px;
-moz-border-radius-bottomright: 9px;
-moz-border-radius-topleft: 9px;
@@ -183,25 +183,17 @@ a.ps-link {
top: 0;
}
-#HelpClose:hover, #ResultsClose:hover {
+#HelpClose:hover {
background: -moz-linear-gradient(center top, #dfdfdf 5%, #ededed 100%);
background-color: #e3e3e3;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#dfdfdf', endColorstr='#ededed');
}
-#ResultsClose:active {
- top: 1px;
-}
-
#ResultsSplitter {
background: url(/sitecore%20modules/PowerShell/Assets/Splitter.png) no-repeat center;
padding: 0 4px 0 4px;
}
-#ResultsClose {
- position: fixed;
-}
-
#Result {
position: fixed;
bottom: 27px;
@@ -421,4 +413,8 @@ a.ps-link {
#CodeEditor * {
font-family: inherit !important;
+}
+
+#ResultsStatusBarAction.status-bar-results-hidden {
+ background-color: rgb(1, 36, 86);
}
\ No newline at end of file
diff --git a/src/Spe/sitecore modules/Shell/PowerShell/PowerShellIse.xml b/src/Spe/sitecore modules/Shell/PowerShell/PowerShellIse.xml
index 6c6b64a18..6ea8206cf 100644
--- a/src/Spe/sitecore modules/Shell/PowerShell/PowerShellIse.xml
+++ b/src/Spe/sitecore modules/Shell/PowerShell/PowerShellIse.xml
@@ -104,7 +104,6 @@
- x
@@ -123,6 +122,10 @@
+
+
+
From b2d0728ea7c051761a9916aa2e24fda6783a21af Mon Sep 17 00:00:00 2001
From: Adam Najmanowicz
Date: Wed, 8 May 2024 19:41:54 +0200
Subject: [PATCH 06/99] #1332 : The ability to open multiple scripts in tabs in
a single ISE
---
src/Spe/Client/Applications/PowerShellIse.cs | 339 ++++++--
src/Spe/Core/Settings/ApplicationSettings.cs | 9 +-
src/Spe/Texts.cs | 3 +-
.../PowerShell/Assets/TabClose.png | Bin 0 -> 332 bytes
.../PowerShell/Scripts/ise.js | 818 +++++++++++-------
.../PowerShell/Styles/ise.css | 70 +-
.../Shell/PowerShell/PowerShellIse.xml | 32 +-
.../Behaviour/PerTabOutput.yml | 35 +
.../PowerShellIse/Meta/EditIseSettings.yml | 6 +-
9 files changed, 906 insertions(+), 406 deletions(-)
create mode 100644 src/Spe/sitecore modules/PowerShell/Assets/TabClose.png
create mode 100644 unicorn/SPE/Core/Templates/Modules/PowerShell Console/PowerShell Console Settings/Behaviour/PerTabOutput.yml
diff --git a/src/Spe/Client/Applications/PowerShellIse.cs b/src/Spe/Client/Applications/PowerShellIse.cs
index 35cfa2943..e2e2df869 100644
--- a/src/Spe/Client/Applications/PowerShellIse.cs
+++ b/src/Spe/Client/Applications/PowerShellIse.cs
@@ -1,9 +1,11 @@
using System;
+using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
+using System.Web.UI.WebControls;
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Data;
@@ -11,6 +13,7 @@
using Sitecore.Data.Managers;
using Sitecore.Diagnostics;
using Sitecore.IO;
+using Sitecore.Mvc.Extensions;
using Sitecore.Resources;
using Sitecore.Security;
using Sitecore.Security.Accounts;
@@ -32,6 +35,7 @@
using Spe.Core.Settings;
using Spe.Core.Settings.Authorization;
using Spe.Core.VersionDecoupling;
+using Literal = Sitecore.Web.UI.HtmlControls.Literal;
namespace Spe.Client.Applications
{
@@ -42,11 +46,12 @@ public class PowerShellIse : BaseForm, IHasCommandContext, IPowerShellRunner
public const string DefaultLanguage = "CurrentLanguage";
protected Memo Editor;
+ protected Memo OpenedScripts;
+ protected Memo ScriptItemIdMemo;
+ protected Memo ScriptItemDbMemo;
protected Literal Progress;
protected Border ProgressOverlay;
- protected Border Result;
protected Border RibbonPanel;
- protected Literal ScriptName;
protected Border ScriptResult;
protected Memo SelectionText;
protected Memo Breakpoints;
@@ -54,7 +59,8 @@ public class PowerShellIse : BaseForm, IHasCommandContext, IPowerShellRunner
protected GridPanel ElevatedPanel;
protected GridPanel ElevationBlockedPanel;
protected Border InfoPanel;
-
+ protected Tabstrip Tabs;
+ protected Border TabsPanel;
public bool Debugging { get; set; }
public bool InBreakpoint { get; set; }
@@ -76,16 +82,32 @@ public string ParentFrameName
set { ServerProperties["ParentFrameName"] = value; }
}
- public static string ScriptItemId
+ public string ScriptItemId
{
- get { return StringUtil.GetString(Context.ClientPage.ServerProperties["ItemID"]); }
- set { Context.ClientPage.ServerProperties["ItemID"] = value; }
+ get { return ScriptItemIdMemo.Value; }
+ set
+ {
+ if (value.IsWhiteSpaceOrNull())
+ {
+ Log.Error("ScriptItemId is null or empty", this);
+ }
+
+ ScriptItemIdMemo.Value = value;
+ }
}
- public static string ScriptItemDb
+ public string ScriptItemDb
{
- get { return StringUtil.GetString(Context.ClientPage.ServerProperties["ItemDb"]); }
- set { Context.ClientPage.ServerProperties["ItemDb"] = value; }
+ get { return ScriptItemDbMemo.Value; }
+ set
+ {
+ if (value.IsWhiteSpaceOrNull())
+ {
+ Log.Error("ScriptItemDb is null or empty", this);
+ }
+
+ ScriptItemDbMemo.Value = value;
+ }
}
public static string ContextItemId
@@ -106,6 +128,12 @@ public static bool ScriptModified
set { Context.ClientPage.ServerProperties["ScriptModified"] = value ? "1" : string.Empty; }
}
+ public static int TabSequencer
+ {
+ get { return (int)(Context.ClientPage.ServerProperties["TabSequencer"] ?? 0); }
+ set { Context.ClientPage.ServerProperties["TabSequencer"] = value; }
+ }
+
public static bool UseContext
{
get
@@ -115,7 +143,7 @@ public static bool UseContext
set { Context.ClientPage.ServerProperties["UseContext"] = value ? string.Empty : "0"; }
}
- public static Item ScriptItem
+ public Item ScriptItem
{
get
{
@@ -161,7 +189,7 @@ public CommandContext GetCommandContext()
{
var itemNotNull = Sitecore.Client.CoreDatabase.GetItem("{FDD5B2D5-31BE-41C3-AA76-64E5CC63B187}");
// /sitecore/content/Applications/PowerShell/PowerShellIse/Ribbon
- var context = new CommandContext {RibbonSourceUri = itemNotNull.Uri};
+ var context = new CommandContext { RibbonSourceUri = itemNotNull.Uri };
return context;
}
@@ -173,7 +201,8 @@ public bool MonitorActive
private static bool IsHackedParameter(string parameter)
{
- var xssCleanup = new Regex(@"||");
+ var xssCleanup =
+ new Regex(@"||");
if (xssCleanup.IsMatch(parameter))
{
return true;
@@ -193,20 +222,23 @@ protected override void OnLoad(EventArgs e)
}
base.OnLoad(e);
-
+
if (Monitor == null)
{
if (!Context.ClientPage.IsEvent)
{
- Monitor = new SpeJobMonitor {ID = "Monitor"};
+ Monitor = new SpeJobMonitor { ID = "Monitor" };
Context.ClientPage.Controls.Add(Monitor);
}
else
{
- Monitor = (SpeJobMonitor) Context.ClientPage.FindControl("Monitor");
+ Monitor = (SpeJobMonitor)Context.ClientPage.FindControl("Monitor");
}
}
+
Monitor.JobFinished += MonitorOnJobFinished;
+
+ Tabs.OnChange += TabsOnChange;
if (Context.ClientPage.IsEvent)
return;
@@ -219,11 +251,11 @@ protected override void OnLoad(EventArgs e)
var itemId = WebUtil.GetQueryString("id");
var itemDb = WebUtil.GetQueryString("db");
- if (itemId.Length > 0)
+
+ if (!itemId.IsWhiteSpaceOrNull())
{
ScriptItemId = itemId;
ScriptItemDb = itemDb;
- LoadItem(itemDb, itemId);
}
ContextItemDb = Context.ContentDatabase.Name;
@@ -238,6 +270,12 @@ protected override void OnLoad(EventArgs e)
UpdateRibbon();
}
+ private void TabsOnChange(object sender, EventArgs e)
+ {
+ var tab = Tabs.Controls.OfType().Skip(Tabs.Active).FirstOrDefault();
+ SelectTabByIndex(Tabs.Active + 1);
+ }
+
public override void HandleMessage(Message message)
{
Error.AssertObject(message, "message");
@@ -261,6 +299,7 @@ public override void HandleMessage(Message message)
? Context.Language.Name
: CurrentLanguage;
}
+
Dispatcher.Dispatch(message, context);
}
@@ -289,6 +328,7 @@ protected void Open(ClientPipelineArgs args)
if (obj != null)
str = obj.ID.ToString();
}
+
var urlString = new UrlString(UIUtil.GetUri("control:PowerShellScriptBrowser"));
urlString.Append("id", selected);
urlString.Append("fo", str);
@@ -310,14 +350,13 @@ protected void MruOpen(ClientPipelineArgs args)
LoadItem(args.Parameters["db"], args.Parameters["id"]);
}
-
+
[HandleMessage("ise:changecontextaccount", true)]
protected void SecurityChangeContextAccount(ClientPipelineArgs args)
{
Assert.ArgumentNotNull(args, "args");
args.CarryResultToNextProcessor = false;
args.AbortPipeline();
- //LoadItem(args.Parameters["db"], args.Parameters["id"]);
}
[HandleMessage("item:load", true)]
@@ -339,10 +378,6 @@ protected void MruUpdate(Item scriptItem)
var id = scriptItem.ID.ToString();
var name = scriptItem.Name;
var icon = scriptItem[FieldIDs.Icon];
- var scriptName = scriptItem.Paths.Path.Substring(ApplicationSettings.ScriptLibraryPath.Length);
- ScriptName.Text = scriptName;
- SheerResponse.Eval($"spe.changeWindowTitle('{scriptName}', false);");
- UpdateStartbarTitle(icon, name);
var mruMenu = ApplicationSettings.GetIseMruContainerItem();
var mruItems = mruMenu.Children;
@@ -370,6 +405,7 @@ protected void MruUpdate(Item scriptItem)
mruItem.Delete();
continue;
}
+
if (!(mruItem["Message"].Contains(id)))
{
var item = mruItem;
@@ -392,11 +428,8 @@ protected void NewScript(ClientPipelineArgs args)
ScriptItemDb = string.Empty;
Editor.Value = string.Empty;
ScriptResult.Value = "";
- SheerResponse.Eval("spe.changeWindowTitle('Untitled', true);");
+ CreateNewTab(null);
UpdateRibbon();
-
- const string icon = "powershell/16x16/ise8.png";
- UpdateStartbarTitle(icon, "Untitled");
}
[HandleMessage("ise:saveas", true)]
@@ -404,10 +437,11 @@ protected void SaveAs(ClientPipelineArgs args)
{
Assert.ArgumentNotNull(args, "args");
args.Parameters["message"] = "ise:saveas";
- if (!RequestSessionElevationEx(args,ApplicationNames.ItemSave,SessionElevationManager.SaveAction))
+ if (!RequestSessionElevationEx(args, ApplicationNames.ItemSave, SessionElevationManager.SaveAction))
{
return;
}
+
if (args.IsPostBack)
{
if (!args.HasResult)
@@ -437,12 +471,14 @@ protected void SaveAs(ClientPipelineArgs args)
if (obj != null)
str = obj.ID.ToString();
}
+
var urlString = new UrlString(UIUtil.GetUri("control:PowerShellScriptBrowser"));
urlString.Append("id", selected);
urlString.Append("fo", str);
urlString.Append("ro", root);
urlString.Append("he", Texts.PowerShellIse_SaveAs_Select_Script_Library);
- urlString.Append("txt", Texts.PowerShellIse_SaveAs_Select_the_Library_that_you_want_to_save_your_script_to_);
+ urlString.Append("txt",
+ Texts.PowerShellIse_SaveAs_Select_the_Library_that_you_want_to_save_your_script_to_);
urlString.Append("ic", icon);
urlString.Append("btn", Sitecore.Texts.SELECT);
SheerResponse.ShowModalDialog(urlString.ToString(), true);
@@ -465,12 +501,28 @@ protected void SaveItem(ClientPipelineArgs args)
{
return;
}
+
var scriptItem = ScriptItem;
if (scriptItem == null)
return;
scriptItem.Edit(
editArgs => { scriptItem.Fields[Templates.Script.Fields.ScriptBody].Value = Editor.Value; });
SheerResponse.Eval("spe.updateModificationFlag(true);");
+ var tabIndex = Tabs.Active + 1;
+ UpdateTabInfo(scriptItem, tabIndex);
+ }
+ }
+
+ [HandleMessage("ise:loadinitialscript", true)]
+ protected void LoadInitialScript(ClientPipelineArgs args)
+ {
+ if (ScriptItemId.Length > 0)
+ {
+ LoadItem(ScriptItemDb, ScriptItemId);
+ }
+ else
+ {
+ CreateNewTab(null);
}
}
@@ -495,9 +547,11 @@ private void LoadItem(string db, string id)
if (scriptItem[Templates.Script.Fields.ScriptBody] != null)
{
Editor.Value = scriptItem[Templates.Script.Fields.ScriptBody];
- SheerResponse.Eval("spe.updateEditor();");
+ var createdNew = CreateNewTab(scriptItem);
+
ScriptItemId = scriptItem.ID.ToString();
ScriptItemDb = scriptItem.Database.Name;
+ SelectTabByIndex(Tabs.Controls.Count);
MruUpdate(scriptItem);
UpdateRibbon();
}
@@ -507,6 +561,79 @@ private void LoadItem(string db, string id)
}
}
+ private bool CreateNewTab(Item scriptItem)
+ {
+ var itemEditing = scriptItem != null;
+ var path = itemEditing
+ ? scriptItem.Paths.Path.Substring(ApplicationSettings.ScriptLibraryPath.Length)
+ : String.Empty;
+ var tabIndex = 0;
+ var searchPath = $"{path}:";
+ var openedScript = OpenedScripts.Value.Split('\n').Select(line => line.Trim())
+ .FirstOrDefault(line => line.StartsWith(searchPath, StringComparison.OrdinalIgnoreCase));
+ var scriptAlreadyOpened = itemEditing && openedScript != null;
+ if (scriptAlreadyOpened)
+ {
+ tabIndex = int.Parse(openedScript.Split(':')[1]);
+ }
+ else
+ {
+ TabSequencer++;
+ SheerResponse.Eval($"spe.createEditor({TabSequencer});");
+ var newTab = new Tab
+ { Header = $"{Tabs.Controls.Count + 1}", Active = true };
+ Tabs.Controls.Add(newTab);
+ tabIndex = Tabs.Controls.Count;
+ UpdateTabInfo(scriptItem, tabIndex);
+ }
+
+ SelectTabByIndex(tabIndex);
+ SheerResponse.Eval("spe.updateEditor();");
+ return !scriptAlreadyOpened;
+ }
+
+ private void SelectTabByIndex(int tabIndex)
+ {
+ if (tabIndex < 0)
+ return;
+
+ var tabIndexString = tabIndex.ToString();
+ Tabs.Controls.OfType().ForEach(tab => tab.Active = tab.Header == tabIndexString);
+ Tabs.Active = tabIndex - 1;
+ var tabsHtml = HtmlUtil.RenderControl(Tabs);
+ TabsPanel.InnerHtml = tabsHtml;
+
+ SheerResponse.Eval($"spe.changeTab({tabIndex});");
+ }
+
+ private void UpdateTabInfo(Item scriptItem, int tabIndex)
+ {
+ var itemEditing = scriptItem != null;
+ var path = itemEditing
+ ? scriptItem.Paths.Path.Substring(ApplicationSettings.ScriptLibraryPath.Length)
+ : String.Empty;
+
+ var title = itemEditing ? scriptItem.Name : $"Untitled{TabSequencer}";
+ var icon = itemEditing ? scriptItem[FieldIDs.Icon] : "powershell/16x16/ise8.png";
+ path = itemEditing ? path : title;
+ var id = itemEditing ? scriptItem.ID.ToString() : string.Empty;
+ var db = itemEditing ? scriptItem.Database.Name : string.Empty;
+
+ var builder = new ImageBuilder
+ {
+ Src = Images.GetThemedImageSource(icon, ImageDimension.id16x16),
+ Width = 16,
+ Height = 16,
+ Margin = "0px 8px 0px 0px",
+ Align = "middle"
+ };
+ var startbarHtml = $"{builder}{title} - ISE";
+
+ SheerResponse.Eval($"spe.changeTabDetails({tabIndex},'{path}', '{startbarHtml}', '{id}', '{db}');");
+ SelectTabByIndex(tabIndex);
+ }
+
+
[HandleMessage("ise:run", true)]
protected virtual void ClientExecute(ClientPipelineArgs args)
{
@@ -527,6 +654,7 @@ protected virtual void ClientExecute(ClientPipelineArgs args)
{
scriptSession.SetItemLocationContext(ContextItem);
}
+
scriptSession.SetExecutedScript(ScriptItem);
scriptSession.ExecuteScriptPart(Editor.Value);
ClearOutput();
@@ -540,6 +668,7 @@ protected virtual void ClientExecute(ClientPipelineArgs args)
var error = ScriptSession.GetExceptionString(exc, ScriptSession.ExceptionStringFormat.Html);
PrintSessionUpdate($"{error}");
}
+
if (settings.SaveLastScript)
{
settings.Load();
@@ -573,7 +702,7 @@ protected virtual void JobExecuteSelection(ClientPipelineArgs args)
protected virtual void JobExecuteScript(ClientPipelineArgs args, string scriptToExecute, bool debug)
{
if (!RequestSessionElevationEx(args, ApplicationNames.ISE, SessionElevationManager.ExecuteAction))
- {
+ {
return;
}
@@ -602,8 +731,10 @@ protected virtual void JobExecuteScript(ClientPipelineArgs args, string scriptTo
var bPoints = strBrPoints.Select(int.Parse);
scriptSession.SetBreakpoints(bPoints);
}
+
scriptToExecute = scriptSession.DebugFile;
}
+
if (UseContext)
{
scriptSession.SetItemLocationContext(ContextItem);
@@ -633,16 +764,17 @@ protected virtual void JobExecuteScript(ClientPipelineArgs args, string scriptTo
"ScriptResult",
string.Format(
"" +
- "

" +
- "
"+
- Texts.PowerShellIse_JobExecuteScript_Please_wait___0_+
+ "
" +
+ Texts.PowerShellIse_JobExecuteScript_Please_wait___0_ +
"
" +
"
" +
"
", executionMessage));
- Context.ClientPage.ClientResponse.Eval("if(spe.preventCloseWhenRunning){spe.preventCloseWhenRunning(true);}");
+ Context.ClientPage.ClientResponse.Eval(
+ "if(spe.preventCloseWhenRunning){spe.preventCloseWhenRunning(true);}");
scriptSession.Debugging = debug;
Monitor.Start($"{DefaultSessionName}", "ISE", progressBoxRunner.Run,
@@ -721,7 +853,8 @@ private static void PrintSessionUpdate(string result)
{
if (!string.IsNullOrEmpty(result))
{
- var xssCleanup = new Regex(@"|
|
");
+ var xssCleanup =
+ new Regex(@"||");
if (xssCleanup.IsMatch(result))
{
result = xssCleanup.Replace(result, "⚠
");
@@ -740,6 +873,7 @@ protected void ExecuteInternal(ScriptSession scriptSession, string script)
{
scriptSession.InitBreakpoints();
}
+
scriptSession.ExecuteScriptPart(script);
}
finally
@@ -750,6 +884,7 @@ protected void ExecuteInternal(ScriptSession scriptSession, string script)
scriptSession.DebugFile = string.Empty;
scriptSession.ExecuteScriptPart("Get-PSBreakpoint | Remove-PSBreakpoint");
}
+
scriptSession.Debugging = false;
scriptSession.Interactive = false;
}
@@ -772,6 +907,7 @@ protected virtual void JobAbort(ClientPipelineArgs args)
ScriptRunning = false;
UpdateRibbon();
}
+
Monitor.SessionID = string.Empty;
ScriptRunning = false;
}
@@ -787,9 +923,11 @@ private void MonitorOnJobFinished(object sender, EventArgs eventArgs)
if (result?.Exception != null)
{
- var error = ScriptSession.GetExceptionString(result.Exception, ScriptSession.ExceptionStringFormat.Html);
+ var error = ScriptSession.GetExceptionString(result.Exception,
+ ScriptSession.ExceptionStringFormat.Html);
PrintSessionUpdate($"{error}");
}
+
SheerResponse.SetInnerHtml("PleaseWait", "");
ProgressOverlay.Visible = false;
ScriptRunning = false;
@@ -802,7 +940,8 @@ private void MonitorOnJobFinished(object sender, EventArgs eventArgs)
protected virtual void UpdateProgress(ClientPipelineArgs args)
{
var showProgress = ScriptRunning &&
- !string.Equals(args.Parameters["RecordType"], "Completed", StringComparison.OrdinalIgnoreCase);
+ !string.Equals(args.Parameters["RecordType"], "Completed",
+ StringComparison.OrdinalIgnoreCase);
ProgressOverlay.Visible = showProgress;
var sb = new StringBuilder();
if (showProgress)
@@ -824,9 +963,9 @@ protected virtual void UpdateProgress(ClientPipelineArgs args)
{
var secondsRemaining = int.Parse(args.Parameters["SecondsRemaining"]);
if (secondsRemaining > -1)
- sb.AppendFormat("{0:c} "+
- Texts.PowerShellIse_UpdateProgress_remaining+
- ".
",
+ sb.AppendFormat("{0:c} " +
+ Texts.PowerShellIse_UpdateProgress_remaining +
+ ".
",
new TimeSpan(0, 0, secondsRemaining));
}
@@ -847,6 +986,82 @@ protected void NotifyScriptModified(Message message)
UpdateRibbon();
}
+ [HandleMessage("ise:closetab")]
+ protected void CloseTabInitiated(Message message)
+ {
+ bool.TryParse(message.Arguments["modified"], out var modified);
+ if (!int.TryParse(message.Arguments["index"], out var tabIndex))
+ tabIndex = -1;
+
+ if (!int.TryParse(message.Arguments["selectIndex"], out var previouslySelectedIndex))
+ previouslySelectedIndex = -1;
+
+ if (modified)
+ {
+ var parameters = new NameValueCollection
+ {
+ ["index"] = $"{tabIndex}",
+ ["message"] =
+ Texts.PowerShellIse_The_script_is_modified_Do_you_want_to_close_it_without_saving_the_changes,
+ ["selectIndex"] = $"{previouslySelectedIndex}"
+ };
+ Context.ClientPage.Start(this, "CloseModifiedScript", parameters);
+ }
+ else
+ {
+ CloseTab(tabIndex, previouslySelectedIndex);
+ }
+
+ UpdateRibbon();
+ }
+
+ protected void CloseModifiedScript(ClientPipelineArgs args)
+ {
+ if (args.IsPostBack)
+ {
+ if (args.Result == "yes")
+ {
+ if (!int.TryParse(args.Parameters["index"], out int index))
+ {
+ index = -1;
+ }
+
+ if (!int.TryParse(args.Parameters["selectIndex"], out int selectIndex))
+ selectIndex = -1;
+
+ CloseTab(index, selectIndex);
+ }
+ }
+ else
+ {
+ var index = int.Parse(args.Parameters["index"]);
+ SelectTabByIndex(index);
+ SheerResponse.Confirm(args.Parameters["message"]);
+ args.WaitForPostBack();
+ }
+ }
+
+ private void CloseTab(int index, int newSelectedIndex)
+ {
+ if (index < 0)
+ return;
+ var tab = Tabs.Controls.OfType().Skip(Tabs.Active).FirstOrDefault();
+ if (tab != null)
+ {
+ Tabs.Controls.RemoveAt(Tabs.Controls.Count - 1);
+ }
+
+ SheerResponse.Eval($"spe.closeScript({index});");
+ if (Tabs.Controls.Count == 0)
+ {
+ CreateNewTab(null);
+ }
+ else
+ {
+ SelectTabByIndex(newSelectedIndex);
+ }
+ }
+
[HandleMessage("ise:updateribbon")]
protected void UpdateRibbon(Message message)
{
@@ -858,7 +1073,7 @@ protected void UpdateRibbon(Message message)
///
private void UpdateRibbon()
{
- var ribbon = new Ribbon {ID = "PowerShellRibbon"};
+ var ribbon = new Ribbon { ID = "PowerShellRibbon" };
var item = ScriptItem;
ribbon.CommandContext = new CommandContext(item);
ribbon.ShowContextualTabs = false;
@@ -890,10 +1105,10 @@ private void UpdateRibbon()
? Texts.PowerShellIse_UpdateRibbon_Single_execution
: (sessionName == DefaultSessionName)
? Factory.GetDatabase("core")
- .GetItem(
- "/sitecore/content/Applications/PowerShell/PowerShellIse/Menus/Sessions/ISE editing session")
- ?
- .DisplayName ?? DefaultSessionName
+ .GetItem(
+ "/sitecore/content/Applications/PowerShell/PowerShellIse/Menus/Sessions/ISE editing session")
+ ?
+ .DisplayName ?? DefaultSessionName
: sessionName;
var obj2 = Context.Database.GetItem("/sitecore/content/Applications/PowerShell/PowerShellIse/Ribbon");
Error.AssertItemFound(obj2, "/sitecore/content/Applications/PowerShell/PowerShellIse/Ribbon");
@@ -915,20 +1130,6 @@ private void UpdateRibbon()
UpdateWarning();
}
- private void UpdateStartbarTitle(string icon, string title)
- {
- var builder = new ImageBuilder
- {
- Src = Images.GetThemedImageSource(icon, ImageDimension.id16x16),
- Width = 16,
- Height = 16,
- Margin = "0px 8px 0px 0px",
- Align = "middle"
- };
- var startbarTitle = $"{builder}{title}";
- SheerResponse.Eval($"spe.changeStartbarTitle('{startbarTitle}');");
- }
-
private void UpdateWarning(string updateFromMessage = "")
{
var isSessionElevated = SessionElevationManager.IsSessionTokenElevated(ApplicationNames.ISE);
@@ -961,6 +1162,7 @@ private void UpdateWarning(string updateFromMessage = "")
controlContent = HtmlUtil.RenderControl(ElevationRequiredPanel);
}
}
+
break;
case SessionElevationManager.TokenDefinition.ElevationAction.Block:
controlContent = HtmlUtil.RenderControl(ElevationBlockedPanel);
@@ -970,7 +1172,6 @@ private void UpdateWarning(string updateFromMessage = "")
InfoPanel.InnerHtml = controlContent;
InfoPanel.Visible = !hidePanel;
SheerResponse.Eval($"spe.showInfoPanel({(!hidePanel).ToString().ToLower()}, '{updateFromMessage}');");
-
}
[HandleMessage("item:updated", true)]
@@ -984,10 +1185,11 @@ protected void SetCurrentSessionId(ClientPipelineArgs args)
{
Assert.ArgumentNotNull(args, "args");
var sessionId = args.Parameters["id"];
- if(IsHackedParameter(sessionId))
+ if (IsHackedParameter(sessionId))
{
return;
}
+
CurrentSessionId = sessionId;
SheerResponse.Eval($"spe.changeSessionId('{sessionId}');");
UpdateRibbon();
@@ -1002,6 +1204,7 @@ protected void SetCurrentLanguage(ClientPipelineArgs args)
{
return;
}
+
CurrentLanguage = language;
new LanguageHistory().Add(language);
UpdateRibbon();
@@ -1016,6 +1219,7 @@ protected void SetCurrentUser(ClientPipelineArgs args)
{
return;
}
+
CurrentUser = user;
new UserHistory().Add(user);
UpdateRibbon();
@@ -1040,6 +1244,7 @@ protected void SetContextItem(ClientPipelineArgs args)
ContextItemDb = contextDb;
ContextItemId = contextId;
}
+
UpdateRibbon();
}
@@ -1050,7 +1255,10 @@ protected virtual void UpdateSettings(ClientPipelineArgs args)
var backgroundColor = OutputLine.ProcessHtmlColor(settings.BackgroundColor);
var bottomPadding = CurrentVersion.IsAtLeast(SitecoreVersion.V80) ? 0 : 10;
SheerResponse.Eval(
- $"spe.changeSettings('{settings.FontFamilyStyle}', {settings.FontSize}, '{backgroundColor}', {bottomPadding}, {settings.LiveAutocompletion.ToString().ToLower()});");
+ $"spe.changeSettings('{settings.FontFamilyStyle}', {settings.FontSize}, " +
+ $"'{backgroundColor}', {bottomPadding}," +
+ $" {settings.LiveAutocompletion.ToString().ToLower()}," +
+ $" {settings.PerTabOutput.ToString().ToLower()});");
}
[HandleMessage("ise:setbreakpoint", true)]
@@ -1158,6 +1366,7 @@ public void SessionElevationPipeline(ClientPipelineArgs args)
{
message = args.Parameters["message"] + "(elevationResult=1)";
}
+
UpdateWarning(message);
}
}
@@ -1180,7 +1389,7 @@ private bool RequestSessionElevationEx(ClientPipelineArgs args, string appName,
var pipelineArgs = new ClientPipelineArgs
{
- Parameters = {["message"] = args.Parameters["message"], ["app"] = appName, ["action"] = action}
+ Parameters = { ["message"] = args.Parameters["message"], ["app"] = appName, ["action"] = action }
};
Context.ClientPage.Start(this, nameof(SessionElevationPipeline), pipelineArgs);
return false;
diff --git a/src/Spe/Core/Settings/ApplicationSettings.cs b/src/Spe/Core/Settings/ApplicationSettings.cs
index 51c0db081..d73f8320b 100644
--- a/src/Spe/Core/Settings/ApplicationSettings.cs
+++ b/src/Spe/Core/Settings/ApplicationSettings.cs
@@ -30,6 +30,7 @@ public class ApplicationSettings
private const string LastScriptSettingFieldName = "LastScript";
private const string SaveLastScriptSettingFieldName = "SaveLastScript";
private const string LiveAutocompletionSettingFieldName = "LiveAutocompletion";
+ private const string PerTabOutputSettingFieldName = "PerTabOutput";
private const string HostWidthSettingFieldName = "HostWidth";
private const string ForegroundColorSettingFieldName = "ForegroundColor";
private const string BackgroundColorSettingFieldName = "BackgroundColor";
@@ -105,6 +106,7 @@ public string FontFamilyStyle
}
public bool LiveAutocompletion { get; set; }
+ public bool PerTabOutput { get; set; }
private string AppSettingsPath => SettingsItemPath + ApplicationName + "/";
private string CurrentUserSettingsPath => AppSettingsPath + CurrentDomain + "/" + CurrentUserName;
@@ -229,7 +231,8 @@ public void Save()
{
configuration[LastScriptSettingFieldName] = HttpUtility.HtmlEncode(LastScript);
((CheckboxField) configuration.Fields[SaveLastScriptSettingFieldName]).Checked = SaveLastScript;
- ((CheckboxField)configuration.Fields[LiveAutocompletionSettingFieldName]).Checked = LiveAutocompletion;
+ ((CheckboxField)configuration.Fields[LiveAutocompletionSettingFieldName]).Checked = LiveAutocompletion;
+ ((CheckboxField)configuration.Fields[PerTabOutputSettingFieldName]).Checked = PerTabOutput;
configuration[HostWidthSettingFieldName] = HostWidth.ToString(CultureInfo.InvariantCulture);
configuration[ForegroundColorSettingFieldName] = ForegroundColor.ToString();
configuration[BackgroundColorSettingFieldName] = BackgroundColor.ToString();
@@ -257,6 +260,9 @@ internal void Load()
LiveAutocompletion =
TryGetSettingValue(LiveAutocompletionSettingFieldName, false,
() => ((CheckboxField) configuration.Fields[LiveAutocompletionSettingFieldName]).Checked);
+ PerTabOutput =
+ TryGetSettingValue(PerTabOutputSettingFieldName, false,
+ () => ((CheckboxField) configuration.Fields[PerTabOutputSettingFieldName]).Checked);
HostWidth =
TryGetSettingValue(HostWidthSettingFieldName,150,
() => int.TryParse(configuration[HostWidthSettingFieldName], out var hostWidth) ? hostWidth : 150);
@@ -297,6 +303,7 @@ private void SetToDefault()
LastScript = string.Empty;
SaveLastScript = true;
LiveAutocompletion = false;
+ PerTabOutput = false;
HostWidth = 150;
ForegroundColor = ConsoleColor.White;
BackgroundColor = ConsoleColor.DarkBlue;
diff --git a/src/Spe/Texts.cs b/src/Spe/Texts.cs
index 25ab48354..4c13109de 100644
--- a/src/Spe/Texts.cs
+++ b/src/Spe/Texts.cs
@@ -26,7 +26,8 @@ public class Texts
public const string PowerShellIse_JobExecuteScript_Working = "Working";
public const string PowerShellIse_LoadItem_The_item_is_not_a_script_ = "The item is not a script.";
public const string PowerShellIse_Open_Open_Script = "Open Script";
-
+ public const string PowerShellIse_The_script_is_modified_Do_you_want_to_close_it_without_saving_the_changes = "The script is modified. Do you want to close it without saving the changes?";
+
public const string PowerShellIse_Open_Select_the_script_item_that_you_want_to_open_ =
"Select the script item that you want to open.";
diff --git a/src/Spe/sitecore modules/PowerShell/Assets/TabClose.png b/src/Spe/sitecore modules/PowerShell/Assets/TabClose.png
new file mode 100644
index 0000000000000000000000000000000000000000..1c1dac4e37c5a30331b0871e89f2d4cf89aa0b6b
GIT binary patch
literal 332
zcmV-S0ki&zP)g$l2)pwN7Is$h1a_VVrTi^i{QH}~(kQ2H-Fwdc{_eT=*X>kQ
zWt!+tMgN7sOns4=+gQhSL>xD218m?bB2L;mSivHOnK`P#LyWM1<<<^xhb7EmkeL-;
zv0HLaWzT1Hnl5DK5w>c8+Wayi_J0(ZAfgSX-Gxr0)@|GSEt#3)a(WNXW%RIFYV87<
zxraVxOWPMX!(++yGjpfTG+kKp^8m
e3%`l~|4eU%#84KxhQWOR0000Ctrl+Space to show the Auto Suggest drop down that will show you all the matching comands/parameters/files depending on your caret position",
"You can show help by pressing Ctrl+Enter for the closest command to the left of the cursor.",
@@ -18,9 +18,27 @@
"You can search for keywords using the Ctrl+F hotkey.",
"You can toggle a comment block using the Ctrl+Shift+/ hotkey.",
"You can toggle a comment using the Ctrl+/ hotkey.",
- "You can find more documentation in the Sitecore PowerShell Extensions book."
+ "You can find more documentation in the Sitecore PowerShell Extensions book."
];
+ class EditorSession {
+ constructor(selectedText, editor, name, editorContainerId, path, index) {
+ this.index = index; // int: sort order
+ this.editor = editor; // string: the ace editor
+ this.name = name; // string: Script name
+ this.editorContainerId = editorContainerId;
+ this.path = path; // string: path
+ this.selectedText = selectedText; // string: selected text
+ this.startBarHtml = ""; // string: start bar html
+ this.tabTitleInnerHTML = ""; // string: tab title inner html
+ this.windowTitleInnerHTML = ""; // string: window title inner html
+ this.isModified = false; // bool: is modified
+ this.initialAssignment = true; // bool: initial assignment
+ this.breakpoints = ""; // string: breakpoints
+ this.results = ""; // string: Script execution results
+ }
+ }
+
var TokenTooltip = ace.require("tooltip").TokenTooltip;
var guid = "ISE_Editing_Session";
const speVariablesCacheKey = "spe::variables";
@@ -30,35 +48,34 @@
var resultsBottomOffset = 10;
var typingTimer;
var resultsVisibilityIntent = true;
-
- var editor = $($("#Editor")[0]);
- editor.hide();
+ var editorSessions = [];
+ var editorFontFamily = "Monaco";
+ var editorFontSize = 12;
+ var editorLiveAutocompletion = false;
+ var currentEditorIndex = 1;
+ var currentEditorSession;
+ var currentAceEditor;
+ var previousIndex = 1;
+ var perTabResults = true;
+ var editor = $($("#Editor")[0]);
+ var openedScriptsMemo = $($("#OpenedScripts")[0]);
+ var selectionTextMemo = $($("#SelectionText")[0]);
+ var breakpointsMemo = $($("#Breakpoints")[0]);
+ var scriptItemIdMemo = $($("#ScriptItemIdMemo")[0]);
+ var scriptItemDbMemo = $($("#ScriptItemDbMemo")[0]);
// Setup the ace code editor.
- var codeeditor = ace.edit("CodeEditor");
- codeeditor.setTheme("ace/theme/powershellise");
- codeeditor.session.setMode("ace/mode/powershell");
- codeeditor.setShowPrintMargin(false);
- codeeditor.session.setValue(editor.val());
- codeeditor.session.on("change", function () {
- editor.val(codeeditor.session.getValue());
- });
- codeeditor.tokenTooltip = new TokenTooltip(codeeditor);
-
- addProxy(codeeditor, "onPaste", function () {
- spe.updateRibbon();
- });
addProxy(scForm, "invoke", function (args) {
if (args[0] === "ise:immediatewindow") {
clearVariablesCache();
}
});
-
+
function registerEventListenersForRibbonButtons() {
[].forEach.call(document.querySelectorAll('.scRibbonToolbarSmallGalleryButton, .scRibbonToolbarLargeComboButtonBottom'), function (div) {
div.addEventListener("click",
- function() {
+ function () {
clearTimeout(typingTimer);
});
});
@@ -71,7 +88,7 @@
}
registerEventListenersForRibbonButtons();
-
+
window.parent.focus();
window.focus();
@@ -84,32 +101,40 @@
};
}
- function setFocusOnConsole() {
- $("body").focus();
- $(codeeditor).focus();
- ("WebForm_AutoFocus" in this) && WebForm_AutoFocus && WebForm_AutoFocus("CodeEditor");
- }
-
- window.addEventListener("focus", function(event) {
+ window.addEventListener("focus", function (event) {
setFocusOnConsole();
}, false);
function getQueryStringValue(key) {
key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, "\\$&");
- var match = location.search.match(new RegExp("[?&]"+key+"=([^&]+)(&|$)"));
+ var match = location.search.match(new RegExp("[?&]" + key + "=([^&]+)(&|$)"));
return match && decodeURIComponent(match[1].replace(/\+/g, " "));
}
- if(getQueryStringValue("sc_bw") === "1"){
- //$("#RibbonPanel").css("padding-top","50px");
- $("#Wrapper").css("padding-top","0px");
+ if (getQueryStringValue("sc_bw") === "1") {
+ $("#Wrapper").css("padding-top", "0px");
+ }
+
+ function hasSessionWithIndex(targetIndex) {
+ return editorSessions.some(session => session.index === targetIndex);
+ }
+
+ function getSessionByIndex(index) {
+ // Find the session with the specified index
+ return editorSessions.find(session => session.index === index);
}
- setTimeout(setFocusOnConsole, 1000);
+ function setFocusOnConsole() {
+ $("body").focus();
+ $(currentAceEditor).focus();
+ ("WebForm_AutoFocus" in this) && WebForm_AutoFocus && WebForm_AutoFocus("CodeEditor");
+ }
+
+ setTimeout(setFocusOnConsole, 1000);
spe.updateRibbon = function () {
- if (!codeeditor.getReadOnly()) {
- scForm.postRequest("", "", "", "ise:scriptchanged(modified=" + !codeeditor.session.getUndoManager().isClean() + ")");
+ if (!currentAceEditor.getReadOnly()) {
+ scForm.postRequest("", "", "", "ise:scriptchanged(modified=" + !currentEditorSession.isModified + ")");
registerEventListenersForRibbonButtons();
}
};
@@ -125,249 +150,343 @@
var posx = $("#PosX");
var posy = $("#PosY");
- $("#CodeEditor").on("keyup mousedown", function() {
- var position = codeeditor.getCursorPosition();
- posx.text(position.column);
- posy.text((position.row + 1));
- spe.updateRibbonNeeded();
- });
- $("#CodeEditor").on("keyup mouseup", function() {
- var range = codeeditor.getSelectionRange();
- $("#SelectionText")[0].value = codeeditor.session.getTextRange(range);
- });
+ spe.updateModificationFlag = function (clear) {
+
+ if (currentEditorSession.initialAssignment) {
+ currentEditorSession.initialAssignment = false;
+ } else
+ if (clear === currentEditorSession.isModified) {
+ currentEditorSession.isModified = !clear;
+ spe.applyWindowTitle(currentEditorIndex);
+ }
+ };
+
+ spe.changeTab = function (index) {
+
+ if (!hasSessionWithIndex(index)) {
+ return;
+ }
+
+ previousIndex = currentEditorIndex;
+ currentEditorIndex = index;
+ currentEditorSession = getSessionByIndex(currentEditorIndex);
+ currentAceEditor = currentEditorSession.editor;
+ clearVariablesCache();
+ editor.val(currentAceEditor.session.getValue());
+ selectionTextMemo.val(currentEditorSession.selectedText);
+ breakpointsMemo.val(currentEditorSession.breakpoints);
+ scriptItemIdMemo.val(currentEditorSession.scriptId);
+ scriptItemDbMemo.val(currentEditorSession.scriptDb);
+ spe.applyWindowTitle(currentEditorIndex);
+
+ editorSessions.forEach(function (editorSession) {
+ if (editorSession.index === index) {
+ $("#" + editorSession.editorContainerId).show();
+ } else {
+ $("#" + editorSession.editorContainerId).hide();
+ }
+ });
+
+ if(perTabResults) {
+ $("#ScriptResultCode").text("");
+ $("#ScriptResultCode").append(currentEditorSession.results);
+ $("#Result").scrollTop($("#Result")[0].scrollHeight);
+ }
+ }
+
+ spe.createEditor = function (index) {
+ previousIndex = currentEditorIndex;
+
+ currentEditorIndex = editorSessions.length + 1;
+
+ var editorContainerId = "CodeEditor" + index;
+ $("#CodeEditors").append("");
+ currentAceEditor = ace.edit(editorContainerId);
- $("#CopyResultsToClipboard").on("click", function() {
- clipboard.copy(spe.getOutput());
- });
+ const newSession = new EditorSession("", currentAceEditor, "", editorContainerId, "", currentEditorIndex);
+ editorSessions.push(newSession);
+ currentEditorSession = newSession;
- ace.config.loadModule("ace/ext/emmet", function() {
- ace.require("ace/lib/net").loadScript("/sitecore modules/PowerShell/Scripts/ace/emmet-core/emmet.js", function() {
- codeeditor.setOption("enableEmmet", true);
+ currentAceEditor.setTheme("ace/theme/powershellise");
+ currentAceEditor.session.setMode("ace/mode/powershell");
+ currentAceEditor.setShowPrintMargin(false);
+ currentAceEditor.session.setValue(editor.val());
+ currentAceEditor.session.on("change", function () {
+ editor.val(currentAceEditor.session.getValue());
+ });
+ currentAceEditor.tokenTooltip = new TokenTooltip(currentAceEditor);
+ currentAceEditor.setOption("fontFamily", editorFontFamily);
+ currentAceEditor.setOption("fontSize", editorFontSize);
+ currentAceEditor.setOptions({
+ enableLiveAutocompletion: editorLiveAutocompletion
});
- codeeditor.setOptions({
- enableSnippets: true,
- enableBasicAutocompletion: true
+ addProxy(currentAceEditor, "onPaste", function () {
+ spe.updateRibbon();
});
- });
- ace.config.loadModule("ace/ext/language_tools", function(module) {
- codeeditor.setOptions({
- enableSnippets: true,
- enableBasicAutocompletion: true
+ $("#CodeEditor" + currentEditorIndex).on("keyup mousedown", function () {
+ var position = currentAceEditor.getCursorPosition();
+ posx.text(position.column);
+ posy.text((position.row + 1));
+ spe.updateRibbonNeeded();
});
- var keyWordCompleter = {
- insertMatch: function(editor) {
+ $("#CodeEditor" + currentEditorIndex).on("keyup mouseup", function () {
+ var range = currentAceEditor.getSelectionRange();
+ currentEditorSession.selectedText = currentAceEditor.session.getTextRange(range);
+ selectionTextMemo.val(currentEditorSession.selectedText);
+ });
- var data = editor.completer.popup.getData(editor.completer.popup.getRow());
+ ace.config.loadModule("ace/ext/emmet", function () {
+ ace.require("ace/lib/net").loadScript("/sitecore modules/PowerShell/Scripts/ace/emmet-core/emmet.js", function () {
+ currentAceEditor.setOption("enableEmmet", true);
+ });
- var ranges = editor.selection.getAllRanges();
- for (var i = 0, range; range = ranges[i]; i++) {
- if (data.meta === "Signature") {
- data.value = data.fullValue;
- } else if (data.meta === "Type") {
- while (range.start.column > 0 && codeeditor.session.getTextRange(range).lastIndexOf("[") !== 0) {
- range.start.column--;
- }
- range.start.column++;
- data.value = data.fullValue;
- } else if (data.meta === "Item" || data.meta === "ProviderItem" || data.meta === "ProviderContainer") {
- range.start.column = data.position;
- data.value = data.fullValue;
-
- //try trim prefix quotes
- range.start.column--;
- range.end.column++;
- var replacedText = codeeditor.session.getTextRange(range);
- var charStart = replacedText.charAt(0);
- var charEnd = replacedText.charAt(replacedText.length-1);
- if (charStart !== '"' && charStart !== "'") {
+ currentAceEditor.setOptions({
+ enableSnippets: true,
+ enableBasicAutocompletion: true
+ });
+ });
+
+ ace.config.loadModule("ace/ext/language_tools", function (module) {
+ currentAceEditor.setOptions({
+ enableSnippets: true,
+ enableBasicAutocompletion: true
+ });
+
+ var keyWordCompleter = {
+ insertMatch: function (editor) {
+
+ var data = editor.completer.popup.getData(editor.completer.popup.getRow());
+
+ var ranges = editor.selection.getAllRanges();
+ for (var i = 0, range; range = ranges[i]; i++) {
+ if (data.meta === "Signature") {
+ data.value = data.fullValue;
+ } else if (data.meta === "Type") {
+ while (range.start.column > 0 && currentAceEditor.session.getTextRange(range).lastIndexOf("[") !== 0) {
+ range.start.column--;
+ }
range.start.column++;
- }
+ data.value = data.fullValue;
+ } else if (data.meta === "Item" || data.meta === "ProviderItem" || data.meta === "ProviderContainer") {
+ range.start.column = data.position;
+ data.value = data.fullValue;
- //try trim trailing quotes
- if (charEnd !== '"' && charEnd !== "'") {
- range.end.column--;
+ //try trim prefix quotes
+ range.start.column--;
+ range.end.column++;
+ var replacedText = currentAceEditor.session.getTextRange(range);
+ var charStart = replacedText.charAt(0);
+ var charEnd = replacedText.charAt(replacedText.length - 1);
+ if (charStart !== '"' && charStart !== "'") {
+ range.start.column++;
+ }
+
+ //try trim trailing quotes
+ if (charEnd !== '"' && charEnd !== "'") {
+ range.end.column--;
+ }
+ } else {
+ range.start.column -= editor.completer.completions.filterText.length;
}
- } else {
- range.start.column -= editor.completer.completions.filterText.length;
+ editor.session.remove(range);
}
- editor.session.remove(range);
- }
- editor.execCommand("insertstring", data.value || data);
- $.lastPrefix = "";
+ editor.execCommand("insertstring", data.value || data);
+ $.lastPrefix = "";
- },
- getCompletions: function(editor, session, pos, prefix, callback) {
- session.$mode.$keywordList = [];
+ },
+ getCompletions: function (editor, session, pos, prefix, callback) {
+ session.$mode.$keywordList = [];
- var range = codeeditor.getSelectionRange();
- range.start.column = 0;
- var line = codeeditor.session.getTextRange(range);
+ var range = currentAceEditor.getSelectionRange();
+ range.start.column = 0;
+ var line = currentAceEditor.session.getTextRange(range);
- if (line) {
+ if (line) {
- if (!$.tabCompletions || !$.lastPrefix || $.lastPrefix.length === 0 || prefix.indexOf($.lastPrefix) !== 0) {
- $.lastPrefix = prefix;
- _getTabCompletions(line);
+ if (!$.tabCompletions || !$.lastPrefix || $.lastPrefix.length === 0 || prefix.indexOf($.lastPrefix) !== 0) {
+ $.lastPrefix = prefix;
+ _getTabCompletions(line);
+ }
+ } else {
+ $.tabCompletions = [""];
}
- } else {
- $.tabCompletions = [""];
- }
- var keywords = $.tabCompletions;
+ var keywords = $.tabCompletions;
- if (keywords && keywords.length > 0 && keywords[0].indexOf("Signature", 0) === 0) {
+ if (keywords && keywords.length > 0 && keywords[0].indexOf("Signature", 0) === 0) {
- callback(null, []);
- $.tabCompletions = null;
+ callback(null, []);
+ $.tabCompletions = null;
+
+ var msgType = "information";
+ if (keywords.length === 1 && keywords[0].indexOf("not found in session", 0) > 0) {
+ msgType = "error";
+ }
- var msgType = "information";
- if (keywords.length === 1 && keywords[0].indexOf("not found in session", 0) > 0) {
- msgType = "error";
+ session.setAnnotations(keywords.map(function (word) {
+ var hint = word.split("|");
+ return {
+ row: pos.row,
+ column: pos.column,
+ text: hint[3],
+ type: msgType // error, warning or information
+ };
+ }));
+ ace.config.loadModule("ace/ext/error_marker", function (module) {
+ module.showErrorMarker(currentAceEditor, -1);
+ });
+ return;
}
- session.setAnnotations(keywords.map(function (word) {
+ var psCompleter = this;
+ callback(null, keywords.map(function (word) {
var hint = word.split("|");
return {
- row: pos.row,
- column: pos.column,
- text: hint[3],
- type: msgType // error, warning or information
+ name: hint[1],
+ value: hint[1],
+ score: 1000,
+ meta: hint[0],
+ position: hint[2],
+ fullValue: hint[3],
+ completer: psCompleter
};
}));
- ace.config.loadModule("ace/ext/error_marker", function (module) {
- module.showErrorMarker(codeeditor, -1);
- });
- return;
}
+ };
- var psCompleter = this;
- callback(null, keywords.map(function(word) {
- var hint = word.split("|");
- return {
- name: hint[1],
- value: hint[1],
- score: 1000,
- meta: hint[0],
- position: hint[2],
- fullValue: hint[3],
- completer: psCompleter
- };
- }));
- }
- };
+ module.addCompleter(keyWordCompleter);
+ });
- module.addCompleter(keyWordCompleter);
- });
+ currentAceEditor.setAutoScrollEditorIntoView(true);
- codeeditor.setAutoScrollEditorIntoView(true);
+ currentAceEditor.on("guttermousedown", function (editor) {
+ var target = editor.domEvent.target;
+ if (target.className.indexOf("ace_gutter-cell") === -1)
+ return;
- codeeditor.on("guttermousedown", function(editor) {
- var target = editor.domEvent.target;
- if (target.className.indexOf("ace_gutter-cell") === -1)
- return;
+ if (editor.clientX > 25 + target.getBoundingClientRect().left)
+ return;
- if (editor.clientX > 25 + target.getBoundingClientRect().left)
- return;
+ var currRow = editor.getDocumentPosition().row;
+ spe.breakpointSet(currRow, "toggle");
+ editor.stop();
+ var sparseKeys = Object.keys(editor.editor.session.getBreakpoints());
+ currentEditorSession.breakpoints = sparseKeys.toString();
+ breakpointsMemo.val(currentEditorSession.breakpoints);
+ });
- var currRow = editor.getDocumentPosition().row;
- spe.breakpointSet(currRow, "toggle");
- editor.stop();
- var sparseKeys = Object.keys(editor.editor.session.getBreakpoints());
- $("#Breakpoints")[0].value = sparseKeys.toString();
- });
+ currentAceEditor.on("input", function () {
+ spe.updateModificationFlag(false);
+ });
- codeeditor.on("input", function () {
- spe.updateModificationFlag(false);
- });
+ var codeeeditorcommands = [
+ {
+ name: "help",
+ bindKey: {win: "ctrl-enter|shift-enter", mac: "ctrl-enter|command-enter", sender: "codeeditor|cli"},
+ exec: function (env, args, request) {
+ var range = currentAceEditor.getSelectionRange();
+ if (range.start.row === range.end.row && range.start.column === range.end.column) {
+ range.start.column = 0;
+ }
+ var command = currentAceEditor.session.getTextRange(range);
+ if (command) {
+ spe.showCommandHelp(command);
+ }
+ },
+ readOnly: true
+ }, {
+ name: "fontSizeIncrease",
+ bindKey: {win: "Ctrl-Alt-Shift-=|Ctrl-Alt-Shift-+", mac: "Ctrl-Alt-Shift-=|Ctrl-Alt-Shift-+"},
+ exec: function (editor) {
+ spe.changeFontSize(editor.getFontSize() + 1);
+ },
+ readOnly: true
+ }, {
+ name: "fontSizeDecrease",
+ bindKey: {win: "Ctrl-Alt-Shift--", mac: "Ctrl-Alt-Shift--"},
+ exec: function (editor) {
+ spe.changeFontSize(Math.max(editor.getFontSize() - 1, 8));
+ },
+ readOnly: true
+ }, {
+ name: "setDebugPoint",
+ bindKey: {win: "F8", mac: "F8"},
+ exec: function (editor) {
+ var currRow = editor.selection.getCursor().row;
+ spe.breakpointSet(currRow, "toggle");
+ },
+ readOnly: true
+ }
+ ];
- var codeeeditorcommands = [
- {
- name: "help",
- bindKey: { win: "ctrl-enter|shift-enter", mac: "ctrl-enter|command-enter", sender: "codeeditor|cli" },
- exec: function(env, args, request) {
- var range = codeeditor.getSelectionRange();
- if (range.start.row === range.end.row && range.start.column === range.end.column) {
- range.start.column = 0;
- }
- var command = codeeditor.session.getTextRange(range);
- if (command) {
- spe.showCommandHelp(command);
- }
- },
- readOnly: true
- }, {
- name: "fontSizeIncrease",
- bindKey: { win: "Ctrl-Alt-Shift-=|Ctrl-Alt-Shift-+", mac: "Ctrl-Alt-Shift-=|Ctrl-Alt-Shift-+" },
- exec: function(editor) {
- spe.changeFontSize(editor.getFontSize() + 1);
- },
- readOnly: true
- }, {
- name: "fontSizeDecrease",
- bindKey: { win: "Ctrl-Alt-Shift--", mac: "Ctrl-Alt-Shift--" },
- exec: function(editor) {
- spe.changeFontSize(Math.max(editor.getFontSize() - 1, 8));
- },
- readOnly: true
- }, {
- name: "setDebugPoint",
- bindKey: { win: "F8", mac: "F8" },
- exec: function (editor) {
- var currRow = editor.selection.getCursor().row;
- spe.breakpointSet(currRow, "toggle");
- },
- readOnly: true
- }
- ];
+ currentAceEditor.commands.addCommands(codeeeditorcommands);
- codeeditor.commands.addCommands(codeeeditorcommands);
+ }
- spe.getOutput = function() {
- return $("#ScriptResultCode")[0].innerText;
+ spe.changeLiveAutocompletion = function (liveAutocompletion) {
+ editorLiveAutocompletion = liveAutocompletion;
+ editorSessions.forEach(function (editor) {
+ editor.editor.setOptions({
+ enableLiveAutocompletion: liveAutocompletion
+ });
+ });
};
- spe.changeFontSize = function(setting) {
- setting = parseInt(setting) || 12;
- codeeditor.setOption("fontSize", setting);
- $("#ScriptResult").css({ "font-size": setting + "px" });
- };
- spe.changeLiveAutocompletion = function(liveAutocompletion) {
- codeeditor.setOptions({
- enableLiveAutocompletion: liveAutocompletion
- });
+ $("#CopyResultsToClipboard").on("click", function () {
+ clipboard.copy(spe.getOutput());
+ });
+
+ spe.getOutput = function () {
+ return $("#ScriptResultCode")[0].innerText;
};
- spe.clearOutput = function() {
+ spe.clearOutput = function () {
$("#ScriptResultCode").text("");
$("#Result").scrollTop($("#Result")[0].scrollHeight);
+ currentEditorSession.results = "";
clearVariablesCache();
};
- spe.appendOutput = function(outputToAppend) {
+ spe.appendOutput = function (outputToAppend) {
var decoded = $("").html(outputToAppend).text();
$("#ScriptResultCode").append(decoded);
$("#Result").scrollTop($("#Result")[0].scrollHeight);
+ currentEditorSession.results = currentEditorSession.results + decoded;
clearVariablesCache();
};
- spe.changeFontFamily = function(setting) {
+ spe.changeFontFamily = function (setting) {
setting = setting || "Monaco";
- codeeditor.setOption("fontFamily", setting);
+ editorFontFamily = setting;
+ editorSessions.forEach(function (editor) {
+ editor.editor.setOption("fontFamily", setting);
+ });
+
document.getElementById("ScriptResult").style.fontFamily = setting;
};
+ spe.changeFontSize = function (setting) {
+ setting = parseInt(setting) || 12;
+ editorFontSize = setting;
+ editorSessions.forEach(function (editor) {
+ editor.editor.setOption("fontSize", setting);
+ });
+ $("#ScriptResult").css({"font-size": setting + "px"});
+ };
+
+
spe.changeBackgroundColor = function (setting) {
- $("#ScriptResult").css({ "background-color": setting });
- $("#Result").css({ "background-color": setting });
+ $("#ScriptResult").css({"background-color": setting});
+ $("#Result").css({"background-color": setting});
};
- spe.changeSettings = function(fontFamily, fontSize, backgroundColor, bottomOffset, liveAutocompletion) {
+ spe.changeSettings = function (fontFamily, fontSize, backgroundColor, bottomOffset, liveAutocompletion, perTabOutput) {
spe.changeBackgroundColor(backgroundColor);
spe.changeFontFamily(fontFamily);
spe.changeFontSize(fontSize);
@@ -375,54 +494,44 @@
spe.changeLiveAutocompletion(liveAutocompletion);
}
resultsBottomOffset = bottomOffset;
+ perTabResults = perTabOutput;
};
spe.changeSessionId = function (sessionId) {
guid = sessionId;
};
- spe.debugStart = function(sessionId) {
- codeeditor.setReadOnly(true);
+ spe.debugStart = function (sessionId) {
+ currentAceEditor.setReadOnly(true);
};
spe.debugStop = function (sessionId) {
setTimeout(spe.breakpointHandled, 100);
- codeeditor.setReadOnly(false);
- };
-
- spe.updateModificationFlag = function (clear) {
- if (clear) {
- codeeditor.getSession().getUndoManager().markClean();
- }
- var scriptModified = $("#scriptModified", window.parent.document);
- if (codeeditor.getSession().getUndoManager().isClean())
- scriptModified.hide();
- else
- scriptModified.show();
+ currentAceEditor.setReadOnly(false);
};
- spe.toggleBreakpoint = function(row, set) {
+ spe.toggleBreakpoint = function (row, set) {
if (set) {
- codeeditor.session.setBreakpoint(row);
+ currentAceEditor.session.setBreakpoint(row);
} else {
- codeeditor.session.clearBreakpoint(row);
+ currentAceEditor.session.clearBreakpoint(row);
}
scForm.postRequest("", "", "", "ise:togglebreakpoint(line=" + row + ",state=" + set + ")");
};
- spe.breakpointSet = function(row, action) {
+ spe.breakpointSet = function (row, action) {
if (action === "toggle") {
- if (codeeditor.session.getBreakpoints()[row] === "ace_breakpoint") {
+ if (currentAceEditor.session.getBreakpoints()[row] === "ace_breakpoint") {
spe.toggleBreakpoint(row, false);
} else {
spe.toggleBreakpoint(row, true);
}
} else if (action === "Set" || action === "Enabled") {
- if (codeeditor.session.getBreakpoints()[row] !== "ace_breakpoint") {
+ if (currentAceEditor.session.getBreakpoints()[row] !== "ace_breakpoint") {
spe.toggleBreakpoint(row, true);
}
} else if (action === "Removed" || action === "Disabled") {
- if (codeeditor.session.getBreakpoints()[row] === "ace_breakpoint") {
+ if (currentAceEditor.session.getBreakpoints()[row] === "ace_breakpoint") {
spe.toggleBreakpoint(row, false);
}
}
@@ -434,30 +543,27 @@
scContent.ribbonNavigatorButtonClick(this, event, "PowerShellRibbon_Strip_DebugStrip");
var Range = ace.require("ace/range").Range;
setTimeout(function () {
- debugMarkers.push(codeeditor.session.addMarker(new Range(line, column, endLine, endColumn + 1), "breakpoint", "text"));
+ debugMarkers.push(currentAceEditor.session.addMarker(new Range(line, column, endLine, endColumn + 1), "breakpoint", "text"));
}, 100);
- if (line < codeeditor.getFirstVisibleRow() || line > codeeditor.getLastVisibleRow()) {
- codeeditor.gotoLine(line);
+ if (line < currentAceEditor.getFirstVisibleRow() || line > currentAceEditor.getLastVisibleRow()) {
+ currentAceEditor.gotoLine(line);
}
};
- spe.breakpointHandled = function() {
+ spe.breakpointHandled = function () {
while (debugMarkers.length > 0) {
- codeeditor.session.removeMarker(debugMarkers.shift());
+ currentAceEditor.session.removeMarker(debugMarkers.shift());
}
scContent.ribbonNavigatorButtonClick(this, event, "PowerShellRibbon_Strip_ImageStrip");
};
- scForm.postRequest("", "", "", "ise:updatesettings");
-
spe.updateEditor = function () {
- codeeditor.getSession().setValue(editor.val());
- spe.clearBreakpoints();
+ currentAceEditor.getSession().setValue(editor.val());
};
spe.insertEditorContent = function (text) {
- var position = codeeditor.getCursorPosition();
- codeeditor.getSession().insert(position, text);
+ var position = currentAceEditor.getCursorPosition();
+ currentAceEditor.getSession().insert(position, text);
spe.clearBreakpoints();
};
@@ -466,16 +572,16 @@
spe.preventCloseWhenRunning(false);
}
clearVariablesCache();
- if(!resultsVisibilityIntent){
+ if (!resultsVisibilityIntent) {
setTimeout(spe.closeResults, 2000);
}
};
- spe.clearBreakpoints = function() {
- var breakPoints = Object.keys(codeeditor.session.getBreakpoints());
+ spe.clearBreakpoints = function () {
+ var breakPoints = Object.keys(currentAceEditor.session.getBreakpoints());
var bpCount = breakPoints.length;
for (var i = 0; i < bpCount; i++) {
- codeeditor.session.clearBreakpoint(breakPoints[i]);
+ currentAceEditor.session.clearBreakpoint(breakPoints[i]);
}
};
@@ -487,40 +593,115 @@
return string.replace(new RegExp(escapeRegExp(find), "g"), replace);
}
- spe.changeWindowTitle = function(newTitle, clearWindow) {
- if (clearWindow) {
- codeeditor.getSession().setValue("");
- }
- newTitle = replaceAll(newTitle, "/", " / ");
+ spe.changeTabDetails = function (codeEditorIndex, newTitle, startBarHtml, scriptId, scriptDb) {
+
+ var editorSession = getSessionByIndex(codeEditorIndex);
+ var itemName = newTitle.split("/").last();
+ editorSession.name = itemName
+ editorSession.path = newTitle;
+ const newTabTitle = replaceAll(editorSession.path, "/", " / ");
+ editorSession.tabTitleInnerHTML = "⬤ " + editorSession.name +
+ "" +
+ " ";
+ const newWindowTitle = replaceAll(editorSession.path, "/", " / ");
+ editorSession.windowTitleInnerHTML = "⬤ " + newWindowTitle + " - ";
+ editorSession.tabTitleHtml = replaceAll(editorSession.path, "/", " / ");
+ editorSession.scriptId = scriptId;
+ editorSession.scriptDb = scriptDb;
+ editorSession.startBarHtml = startBarHtml;
+ var openedScripts = editorSessions.map(session => session.path + ":" + session.index).join('\n');
+ openedScriptsMemo.val(openedScripts);
+ }
+
+ spe.applyWindowTitle = function (codeEditorIndex) {
+
+ var editorSession = getSessionByIndex(codeEditorIndex);
var windowCaption = $("#WindowCaption", window.parent.document);
if (windowCaption.length > 0) {
- windowCaption[0].innerHTML = "" + newTitle + " (*) - ";
+ windowCaption[0].innerHTML =
+ editorSession.windowTitleInnerHTML.
+ replace("#tabindex#", editorSession.index).
+ replace("#styles#", editorSession.isModified ? "display:inline;" : "display:none;");
+
}
- codeeditor.getSession().getUndoManager().markClean();
- spe.clearBreakpoints();
- };
- spe.changeStartbarTitle = function (newTitle) {
+ var styles = $("#ModifiedStatusStyles");
+ if (styles.length === 0) {
+ var head = $("head");
+ head.append("");
+ styles = $("#ModifiedStatusStyles");
+ }
+ var stylesinnerHTML = "";
+ editorSessions.forEach(function (currEditor) {
+ var tabHeader = $("#Tabs_tab_" + (currEditor.index - 1))
+ if (tabHeader.length > 0) {
+ tabHeader[0].innerHTML = currEditor.tabTitleInnerHTML.replaceAll("#tabindex#", currEditor.index);
+ if (currEditor.isModified) {
+ stylesinnerHTML = stylesinnerHTML + ".ModifiedMark" + currEditor.index + "{display:inline;}";
+ }
+ }
+ });
+ styles[0].innerHTML = stylesinnerHTML;
+
+
if (window.parent && window.parent.frameElement) {
var frameId = window.parent.frameElement.id;
var startbar = window.parent.parent.document.getElementById('startbar_application_' + frameId);
- $(startbar).find('span').html(newTitle);
+ $(startbar).find('span').html(editorSession.startBarHtml);
}
};
- spe.resizeEditor = function() {
- codeeditor.resize();
- var resultsHeight =$(window).height() -$("#ResultsSplitter").offset().top - $("#ResultsSplitter").height() - $("#StatusBar").height() - resultsBottomOffset - 10;
- $("#Result").height(resultsHeight);
+
+ spe.closeTab = function (event, index) {
+
+ event.stopPropagation();
+ var closingEditorSession = getSessionByIndex(index);
+ var selectIndex = currentEditorIndex;
+ if (index === currentEditorIndex) {
+ selectIndex = previousIndex;
+ }
+ if (selectIndex > index) {
+ selectIndex--;
+ }
+ selectIndex = Math.min(selectIndex, editorSessions.length - 1);
+ scForm.postRequest("", "", "", "ise:closetab(index=" + index + ",modified=" + closingEditorSession.isModified + ",selectIndex=" + selectIndex + ")");
+ };
+
+ spe.closeScript = function (index) {
+
+ // Remove the session with the specified index
+ var closingEditorSession = getSessionByIndex(index);
+
+ editorSessions = editorSessions.filter(session => session.index !== index);
+
+ // cleanup the DOM and script content
+ var editorContainer = $(closingEditorSession.editor.container)
+ closingEditorSession.editor.destroy();
+ editorContainer.remove();
+ editor.val("");
+
+ // Update the indices of the remaining sessions
+ editorSessions.forEach((session, i) => {
+ session.index = i + 1;
+ });
+ }
+
+ spe.resizeEditor = function () {
+ if (currentAceEditor !== undefined) {
+ currentAceEditor.resize();
+ }
+ var resultsHeight = $(window).height() - $("#ResultsSplitter").offset().top - $("#ResultsSplitter").height() - $("#StatusBar").height() - resultsBottomOffset - 10;
+ $("#Result").height(resultsHeight);
$("#Result").width($(window).width() - $("#Result").offset().left * 2);
- $("#ProgressOverlay").css("top",($("#Result").offset().top+4)+"px");
+ $("#ProgressOverlay").css("top", ($("#Result").offset().top + 4) + "px");
+
};
function isEmpty(val) {
return (val === undefined || val == null || val.length <= 0) ? true : false;
}
- spe.showInfoPanel = function(showPanel, updateFromMessage) {
+ spe.showInfoPanel = function (showPanel, updateFromMessage) {
if (showPanel) {
$("#InfoPanel").css("display", "block");
} else {
@@ -532,21 +713,21 @@
}
};
- spe.requestElevation = function() {
+ spe.requestElevation = function () {
scForm.postRequest("", "", "", "ise:requestelevation");
};
- spe.restoreResults = function() {
+ spe.restoreResults = function () {
$("#ResultsSplitter").show();
$("#ResultsRow").show();
spe.resizeEditor();
$("#ResultsStatusBarAction").removeClass("status-bar-results-hidden")
};
- spe.closeResults = function() {
+ spe.closeResults = function () {
$("#ResultsSplitter").hide();
- $("#ResultsRow").hide("slow", function() {
- codeeditor.resize();
+ $("#ResultsRow").hide("slow", function () {
+ currentAceEditor.resize();
});
$("#ResultsStatusBarAction").addClass("status-bar-results-hidden")
};
@@ -599,7 +780,7 @@
return cachedValue;
}
- getPowerShellResponse({ "guid": sessionId, "variableName": variableName }, "GetVariableValue",
+ getPowerShellResponse({"guid": sessionId, "variableName": variableName}, "GetVariableValue",
function (json) {
data = json.d;
});
@@ -608,16 +789,16 @@
return data;
};
- spe.getAutocompletionPrefix = function(text) {
+ spe.getAutocompletionPrefix = function (text) {
var data;
- getPowerShellResponse({ "guid": guid, "command": text }, "GetAutoCompletionPrefix",
- function(json) {
+ getPowerShellResponse({"guid": guid, "command": text}, "GetAutoCompletionPrefix",
+ function (json) {
data = JSON.parse(json.d);
});
return data;
};
- spe.showCommandHelp = function(command) {
+ spe.showCommandHelp = function (command) {
_getCommandHelp(command);
if (spe.ajaxDialog)
spe.ajaxDialog.remove();
@@ -631,7 +812,7 @@
spe.ajaxDialog.dialog("close");
});
},
- close: function(event, ui) {
+ close: function (event, ui) {
$(this).remove();
},
height: $(window).height() - 20,
@@ -645,7 +826,7 @@
$.commandHelp = "";
- spe.changeWindowTitle($("#ScriptName")[0].innerHTML, false);
+
var tipIndex = Math.floor(Math.random() * tips.length);
var tip = tips[tipIndex];
@@ -653,37 +834,37 @@
$("#StatusTip").html(tip);
$("#TipOfTheSession").position({
- my: "left bottom",
- at: "left bottom-30px",
- within: $("#Result"),
- of: $("#Result")
- }).css({
- right: 0,
- left: 0
- }).hide()
- .show("drop", { direction: "down" }, "400")
+ my: "left bottom",
+ at: "left bottom-30px",
+ within: $("#Result"),
+ of: $("#Result")
+ }).css({
+ right: 0,
+ left: 0
+ }).hide()
+ .show("drop", {direction: "down"}, "400")
.delay(5000)
- .hide("drop", { direction: "down" }, "400",
- function() {
- $(".status-bar-text").animate({ backgroundColor: "#fcefa1" }).animate({ backgroundColor: "#fff" });
+ .hide("drop", {direction: "down"}, "400",
+ function () {
+ $(".status-bar-text").animate({backgroundColor: "#fcefa1"}).animate({backgroundColor: "#fff"});
});
- $(".status-bar-text").click(function() {
+ $(".status-bar-text").click(function () {
tipIndex++;
if (tipIndex >= tips.length) {
tipIndex = 0;
}
var nextTip = tips[tipIndex];
- $(".status-bar-text").animate({ backgroundColor: "#fcefa1" },
- function() {
+ $(".status-bar-text").animate({backgroundColor: "#fcefa1"},
+ function () {
$("#TipText").html(nextTip);
$("#StatusTip").html(nextTip);
- }).animate({ backgroundColor: "#fff" });
+ }).animate({backgroundColor: "#fff"});
});
-
- $("#ShowHideResults").click(function() {
+
+ $("#ShowHideResults").click(function () {
if ($("#ResultsRow").is(":visible")) {
resultsVisibilityIntent = false;
spe.closeResults();
@@ -692,44 +873,51 @@
spe.restoreResults();
}
});
-
+
function _getCommandHelp(str) {
- getPowerShellResponse({ "guid": guid, "command": str }, "GetHelpForCommand",
- function(json) {
+ getPowerShellResponse({"guid": guid, "command": str}, "GetHelpForCommand",
+ function (json) {
var data = JSON.parse(json.d);
$.commandHelp = data[0];
});
}
function _getTabCompletions(str) {
- getPowerShellResponse({ "guid": guid, "command": str }, "CompleteAceCommand",
- function(json) {
+ getPowerShellResponse({"guid": guid, "command": str}, "CompleteAceCommand",
+ function (json) {
var data = JSON.parse(json.d);
$.tabCompletions = data;
});
}
function getPowerShellResponse(callData, remotefunction, doneFunction, errorFunction) {
- if(remotefunction != "GetVariableValue"){
+ if (remotefunction != "GetVariableValue") {
spe.requestElevation();
- };
+ }
+ ;
var datastring = JSON.stringify(callData);
$.ajax({
- type: "POST",
- contentType: "application/json; charset=utf-8",
- dataType: "json",
- url: "/sitecore modules/PowerShell/Services/PowerShellWebService.asmx/" + remotefunction,
- data: datastring,
- processData: false,
- cache: false,
- async: false
- }).done(doneFunction)
+ type: "POST",
+ contentType: "application/json; charset=utf-8",
+ dataType: "json",
+ url: "/sitecore modules/PowerShell/Services/PowerShellWebService.asmx/" + remotefunction,
+ data: datastring,
+ processData: false,
+ cache: false,
+ async: false
+ }).done(doneFunction)
.fail(errorFunction);
}
- $(window).on('resize', function(){
- spe.resizeEditor();
+ $(window).on('resize', function () {
+ spe.resizeEditor();
}).trigger('resize');
+
+ setTimeout(function () {
+ scForm.postRequest("", "", "", "ise:updatesettings");
+ scForm.postRequest("", "", "", "ise:loadinitialscript");
+ }, 100);
+
});
}(jQuery, window, window.spe = window.spe || {}, window.ace = window.ace || {}));
diff --git a/src/Spe/sitecore modules/PowerShell/Styles/ise.css b/src/Spe/sitecore modules/PowerShell/Styles/ise.css
index 0d092dc54..406b1a7f1 100644
--- a/src/Spe/sitecore modules/PowerShell/Styles/ise.css
+++ b/src/Spe/sitecore modules/PowerShell/Styles/ise.css
@@ -9,7 +9,10 @@
background-color: white;
}
-#ResultsSplitter + tr > td { height: 100%; }
+#ResultsSplitter + tr > td {
+ height: 100%;
+ overflow: auto;
+}
#Databases {
border: solid 1px ButtonShadow;
@@ -194,10 +197,10 @@ a.ps-link {
padding: 0 4px 0 4px;
}
-#Result {
- position: fixed;
- bottom: 27px;
-}
+/*#Result {*/
+/* position: fixed;*/
+/* bottom: 27px;*/
+/*}*/
#HelpClose {
font-size: 18px;
@@ -417,4 +420,59 @@ a.ps-link {
#ResultsStatusBarAction.status-bar-results-hidden {
background-color: rgb(1, 36, 86);
-}
\ No newline at end of file
+}
+
+.scTabPage {
+ padding: 4px 0 0 0;
+}
+
+.scTab, .scTab_Hover, .scTabActive, .scTabActive_Hover {
+ text-transform: none;
+ line-height: 30px;
+}
+
+.scTabActive:after, .scTabActive_Hover:after {
+ height: 30px;
+}
+
+.ff .scTabstrip {
+ margin-top: 4px;
+ height: 33px;
+}
+
+.scTabs {
+ top: 30px;
+ display:none;
+}
+
+.aceCodeEditor, #EditingArea, #Content, #Wrapper, #Result {
+ width: 100%;
+ height: 100%;
+}
+
+#TabsPanel {
+ width: 100%;
+ height: 35px;
+}
+
+#EditingArea {
+ overflow: auto;
+}
+
+#CodeEditors {
+ width: 100%;
+ height: calc(100% - 40px);
+}
+
+.scriptModified{
+ display:none;
+ color:#fc2929
+}
+
+.closeTab {
+ display: inline-block;
+ cursor: pointer;
+ background: url(/sitecore%20modules/PowerShell/Assets/TabClose.png) no-repeat center;
+ padding: 0 4px 0 4px;
+ margin: 0 -10px 0 10px;
+}
diff --git a/src/Spe/sitecore modules/Shell/PowerShell/PowerShellIse.xml b/src/Spe/sitecore modules/Shell/PowerShell/PowerShellIse.xml
index 6ea8206cf..7339182a3 100644
--- a/src/Spe/sitecore modules/Shell/PowerShell/PowerShellIse.xml
+++ b/src/Spe/sitecore modules/Shell/PowerShell/PowerShellIse.xml
@@ -3,15 +3,15 @@
-
-
+
+
+
-
@@ -32,11 +32,14 @@
-
+
+
+
+
-
+
@@ -80,21 +83,20 @@
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
-
diff --git a/unicorn/SPE/Core/Templates/Modules/PowerShell Console/PowerShell Console Settings/Behaviour/PerTabOutput.yml b/unicorn/SPE/Core/Templates/Modules/PowerShell Console/PowerShell Console Settings/Behaviour/PerTabOutput.yml
new file mode 100644
index 000000000..cf796b49c
--- /dev/null
+++ b/unicorn/SPE/Core/Templates/Modules/PowerShell Console/PowerShell Console Settings/Behaviour/PerTabOutput.yml
@@ -0,0 +1,35 @@
+---
+ID: "08c36097-57d5-440d-ab36-0ed73e0cb11e"
+Parent: "86d29da6-ffad-4f0e-a659-aae49f0e4a6b"
+Template: "455a3e98-a627-4b40-8035-e683a0331ac7"
+Path: /sitecore/templates/Modules/PowerShell Console/PowerShell Console Settings/Behaviour/PerTabOutput
+DB: master
+SharedFields:
+- ID: "ab162cc0-dc80-4abf-8871-998ee5d7ba32"
+ Hint: Type
+ Value: Checkbox
+- ID: "ba3f86a2-4a1c-4d78-b63d-91c2779c1b5e"
+ Hint: __Sortorder
+ Value: 500
+Languages:
+- Language: en
+ Fields:
+ - ID: "19a69332-a23e-4e70-8d16-b2640cb24cc8"
+ Hint: Title
+ Value: Separate output per script tab
+ - ID: "9541e67d-ce8c-4225-803d-33f7f29f09ef"
+ Hint: __Short description
+ Value: Only valid in ISE
+ Versions:
+ - Version: 1
+ Fields:
+ - ID: "25bed78c-4957-4165-998a-ca1b52f67497"
+ Hint: __Created
+ Value: 20240508T164719Z
+ - ID: "5dd74568-4d4b-44c1-b513-0af5f4cda34f"
+ Hint: __Created by
+ Value: |
+ sitecore\Admin
+ - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f"
+ Hint: __Revision
+ Value: "06f92fff-ad52-473a-835d-01976a02eb94"
diff --git a/unicorn/SPE/UI/Applications/PowerShell/PowerShellIse/Meta/EditIseSettings.yml b/unicorn/SPE/UI/Applications/PowerShell/PowerShellIse/Meta/EditIseSettings.yml
index f6518e174..f1332c9c4 100644
--- a/unicorn/SPE/UI/Applications/PowerShell/PowerShellIse/Meta/EditIseSettings.yml
+++ b/unicorn/SPE/UI/Applications/PowerShell/PowerShellIse/Meta/EditIseSettings.yml
@@ -13,7 +13,7 @@ SharedFields:
Value: 200
- ID: "cf738220-908d-4c3f-9482-32e625daf13c"
Hint: Fields
- Value: FontSize|FontFamily|HostWidth|ForegroundColor|BackgroundColor|SaveLastScript|LiveAutocompletion
+ Value: FontSize|FontFamily|HostWidth|ForegroundColor|BackgroundColor|SaveLastScript|LiveAutocompletion|PerTabOutput
Languages:
- Language: da
Fields:
@@ -46,14 +46,14 @@ Languages:
Fields:
- ID: "25bed78c-4957-4165-998a-ca1b52f67497"
Hint: __Created
- Value: 20090528T094300
+ Value: 20090528T074300Z
- ID: "5dd74568-4d4b-44c1-b513-0af5f4cda34f"
Hint: __Created by
Value: |
sitecore\admin
- ID: "8cdc337e-a112-42fb-bbb4-4143751e123f"
Hint: __Revision
- Value: "5e8783c0-22a5-4016-8fc7-bb89272a6485"
+ Value: "76e07e71-259f-4afe-8ba4-bce99247a128"
- Language: "ja-JP"
Fields:
- ID: "108d3a63-baaa-4560-86d8-3a112ed84717"
From 987c37a19d4fd2b08385d85a90613b3556577fe2 Mon Sep 17 00:00:00 2001
From: Adam Najmanowicz
Date: Fri, 10 May 2024 00:37:56 +0200
Subject: [PATCH 07/99] #1269 : New-Item -ForceID does not work with branch
templates
---
src/Spe/Core/Provider/PsSitecoreItemProvider.cs | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/Spe/Core/Provider/PsSitecoreItemProvider.cs b/src/Spe/Core/Provider/PsSitecoreItemProvider.cs
index b35646544..d187d521c 100644
--- a/src/Spe/Core/Provider/PsSitecoreItemProvider.cs
+++ b/src/Spe/Core/Provider/PsSitecoreItemProvider.cs
@@ -766,13 +766,11 @@ protected override void NewItem(string path, string itemTypeName, object newItem
switch (TemplateUtils.GetType(templateItem))
{
case TemplateItemType.Template:
+ case TemplateItemType.Branch:
createdItem = forcedId != ID.Null
? ItemManager.AddFromTemplate(name, templateItem.ID, parentItem, forcedId)
: ItemManager.AddFromTemplate(name, templateItem.ID, parentItem);
break;
- case TemplateItemType.Branch:
- createdItem = parentItem.Add(name, (BranchItem)templateItem);
- break;
default:
WriteError(
new ErrorRecord(new InvalidOperationException("Cannot create item as type provided is neither Template nor Branch"),
From bf8193454b9f3582845f188d246fe902cb7cdf2e Mon Sep 17 00:00:00 2001
From: Michael West
Date: Fri, 10 May 2024 20:51:37 -0500
Subject: [PATCH 08/99] Create stale.yml
---
.github/stale.yml | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
create mode 100644 .github/stale.yml
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 000000000..30e1c6240
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,16 @@
+# Number of days of inactivity before an issue or PR becomes stale
+daysUntilStale: 365
+# Number of days of inactivity before a stale issue or PR is closed
+daysUntilClose: 30
+# Issues or PR's with these labels will never be considered stale
+exemptLabels:
+ - keep
+# Label to use when marking issues or PR's as stale
+staleLabel: stale
+# Comment to post when marking an issue or PR as stale. Set to `false` to disable
+markComment: >
+ This has been automatically marked as stale because it has not had recent activity.
+ It will be closed if there is no further activity within 30 days.
+ You may add comments or the 'keep' label to prevent it from closing. Thank you for your contributions.
+# Comment to post when closing a stale issue or PR. Set to `false` to disable
+closeComment: false
From f524a37787ab83281b0eb8aa18be8c47165b80f9 Mon Sep 17 00:00:00 2001
From: Michael West
Date: Fri, 10 May 2024 21:32:45 -0500
Subject: [PATCH 09/99] Create stale.yml
---
.github/workflows/stale.yml | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 .github/workflows/stale.yml
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
new file mode 100644
index 000000000..4cef1e978
--- /dev/null
+++ b/.github/workflows/stale.yml
@@ -0,0 +1,22 @@
+name: Close inactive issues
+on:
+ schedule:
+ - cron: "30 1 * * *"
+
+jobs:
+ close-issues:
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ pull-requests: write
+ steps:
+ - uses: actions/stale@v5
+ with:
+ days-before-issue-stale: 365
+ days-before-issue-close: 30
+ stale-issue-label: "stale"
+ stale-issue-message: "This issue is stale because it has been open for 365 days with no activity."
+ close-issue-message: "This issue was closed because it has been inactive for 30 days since being marked as stale."
+ days-before-pr-stale: -1
+ days-before-pr-close: -1
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
From d4ee851aa47630e6bd0a92be3a55378529c0bdc2 Mon Sep 17 00:00:00 2001
From: Michael West
Date: Fri, 10 May 2024 21:33:48 -0500
Subject: [PATCH 10/99] Delete .github/stale.yml
---
.github/stale.yml | 16 ----------------
1 file changed, 16 deletions(-)
delete mode 100644 .github/stale.yml
diff --git a/.github/stale.yml b/.github/stale.yml
deleted file mode 100644
index 30e1c6240..000000000
--- a/.github/stale.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-# Number of days of inactivity before an issue or PR becomes stale
-daysUntilStale: 365
-# Number of days of inactivity before a stale issue or PR is closed
-daysUntilClose: 30
-# Issues or PR's with these labels will never be considered stale
-exemptLabels:
- - keep
-# Label to use when marking issues or PR's as stale
-staleLabel: stale
-# Comment to post when marking an issue or PR as stale. Set to `false` to disable
-markComment: >
- This has been automatically marked as stale because it has not had recent activity.
- It will be closed if there is no further activity within 30 days.
- You may add comments or the 'keep' label to prevent it from closing. Thank you for your contributions.
-# Comment to post when closing a stale issue or PR. Set to `false` to disable
-closeComment: false
From 545fd9afd872ca2ecb89cc1ac853fb5eaf63a7cc Mon Sep 17 00:00:00 2001
From: Adam Najmanowicz
Date: Sat, 11 May 2024 10:44:20 +0200
Subject: [PATCH 11/99] #1241: Receive-file dialog errors out when invalid file
name upload is attempted + solved problems with the dialog not working at all
in Sitecore 10.3+
---
src/Spe/App_Config/Include/Spe/Spe.config | 10 ++++++
.../UploadFile/PowerShellUploadFileForm.cs | 35 ++++++++++---------
.../UploadFile/PowerShellUploadFilePage2.cs | 13 +++++--
src/Spe/Texts.cs | 2 ++
.../PowerShell/Styles/VariablePrompt.css | 4 +++
.../UploadFile/PowerShellUploadFile.xml | 17 ++++++---
6 files changed, 57 insertions(+), 24 deletions(-)
diff --git a/src/Spe/App_Config/Include/Spe/Spe.config b/src/Spe/App_Config/Include/Spe/Spe.config
index 4f4323419..0a1b57ba5 100644
--- a/src/Spe/App_Config/Include/Spe/Spe.config
+++ b/src/Spe/App_Config/Include/Spe/Spe.config
@@ -381,5 +381,15 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Spe/Client/Applications/UploadFile/PowerShellUploadFileForm.cs b/src/Spe/Client/Applications/UploadFile/PowerShellUploadFileForm.cs
index af74fa0bc..b15f2f06f 100644
--- a/src/Spe/Client/Applications/UploadFile/PowerShellUploadFileForm.cs
+++ b/src/Spe/Client/Applications/UploadFile/PowerShellUploadFileForm.cs
@@ -20,7 +20,7 @@ public class PowerShellUploadFileForm : BaseForm
protected XmlControl Dialog;
protected Literal DialogDescription;
protected Literal DialogHeader;
- protected Literal UploadWarning;
+ protected Literal UploadWarning;
protected Image DialogIcon;
protected GenericControl ItemUri;
protected GenericControl LanguageName;
@@ -28,7 +28,9 @@ public class PowerShellUploadFileForm : BaseForm
protected GenericControl Overwrite;
protected GenericControl Unpack;
protected GenericControl Versioned;
-
+ protected Border MessageBar;
+ protected Literal Message;
+ protected Scrollbox ValuePanel;
protected void EndUploading(string id)
{
SheerResponse.SetDialogValue(ID.TryParse(id, out _) ? id : HttpUtility.UrlDecode(id));
@@ -38,6 +40,7 @@ protected void EndUploading(string id)
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
+ MessageBar.Visible = false;
if (Context.ClientPage.IsEvent || Context.ClientPage.IsPostBack) return;
var handle = UrlHandle.Get();
@@ -116,7 +119,13 @@ protected void CancelClick()
protected void ShowError()
{
- SheerResponse.Alert(Sitecore.Texts.AN_ERROR_OCCURED_WHILE_UPLOADING_THE_REASON_MAY_BE_THAT_THE_FILE_DOES_NOT_EXIST);
+ ShowError(Sitecore.Texts.AN_ERROR_OCCURED_WHILE_UPLOADING_THE_REASON_MAY_BE_THAT_THE_FILE_DOES_NOT_EXIST);
+ }
+
+ protected void ShowError(string errorText)
+ {
+ MessageBar.Visible = true;
+ Message.Text = Translate.Text(Texts.UploadDialog_An_error_occured_while_uploading_the_file_0, errorText);
OKButton.Disabled = true;
CancelButton.Disabled = true;
OKButton.Disabled = false;
@@ -125,25 +134,17 @@ protected void ShowError()
protected void ShowFileTooBig()
{
- SheerResponse.Alert(
- Translate.Text(Sitecore.Texts.THE_FILE_IS_TOO_BIG_TO_BE_UPLOADED_THE_MAXIMUM_SIZE_FOR_UPLOADING_FILES_IS_0, MainUtil.FormatSize(Settings.Upload.MaximumDatabaseUploadSize))
- );
- OKButton.Disabled = true;
- CancelButton.Disabled = true;
- OKButton.Disabled = false;
- CancelButton.Disabled = false;
+ ShowError(Translate.Text(
+ Sitecore.Texts.THE_FILE_IS_TOO_BIG_TO_BE_UPLOADED_THE_MAXIMUM_SIZE_FOR_UPLOADING_FILES_IS_0,
+ MainUtil.FormatSize(Settings.Upload.MaximumDatabaseUploadSize)));
}
protected void ShowFileTooBig(string filename)
{
Assert.ArgumentNotNullOrEmpty(filename, "filename");
- SheerResponse.Alert(
- Translate.Text(Sitecore.Texts.THE_FILE_0_IS_TOO_BIG_TO_BE_UPLOADED_THE_MAXIMUM_SIZE_FOR_UPLOADING_FILES_IS_1, filename, MainUtil.FormatSize(Settings.Upload.MaximumDatabaseUploadSize))
- );
- OKButton.Disabled = true;
- CancelButton.Disabled = true;
- OKButton.Disabled = false;
- CancelButton.Disabled = false;
+ ShowError(Translate.Text(
+ Sitecore.Texts.THE_FILE_0_IS_TOO_BIG_TO_BE_UPLOADED_THE_MAXIMUM_SIZE_FOR_UPLOADING_FILES_IS_1, filename,
+ MainUtil.FormatSize(Settings.Upload.MaximumDatabaseUploadSize)));
}
protected void StartUploading()
diff --git a/src/Spe/Client/Applications/UploadFile/PowerShellUploadFilePage2.cs b/src/Spe/Client/Applications/UploadFile/PowerShellUploadFilePage2.cs
index c89371cc7..8621f09a5 100644
--- a/src/Spe/Client/Applications/UploadFile/PowerShellUploadFilePage2.cs
+++ b/src/Spe/Client/Applications/UploadFile/PowerShellUploadFilePage2.cs
@@ -105,14 +105,23 @@ protected override void OnLoad(EventArgs e)
}
catch (Exception ex)
{
- if (ex.InnerException is OutOfMemoryException)
+ while (ex.InnerException != null)
+ {
+ ex = ex.InnerException;
+ }
+ if (ex is OutOfMemoryException)
HttpContext.Current.Response.Write(
"Done");
else
+ {
+ var message = ex.Message.Replace("\"", "").Replace("'", "");
HttpContext.Current.Response.Write(
- "Done");
+ "Done");
+ }
}
}
}
diff --git a/src/Spe/Texts.cs b/src/Spe/Texts.cs
index 25ab48354..70bf058ed 100644
--- a/src/Spe/Texts.cs
+++ b/src/Spe/Texts.cs
@@ -87,5 +87,7 @@ public const string
public const string SessionIDGallery_User = "User: {0}";
public const string TemplateMissing = "The template with ID {0} is missing in the {1} database.";
+ public const string UploadDialog_An_error_occured_while_uploading_the_file_0 = "An error occured while uploading a file:\n\n{0}";
+
}
}
\ No newline at end of file
diff --git a/src/Spe/sitecore modules/PowerShell/Styles/VariablePrompt.css b/src/Spe/sitecore modules/PowerShell/Styles/VariablePrompt.css
index 5ee61af51..d180e0299 100644
--- a/src/Spe/sitecore modules/PowerShell/Styles/VariablePrompt.css
+++ b/src/Spe/sitecore modules/PowerShell/Styles/VariablePrompt.css
@@ -219,3 +219,7 @@ input[type="number"] {
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
}
+
+.scUploadDialogContentContainer {
+ top: 50px;
+}
\ No newline at end of file
diff --git a/src/Spe/sitecore modules/Shell/PowerShell/UploadFile/PowerShellUploadFile.xml b/src/Spe/sitecore modules/Shell/PowerShell/UploadFile/PowerShellUploadFile.xml
index 3af6056ba..c9ac45430 100644
--- a/src/Spe/sitecore modules/Shell/PowerShell/UploadFile/PowerShellUploadFile.xml
+++ b/src/Spe/sitecore modules/Shell/PowerShell/UploadFile/PowerShellUploadFile.xml
@@ -4,6 +4,8 @@
xmlns:x="http://www.sitecore.net/xaml">
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Col:
+
+
+
+ Ln:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+ This is dialog content.
-
-
-
-
-
+
+
-
+
+
+ Hey! Did you know that...
+
+
-
-
-
-
-
-
-
-
-
-
- Col:
-
-
- Ln:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- This is dialog content.
-
-
-
-
-
-
- Hey! Did you know that...
-
-
-
-
-
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/src/Spe/sitecore modules/Shell/PowerShell/PowerShellResultViewerList.xml b/src/Spe/sitecore modules/Shell/PowerShell/PowerShellResultViewerList.xml
index 8451584a4..7afa03e29 100644
--- a/src/Spe/sitecore modules/Shell/PowerShell/PowerShellResultViewerList.xml
+++ b/src/Spe/sitecore modules/Shell/PowerShell/PowerShellResultViewerList.xml
@@ -68,7 +68,6 @@
-
From fd9ba32d948f4825b17a744ecc0a9f177e39cce4 Mon Sep 17 00:00:00 2001
From: Adam Najmanowicz
Date: Mon, 20 May 2024 17:19:25 +0200
Subject: [PATCH 19/99] #1287 : Rename-Item do not take info account language
version
---
src/Spe/Core/Extensions/ItemExtensions.cs | 23 ++++++++++++++++++-
.../Core/Provider/PsSitecoreItemProvider.cs | 10 ++++----
2 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/src/Spe/Core/Extensions/ItemExtensions.cs b/src/Spe/Core/Extensions/ItemExtensions.cs
index 138a6b853..114d1a0bf 100644
--- a/src/Spe/Core/Extensions/ItemExtensions.cs
+++ b/src/Spe/Core/Extensions/ItemExtensions.cs
@@ -1,4 +1,5 @@
using System;
+using System.Linq;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Data.Managers;
@@ -42,7 +43,7 @@ public static bool IsPowerShellLibrary(this Item item)
public static void Edit(this Item item, Action action)
{
- var args = new ItemEditArgs();
+ var args = new ItemEditArgs() { Item = item };
try
{
var wasEditing = item.Editing.IsEditing;
@@ -102,6 +103,12 @@ public class ItemEditArgs
/// default: false
///
public bool SaveOnError { get; set; }
+
+ ///
+ /// Edited Item
+ /// default: false
+ ///
+ public Item Item { get; set; }
}
public static bool IsVersioned(this Item item)
@@ -115,5 +122,19 @@ public static bool IsVersioned(this Item item)
return false;
}
+
+ public static Item FirstExistingVersion(this Item item)
+ {
+ if (item != null && item.Versions.Count == 0)
+ {
+ var allVersions = item.Versions.GetVersions(true);
+ if (allVersions.Any())
+ {
+ return allVersions.FirstOrDefault();
+ }
+ }
+
+ return item;
+ }
}
}
\ No newline at end of file
diff --git a/src/Spe/Core/Provider/PsSitecoreItemProvider.cs b/src/Spe/Core/Provider/PsSitecoreItemProvider.cs
index d187d521c..4f4cfa501 100644
--- a/src/Spe/Core/Provider/PsSitecoreItemProvider.cs
+++ b/src/Spe/Core/Provider/PsSitecoreItemProvider.cs
@@ -542,7 +542,7 @@ private Item TransferItem(Item sourceItem, Item destinationItem, string leafName
AuditFormatter.FormatItem(destinationItem));
if (transferredItem.Name != leafName)
{
- transferredItem.Edit(args => transferredItem.Name = leafName);
+ transferredItem.FirstExistingVersion().Edit(args => args.Item.Name = leafName);
}
return transferredItem;
@@ -664,8 +664,8 @@ protected override void MoveItem(string path, string destination)
if (sourceItem.Name != leafName)
{
- sourceItem.Edit(
- args => { sourceItem.Name = leafName; });
+ sourceItem.FirstExistingVersion().Edit(
+ args => { args.Item.Name = leafName; });
}
}
catch (Exception ex)
@@ -689,8 +689,8 @@ protected override void RenameItem(string path, string newName)
CheckOperationAllowed("rename", item.Access.CanRename(), item.Uri.ToString());
if (ShouldProcess(item.Paths.Path, "Rename to '" + newName + "'"))
{
- item.Edit(
- args => { item.Name = newName; });
+ item.FirstExistingVersion().Edit(
+ args => { args.Item.Name = newName; });
}
}
}
From ac58a6c1d35fc78e198a69a969939acb90d80bed Mon Sep 17 00:00:00 2001
From: Adam Najmanowicz
Date: Mon, 20 May 2024 19:35:49 +0200
Subject: [PATCH 20/99] #1331 : NullReferenceException occurs when trying to
accept VersionAddedNotification via PowerShell in Sitecore
---
.../Data/Clones/ReceiveItemCloneNotificationCommand.cs | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/Spe/Commands/Data/Clones/ReceiveItemCloneNotificationCommand.cs b/src/Spe/Commands/Data/Clones/ReceiveItemCloneNotificationCommand.cs
index 47ba4279c..b8e14bf5f 100644
--- a/src/Spe/Commands/Data/Clones/ReceiveItemCloneNotificationCommand.cs
+++ b/src/Spe/Commands/Data/Clones/ReceiveItemCloneNotificationCommand.cs
@@ -37,6 +37,10 @@ protected override void ProcessNotification(Notification notification)
switch (Action)
{
case (NotificationAction.Accept):
+ if(notification is VersionAddedNotification versionAddedNotification)
+ {
+ versionAddedNotification.ForceAccept = true;
+ }
notification.Accept(clone);
break;
case (NotificationAction.Reject):
From 6402209b78e8740c8731b6e8d1cd4c5379708ca4 Mon Sep 17 00:00:00 2001
From: Adam Najmanowicz
Date: Mon, 20 May 2024 20:22:02 +0200
Subject: [PATCH 21/99] #1016 : Get-ItemField command should not define the
-Language parameter
---
src/Spe/Commands/Data/GetItemFieldCommand.cs | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/src/Spe/Commands/Data/GetItemFieldCommand.cs b/src/Spe/Commands/Data/GetItemFieldCommand.cs
index a1fec7514..08afca1b8 100644
--- a/src/Spe/Commands/Data/GetItemFieldCommand.cs
+++ b/src/Spe/Commands/Data/GetItemFieldCommand.cs
@@ -12,7 +12,7 @@ namespace Spe.Commands.Data
[Cmdlet(VerbsCommon.Get, "ItemField")]
[OutputType(typeof (TemplateField), typeof (string), typeof (Field),
ParameterSetName = new[] {"Item from Pipeline", "Item from Path", "Item from ID"})]
- public class GetItemFieldCommand : BaseItemCommand
+ public class GetItemFieldCommand : BaseLanguageAgnosticItemCommand
{
public enum ReturnValue
{
@@ -35,7 +35,6 @@ public enum ReturnValue
protected override void BeginProcessing()
{
- Language = null;
base.BeginProcessing();
if (Name != null && Name.Any())
From 71e785707daabd53f2f3ef2949808f7807861e16 Mon Sep 17 00:00:00 2001
From: Adam Najmanowicz
Date: Thu, 30 May 2024 23:35:13 +0200
Subject: [PATCH 22/99] #1340 - Add ability to send deferred sheer messages and
execute javascript to make it possible to e.g. refresh the content editor
tree post script execution
---
src/Spe/Client/Applications/PowerShellIse.cs | 61 ++++++------
.../PowerShellResultViewerList.cs | 8 ++
.../Client/Applications/PowerShellRunner.cs | 11 +--
src/Spe/Client/Applications/RunnerOutput.cs | 3 +-
src/Spe/Client/Applications/ScriptRunner.cs | 4 +-
.../MenuItems/ExecutePowerShellScript.cs | 20 ++--
.../Interactive/InvokeJavaScriptCommand.cs | 11 ++-
.../Interactive/SendSheerMessageCommand.cs | 29 ++++--
src/Spe/Core/Extensions/MessageExtensions.cs | 26 +++++
src/Spe/Core/Host/CommandCompletion.cs | 7 +-
src/Spe/Core/Host/ScriptExecutionResult.cs | 94 +++++++++++++++++++
src/Spe/Core/Host/ScriptSession.cs | 44 +++++----
src/Spe/Core/Host/ScriptingHost.cs | 6 +-
src/Spe/Core/Host/ScriptingHostPrivateData.cs | 7 +-
src/Spe/Spe.csproj | 5 +
.../PowerShell/Styles/ise.css | 32 +++++++
16 files changed, 280 insertions(+), 88 deletions(-)
create mode 100644 src/Spe/Core/Extensions/MessageExtensions.cs
create mode 100644 src/Spe/Core/Host/ScriptExecutionResult.cs
diff --git a/src/Spe/Client/Applications/PowerShellIse.cs b/src/Spe/Client/Applications/PowerShellIse.cs
index e2e2df869..348afe1e6 100644
--- a/src/Spe/Client/Applications/PowerShellIse.cs
+++ b/src/Spe/Client/Applications/PowerShellIse.cs
@@ -66,25 +66,25 @@ public class PowerShellIse : BaseForm, IHasCommandContext, IPowerShellRunner
protected bool ScriptRunning
{
- get { return StringUtil.GetString(Context.ClientPage.ServerProperties["ScriptRunning"]) == "1"; }
- set { Context.ClientPage.ServerProperties["ScriptRunning"] = value ? "1" : string.Empty; }
+ get => StringUtil.GetString(Context.ClientPage.ServerProperties["ScriptRunning"]) == "1";
+ set => Context.ClientPage.ServerProperties["ScriptRunning"] = value ? "1" : string.Empty;
}
protected bool WasElevated
{
- get { return StringUtil.GetString(Context.ClientPage.ServerProperties["WasElevated"]) == "1"; }
- set { Context.ClientPage.ServerProperties["WasElevated"] = value ? "1" : string.Empty; }
+ get => StringUtil.GetString(Context.ClientPage.ServerProperties["WasElevated"]) == "1";
+ set => Context.ClientPage.ServerProperties["WasElevated"] = value ? "1" : string.Empty;
}
public string ParentFrameName
{
- get { return StringUtil.GetString(ServerProperties["ParentFrameName"]); }
- set { ServerProperties["ParentFrameName"] = value; }
+ get => StringUtil.GetString(ServerProperties["ParentFrameName"]);
+ set => ServerProperties["ParentFrameName"] = value;
}
public string ScriptItemId
{
- get { return ScriptItemIdMemo.Value; }
+ get => ScriptItemIdMemo.Value;
set
{
if (value.IsWhiteSpaceOrNull())
@@ -98,7 +98,7 @@ public string ScriptItemId
public string ScriptItemDb
{
- get { return ScriptItemDbMemo.Value; }
+ get => ScriptItemDbMemo.Value;
set
{
if (value.IsWhiteSpaceOrNull())
@@ -112,35 +112,32 @@ public string ScriptItemDb
public static string ContextItemId
{
- get { return StringUtil.GetString(Context.ClientPage.ServerProperties["ContextItemID"]); }
- set { Context.ClientPage.ServerProperties["ContextItemID"] = value; }
+ get => StringUtil.GetString(Context.ClientPage.ServerProperties["ContextItemID"]);
+ set => Context.ClientPage.ServerProperties["ContextItemID"] = value;
}
public static string ContextItemDb
{
- get { return StringUtil.GetString(Context.ClientPage.ServerProperties["ContextItemDb"]); }
- set { Context.ClientPage.ServerProperties["ContextItemDb"] = value; }
+ get => StringUtil.GetString(Context.ClientPage.ServerProperties["ContextItemDb"]);
+ set => Context.ClientPage.ServerProperties["ContextItemDb"] = value;
}
public static bool ScriptModified
{
- get { return StringUtil.GetString(Context.ClientPage.ServerProperties["ScriptModified"]) == "1"; }
- set { Context.ClientPage.ServerProperties["ScriptModified"] = value ? "1" : string.Empty; }
+ get => StringUtil.GetString(Context.ClientPage.ServerProperties["ScriptModified"]) == "1";
+ set => Context.ClientPage.ServerProperties["ScriptModified"] = value ? "1" : string.Empty;
}
public static int TabSequencer
{
- get { return (int)(Context.ClientPage.ServerProperties["TabSequencer"] ?? 0); }
- set { Context.ClientPage.ServerProperties["TabSequencer"] = value; }
+ get => (int)(Context.ClientPage.ServerProperties["TabSequencer"] ?? 0);
+ set => Context.ClientPage.ServerProperties["TabSequencer"] = value;
}
public static bool UseContext
{
- get
- {
- return string.IsNullOrEmpty(StringUtil.GetString(Context.ClientPage.ServerProperties["UseContext"]));
- }
- set { Context.ClientPage.ServerProperties["UseContext"] = value ? string.Empty : "0"; }
+ get => string.IsNullOrEmpty(StringUtil.GetString(Context.ClientPage.ServerProperties["UseContext"]));
+ set => Context.ClientPage.ServerProperties["UseContext"] = value ? string.Empty : "0";
}
public Item ScriptItem
@@ -167,20 +164,20 @@ public static Item ContextItem
public static string CurrentSessionId
{
- get { return StringUtil.GetString(Context.ClientPage.ServerProperties["CurrentSessionId"]); }
- set { Context.ClientPage.ServerProperties["CurrentSessionId"] = value; }
+ get => StringUtil.GetString(Context.ClientPage.ServerProperties["CurrentSessionId"]);
+ set => Context.ClientPage.ServerProperties["CurrentSessionId"] = value;
}
public static string CurrentUser
{
- get { return StringUtil.GetString(Context.ClientPage.ServerProperties["CurrentUser"]); }
- set { Context.ClientPage.ServerProperties["CurrentUser"] = value; }
+ get => StringUtil.GetString(Context.ClientPage.ServerProperties["CurrentUser"]);
+ set => Context.ClientPage.ServerProperties["CurrentUser"] = value;
}
public static string CurrentLanguage
{
- get { return StringUtil.GetString(Context.ClientPage.ServerProperties["CurrentLanguage"]); }
- set { Context.ClientPage.ServerProperties["CurrentLanguage"] = value; }
+ get => StringUtil.GetString(Context.ClientPage.ServerProperties["CurrentLanguage"]);
+ set => Context.ClientPage.ServerProperties["CurrentLanguage"] = value;
}
public SpeJobMonitor Monitor { get; private set; }
@@ -195,8 +192,8 @@ public CommandContext GetCommandContext()
public bool MonitorActive
{
- get { return Monitor.Active; }
- set { Monitor.Active = value; }
+ get => Monitor.Active;
+ set => Monitor.Active = value;
}
private static bool IsHackedParameter(string parameter)
@@ -302,7 +299,7 @@ public override void HandleMessage(Message message)
Dispatcher.Dispatch(message, context);
}
-
+
[HandleMessage("ise:open", true)]
protected void Open(ClientPipelineArgs args)
{
@@ -683,6 +680,7 @@ protected virtual void JobExecute(ClientPipelineArgs args)
{
args.Parameters.Add("message", "ise:execute");
JobExecuteScript(args, Editor.Value, false);
+ ClearOutput();
}
[HandleMessage("ise:debug", true)]
@@ -928,6 +926,9 @@ private void MonitorOnJobFinished(object sender, EventArgs eventArgs)
PrintSessionUpdate($"{error}");
}
+ var executionResult = new ScriptExecutionResult(result);
+ executionResult.GetIseResult(result.CloseRunner).ForEach(PrintSessionUpdate);
+
SheerResponse.SetInnerHtml("PleaseWait", "");
ProgressOverlay.Visible = false;
ScriptRunning = false;
diff --git a/src/Spe/Client/Applications/PowerShellResultViewerList.cs b/src/Spe/Client/Applications/PowerShellResultViewerList.cs
index 031a5f758..c5e790dc1 100644
--- a/src/Spe/Client/Applications/PowerShellResultViewerList.cs
+++ b/src/Spe/Client/Applications/PowerShellResultViewerList.cs
@@ -244,6 +244,13 @@ private void MonitorOnJobFinished(object sender, EventArgs eventArgs)
{
var args = eventArgs as SessionCompleteEventArgs;
var result = args?.RunnerOutput;
+
+ if(result != null)
+ {
+ var resultActions = new ScriptExecutionResult(result);
+ resultActions.ExecuteResults();
+ }
+
if (result?.CloseRunner ?? false)
{
Sitecore.Shell.Framework.Windows.Close();
@@ -505,6 +512,7 @@ private void ExecuteScriptJob(Item scriptItem, ScriptSession scriptSession, Mess
scriptSession.SetExecutedScript(scriptItem);
scriptSession.Interactive = true;
ScriptSessionId = scriptSession.ID;
+ scriptSession.PrivateData.DeferredMessages.Clear();
var jobUser = DelegatedAccessManager.GetDelegatedUser(Context.User, scriptItem);
PowerShellLog.Info($"[Report] Running script {scriptItem.ID} for Context User {Context.User.Name} as {jobUser.Name}.");
diff --git a/src/Spe/Client/Applications/PowerShellRunner.cs b/src/Spe/Client/Applications/PowerShellRunner.cs
index ce8ff95f8..79432ba5e 100644
--- a/src/Spe/Client/Applications/PowerShellRunner.cs
+++ b/src/Spe/Client/Applications/PowerShellRunner.cs
@@ -3,6 +3,7 @@
using System.Management.Automation;
using System.Text;
using System.Web;
+using Newtonsoft.Json;
using Sitecore;
using Sitecore.Configuration;
using Sitecore.Data;
@@ -320,10 +321,6 @@ private void MonitorOnJobFinished(object sender, EventArgs e)
printResults += $"{error}";
}
Result.Value = printResults;
- if(!(result?.DialogResult).IsEmptyOrWhitespace())
- {
- SheerResponse.SetDialogValue(result?.DialogResult);
- }
PsProgress.Text = string.Empty;
SitecoreVersion.V80
@@ -337,10 +334,10 @@ private void MonitorOnJobFinished(object sender, EventArgs e)
OkButton.Visible = true;
AbortButton.Visible = false;
Monitor.SessionID = string.Empty;
- if (result.CloseMessages.Any())
+ if (result.DeferredMessages.Any() || result.DialogResult != null)
{
- SheerResponse.SetDialogValue(
- result.CloseMessages.Aggregate((serialized, message) => serialized + "\n" + message));
+ ScriptExecutionResult dialogResult = new ScriptExecutionResult(result);
+ SheerResponse.SetDialogValue(dialogResult.ToString());
}
if (result.CloseRunner)
{
diff --git a/src/Spe/Client/Applications/RunnerOutput.cs b/src/Spe/Client/Applications/RunnerOutput.cs
index 53bf78369..a85fe9052 100644
--- a/src/Spe/Client/Applications/RunnerOutput.cs
+++ b/src/Spe/Client/Applications/RunnerOutput.cs
@@ -10,7 +10,6 @@ public class RunnerOutput
public Exception Exception { get; set; }
public bool HasErrors { get; set; }
public bool CloseRunner { get; set; }
- public List CloseMessages { get; set; }
-
+ public List DeferredMessages { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Spe/Client/Applications/ScriptRunner.cs b/src/Spe/Client/Applications/ScriptRunner.cs
index 6c871916f..30785510a 100644
--- a/src/Spe/Client/Applications/ScriptRunner.cs
+++ b/src/Spe/Client/Applications/ScriptRunner.cs
@@ -48,7 +48,7 @@ public void Run()
DialogResult = Session.Output.GetDialogRessult(),
HasErrors = Session.Output.HasErrors,
CloseRunner = Session.CloseRunner,
- CloseMessages = Session.CloseMessages
+ DeferredMessages = Session.DeferredMessages
};
job.StatusResult = output;
@@ -76,7 +76,7 @@ public void Run()
DialogResult = Session.Output.GetDialogRessult(),
HasErrors = true,
CloseRunner = Session.CloseRunner,
- CloseMessages = Session.CloseMessages
+ DeferredMessages = Session.DeferredMessages
};
job.StatusResult = output;
diff --git a/src/Spe/Client/Commands/MenuItems/ExecutePowerShellScript.cs b/src/Spe/Client/Commands/MenuItems/ExecutePowerShellScript.cs
index df98c0234..ce4fba9b5 100644
--- a/src/Spe/Client/Commands/MenuItems/ExecutePowerShellScript.cs
+++ b/src/Spe/Client/Commands/MenuItems/ExecutePowerShellScript.cs
@@ -3,11 +3,16 @@
using Sitecore;
using Sitecore.Data;
using Sitecore.Diagnostics;
+using Sitecore.Globalization;
+using Sitecore.Shell.Applications.ContentManager;
using Sitecore.Shell.Framework.Commands;
using Sitecore.StringExtensions;
using Sitecore.Text;
+using Sitecore.Web.UI.HtmlControls;
using Sitecore.Web.UI.Sheer;
using Spe.Core.Extensions;
+using Spe.Core.Host;
+using Version = Sitecore.Data.Version;
namespace Spe.Client.Commands.MenuItems
{
@@ -59,19 +64,20 @@ public override void Execute(CommandContext context)
Context.ClientPage.Start(this, "Process");
}
+ protected void Test()
+ {
+
+ }
protected void Process(ClientPipelineArgs args)
{
Assert.ArgumentNotNull(args, "args");
if (args.IsPostBack)
{
- Context.ClientPage.SendMessage(this, $"item:refresh(id={itemId})");
- Context.ClientPage.SendMessage(this, $"item:refreshchildren(id={itemId})");
+ var item1 = ContentEditorForm.GetContextItem();
+ var item = Database.GetDatabase(itemDb).GetItem(itemId, Language.Parse(itemLang), Version.Parse(itemVer));
if (!args.HasResult || args.Result.IsNullOrEmpty()) return;
-
- foreach (var closeMessage in args.Result.Split('\n'))
- {
- Context.ClientPage.ClientResponse.Timer(closeMessage, 2);
- }
+ ScriptExecutionResult result = ScriptExecutionResult.Parse(args.Result);
+ result.ExecuteResults();
}
else
{
diff --git a/src/Spe/Commands/Interactive/InvokeJavaScriptCommand.cs b/src/Spe/Commands/Interactive/InvokeJavaScriptCommand.cs
index 81aca595f..a92a216b1 100644
--- a/src/Spe/Commands/Interactive/InvokeJavaScriptCommand.cs
+++ b/src/Spe/Commands/Interactive/InvokeJavaScriptCommand.cs
@@ -9,10 +9,19 @@ public class InvokeJavaScriptCommand : BaseShellCommand
[Parameter(ValueFromPipeline = true, Position = 0, Mandatory = true)]
public string Script { get; set; }
+ [Parameter]
+ public SwitchParameter OnScriptEnd { get; set; }
+
protected override void ProcessRecord()
{
- if (!CheckSessionCanDoInteractiveAction()) return;
+ if (OnScriptEnd)
+ {
+ HostData.DeferredMessages.Add($"script:{Script}");
+ return;
+ }
+ if (!CheckSessionCanDoInteractiveAction())
+ return;
LogErrors(() => PutMessage(new InvokeJavaScriptMessage(Script)));
}
}
diff --git a/src/Spe/Commands/Interactive/SendSheerMessageCommand.cs b/src/Spe/Commands/Interactive/SendSheerMessageCommand.cs
index c01c7538f..2aecbbaae 100644
--- a/src/Spe/Commands/Interactive/SendSheerMessageCommand.cs
+++ b/src/Spe/Commands/Interactive/SendSheerMessageCommand.cs
@@ -3,6 +3,9 @@
using Sitecore.Jobs.AsyncUI;
using Sitecore.Web.UI.Sheer;
using Spe.Abstractions.VersionDecoupling.Interfaces;
+using Spe.Commands.Interactive.Messages;
+using Spe.Core.Extensions;
+using Spe.Core.Host;
using Spe.Core.VersionDecoupling;
namespace Spe.Commands.Interactive
@@ -13,15 +16,18 @@ public class SendSheerMessageCommand : BaseShellCommand
[Parameter(ValueFromPipeline = true, Position = 0, Mandatory = true)]
public string Name { get; set; }
- [Parameter]
+ [Parameter(ParameterSetName = "InRunner")]
public SwitchParameter GetResult { get; set; }
[Parameter]
public Hashtable Parameters { get; set; }
+ [Parameter(ParameterSetName = "OnScriptEnd")]
+ public SwitchParameter OnScriptEnd { get; set; }
+
protected override void ProcessRecord()
{
- if (!CheckSessionCanDoInteractiveAction()) return;
+ if (!OnScriptEnd && !CheckSessionCanDoInteractiveAction()) return;
var message = Message.Parse(null, Name);
message.Arguments.Add("ScriptSession.Id", HostData.SessionId);
@@ -29,16 +35,23 @@ protected override void ProcessRecord()
{
foreach (var key in Parameters.Keys)
{
- message.Arguments.Add(key.ToString(), Parameters[key].ToString());
+ message.Arguments.Add(key.ToString(), Parameters[key]?.ToString());
}
}
var msgHandler = new SendMessageMessage(message, GetResult.IsPresent);
- LogErrors(() => PutMessage(msgHandler));
- var jobManager = TypeResolver.ResolveFromCache();
- var job = jobManager.GetContextJob();
- if (job != null && GetResult.IsPresent)
+ if (OnScriptEnd)
+ {
+ HostData.DeferredMessages.Add($"message:{message.Serialize()}");
+ }
+ else
{
- WriteObject(job.MessageQueue.GetResult());
+ LogErrors(() => PutMessage(msgHandler));
+ var jobManager = TypeResolver.ResolveFromCache();
+ var job = jobManager.GetContextJob();
+ if (job != null && GetResult.IsPresent)
+ {
+ WriteObject(job.MessageQueue.GetResult());
+ }
}
}
}
diff --git a/src/Spe/Core/Extensions/MessageExtensions.cs b/src/Spe/Core/Extensions/MessageExtensions.cs
new file mode 100644
index 000000000..395d3578f
--- /dev/null
+++ b/src/Spe/Core/Extensions/MessageExtensions.cs
@@ -0,0 +1,26 @@
+using System.Linq;
+using Sitecore.Web.UI.Sheer;
+
+namespace Spe.Core.Extensions
+{
+ public static class MessageExtensions
+ {
+ public static string Serialize(this Message message)
+ {
+ if (message == null)
+ {
+ return string.Empty;
+ }
+
+ if (message.Arguments != null && message.Arguments.Count > 0)
+ {
+ var paramsArray = message.Arguments.AllKeys.Select(key => $"{key}={message.Arguments[key]}").ToArray();
+ var result =
+ $"{message.Name}({string.Join(",", paramsArray)})";
+ return result;
+ }
+
+ return message.Name;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Spe/Core/Host/CommandCompletion.cs b/src/Spe/Core/Host/CommandCompletion.cs
index 2b2c4991c..3d7bdc5d9 100644
--- a/src/Spe/Core/Host/CommandCompletion.cs
+++ b/src/Spe/Core/Host/CommandCompletion.cs
@@ -394,8 +394,11 @@ private static string TruncatedCommand(ScriptSession session, string command, ou
if (session.TryInvokeInRunningSession(teCmd, out psResult))
{
var teResult = psResult.Cast().FirstOrDefault();
- lastToken = command.Substring(teResult);
- return command.Substring(0, teResult);
+ if (teResult >= 0)
+ {
+ lastToken = command.Substring(teResult);
+ return command.Substring(0, teResult);
+ }
}
}
lastToken = string.Empty;
diff --git a/src/Spe/Core/Host/ScriptExecutionResult.cs b/src/Spe/Core/Host/ScriptExecutionResult.cs
new file mode 100644
index 000000000..18d1c96af
--- /dev/null
+++ b/src/Spe/Core/Host/ScriptExecutionResult.cs
@@ -0,0 +1,94 @@
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using Sitecore;
+using Sitecore.Web.UI.Sheer;
+using Spe.Client.Applications;
+
+namespace Spe.Core.Host
+{
+ [Serializable]
+ public class ScriptExecutionResult
+ {
+ public ScriptExecutionResult()
+ {
+ }
+
+ public ScriptExecutionResult(RunnerOutput result)
+ {
+ ScriptResult = result.DialogResult;
+ DeferredMessages = result.DeferredMessages.ToArray();
+ }
+
+ public string[] DeferredMessages { get; set; }
+
+ public string ScriptResult { get; set; }
+
+ public override string ToString()
+ {
+ return JsonConvert.SerializeObject(this);
+ }
+
+ public static ScriptExecutionResult Parse(string json)
+ {
+ return JsonConvert.DeserializeObject(json);
+ }
+
+ public void ExecuteResults()
+ {
+ foreach (var deferredMessage in DeferredMessages)
+ {
+ switch(deferredMessage)
+ {
+ case string message when message.StartsWith("message:"):
+ Context.ClientPage.ClientResponse.Timer(UnpackMessage(message), 2);
+ break;
+ case string message when message.StartsWith("script:"):
+ SheerResponse.Eval(UnpackMessage(message));
+ break;
+ case string message when message.StartsWith("alert:"):
+ SheerResponse.Alert(UnpackMessage(message),false);
+ break;
+ default:
+ Context.ClientPage.ClientResponse.Timer(deferredMessage, 2);
+ break;
+ }
+ }
+ }
+
+ private string UnpackMessage(string message)
+ {
+ return message.Substring(message.IndexOf(":", StringComparison.Ordinal) + 1);
+ }
+
+ public IEnumerable GetIseResult(bool closeWindow)
+ {
+ foreach (var deferredMessage in DeferredMessages)
+ {
+ switch(deferredMessage)
+ {
+ case string message when message.StartsWith("message:"):
+ yield return
+ "Send shell message" +
+ UnpackMessage(message) + "
";
+ break;
+ case string message when message.StartsWith("script:"):
+ yield return
+ "Execute JavaScript" +
+ UnpackMessage(message) + "
";
+ break;
+ case string message when message.StartsWith("alert:"):
+ SheerResponse.Alert(UnpackMessage(message),false);
+ break;
+ default:
+ Context.ClientPage.ClientResponse.Timer(deferredMessage, 2);
+ break;
+ }
+ }
+ if (closeWindow)
+ {
+ yield return "Close Runner Window Request
";
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Spe/Core/Host/ScriptSession.cs b/src/Spe/Core/Host/ScriptSession.cs
index a980cd8b0..bbe7b77f6 100644
--- a/src/Spe/Core/Host/ScriptSession.cs
+++ b/src/Spe/Core/Host/ScriptSession.cs
@@ -142,7 +142,7 @@ private void OnRunspaceStateEvent(object sender, RunspaceStateEventArgs e)
internal bool IsRunning => powerShell != null && powerShell.InvocationStateInfo.State == PSInvocationState.Running;
- internal System.Management.Automation.PowerShell NewPowerShell()
+ private System.Management.Automation.PowerShell NewPowerShell()
{
if (IsRunning)
return powerShell.CreateNestedPowerShell();
@@ -177,57 +177,53 @@ public InitialSessionState SpeInitialSessionState
}
}
- public static Version PsVersion { get; private set; }
+ public static Version PsVersion { get; }
public bool AutoDispose
{
- get { return host.AutoDispose; }
- internal set { host.AutoDispose = value; }
+ get => host.AutoDispose;
+ internal set => host.AutoDispose = value;
}
public bool CloseRunner
{
- get { return host.CloseRunner; }
- internal set { host.CloseRunner = value; }
+ get => host.CloseRunner;
+ internal set => host.CloseRunner = value;
}
- public List CloseMessages
- {
- get { return host.CloseMessages; }
- internal set { host.CloseMessages = value; }
- }
+ public List DeferredMessages => host.DeferredMessages;
public string ID
{
- get { return host.SessionId; }
- internal set { host.SessionId = value; }
+ get => host.SessionId;
+ internal set => host.SessionId = value;
}
public bool Interactive
{
- get { return host.Interactive; }
- internal set { host.Interactive = value; }
+ get => host.Interactive;
+ set => host.Interactive = value;
}
public string UserName
{
- get { return host.User; }
- internal set { host.User = value; }
+ get => host.User;
+ private set => host.User = value;
}
public string JobName
{
- get { return host.JobName; }
- internal set { host.JobName = value; }
+ get => host.JobName;
+ internal set => host.JobName = value;
}
public List LastErrors { get; set; }
public string Key
{
- get { return host.SessionKey; }
- internal set { host.SessionKey = value; }
+ get => host.SessionKey;
+ internal set => host.SessionKey = value;
}
public ApplicationSettings Settings { get; }
@@ -375,7 +371,7 @@ private void DebuggerOnDebuggerStop(object sender, DebuggerStopEventArgs args)
position = args.InvocationInfo.GetType()
.GetProperty("ScriptPosition",
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty)
- .GetValue(args.InvocationInfo) as IScriptExtent;
+ ?.GetValue(args.InvocationInfo) as IScriptExtent;
}
catch (Exception)
{
@@ -499,7 +495,7 @@ public enum OutTarget
OutNone
}
- public Collection InvokeInNewPowerShell(Command command, OutTarget target)
+ private Collection InvokeInNewPowerShell(Command command, OutTarget target)
{
return InvokeInNewPowerShell(ps => ps.Commands.AddCommand(command), target);
}
@@ -588,6 +584,7 @@ public ScriptBlock GetScriptBlock(string scriptBlock)
public List