Skip to content

Commit

Permalink
#29 | Sitecore Applications commands provider
Browse files Browse the repository at this point in the history
  • Loading branch information
alan-null committed Jun 13, 2016
1 parent 84259ac commit 8cf2179
Show file tree
Hide file tree
Showing 11 changed files with 274 additions and 6 deletions.
1 change: 1 addition & 0 deletions app/sc_ext/Application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ if (SitecoreExtensions.Context.IsValid()) {

launcher.registerProviderCommands(new Modules.SectionSwitches.SectionSwitchesCommandsProvider());
launcher.registerProviderCommands(new Modules.LastLocation.RestoreLastLocationCommandProvider());
launcher.registerProviderCommands(new Modules.ShortcutsRunner.Providers.SitecoreApplicationsCommandsProvider());

window.postMessage({
sc_ext_enabled: true,
Expand Down
5 changes: 3 additions & 2 deletions app/sc_ext/Context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,15 @@ namespace SitecoreExtensions {

static Location(): Location {
if (typeof scContentEditor != 'undefined') {
if (document.querySelector('#__FRAMENAME') != undefined) {
if (document.querySelector('#__CurrentItem') != undefined) {
return Location.ContentEditor;
}
}
if (document.querySelector('.sc-launchpad') !== null) {
return Location.Launchpad;
}
if (document.querySelector('input#__FRAMENAME') !== null) {
let frameName = document.querySelector('input#__FRAMENAME') as HTMLInputElement
if (frameName !== null && frameName.value == "Shell") {
return Location.Desktop;
}
if (document.querySelector('#scWebEditRibbon') !== null || document.querySelector('[data-sc-id=PageEditBar]') != null) {
Expand Down
12 changes: 10 additions & 2 deletions app/sc_ext/_all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
/// <reference path='types/Dictionary.ts'/>
/// <reference path='types/IDictionary.ts'/>

// Http
/// <reference path='http/Method.ts'/>
/// <reference path='http/HttpRequest.ts'/>

// Libraries
/// <reference path='libraries/Fuzzy.ts'/>

Expand Down Expand Up @@ -45,5 +49,9 @@
/// <reference path='modules/LastLocation/RestoreLastLocation.ts'/>
/// <reference path='modules/LastLocation/LastLocationStore.ts'/>
/// <reference path='modules/LastLocation/RestoreLastLocationCommandProvider.ts'/>


// ShortcutsRunner
/// <reference path='modules/ShortcutsRunner/Token.ts'/>
/// <reference path='modules/ShortcutsRunner/TokenService.ts'/>
/// <reference path='modules/ShortcutsRunner/ShortcutRunner.ts'/>
/// <reference path='modules/ShortcutsRunner/Providers/AppShortcutCommand.ts'/>
/// <reference path='modules/ShortcutsRunner/Providers/SitecoreApplicationsCommandsProvider.ts'/>
41 changes: 41 additions & 0 deletions app/sc_ext/http/HttpRequest.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/// <reference path='../_all.ts'/>

namespace SitecoreExtensions.Http {
export class HttpRequest {
private url: string;
private method: Method;
private callback: any;

constructor(url: string, method: Method, callback) {
this.url = url;
this.method = method;
this.callback = callback;
}

public execute(postData?: any) {
var method = this.getMethodValue(this.method);
var async = true;
var request = new XMLHttpRequest();
request.onload = this.callback
request.open(method, this.url, async);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
if (postData) {
request.send(postData);
}
else {
request.send();
}
}

private getMethodValue(method: Method): string {
switch (method) {
case Method.POST:
return "POST";
case Method.GET:
return "GET";
}
return "GET";
}
}
}

6 changes: 6 additions & 0 deletions app/sc_ext/http/Method.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace SitecoreExtensions.Http {
export enum Method {
POST,
GET
}
}
10 changes: 8 additions & 2 deletions app/sc_ext/modules/launcher/LauncherModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,14 @@ namespace SitecoreExtensions.Modules.Launcher {
}

registerCommand(command: ICommand): void {
command.id = this.commands.length + 1;
this.commands.push(command);
if (this.isUnique(command)) {
command.id = this.commands.length + 1;
this.commands.push(command);
}
}

private isUnique(command: ICommand): boolean {
return this.commands.filter(c => c.name == command.name && c.canExecute() == command.canExecute()).length == 0
}

showLauncher(): void {
Expand Down
55 changes: 55 additions & 0 deletions app/sc_ext/modules/shortcutsRunner/ShortcutRunner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/// <reference path='../../_all.ts'/>

namespace SitecoreExtensions.Modules.ShortcutsRunner {
import HttpRequest = Http.HttpRequest;
import Method = Http.Method;

export class ShortcutRunner {
private tokenService: TokenService;
private token: Token;
private cacheKey: string = 'sc_ext::request_token';
private baseUrl: string = window.top.location.origin + "/sitecore/shell/default.aspx";

constructor() {
this.tokenService = new TokenService();
this.token = this.tokenService.getToken();
}

public runShortcutCommand(shortcutId: string): void {
this.getShortcutUrl((e) => {
if (e.currentTarget.status == 500) {
this.handleErrorAndRetry(shortcutId);
} else {
var data = JSON.parse(e.currentTarget.responseText);
this.invokeCommand(data);
}
}, shortcutId)
}

private invokeCommand(data): void {
var lastCommandIndex = data.commands.length - 1;
var iFrame = data.commands[lastCommandIndex].value;
var urls = iFrame.match(/\/sitecore\/shell(.)*png/)
if (urls) {
var url = urls[0]
window.top.document.location.href = window.top.location.origin + url;
}
}

private handleErrorAndRetry(shortcutId: string): void {
this.tokenService.invalidateToken((token) => {
this.token = token;
this.runShortcutCommand(shortcutId);
});
}

private getShortcutUrl(callback: Function, shortcutId: string): void {
var req = new HttpRequest(this.baseUrl, Method.POST, callback);
var postData = "&__PARAMETERS=" + "RunShortcut%28%26quot%3B%7B" + shortcutId + "%7D%26quot%3B%29"
+ "&__ISEVENT=" + "1"
+ "&__CSRFTOKEN=" + this.token.__CSRFTOKEN
+ "&__VIEWSTATE=" + this.token.__VIEWSTATE
req.execute(postData);
}
}
}
10 changes: 10 additions & 0 deletions app/sc_ext/modules/shortcutsRunner/Token.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace SitecoreExtensions.Modules.ShortcutsRunner {
export class Token {
__CSRFTOKEN: string;
__VIEWSTATE: string;
constructor(csrftoken, viewstate) {
this.__CSRFTOKEN = csrftoken;
this.__VIEWSTATE = viewstate;
}
}
}
57 changes: 57 additions & 0 deletions app/sc_ext/modules/shortcutsRunner/TokenService.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/// <reference path='../../_all.ts'/>

namespace SitecoreExtensions.Modules.ShortcutsRunner {
import HttpRequest = Http.HttpRequest;
import Method = Http.Method;

export class TokenService {
private token: Token;
private cacheKey: string = 'sc_ext::request_token';
private baseUrl: string = window.top.location.origin + "/sitecore/shell/default.aspx";

constructor() {
this.token = this.getTokenFromCache(this.cacheKey);
if (this.token == undefined) {
this.getRequestToken((t) => {
this.token = t;
this.storeTokenInCache(this.cacheKey, t);
});
}
}

public getToken(): Token {
return this.token;
}

public invalidateToken(callback) {
localStorage.clear();
this.getRequestToken((t) => {
this.token = t;
callback(t);
this.storeTokenInCache(this.cacheKey, t);
});
}

private getRequestToken(callback: Function): void {
new HttpRequest(this.baseUrl, Method.GET, (e) => {
var data = e.currentTarget.responseText;
var parser = new DOMParser()
var doc = parser.parseFromString(data, "text/xml");
var __CSRFTOKEN = (doc.querySelector('#__CSRFTOKEN') as HTMLInputElement).attributes['value'].value;
var __VIEWSTATE = (doc.querySelector('#__VIEWSTATE') as HTMLInputElement).attributes['value'].value;
callback(new Token(__CSRFTOKEN, __VIEWSTATE))
}).execute();
}

private getTokenFromCache(key: string): Token {
var cached = localStorage[key];
if (cached != undefined) {
return JSON.parse(cached);
}
}

private storeTokenInCache(key: string, value: any): void {
localStorage[key] = JSON.stringify(value);
}
}
}
29 changes: 29 additions & 0 deletions app/sc_ext/modules/shortcutsRunner/providers/AppShortcutCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/// <reference path="../../../_all.ts"/>

namespace SitecoreExtensions.Modules.ShortcutsRunner.Providers {
import ICommand = Launcher.ICommand

export class AppShortcutCommand implements ICommand {
id: number;
name: string;
description: string;
runner: ShortcutRunner;
shortcutID: string;

constructor(name, description, runner, shortcutID) {
this.id = 0;
this.runner = runner;
this.name = name;
this.description = description;
this.shortcutID = shortcutID;
}

public canExecute(): boolean {
return true;
}

public execute(): void {
this.runner.runShortcutCommand(this.shortcutID);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/// <reference path="../../../_all.ts"/>

namespace SitecoreExtensions.Modules.ShortcutsRunner.Providers {
import ICommand = Launcher.ICommand

export class SitecoreApplicationsCommandsProvider implements Launcher.Providers.ICommandsProvider {
private commands: ICommand[];
private runner: ShortcutRunner;

constructor() {
this.commands = Array<ICommand>();
this.runner = new ShortcutRunner();
this.createCommands();
}
public getCommands(): ICommand[] {
return this.commands;
}

private createCommands() {
this.addCommand("About", "License Details", "{70EEF2F0-4A17-427B-99A1-5069658EAE7A}");
this.addCommand("Access Viewer", "Get an overview of the access rights assigned to each account for each item in the content tree", "{D2D8EF5D-ABA7-485B-ACA6-CEDCD495AB5D}");
this.addCommand("Archive", "See archived items", "{ABF5E348-B8C1-4796-8100-8F012AE4713E}");
this.addCommand("Content Editor", "Manage your website content.", "{E28353A0-FB68-455B-9B2E-99AD280EF64E}");
this.addCommand("Developer Center", "Create new functionality.", "{6041C6E9-4054-4116-95C0-7967DB8A0583}");
this.addCommand("Domain Manager", "Use the Domain Manager to create and manage domains", "{FDDE6301-442C-44B8-B934-0F1FF29413F6}");
this.addCommand("File Explorer", "Browse your web application files.", "{9EA291E8-3E56-4335-B8B9-296F13638DAC}");
this.addCommand("Image Editor", "Edit images", "{42D4CBE0-60A9-4A8B-81A6-9596246976C5}");
this.addCommand("Install Package", "Package design tool", "{DCA06E38-AF13-4299-BFA3-4D0DDCA0A9BF}");
this.addCommand("Keyboard Map", "You can use this functionality to assign keyboard shortcuts to an action in Sitecore, for example, Save or Open.", "{5F4DA892-CD7F-40A6-B115-31019633639D}");
this.addCommand("Licenses", "Information about installed licenses.", "{B079E515-F945-41CC-A3C8-B94777BF4B95}");
this.addCommand("Log Viewer", "View your applications logs", "{27EC41F4-EA84-4FC6-A996-C56FE397EC18}");
this.addCommand("Marketing Control Panel", "Configure marketing features.", "{B55C7E99-8692-4756-B24C-29DD003888F9}");
this.addCommand("Media Library", "Maintain your media items.", "{7CF7BC24-FA44-46C3-A82B-5A9A1E9E2A0F}");
this.addCommand("Package Designer", "Package design tool", "{584C2F78-42A4-4E46-B5DC-211D245169E9}");
this.addCommand("Recycle Bin", "Restore deleted items or remove them from Sitecore completely.", "{6FED6C55-9558-4E80-AB88-42E519D6DFD8}");
this.addCommand("Role Manager", "Create and manage the roles that you want to assign the users of your system", "{18156152-715C-4E3F-969A-94BE59A049E9}");
this.addCommand("Run", "Enter the name of the application, folder, document, or internet resource that you want to open.", "{8CC6D3B6-9081-4E04-84E3-F051A3194CB4}");
this.addCommand("Scan for Broken Links", "Scan for Broken Links", "{92BFFD39-D745-4B42-A356-1CD24540CD53}");
this.addCommand("Search", "Sitecore search application", "{0490EE27-D17D-46F6-A4DF-C0864EE9DD52}");
this.addCommand("Security Editor", "Manage the access rights that roles and users have to the items in Sitecore", "{0EF5CACF-4C67-46F5-8DEA-DA93700B52F7}");
this.addCommand("Template Manager", "Create new templates.", "{B3702304-16E6-4EA0-ADDA-5390B56A4164}");
this.addCommand("User manager", "Create and manage the users that have access to the system", "{E89F2A3C-8F3E-491E-AB81-695FBDE3479E}");
this.addCommand("Workbox", "Displays information about the items in a workflow such as editing history or the number of items that you can find in each workflow state", "{5AB73C5D-6B10-464D-B7B7-12CDB9DA5931}");
}

private addCommand(name: string, description: string, id: string): void {
this.commands.push(new AppShortcutCommand(name, description, this.runner, this.trimId(id)))
}

private trimId(id: string): string {
return id.replace('{', '').replace('}', '');
}
}
}

0 comments on commit 8cf2179

Please sign in to comment.