I was playing with Office 365 add-in for MS word. I have a dialog to manipulate selected word image. I need to pass that image (maybe a Base64 value of that) to my dialog so that I can play with the image before replacing back to the word(same location).
I am using below code to show the popup:
Office.context.ui.displayDialogAsync("https://" + location.host + "/Views/ImageManager.html", { width: 64, height: 55, requireHTTPS: true }, function (asyncResult) {
dialog = asyncResult.value;
dialog.addEventHandler(Office.EventType.DialogMessageReceived, processMessage);
if (asyncResult.status !== Office.AsyncResultStatus.Succeeded) {
return;
}
});
Thing I wanted to do?
When the user selects an image to play with that in a word document and click ribbon button to open this dialog, I need to pass that image to the dialog to show in the dialog.
How can I pass my Image model to the dialog?
There are at least two ways to pass things to the dialog:
Pass it as a query parameter on the URL that you pass to displayDialogAsync()
Store it in window.localStorage in the host script and retrieve it from there in script on the dialog page.
UPDATE: You can vote up this Office Dev User Voice request for better communication between the dialog and its host: https://officespdev.uservoice.com/forums/224641-feature-requests-and-feedback/suggestions/17196659-improve-custom-dialog
Related
I am using the following code to implement the Set up Gigya share bar:
if ($window.gigya) {
// Step 1: Construct a UserAction object and fill it with data
var ua = new $window.gigya.socialize.UserAction();
ua.setLinkBack(articleUrl);
ua.setTitle($scope.title);
// Step 2: Define the Share Bar add-on's params object
var params = {
userAction: ua,
//shareButtons: 'linkedin,twitter,facebook,sina,email', // list of providers
shareButtons: 'linkedin,twitter,facebook,sina,email',
containerID: 'share-bar',
showCounts: 'none',
deviceType: 'auto',
cid: '',
wrap: true,
operationMode:'multiSelect',
onShareButtonClicked:function (e) {
console.log(e);
console.log(e.shareItem.provider);
if (e.shareItem.provider == 'email') {
var mailString = 'mailto:test#example.com'
$window.location.href = mailString;
}
}
};
// Step 3: Load the Share Bar add-on:
$window.gigya.socialize.showShareBarUI(params);
}
The above code displays the share bar provided by Gigya.
Now clicking the email option I am trying to open the default client mail (for example outlook). I see that the default email popup also get opened along with the outlook.
How to stop the default UI from opening in this case. I tried all the options but none are working for me.
Can anyone help me to know how to fix this issue.
I don't believe this behavior is supported. By design, the Share add-on, when sharing via email, constructs the actual message on the server using the UserAction passed in the request and then sends it from there. So, even if you got the default UI to not populate, how would you be getting the actual share data inside the 3rd party email program?
This is related to some other questions I am working on.
Say, for whatever reason, a user has bookmarked a page (call it pageURL of the pattern moz-extensions://MY-OWN-WEBEXT-ID/*) intended to be opened from a browser action context menu, and opened it in a tab, then opened many other tabs and possibly other windows. User knows the extension tab exists somewhere and doesn't want to keep opening new bookmarks, and so wants to use the add-on's browser action context menu to find the extension page's tab. Likewise, I don't want my add-on to open a duplicate tab.
The problem, since the add-on did not create the tab (a bookmark did), I have no tab ID to pass to browser.tabs.update( WebExtTab.id, { active: true } ) or window ID to pass to browser.windows.update( WebExtWindow.id, { focused: true } ). (WebExtWindow referring to a WebExtensions browser.windows.Window object, not a browser window object.
I can use browser.extension.getViews( ) to generate a list of browser window objects (aka tabs), and checking each window.location.href find that indeed the URL (and thus tab) does exist (somewhere), but I can't use that window object to focus on the tab nor to get a tab ID for browser.tabs.update().
In the case of multiple browser windows, I can't even get the right browser window to raise up given that window object, because the window objects returned by getViews have no id property with which to call browser.windows.update(). Similar to the tabs problem.
Finally, I can't use browser.tabs.query( { 'url': pageURL } ) to find the tab ID, because the url option must conform to match patterns, which FORBID using the moz-extension:// scheme.
What would be exceptionally useful was if the WebExtensions API allowed an extension to find the tabs and windows of all pages that belong to itself, regardless if those pages were opened by the add-on, manually entered, a bookmark or clicking a link.
For example, given a pageURL conforming to moz-extension://MY-OWN-WEBEXT-ID/*, one could do a browser.tabs.query and/or a browser.windows.query on a url matching the above pattern, and return a WebExt tab/window object, respectively. If such a tab/window was not opened by the WebExt API (i.e. bookmark), then generate a new object (i.e. a pseudo-create), to populate with existing data (i.e. location.href, status flags, etc) and generate new data as needed (i.e. the ID numbers), such that the returned object is usable within the context of the API.
This would fill a gap in API coverage where certain methods (i.e. getViews) return dead-end browser objects which have no hooks and no connection with the WebExt API and are thus mostly useless.
The simple answer: ++RTFM. browser.windows.getAll() will allow you to populate the windows objects with tab info. You need the permissions: [ "tabs" ] in manifest.json to get the tab.url property. But other than that, all the windows and tab objects will have an ID so that you can trivially focus window and switch active tab!
Note: This requires Firefox 52.0+ to make use of the async/await feature. Otherwise, you just have to use function generators and promises. Also, I've omitted any error checking, for demonstration purposes, but it might be a good idea to put them back in later.
async function tabCreate ( opts ) {
var pageURL = browser.runtime.getURL( opts.page + '.html' );
var extWins = await browser.windows.getAll( { populate: true, windowTypes: [ 'normal' ] } );
// Look for tab by comparing url, if url matches (i.e. tab exists), then focus window and make tab active.
for ( var extWin of extWins ) {
for ( var extTab of extWin.tabs ) {
if ( pageURL === extTab.url ) {
console.log( `My Extension->tabCreate(): Window ${extWin.id}, Tab ${extTab.id}:\n\t${extTab.url}` );
browser.windows.update( extWin.id, { focused: true } );
browser.tabs.update( extTab.id, { active: true } );
return;
}
}
}
// Otherwise, create tab.
browser.tabs.create( { url: pageURL } );
}
Opinion: I wish I didn't have to give away the tabs permission just for this feature. It would be nice if we always got our own moz-extension://MY-OWN-WEBEXT-ID/* urls, and null URLs for other tabs, without permissions given to access all tabs, but oh well.
Example Usage:
function myWebExt_Options ( ) {
tabCreate( {
'page': 'options',
'panel': 1
} );
}
browser.contextMenus.create( {
title: 'Options',
contexts: [ 'browser_action' ],
onclick: myWebExt_Options
} );
Note: I've implemented this to expect options in an opts object that has a page property, which I use as a shorthand to generate the full page URL. This is because of another question which requires passing a message to the page, which I store in opts.panel. But none of that is necessary. It could be changed to a flat string, or use the full 'getURL' generated elsewhere as a parameter. Change to suit your need and style.
I want to insert a timelineitem with video attachment and if user selects a specific menu item, glass to play the video. I'm doing all from .net app like this, please correct me, if i'm doing wrong.
TimelineItem item = new TimelineItem()
item.MenuItems.Insert(0, new MenuItem(){Action="what is the action to use?";...});
request = Service.Timeline.Insert(item, attachment, contentType);
request.Upload();
I would like to know, do i need a menu item, if yes, what is the action i should use?
Currently i'm sending the video attachment, but there is no way to play the video.
Any help is greatly appreciated.
You don't need to specify any menuItems but your timeline item should not contain html content.
Make sure that your video is of a supported format: once it's inserted, and Glass has synced and fully downloaded the attached video, it should start playing right when you land on the item in your timeline.
This works using the QuickStart project for Java (mirror-java-starter-demo):
https://github.com/googleglass/mirror-quickstart-java
Replace the lines near line 119 in MainServlet.java with this:
URL url = new URL(req.getParameter("imageUrl"));
String contentType = req.getParameter("contentType");
url = new URL("http://localhost:8888/static/videos/video.mp4");
contentType = "video/mp4";
byte[] b = ByteStreams.toByteArray(url.openStream());
int i = b.length;
InputStream temp = url.openStream();
MirrorClient.insertTimelineItem(credential, timelineItem, contentType, temp);
Then run the project and click the "A Picture" button to upload a video from a new folder inside static called videos called video.mp4. I used a 10 second clip I recorded with glass (6.30 MB).
Note that when running with App Engine 1.76 on a windows machine I got this error when uploading, but changing to 1.80 made this issue go away:
Here is Windows metadata about the video that might be useful:
Depending on your network connection it might take a little bit for the video to show in your timeline, but mine plays.
I am working on extjs 4.2 application. Trying to create a menu toolbar where I can add and delete files. For example:
When I press Open, I want to see the file browser window. And when I finish choosing the file and click "open", I will see something like this:
I know that I need to use onItemClick() function to open the browser. But I have no idea how to call that window. Also how can you program so only certain file extensions can be chosen.
I am guessing that once you press "open" on the file browser window, the file tree in the left panel will dynamically add that file. But have no idea how can I connect "open" to my tree.
Just to clarify - this is going to be user based app, it is not going to be a webapp. This will be opened in user's browser and that is it. No need to get some info from server or send something to client.
EDIT: I have been able to solve the part where you click on Open the file browser dialog pops up. Then when I select a file and press "open", it displays a message box with file's name.
Here is the code for that part:
var item = Ext.create('Ext.form.field.File', {
buttonOnly: true,
buttonText: 'Open',
hideLabel: true,
listeners: {
'change': function(fb, v){
Ext.Msg.alert('Status', v);
}
}
});
var mainmenu = Ext.create('Ext.menu.Menu', {
width: 200,
margin: '0 0 10 0',
items: [item]
});
Now the problem is that I need to get the FULL PATH of the file. This message only shows file's name. Any help?
Using files on the web can be tricky, so you're going to have to be patient, diligent, and be prepared for some self-learning.
A. If you want to be compatible with all browsers, you need to upload the file to a server, and have the server return info about the file. Or you can try Sencha Desktop Packager, flash, or signed Java Applets.
If you are okay with only modern browsers, you will need to read and learn the HTML5 File API. Here's a start:
https://developer.mozilla.org/en-US/docs/Web/API/FileReader?redirectlocale=en-US&redirectslug=DOM%2FFileReader
B. Start with a filefield button for now, and add it as a menuitem later, just to keep things simple. You will want to listen to the filefield's change event if you want to read the file.
C. To restrict file types (only modern browsers allow this), you'll need to do something like this (audio/* is just an example):
{
xtype:'filefield',
listeners:{
afterrender:function(cmp){
cmp.fileInputEl.set({
accept:'audio/*'
});
}
}
}
D. After you get the file, you will want to add it's info to the tree's TreeStore.
I download fine uploader 3.5, created http handler for a file upload function in my little website . the website is done by asp.net ajax and jquery. it runs at IE9. every time I upload a file, there is a list of file names shown below the load button. if I don't want thme, what should I do?
my code is like this:
html: ...
'<tr><td><div id="jquery-wrapped-fine-uploader"></div></td></tr>...
'ajax/jquery:...
'$('#jquery-wrapped-fine-uploader').fineUploader({
'request: { endpoint: 'xxx.ashx' }
'})
'$('#jquery-wrapped-fine-uploader').on("complete",
'function (event, id, fileName, responseJSON) {
' alert("UPLOAD SUCCESS");
' $.ajax({some ajax calls here});
' })
// WHERE TO PUT this TO CLEAR the UPLOADED FILE LIST??? $('#jquery-wrapped-fine-uploader').fineUploader('reset');
XXX.ashx:
'... public void ProcessRequest (HttpContext context) {
'do some http request work..
'context.Response.ContentType = "text/plain";
'context.Response.Write("{\"success\":true}");
'}
My question is:
I want to completely remove the uploaded file list which shows automatically in green color ( or red if they fail), in order to clear them, I tried to put: $('#jquery-wrapped-fine-uploader').fineUploader('reset'); right after .on('complete'), it's not working, also #jquery-wrapped-fine-uploader seems cached all the time. please help on this.
If you don't want to see the file list at all, you should be using FineUploaderBasic mode instead of using FineUploader mode and then removing all elements in the pre-built UI. FineUploaderBasic mode gives you access to the API, options, and callbacks, but assumes you will be creating your own UI. In other words, FineUploaderBasic mode does not create any DOM elements (except the opaque file input element as a child of your button container, if you supply one). This is all explained (in a great amount of detail) in the documentation.
Start here: http://docs.fineuploader.com