Are these 2 capabilities supported in Safari extension development? - safari-extension

I've written a Chrome/Opera extension and am considering porting it to Safari. It needs 2 specific capabilities and the absence of either would veto the whole plan.
Ability to read HTTPS urls - Chrome supports this as part of the "tabs" permission. Firefox (last I checked) does not.
Ability to dynamically change the appearance of the activation button. - In Chrome, this is achieved by having a single canvas on the background page (i.e. the button)...
-body- -canvas id="button_canvas" width="19" height="19"- -/canvas- -/body-
... and then dynamically changing it whenever necessary ...
var canvas = document.getElementById("button_canvas");
var context = canvas.getContext("2d");
var imageData = context.getImageData(0, 0, 19, 19);
// write stuff to the canvas
context.putImageData(imageData, 0, 0);
imageData = context.getImageData(0, 0, 19, 19);
// key element below
chrome.browserAction.setIcon({
imageData: imageData
});
If anyone can answer these two questions definitively before I buy a used Mac on Craigslist, I'd appreciate it. Thanks!
p.s. FWIW, my own Googling suggests that #2 is not possible in Safari. No idea about #1.

I believe both are possible.
For HTTPS URLs: In the Safari extension builder, under Extension Website Access, set Access Level to All and tick the Include Secure Pages checkbox.
To dynamically change the icon displayed on a toolbar icon, first set any icon in the Safari extension builder. Then if you want to change in response to a toolbar button click:
safari.application.addEventListener('command', performCommand, false);
function performCommand(event) {
if (event.command === 'changeIcon') {
event.target.image = safari.extension.baseURI+'othericon.png';
}
}
Under other circumstances, you can iterate your toolbar buttons to modify the one you want:
var toolbarButtons = safari.extension.toolbarItems;
for (var i = 0; i < itemArray.length; ++i) {
var item = toolbarButtons[i];
if (item.identifier === "mybutton") {
item.image = safari.extension.baseURI+'othericon.png';
}
}

Related

nightWatch resizeWindow sets different values on different browsers

module.exports = {
"resizeWindow" : function (browser) {
browser
.url("about:blank")
.waitForElementVisible("body", 1)
.resizeWindow(960, 600)
.execute(function(){
alert(document.body.clientWidth);
})
}
};
alert values:
internet explorer: 944
chrome: 944
firfefox: 946
It could at least all be the same
I also opened an issue on github: https://github.com/beatfactor/nightwatch/issues/377
any ideas ? :)
edit:
I found the problem is that selenium sets browser window width which unless maximized, has its frame and browser body width is always narrower than window width.
Any ideas how to set browser body width, not window width ?
If you know the difference between the window width and body width, you could write a custom command which takes the browser as an argument and resizes it based on the current browser environment.
I.e
exports.command = function() {
var browserName = this.options.desiredCapabilities.browserName;
if (browserName === 'firefox') {
this
.resizeWindow(974, 600)
}
// allows command to be chained
return this;
};
It's not the most elegant solution, but it should work. Add whatever other browsers you need, with the correct width + browserWidthOffset, and simply call it at the beginning of each test.

Soundcloud custom widget : change container background color w/o waveform.js?

Is there any way to change the sc-waveform container background from #efefef without having to load the waveform.js library? I have enough libraries loading already and the conainer bg conflicts with our site background color
I am experiencing the same issue and have had this problem before ( Overlay visible areas of transparent black silhouette PNG with pattern using CSS3 or JS ).
Here is an example with your waveform: http://jsfiddle.net/eLmmA/3/
$(function() {
var canvas = document.createElement('canvas');
canvas.width = 1800; // must match
canvas.height = 280; // must match
var canvas_context = canvas.getContext("2d");
var img = new Image();
img.onload = function(){
var msk = new Image();
msk.onload = function(){
canvas_context.drawImage(img, 0, 0);
canvas_context.globalCompositeOperation = "destination-in";
canvas_context.drawImage(msk, 0, 0);
canvas_context.globalCompositeOperation = "source-over";
};
msk.src = 'WAVEFORM_IMAGE.EXT';
}
img.src = 'OVERLAY_IMAGE.EXT';
document.body.appendChild(canvas);
});
I think I understand what you mean. You want to change the color of the waveform background, the gray stuff around the waveform:
The problem here is that waveforms you get from SoundCloud API are represented as partly transparent PNG images, where waveform itself is transparent and the chrome around it is gray (#efefef) color.
So, unless the library you want to use for waveform customisation is using HTML5 canvas, you won't be able to use change the color of that chrome (so no, not possible with either HTML5 Widget API or Custom Player API). And you have to use waveform.js or the likes (or modify the waveform image on canvas yourself).
You could try to experiment with newest CSS filters (webkit only for now) and SVG filters, and possibly some MS IE filters for older IE versions, but I am not sure you'd manage to just change the color.

dojo splitter not resizing properly with dynamic content

I'm creating a seemingly simple dojo 1.8 web page which contains an app layout div containing a tab container and an alarm panel below the tab container. They are separated by a splitter so the user can select how much of the alarms or the tabcontainer they want to see.
Here's the example on jsfiddle:
http://jsfiddle.net/bfW7u/
For the purpose of the demo, there's a timer which grows the table in the alarm panel by an entry every 2 seconds.
The problem(s):
If one doesn't do anything and just lets the table grow, no scroll bar appears in the alarm panel.
If one moves the splitter without having resized the browser window first, the splitter handle ends up in a weird location.
Resizing the browser window makes it behave like I would expect it to begin with.
Questions:
Am I doing something wrong in the way I'm setting things up and that's causing this problem?
How can I catch the splitter has been moved event (name?)
How do I resize the splitter pane to an arbitrary height? I've tried using domStyle.set("alarmPanel", "height", 300) and this indeed sets the height property... but the pane does not resize!
Any help greatly appreciated!
I forked your jsFiddle and made some modifications to it: http://jsfiddle.net/phusick/f7qL6/
Get rid of overflow: hidden in html, body and explicitly set height of alarmPanel:
.claro .demoLayout .edgePanel {
height: 150px;
}
This tricky one. You have two options: to listen to splitter's drag and drop or to listen to ContentPane.resize method invocation. Both via dojo/aspect:
// Drag and Drop
var splitter = registry.byId("appLayout").getSplitter("bottom");
var moveHandle = null;
aspect.after(splitter, "_startDrag", function() {
moveHandle = aspect.after(splitter.domNode, "onmousemove", function() {
var coords = {
x: !splitter.horizontal ? splitter.domNode.style.left : 0,
y: splitter.horizontal ? splitter.domNode.style.top : 0
}
dom.byId("dndOutput").textContent = JSON.stringify(coords);
})
});
aspect.after(splitter, "_stopDrag", function() {
moveHandle && moveHandle.remove();
});
// ContentPane.resize()
aspect.after(registry.byId("alarmPanel"), "resize", function(duno, size) {
dom.byId("resizeOutput").textContent = JSON.stringify(size);
});
Call layout() method after changing the size:
registry.byId("alarmPanel").domNode.style.height = "200px";
registry.byId("appLayout").layout();

Windowless (not chromeless) Adobe AIR app

What would be the best way to go about building an Adobe AIR app that doesn't have any windows (i.e. exists only in the system tray / dock)? I noticed that the default base tag in Flash Builder is <s:WindowedApplication> which seems to imply there'll be a window.
Should I just use <s:WindowedApplication> and call window.hide()? I saw there's another base class, <s:Application>, but I got the sense that was more for files that run in the browser. It seems like using window.hide() would briefly flash a window when the application starts which could confuse users. However I'd also ideally like to retain the ability to have the app open a window later if needed, or also to change the application from tray-only to windowed through an update.
You need to edit the app-config file to enable transparent chrome and visible = false. Then you need to change the WindowedApplication tag to and app your custom skin. You need to add control buttons for close etc, since that functionality isn't present in a web-app (since you have changed the tag). Also you need to add drag functionality. If you like to make your application re-sizable you need to add that too, manually.
In your manifest (-app.xml) file set systemChrome to none and transparent to true. The visible property is irrelevant, and the default is false anyway so ignore it.
you'll have to tweak this, import whatever classes are missing, etc... you could also do it as an mxml component and just set visible and enabled to false on the root tag. Fill up the trayImages array with the icons you want in the dock.
p
ackage{
import spark.components.WindowedApplication;
public class HiddenApplication extends WindowedApplication{
public function HiddenApplication(){
super();
enabled=false;
visible=false;
var trayImages:Array;
if(NativeApplication.supportsDockIcon||NativeApplication.supportsSystemTrayIcon){
NativeApplication.nativeApplication.activate();
var sep:NativeMenuItem = new NativeMenuItem(null,true);
var exitMenu:NativeMenuItem = new NativeMenuItem('Exit',false);
exitMenu.addEventListener(Event.SELECT,shutdown);
var updateMenu:NativeMenuItem = new NativeMenuItem('Check for Updates',false);
updateMenu.addEventListener(Event.SELECT,upDcheck);
var prefsMenu:NativeMenuItem = new NativeMenuItem('Preferences',false);
prefsMenu.addEventListener(Event.SELECT,Controller.showSettings);
NativeApplication.nativeApplication.icon.addEventListener(ScreenMouseEvent.CLICK,showToolBar);
if(NativeApplication.supportsSystemTrayIcon){
trayIcon = SystemTrayIcon(NativeApplication.nativeApplication.icon);
setTrayIcons();
trayIcon.tooltip = "Some random tooltip text";
trayIcon.menu = new NativeMenu();
trayIcon.menu.addItem(prefsMenu);
trayIcon.menu.addItem(sep);
trayIcon.menu.addItem(updateMenu);
trayIcon.menu.addItem(exitMenu);
}
else{
dockIcon = DockIcon(NativeApplication.nativeApplication.icon);
setTrayIcons();
dockIcon.menu = new NativeMenu();
dockIcon.menu.addItem(prefsMenu);
dockIcon.menu.addItem(sep);
dockIcon.menu.addItem(updateMenu);
dockIcon.menu.addItem(exitMenu);
}
}
function setTrayIcons(n:Number=0):void{
if(showTrayIcon&&(trayIcon||dockIcon)){
Controller.debug('Updating tray icon');
if(NativeApplication.supportsSystemTrayIcon){
trayIcon.bitmaps = trayImages;
}
else if(NativeApplication.supportsDockIcon){
dockIcon.bitmaps = trayImages;
}
}
else if(trayIcon||dockIcon) trayIcon.bitmaps = new Array();
}
}
}

How can I programmatically create a screen shot of a given Web site?

I want to be able to create a screen shot of a given Web site, but the Web site may be larger than can be viewed on the screen. Is there a way I can do this?
Goal is to do this with .NET in C# in a WinForms application.
There are a few tools.
The thing is, you need to render it in some given program, and take a snapshot of it.
I don't know about .NET but here are some tools to look at.
KHTML2PNG
imagegrabwindow() (Windows PHP Only)
Create screenshots of a web page using Python and QtWebKit
Website Thumbnails Service
Taking automated webpage screenshots with embedded Mozilla
I just found out about the website browsershots.org which generates screenshots for a whole bunch of different browsers. To a certain degree you can even specify the resolution.
I wrote a program in VB.NET that did what you specified, except for the screen size issue.
I embedded a web control(look at the very bottom of all controls) onto my form, and tweaked it's settings(Hide scroll). I used a timer to wait on dynamic content, and then I used "copyFromScreen" to get the image.
My program had dynamic dimensions(settable via command line). I found that if I made my program larger than the screen, the image would just return black pixels for the off screen area. I did not research farther since my job was complete at that time.
Hope that gives you a good start. Sorry for any wrong wordings. I log onto windows to develop only once every couple of months.
Doing at as a screen shot is likely to get ugly. It's easy enough to capture the entire content of the page with wget, but the image means capturing the rendering.
Here's some tools that purport to do it.
You can render it on WebBrowser control and then take snapshot if page size bigger than screen size you have to scroll control take one or more snapshots and then merge all pictures :)
This is the code for creating screenshot programatically:
using System.Drawing.Imaging;
int screenWidth = Screen.GetBounds(new Point(0, 0)).Width;
int screenHeight = Screen.GetBounds(new Point(0, 0)).Height;
Bitmap bmpScreenShot = new Bitmap(screenWidth, screenHeight);
Graphics gfx = Graphics.FromImage((Image)bmpScreenShot);
gfx.CopyFromScreen(0, 0, 0, 0, new Size(screenWidth, screenHeight));
bmpScreenShot.Save("test.jpg", ImageFormat.Jpeg);
Java ScreenShots of WebSite
Combine Screens together for Final Entire WebPage Screenshot.
public static void main(String[] args) throws FileNotFoundException, IOException {
System.setProperty("webdriver.chrome.driver", "D:\\chromedriver.exe");
ChromeDriver browser = new ChromeDriver();
WebDriver driver = browser;
driver.get("https://news.google.co.in/");
driver.manage().timeouts().implicitlyWait(500, TimeUnit.SECONDS);
JavascriptExecutor jse = (JavascriptExecutor) driver;
Long clientHeight = (Long) jse.executeScript("return document.documentElement.clientHeight");
Long scrollHeight = (Long) jse.executeScript("return document.documentElement.scrollHeight");
int screens = 0, xAxis = 0, yAxis = clientHeight.intValue();
String screenNames = "D:\\Screenshots\\Yash";
for (screens = 0; ; screens++) {
if (scrollHeight.intValue() - xAxis < clientHeight) {
File crop = new File(screenNames + screens+".jpg");
FileUtils.copyFile(browser.getScreenshotAs(OutputType.FILE), crop);
BufferedImage image = ImageIO.read(new FileInputStream(crop));
int y_Axixs = scrollHeight.intValue() - xAxis;
BufferedImage croppedImage = image.getSubimage(0, image.getHeight()-y_Axixs, image.getWidth(), y_Axixs);
ImageIO.write(croppedImage, "jpg", crop);
break;
}
FileUtils.copyFile(browser.getScreenshotAs(OutputType.FILE), new File(screenNames + screens+".jpg"));
jse.executeScript("window.scrollBy("+ xAxis +", "+yAxis+")");
jse.executeScript("var elems = window.document.getElementsByTagName('*');"
+ " for(i = 0; i < elems.length; i++) { "
+ " var elemStyle = window.getComputedStyle(elems[i], null);"
+ " if(elemStyle.getPropertyValue('position') == 'fixed' && elems[i].innerHTML.length != 0 ){"
+ " elems[i].parentNode.removeChild(elems[i]); "
+ "}}"); // Sticky Content Removes
xAxis += yAxis;
}
driver.quit();
}