How to handle a custom URL scheme in Webkit GTK? - webkit

Let's say I want to use a WebKitWebView in GTK to display some static HTML pages. These pages use a custom URL scheme, let's call it custom://. This scheme represents a local file whose location is not known beforehand, at the time the HTML is generated. What I do is connect to the navigation-requested signal of the webview, and do this:
const gchar *uri = webkit_network_request_get_uri(request);
gchar *scheme = g_uri_parse_scheme(uri);
if(strcmp(scheme, "custom") == 0) {
/* DO FILE LOCATING MAGIC HERE */
webkit_web_view_open(webview, real_location_of_file);
return WEBKIT_NAVIGATION_RESPONSE_IGNORE;
}
/* etc. */
This seems to work fine, unless the scheme is used in an <img> tag, for example: <img src="custom://myfile.png">, apparently these don't go through the navigation-requested signal.
It seems to me there should be some way to register a handler for the custom URL scheme with Webkit. Is this possible?

I'm more familiar with the Chromium port of WebKit, but I believe that you might need to use webkit_web_resource_get_uri (see webkitwebresource.h) to handle resources such as images.

In WebKit GTK 2, there is a more official route for this:
WebKitWebContext *context = webkit_web_context_get_default();
webkit_web_context_register_uri_scheme(context, "custom",
(WebKitURISchemeRequestCallback)handle_custom,
NULL, NULL);
/* ... */
static void
handle_custom(WebKitURISchemeRequest *request)
{
/* DO FILE LOCATING MAGIC HERE */
GFile *file = g_file_new_for_path(real_location_of_file);
GFileInputStream *stream = g_file_read(file, NULL, NULL);
g_object_unref(file);
webkit_uri_scheme_request_finish(request, stream, -1, NULL);
g_object_unref(stream);
}

Related

GWT Image Upload empty content

I am trying to implement GWT image upload functionality. I have made the required code change but for some reason upload is not happening. At the server side the image is not being received. So I checked at the client side (browser) the request header and content and then I found that Content-Length: 44 (just 44). Then I realized that the image is not being sent to server on from submission. Please check the below GWT code.
VerticalPanel vp = new VerticalPanel();
vp.add(CommonFormLayoutUtil.createLabel("Upload"));
final FormPanel form = new FormPanel();
form.setAction("CGIImageUpload");
// set form to use the POST method, and multipart MIME encoding.
form.setEncoding(FormPanel.ENCODING_MULTIPART);
form.setMethod(FormPanel.METHOD_POST);
final FileUpload fileUpload = new FileUpload();
Button uploadButton = new Button("Upload");
uploadButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
//get the filename to be uploaded
String filename = fileUpload.getFilename();
if (filename.length() == 0) {
showError("No File Specified!", null);
} else {
//submit the form
form.submit();
}
}
});
vp.add(fileUpload);
vp.add(uploadButton);
form.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() {
#Override
public void onSubmitComplete(SubmitCompleteEvent event) {
// When the form submission is successfully completed, this
//event is fired. Assuming the service returned a response
//of type text/html, we can get the result text here
showError(event.getResults(), null);
}
});
form.add(vp);
Am i missing anything here? Please suggest.
Thanks.
FormPanel states the following:
"This panel can be used to achieve interoperability with servers that accept traditional HTML form encoding. The following widgets (those that implement com.google.gwt.user.client.ui.HasName) will be submitted to the server if they are contained within this panel" (emphasis mine)
You need to set the name of the FileUpload widget otherwise it will not be submitted by the FormPanel.
fileUpload.setName("someName");
Try setting this and it should work

Gecko Engine in ABCPDF not finding tags

Has anyone tried to implement tags using the ABCPDF Gecko engine? I have it working fine on the MSHTML engine (Internet Explorer) as soon as I use Gecko, which is rendering my HTML better, it can't find the tags specified in the HTML.
I'm using style="abcpdf-tag-visible: true;" to specify a tag which works using the default engine.
The following code produces a blank document.
[Test]
public void Tags_With_Gecko()
{
Doc theDoc = new Doc();
theDoc.Rect.Inset(100, 100);
theDoc.Rect.Top = 700;
theDoc.HtmlOptions.Engine = EngineType.Gecko;
// Tag elements with style 'abcpdf-tag-visible: true'
theDoc.HtmlOptions.ForGecko.AddTags = true;
int id = theDoc.AddImageHtml("<FONT id=\"p1\" style=\"abcpdf-tag-visible: true; font-size: 72pt\">Gallia est omnis divisa in partes tres.</FONT>");
// Frame location of the tagged element
XRect[] tagRects = theDoc.HtmlOptions.ForGecko.GetTagRects(id);
foreach (XRect theRect in tagRects)
{
theDoc.Rect.String = theRect.ToString();
theDoc.FrameRect();
}
// Output tag ID
string[] tagIds = theDoc.HtmlOptions.ForGecko.GetTagIDs(id);
theDoc.Rect.String = theDoc.MediaBox.String;
theDoc.Rect.Inset(20, 20);
theDoc.FontSize = 64;
theDoc.Color.String = "255 0 0";
theDoc.AddText("Tag ID \"" + tagIds[0] + "\":");
// Save the document
const string testFilename = #"C:\pdf\HtmlOptionsGetTagRects.pdf";
if (File.Exists(testFilename))
File.Delete(testFilename);
theDoc.Save(testFilename);
theDoc.Clear();
Process.Start(testFilename);
}
Almost identical code for the default engine produces it correctly.
I've been talking to WebSuperGoo support. Found out the documentation isn't consistent/complete.
http://www.websupergoo.com/helppdfnet/source/5-abcpdf/xhtmloptions/2-properties/addtags.htm
In Gecko, your tag has to have a visible impact on the page for it to be picked up. In my case, I had a tag that displayed a non-breaking space, and thus it wasn't found.
From their example, changing the style to the following got it to be findable:
style="abcpdf-tag-visible: true; border: 1px solid transparent"
Note the Border settings is what makes this work apparently.
Again, this fixes their demo and thus should fix Dillorscroft's example.
I have to futz a bit more to fix my problem, as I am trying to allocate blank spaces on the page (for a table of contents) so they can be updated after the html is rendered and I know where the first content page will start.

Are these 2 capabilities supported in Safari extension development?

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';
}
}

How to submit a form in Geb (WebDriver) that has no submit button

I'm building up a test in Geb (WebDriver) that has the need to work with a form that has no submit button. From the user's perspective, it is as simple to use as typing in the search term and hitting the enter key on their keyboard.
Using Geb in a purely script form I can get around this by appending the special key code to the text being typed in, as seen in the following:
import org.openqa.selenium.Keys
$('input[id=myInputField]') << "michael"+Keys.ENTER
That works fine. But if I want to use Geb's recommended Page Object pattern (http://www.gebish.org/manual/0.7.1/pages.html#the_page_object_pattern), I don't see what I should do. What do I define in the content section of my EmployeeSearchPage object to duplicate the missing searchButton and its "to" object reference that tells Geb how to handle the resulting page?
class EmployeeSearchPage extends Page {
static url = "http://localhost:8888/directory/"
static at = { title == "Employee Directory" }
static content = {
searchField { $("input[id=myInputField]") }
// THE FOLLOWING BUTTON DOESN'T EXIST IN MY CASE
searchButton(to: EmployeeListPage) { $("input[value='SUBMIT']") }
}
}
I realize that I could add a submit button to the form that I could for the test and use CSS to position it out of the user's view, but why should I have to adapt the app to the test? Things should work the other way around.
I've been evaluating a lot of web testing frameworks and find that this type of form presents a problem for many of them - at least as far as their documentation is concerned.
Any ideas? Thanks!
You don't need to use js integration to achieve what you want.
You can also define methods on your page class, not only content. You could implement a submit method that would do what you are looking for in the following way:
class EmployeeSearchPage extends Page {
static url = "http://localhost:8888/directory/"
static at = { title == "Employee Directory" }
static content = {
searchField { $("input[id=myInputField]")
}
void submitForm() {
searchField << Keys.ENTER
browser.page EmployeeSearchResultsPage
}
}
and then to use it:
to EmployeeSearchPage
searchField << 'michael' // searchField = 'michael' would have the same effect
submitForm()
Geb provides support to execute JavaScript in the context of the browser, details can be found here in the Geb documentation.
You could use this to submit the form exactly like you would submit it using JavaScript in the webapp itself. For example, if you are using jQuery it would be as simple as:
js.exec('$("#myForm").submit()')

How do you read localsettings variables in default.css file in a windows store app?

I am building a windows store app that has a default css and a default font size in that css. I am allowing the user to customize the font size from settings screen and that preference gets stored in local settings. How do I update my app to reflect the new font size? Are there any current patterns? This is a Html5/js app. Can I simply reload the css value from the change event?
When your app launches, read the font size from local settings and then set the document's font size with JavaScript:
document.body.style.fontSize = fontSizeFromSettings;
When the app is running and the user changes the font size, also call the above line. You could do this right after your code which saves the font size to local settings.
Naturally, you can also change the font size of individual elements using document.getElementById("myId").style.fontSize.
I read this as the OP having a class selector already defined, like
.myclass
{
font-size: 36px;
}
and wanting to modify all elements with the .myclass selector to be a new value, say 72px. If that's the intent, then you can dynamically modify the CSS.
Here's a simple (and fragile, not-suitable-for-production) function that looks for a specific style selector in a known CSS file and modifies it on the fly. You could probably generalize this, take a look at Changing External Stylesheets and How to change CSS Stylesheets with JavaScript for more details.
function updateFontSize(newFontSize) {
for (var i = 0; i < document.styleSheets.length; i++) {
if (document.styleSheets[i].href.indexOf("default.css") >= 0) {
var mySheet = document.styleSheets[i];
for (var r in mySheet.cssRules) {
if (mySheet.cssRules[r].selectorText == ".myclass") {
var myRule = mySheet.cssRules[r];
myRule.style.fontSize = newFontSize;
return;
}
}
}
}
};
Then somewhere you call it like (without hardcoding the value, of course):
updateFontSize("128px");