I want to iterate over opened tabs and do specific tasks.
Is there a way to get the amount of opened tabs?
This is the way that Firefox currently uses to count opened windows and tabs, for telemetry:
function getOpenTabsAndWinsCounts() {
let tabCount = 0;
let winCount = 0;
for (let win of Services.wm.getEnumerator("navigator:browser")) {
winCount++;
tabCount += win.gBrowser.tabs.length;
}
return { tabCount, winCount };
}
Please note how it iterates through the results of Services.wm.getEnumerator("navigator:browser"), to capture the numbers of all the different opened windows.
Depending on where you want to use the script, you might need to use var wm = Components.classes["#mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator) rather than Services.wm, as suggested by #Shugar.
If you need a js-script, I hope the following code should be helpful:
var wM = Components.classes["#mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
var numberOfTabs = wM.getMostRecentWindow("navigator:browser").gBrowser.browsers.length;
Related
I need to transfer ownership of thousands of files I own to someone else with editing access, but I've learned that Google Drive requires you to do this one file at a time. With intermediate but growing JS experience I decided to write a script to change the owner from a list of file IDs in a spreadsheet, however I've run into trouble and I have no idea why. The debugger just runs through the script and everything looks sound for me. I'd greatly appreciate any help.
function changeOwner() {
var ss = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/********/').getSheetByName('Sheet1');
var range = ss.getRange(1,1,2211);
for (i = 0; i < range.length; i++){
var file = range[i][0].getValue();
var fileid = DriveApp.getFileById(file);
fileid.setOwner('******#gmail.com');
}
}
Tested below code working fine with IDs,
function myFunction() {
var spreadsheet = SpreadsheetApp.openById('ID');
var range = spreadsheet.getDataRange().getValues();
for (i = 0; i < range.length; i++){
var file = range[i][0].toString();
var fileid = DriveApp.getFileById(file);
fileid.setOwner('***#gmail.com');
}
}
Your issue is that the Range class had no length property. Instead, perform a getValues() call on the range to efficiently create a JavaScript array, and iterate on it:
function changeOwner() {
var ss = SpreadsheetApp.openByUrl('https://docs.google.com/spreadsheets/d/********/').getSheetByName('Sheet1');
var values = ss.getRange(1, 1, 2211).getValues();
for (i = 0; i < values.length; ++i){
var fileid = value[i][0];
var file = DriveApp.getFileById(fileid);
file.setOwner('******#gmail.com');
}
}
There are other improvements you can make, such as:
dynamic range read (rather than the fixed assumption of 2211 rows of data)
writing to a second array to keep track of which files you have yet to process
checks for if the file exists
checks for if the file is actually owned by you
checks for execution time remaining, to allow serializing any updates/tracking you do that prevents the next execution from repeating what you just did
and so on. I'll let you research those topics, and the methods available in Apps Script documentation for the DriveApp, SpreadsheetApp, Sheet, and Range classes. Note that you also have all features of Javascript 1.6 available, so many of the things you find on a Javascript Developer Reference (like MDN) are also available to you.
I'd like my add-on to restart Firefox and upon restart have a pre-defined webpage displayed.
When I restart the browser via nsIAppStartup.quit(), all of the tabs I had been viewing will be re-opened after restart. I have tried to cope with this manually by closing all the tabs before restarting (see code below), but I find that although I can visually confirm that all of the tabs are closed, they will be present again after a restart.
I assume that some session restore mechanism is re-creating them after the restart. I have found several preferences regarding "SessionStore" (browser.sessionstore.max_tabs_undo, browser.sessionstore.resume_from_crash, etc), but toggling them does not seem to help me resolve this issue.
How should I go about ensuring that the old tabs are closed after a restart? Thank you!
// get gBrowser reference
var mainWindow = Cc["#mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator).getMostRecentWindow("navigator:browser");
var gBrowser = mainWindow.gBrowser;
// build a collection of tabs to close
var tabsToClose = [];
for( var i = 0; i < gBrowser.mTabContainer.childNodes.length - 1; i++ ){
tabsToClose.push( gBrowser.mTabContainer.childNodes[i] );
}
// Open homepage in new tab
gBrowser.addTab(DEFAULT_HOMEPAGE);
// Close all tabs except for homepage
for( var i = 0; i < tabsToClose.length; i++ ){
gBrowser.removeTab( tabsToClose[i] );
}
// restart browser
Cc["#mozilla.org/toolkit/app-startup;1"].getService(nsIAppStartup).quit(nsIAppStartup.eRestart | nsIAppStartup.eAttemptQuit);
I changed your code a bit and came up with this solution:
var Cc = Components.classes;
var Ci = Components.interfaces;
var pref = Cc["#mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefService);
pref.setBoolPref("browser.tabs.warnOnCloseOtherTabs",false);
var mainWindow = Cc["#mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator).getMostRecentWindow("navigator:browser");
var gBrowser = mainWindow.gBrowser;
var newTab = gBrowser.addTab("www.google.com");
// Easier solution than having two loops to identify the open tabs
gBrowser.removeAllTabsBut(newTab);
var nsIAppStartup = Ci.nsIAppStartup; // You were missing this part on your question
Cc["#mozilla.org/toolkit/app-startup;1"].getService(nsIAppStartup).quit(nsIAppStartup.eRestart | nsIAppStartup.eAttemptQuit);
The preference that you need to change is browser.tabs.warnOnCloseOtherTabs so you don't get a warning when closing multiple tabs. The other sessionstore prefs i didn't touch.
Hope it helps.
Is there any trick to break a label text? Because '\n' '\r' '\n\r' don't work.
Many Thanks
if you use those 2 parameters you do what you want don't you ?
app.createLabel(text).setWidth(width).setWordWrap(true)
here is an example (among other widgets ;-):
function showurl() {
var app = UiApp.createApplication();
app.setTitle("Anchor in a popup ;-)");
var panel = app.createFlowPanel()
var image = app.createImage('https://sites.google.com/site/appsscriptexperiments/home/photo.jpg').setPixelSize(50, 50)
var link = app.createAnchor('This is your link', 'https://sites.google.com/site/appsscriptexperiments/home');
var lab = app.createLabel("wrap it because it's too narrow").setWidth(90).setWordWrap(true);
var quit = app.createButton('quit');
panel.add(image).add(link).add(lab).add(quit);
app.add(panel);
var doc = SpreadsheetApp.getActive();
doc.show(app);
}
EDIT : I found an old post(on the Google group forum, thanks again Henrique ;-) about breaking lines in toast messages and here is the code I used for that case... the principle should work for Labels too but I didn't try.
To use it, just use \n (where you want to break the line) in a variable containing your text and pass it through this function. (there are some comment in the script to explain)
function break_(msg){
var temp = escape(msg);// shows codes of all chars
msg = unescape(temp.replace(/%20/g,"%A0")); // replace spaces by non break spaces
temp = msg.replace("\n"," "); // and replace the 'newline' by a normal space
return temp; // send back the result
}
Would something like this work?
//takes a line of text and returns a flex table broken by \n
function breakLabel(text) {
var app = UiApp.getActiveApplication();
var flexTable = app.createFlexTable();
text = text.split('\n'); // split into an array
for (var i=0; i<text.length; i++){
flexTable.setWidget(i, 0, app.createLabel(text[i].toString()));
}
return flexTable;
}
Adding them to a vertical panel helps as well (not the way you want, but still..):
var vPanel = app.createVerticalPanel().setSize(100,100);
var label = app.createLabel('predominantly blabla blala blabla');
app.add(vPanel.add(label));
See reference
For anyone just now stumbling upon this, the best solution seems to be creating an HTML output for anything that needs line breaks.
Documentation
var htmlApp = HtmlService
.createHtmlOutput('<p>A change of speed, a change of style...</p>')
.setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('My HtmlService Application')
.setWidth(250)
.setHeight(300);
SpreadsheetApp.getActiveSpreadsheet().show(htmlApp);
// The script resumes execution immediately after showing the dialog.
i'm developing a firefox extension and i want to be able to close a specific tab. For example if there are many open tabs in the browser o want to close only the tab with a specific url.
I know that i can use gBrowser.removeTab(tab) but i don't know how to get tab object.
On the other hand i can get the browser that corresponds to the url but the param of the removeTab() function must be a "tab object". How cat i get the tab object.
Any ideas?
tabbrowser.getBrowserForTab() method is actually the easiest way of associating browsers with tabs. So you would do something like this:
var tabs = gBrowser.tabs;
for (var i = tabs.length - 1; i >= 0; i--)
{
var tab = tabs[i];
var browser = gBrowser.getBrowserForTab(tab);
if (browser.currentURI && browser.currentURI.spec == "...")
gBrowser.removeTab(tab);
}
I think you can use this method: gBrowser.removeCurrentTab(); this example closes the currently selected tab.
For more code, please refers this link: https://developer.mozilla.org/en/Code_snippets/Tabbed_browser
The bottom of the page is truncated when printed. (Approx 1/2 to 1").
This printing problem does not seem to be specific to Flash (printing certain PDFs also yields this problem), but that is where we found it.
The problem does not occur in older versions of OS X, but does occur in the most recent versions (10.5.5 and up). Not sure where the line is. The same application on Windows works fine.
It happens in Safari and Firefox.
Our Flash CS3 (AS2) application uses the PrintJob object to send pages to the printer. The pages are supposed to be letter-sized. On Windows they are letter-sized and print fine. But on the Mac, the pages are truncated. When the browser Print dialog comes up, if you change paper size to A4, the document prints fine. IT IS NOT SUPPOSED TO BE A4.
What is going on?
Here is a fraction of our printing code:
private function runPagePrintJob(pages:Array):Void {
var pj:PrintJob = new PrintJob();
if (pj.start()) {
var paperHeight:Number = this.pointsToPixels(pj.pageHeight);
var paperWidth:Number = this.pointsToPixels(pj.pageWidth);
for (var i:Number=0; i<pages.length; i++) {
var mc:PrintablePage = pages[i];
var xScale:Number = paperWidth / mc._width;
var yScale:Number = paperHeight / mc._height;
if ((xScale < 1) || (yScale < 1)) {
mc.setScale(Math.min(xScale, yScale) * 100);
}
mc.setBGSize(paperWidth, paperHeight);
var xMin:Number = 0;
var xMax:Number = paperWidth;
var yMin:Number = 0;
var yMax:Number = paperHeight;
pj.addPage(mc, {xMin:xMin, xMax:xMax, yMin:yMin, yMax:yMax}, {printAsBitmap:true});
}
pj.send();
}
delete pj;
this.close();
}
private function pointsToPixels(pts:Number):Number {
return pts/72*System.capabilities.screenDPI;
}
Have you tried this with more than one printer model? I've seen similar problems that have been the result of a buggy printer driver.