Custom menu in TFS web access (TFS 15) - tfs

I tried these steps and i created a sample extension similar to this site https://www.visualstudio.com/en-us/docs/integrate/extensions/get-started/node .
But i need to pass parameter to the site which i am opening using this new extension. Is it possible ?
Parameters like : project name , environment(TFS URL) where the TFS is running.
And i am facing an error when trying to open a page in an MVC application hosted on IIS internally, the application uses Durandal ,Knockout and HTML 5 for the UI.
Not able attach the screen shot pasting the part of new extension script
"icons": {
},
"contributions": [
{
"id": "Fabrikam.HelloWorld",
"type": "ms.vss-web.hub",
"description": "Adds a 'Hello' hub to the Work hub group.",
"targets": [
"ms.vss-work-web.work-hub-group"
],
"properties": {
"name": "Hello Testing",
"order": 99,
"uri": "http://test-server/AdminConsole2015Beta/#/tfsreports/boc_projects/ALM/alm-beta-app1/0"
}
}
],
"scopes": [
"vso.work"
],
"files": [
{
"path": "tfsReports.html", "addressable": true
},
{
"path": "scripts", "addressable": true
},
{
"path": "sdk/scripts", "addressable": true
}
]
}
In the above script i want to open the URL in the URI property which opens the page tfsreports.html after routing using durandal. Is that possible here? See screen shot for refrence

Update your extension to below:
In the manifest file, update the "uri" of the "contributions" to "tfsReports.html".
"properties": {
"name": "Hello Testing",
"order": 99,
"uri": "tfsReports.html"
}
Add followings content in "tfsReports.html":
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Hello World</title>
<script src="sdk/scripts/VSS.SDK.js"></script>
</head>
<body>
<script type="text/javascript">VSS.init();</script>
<h1>Hello World</h1>
<script type="text/javascript">
VSS.init();
VSS.ready(function () {
var webContext = VSS.getWebContext();
var projectname = webContext.project.name;
var TFSUrl = webContext.collection.uri;
var reportFrame = document.getElementById("reportFrame");
var finalurl = "http://test-server/AdminConsole2015Beta/#/tfsreports/boc_projects/ALM/alm-beta-app1/0/" + projectname + "/" + TFSUrl;
reportFrame.src = finalurl;
VSS.notifyLoadSucceeded();
});
</script>
<div id="tfsreport">
<iframe id="reportFrame" style="width:100%" frameborder="0"></iframe>
</div>
</body>
</html>

Related

How to post message from VSCode extension to custom webview created with WebviewProvider?

I am building a VSCode extension where I create a custom tab in the panel with a Webview Provider. I want to direct the output of an extension command to Webview and render in html script. The alternative is to execute vscode extension command inside html script of the webview. However I could not find an example that uses Webview Provider, instead they all have
currentPanel.webview.postMessage({ command: 'refactor' });
which is undefined in my case because I do not create a panel.
extension.js
let disposable = vscode.commands.registerCommand(
"this is where I want to send data to webview"
...
);
var thisProvider={
resolveWebviewView:function(thisWebview, thisWebviewContext, thisToke){
thisWebview.webview.options={enableScripts:true}
thisWebview.webview.html=`<!DOCTYPE html>
<html>
<body>
<div id="results" style="white-space: pre;" />
<script>
const resultsEl = document.getElementById("results");
window.addEventListener('message', event => {
const message = event.data; // The JSON data our extension sent
switch (message.command) {
case 'results':
console.log(results);
break;
}
});
</script>
</body>
</html>`;
}
}
context.subscriptions.push(
vscode.window.registerWebviewViewProvider("monitor.output", thisProvider)
);
package.json:
"contributes": {
"commands": [
{
"command": "monitor.listen",
"title": "Connect"
}
],
"menus": {
"view/title": [
{
"command": "monitor.listen",
"group": "navigation",
"when": "view == monitor.output"
}
]
},
"viewsContainers": {
"panel": [
{
"id": "monitor",
"title": "Monitor",
"icon": "resources/monitor.jpeg"
}
]
},
"views": {
"monitor": [
{
"type": "webview",
"id": "monitor.output",
"name": "Monitor"
}
]
}
}
I was looking for this too, but there is really no example showing how this could be added.
You can get and save the reference to the current webView inside resolveWebView function in your provider.
Store the view in a private instance variable private _view?: vscode.WebviewView; and use it in a public method public postMessageToWebview(message: any)
The provider code:
import * as vscode from 'vscode';
function getNonce() {
let text = "";
const possible =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (let i = 0; i < 32; i++) {
text += possible.charAt(Math.floor(Math.random() * possible.length));
}
return text;
}
export class WebViewProvider
implements vscode.WebviewViewProvider
{
public static readonly viewType = 'myExtension.controlsView';
private _view?: vscode.WebviewView;
constructor(private readonly _extensionUri: vscode.Uri) {
}
public postMessageToWebview(message: any) {
this._view?.webview.postMessage(message);
}
public resolveWebviewView(
webviewView: vscode.WebviewView,
context: vscode.WebviewViewResolveContext,
_token: vscode.CancellationToken,
) {
this._view = webviewView; // needed so we can use it in postMessageToWebview later
webviewView.webview.options = {
// Allow scripts in the webview
enableScripts: true,
localResourceRoots: [this._extensionUri],
};
webviewView.webview.html = this._getHtmlForWebview(
webviewView.webview,
);
webviewView.webview.onDidReceiveMessage((data) => {
switch (data.type) {
// other message types ...
case 'onYourEvent': {
console.log(data.value); // see below webview to extension communication snippet
break;
}
case 'onInfo': {
if (!data.value) {
return;
}
vscode.window.showInformationMessage(data.value);
break;
}
case 'onError': {
if (!data.value) {
return;
}
vscode.window.showErrorMessage(data.value);
break;
}
}
});
}
private _getHtmlForWebview(webview: vscode.Webview) {
// // And the uri we use to load this script in the webview
const scriptUri = webview.asWebviewUri(
vscode.Uri.joinPath(
this._extensionUri,
'out',
'svelte-app/bundle.js',
),
);
// const scriptUri = webview.asWebviewUri(
// vscode.Uri.joinPath(this._extensionUri, "media", "main.js")
// );
// Local path to css styles
const styleResetPath = vscode.Uri.joinPath(
this._extensionUri,
'media',
'reset.css',
);
const stylesPathMainPath = vscode.Uri.joinPath(
this._extensionUri,
'media',
'vscode.css',
);
// Uri to load styles into webview
const stylesResetUri = webview.asWebviewUri(styleResetPath);
const stylesMainUri = webview.asWebviewUri(stylesPathMainPath);
const cssUri = webview.asWebviewUri(
vscode.Uri.joinPath(
this._extensionUri,
'out/svelte-app',
'bundle.css',
),
// vscode.Uri.joinPath(this._extensionUri, "media", "main.css")
);
// Use a nonce to only allow specific scripts to be run
const nonce = getNonce();
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--
Use a content security policy to only allow loading images from https or from our extension directory,
and only allow scripts that have a specific nonce.
-->
<meta http-equiv="Content-Security-Policy" content="img-src https: data:; style-src 'unsafe-inline' ${webview.cspSource}; script-src 'nonce-${nonce}';">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="${stylesResetUri}" rel="stylesheet">
<link href="${stylesMainUri}" rel="stylesheet">
<link href="${cssUri}" rel="stylesheet">
<script nonce="${nonce}">
const tsvscode = acquireVsCodeApi();
</script>
</head>
<body>
</body>
<script nonce="${nonce}" src="${scriptUri}"></script>
</html>`;
}
}
Note:
To get started remove the svelte bundle stuff (this was just part of my code base) and add a script file media/main.js with the code from the webview snippet below.
The CSS files reset.css and vscode.css can be downloaded from a VS Code example
To see your console.log messages you can open your dev. tools in your extension host VS code instance by hitting ctrl+shif+p and type Open webview dev - maybe you have to open/close your webview to generate new console logs.
You can use it in your extension.ts:
import * as vscode from 'vscode';
import { WebViewProvider } from './WebViewProvider';
export function activate(context: vscode.ExtensionContext) {
const provider = new WebViewProvider(context.extensionUri);
context.subscriptions.push(
vscode.commands.registerCommand('myExtension.sayHello', () => {
// The code you place here will be executed every time your command is executed
// Display a message box to the user
// vscode.window.showInformationMessage(output);
provider.postMessageToWebview({
type: 'greeting',
message: 'HelloWorld',
});
}),
);
context.subscriptions.push(
vscode.window.registerWebviewViewProvider(
WebViewProvider.viewType,
provider,
),
);
}
Add it to the package.json so the command & view will be available:
{
"other-config": "...",
"activationEvents": [
"onView:myExtension.controlsView",
"onCommand:myExtension.sayHello"
],
"contributes": {
"views": {
"explorer": [
{
"type": "webview",
"id": "myExtension.controlsView",
"name": "MyExtension"
}
],
},
"commands": [
{
"command": "myExtension.sayHello",
"category": "myExtension",
"title": "SayHello"
},
]
}
}
Webviews can be added at multiple locations in this code it will be added to the explorer view.
Use the following code in your webview script to get the message from the extension:
// main.js code
const handleExtensionMessages = (event) => {
const { message, type }= event.data;
switch (message.type) {
case 'greeting':
console.log("received", message);
break;
}
}
window.addEventListener("message", handleExtensionMessages);
For the other "direction" web view to extension communication.
You can use in your webview content script:
tsvscode.postMessage({
type: "onYourEvent",
value: "anything you like to return",
});
The global tsvscode variable is generated in _getHtmlForWebview with acquireVsCodeApi().
To fix the typing for the global tsvscode. Install #types/vscode-webview with npm as devDependency and add a global.d.ts to your webview script with this content:
import type WebViewApi from '#types/vscode-webview';
global {
declare const tsvscode: WebViewApi<unknown>;
}
Or if you don't like the global variable tsvscode and the typing above. You could also create a VS Code API wrapper like in the following repository.
Just to get this code running, create an extension as mentioned in the Getting Started Guide with Yeoman generator by running yo code in your terminal.
You can also find the snippets in the following Github gist.

Why does my browser extension do nothing on page load (except in the toolbox)?

I've been trying to make a Firefox extension. I've had success with doing stuff after a user interaction (like a browser action). But I want my extension to do something without user interaction. But no matter what I do, I can't get anything to happen on page load. Here is my super reduced code:
manifest.json
{
"name": "Test",
"version": "0.1",
"manifest_version": 2,
"background": {
"scripts": ["test.js"]
}
}
test.js
document.addEventListener("DOMContentLoaded", init);
function init() {
document.body.innerHTML = "Hello world!";
}
What am I doing wrong here? It works in the toolbox, just not anywhere else!
I've also tried adding host permissons like this:
"permissions": [
"*://*.facebook.com/*"
],
Try this:
manifest.json
{
"name": "Test",
"version": "0.1",
"manifest_version": 2,
"background": {
"scripts": ["background.js"]
},
"permissions": ["webNavigation", "*://*.facebook.com/*"]
}
background.js
browser.webNavigation.onDOMContentLoaded.addListener(handleOnDOMContentLoaded, {
url: [{ hostEquals: 'www.facebook.com' }],
});
function handleOnDOMContentLoaded({ tabId }) {
browser.tabs.executeScript(tabId, { file: 'test.js' });
}
test.js
document.body.innerHTML = 'Hello world!';

clear google spreadsheet data using http

I have try to clear spreadsheet using http request.
Below is my http request
https://sheets.googleapis.com/v4/spreadsheets/spresheetId/values/B2:B10?key=APIKEY
but json return below error
{
"error": {
"code": 403,
"message": "Requests from referer \u003cempty\u003e are blocked.",
"status": "PERMISSION_DENIED",
"details": [
{
"#type": "type.googleapis.com/google.rpc.Help",
"links": [
{
"description": "Google developer console API key",
"url": "https://console.developers.google.com/project/562822880211/apiui/credential"
}
]
}
]
}
}
so how can i clear my spreadsheet using http
When you deploy as a webapp you'll get a url that looks something like this: https://script.google.com/macros/s/.../exec add a querystring to it so it looks like this: https://script.google.com/macros/s/.../exec?ssid=spreadsheetid only replace spreadsheetid for the real spreadsheet id.
This is the gs file:
function clearSpreadSheet()
{
var ssid=PropertiesService.getScriptProperties().getProperty('SSID');
var ss=SpreadsheetApp.openById(ssid);
var allSheets=ss.getSheets();
for(var i=0;i<allSheets.length;i++)
{
allSheets[i].clear();//clear all
//allSheets[i].getRange(2,1,sheet.getLastRow(),sheet.getLastColumn()).clear();//everything but first row.
}
return{'clearMessage':'Spreadsheet has been cleared.','ssid':ssid}
}
function doGet(e)
{
PropertiesService.getScriptProperties().setProperty('SSID', e.parameter.ssid)
var html = HtmlService.createHtmlOutputFromFile('clearss');
return html.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL)
}
This is the clearss.html file:
<!DOCTYPE html>
<html>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function() {
google.script.run
.withSuccessHandler(dispCleared)
.clearSpreadSheet();//runs when DOM is loaded
});
function dispCleared(data)//runs after spreadsheet is cleared via the SuccessHandler
{
$('#clrd').text(data.clearMessage);
$('#ssid').text('SpreadSheet ID is ' + data.ssid);
}
console.log('My Code');
</script>
</head>
<body>
<h1 id="clrd"></h1>
<h2 id="ssid"></h2>
</body>
</html>
This is a contained web app. So load these files into the script editor of a spreadsheet.

browser.runtime.connect api not working as expected with Firefox for android?

I am developing an extension for Firefox for Android, but since tabs APIs are not supported on Firefox(Android), I am using the following code. It is working fine on Firefox but when porting it to Firefox Android(52 version), background script messages are not being passed to content script listener.
//Content script code
var myPort = browser.runtime.connect({name:"port-from-cs"});
myPort.postMessage({greeting: "hello from content script"});
myPort.onMessage.addListener(function(m) {
console.log("In content script, received message from background script: ");
console.log(m.greeting);
});
// background script
var portFromCS;
function connected(p) {
portFromCS = p;
portFromCS.postMessage({greeting: "hi there content script!"});
portFromCS.onMessage.addListener(function(m) {
console.log("In background script, received message from content script")
console.log(m.greeting);
portFromCS.postMessage({greeting: "hi there content script!"});
});
}
browser.runtime.onConnect.addListener(connected);
//manifest
{
"version": "0.1.5",
"content_scripts": [
{
"js": [
"js/myContentScript.js",
"js/lib/jquery-1.9.1.min.js"
],
"matches": [
"<all_urls>"
],
"run_at": "document_start"
}
],
"description": "xxx",
"manifest_version": 2,
"name": "xx",
"applications": {
"gecko": {
"id": "vpt#mozilla.org"
}
},
"permissions": [
"webRequest",
"notifications",
"http://*/",
"https://*/",
"storage",
"webRequestBlocking"
],
"background": {
"scripts": [
"js/background.js"
]
},
"web_accessible_resources": [
"xxx.js"
]
}
content script is passing the message to background script, but background script messages are caught by portFromCS.onMessage listener. Is my approach correct?

How to customise Shell container in SAPUI5

I've a shell container and on big screens i want to utilize full with of screen. i want to cover full area. how i can customize it.
I assume you are using XML for your views. Add the following attribute appWidthLimited="false" to the Shell tag.
When working with a manifest.json file and the UI5-framework instantiates a shell control, do the following (appWidthLimited="false" cannot be used as you don't have a xml containing a shell 'tag').
manifest.json
...
"sap.ui5": {
"config": {
"fullWidth": true
},
...
...
As per latest documentation, I referred to 1.48.X, and it's not there in the sap.ui5 anymore:
"sap.ui": {
"technology": "UI5",
"icons": {
"icon": "sap-icon://add-contact",
"favIcon": "icon/F1373_Approve_Purchase_Orders.ico",
"phone": "icon/launchicon/57_iPhone_Desktop_Launch.png",
"phone#2": "icon/launchicon/114_iPhone-Retina_Web_Clip.png",
"tablet": "icon/launchicon/72_iPad_Desktop_Launch.png",
"tablet#2": "icon/launchicon/144_iPad_Retina_Web_Clip.png"
},
"deviceTypes": {
"desktop": true,
"tablet": true,
"phone": false
},
"supportedThemes": [
"sap_hcb"
],
"fullWidth": true
},
For more info: https://openui5.hana.ondemand.com/#/topic/be0cf40f61184b358b5faedaec98b2da
Also, if you are using sap.m.Shell, then the above will not help.
For that you need to set the property appWidthLimited: false:
<script>
sap.ui.getCore().attachInit(function () {
new sap.m.Shell({
app: new sap.ui.core.ComponentContainer({
height: "100%",
name: "APPNAME"
}),
appWidthLimited: false
})
.placeAt("content");
});
</script>
It can be done either statically, via XML-template:
<mvc:View controllerName="letterboxing.widescreen.controller.index" xmlns:mvc="sap.ui.core.mvc" displayBlock="true" xmlns="sap.m">
<Shell id="shell" appWidthLimited="false">
<App id="app">
<pages>
<Page id="page" title="{i18n>title}">
<content></content>
</Page>
</pages>
</App>
</Shell>
</mvc:View>
Or dynamically via JS-controller, which will set appWidthLimited:false to the sap.m.Shell.

Resources