UIWebView supporting both internal (stays in webview) and external (safari) links - uiwebview

I have an ipad app which acts as an ebook. It's basically a bunch of html pages linked together. I also have some external links which have been opening in the webview, but I now want to open in Safari.
I have implemented this method:
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if(navigationType == UIWebViewNavigationTypeLinkClicked)
{
[[UIApplication sharedApplication] openURL:request.URL];
return NO;
}
else
return YES;
}
Now my external links work and also my archor navigations tags (for some reason):
www.TheFOA.org
Back To Top
But my internal links no longer work:
Table Of Contents
Is there a way that I can change my internal (or external) links to specify one or the other as UIWebViewNavigationTypeOther? And how do I go about doing this? Ideally, if I have change any html, there are a lot less external links.

Related

Add alternate tag to individual pages in liferay

I want to add a meta tag in my each individual page of life ray. I am could only find meta tag with description which is in the SEO of the pages in Control panel.
<link rel="alternate" href="http://example.com/xyz/abc" hreflang="en-au" />
Please help me out with this. I am unable to find an answer to this.
The best and permanent way is to create custom theme (or modify default one) and add general meta-tags, javascript / css files (which you want to appear on each page of portal) through head section of theme's portal_normal.vm file. However, if you want to restrict these tags for specific page(s) you can still do it through Velocity Objects like public / private layout, admin / user difference, current page name / URL, there are numerous options available.
If you are new to theme design, you can start with: Creating Liferay Themes
The other possible and quick way is to add js / css dynamically using javascript / jQuery as following:
if you are using pure javascript:
window.onload = function(){
loadjscssfile("myscript.js", "js");
loadjscssfile("javascript.php", "js");
loadjscssfile("mystyle.css", "css");
}
Or you can use jQuery:
jQuery(function(){
loadjscssfile("myscript.js", "js");
loadjscssfile("javascript.php", "js");
loadjscssfile("mystyle.css", "css");
});
general method:
function loadjscssfile(filename, filetype){
if (filetype=="js"){
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
}
else if (filetype=="css"){
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref);
}
Reference: http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
Add above code to the javascript section of the root of your pages.

UIWebView on iOS 6 does not display images with relative URLs in webarchives

We are using webarchives in our apps sometimes as it is very convenient way to store HTML + all associated images/CSS/scripts/etc inside a single file on the desktop, put it into the project, and then load it into a UIWebView with a single call like that:
NSData *webArchiveData = /* ... Load data from a single file ... */ ;
[webView
loadData:webArchiveData
MIMEType:#"application/x-webarchive"
textEncodingName:#"utf-8"
baseURL:nil
];
This stopped working on iOS 6 however: the HTML is loaded, but images referenced via relative URLs are not displayed anymore.
I traced location.href from a bit of JavaScript within the webarchive and found that on iOS 5 and lower this is the URL of the original HTML that was saved as webarchive. It was serving as a base URL, so relative URLs of resources referenced from the HTML (images, etc.) could be resolved properly and then found within the webarchive (as they are stored there with their original absolute URLs).
On iOS 6 however tracing location.href gives URLs like applewebdata://1B648BC1-F143-4245-A7AD-6424C3E3D227, so all relative URLs are resolved relative to this one and of course cannot be found in the webarchive anymore.
One of the workarounds I found is to pass something different from nil into loadData:MIMEType:textEncodingName:baseURL:, like this:
[webView
loadData:serializedWebArchive
MIMEType:#"application/x-webarchive"
textEncodingName:#"utf-8"
baseURL:[NSURL URLWithString:#"file:///"] // Passing nil here won't work on iOS 6
];
It works on both iOS 6 and iOS 5 and dumping location.href gives the same absolute URL of the original HTML as before.
Any drawbacks/suggestions?

Region-based network links in Google Earth API

I have many large KML data-sets, which are served using a hierarchy of region-based network-links; as described in the KML reference:
Using Regions in conjunction with NetworkLinks, you can create a hierarchy of pointers, each of which points to a specific sub-Region. The <viewRefreshMode>, as shown in the following KML file, has an onRegion option, which specifies to load the Region data only when the Region is active. If you provide nested Regions with multiple levels of detail, larger amounts of data are loaded only when the user's viewpoint triggers the next load.
This works nicely when loaded in Google Earth.
I now wish to load these in an application using the Google Earth plug-in. And I need to access the loaded content via the Google Earth API; (i.e. attach click events, alter styles) to integrate the content into the application.
The issue is, I haven't found any reference to an 'on-load' event for network links. In my mind, the way this would work is:
Load top-level network link via the API, attaching a call-back function which will be invoked when the network-link is loaded.
In the call-back function, parse the KML returned by network link. For intermediate levels in the regionation hierarchy, this KML will contain only network links to the next regionation level. Load these into the plug-in via the API, again specifying the same call-back function, which will be invoked when these are loaded (i.e. when their region becomes visible).
Eventually, the KML returned will contain the actual 'content'. At this stage we load the actual content (i.e. placemarks) into the plug-in, after performing any desired modifications (e.g. attaching event-listeners, setting styles, etc).
I'm thinking the javascript would look something like the following.
Please note: this is just a rough sketch to perhaps aid in understanding my question. I am NOT asking why this code doesn't work.
//create network link
var networkLink = ge.createNetworkLink("");
networkLink.setName("Regionated hierarchy root");
// create a Link object
//the network-links contained in the kml that will be returned in this file
//are region-based; they will only be loaded when the user zooms into the relevant
//region.
var link = ge.createLink("");
link.setHref("http://foo.com/regionatedRoot.kml");
// attach the Link to the NetworkLink
networkLink.setLink(link);
//specify the callback function to be invoked when the network link is loaded
//this is is the part that doesn't actually exist; pure fiction...
networkLink.onLoad = networkLinkLoaded;
// add the NetworkLink feature to Earth
ge.getFeatures().appendChild(networkLink);
// function which will be invoked when a network-link is loaded
// i.e. when its region becomes active
function networkLinkLoaded(kml) {
//parse the kml returned for child network links,
//this will create the network link KmlObject, with a
//region specified on it.
for (childNetworkLink in parseNetworkLinks(kml)) {
//and append them, again hooking up the call-back
childNetworkLink.onLoad = networkLinkLoaded;
ge.getFeatures().appendChild(childNetworkLink);
}
//if the user has zoomed in far enough, then the kml returned will
//contain the actual content (i.e. placemarks).
//parse the kml returned for content (in this case placemarks)
for (placemark in parsePlacemarks(kml)) {
//here we would attach event-listeners to the placemark
ge.getFeatures().appendChild(placemark);
}
}
Is this possible?
Have I taken a wrong turn in my thinking? I believe I have followed recommended practices for managing large KML datasets, but I am unsure how to use these via the API.
Addendum:
As an example of the type of problem I am trying to solve:
Imagine you are building a web application using the Google Earth Plugin, and you want to display a placemark for every set of traffic-lights in the world. The placemarks should only display at an appropriate level-of-detail (e.g. when the camera is at 5km altitude). When a user clicks on a placemark, we want the web app to load statistics for that set of traffic-lights, and display them in a sidebar.
How would you engineer this?
You wouldn't need access to the object data directly to provide the functionality you require. You would handle the data load exactly like you have done, using a hierarchy of region-based network-links.
Then if your usage scenario is like the one you set out in your addendum then you would simply use the target data from the click event to load your statistical data based on the placemarks as required.
For example, you could simply set up a generic mousedown event handler on the window object and then test to see if the target is a placemark. You can add this generic listener before you load any data and it will still be fired when you click on your dynamically loaded placemarks. There is no need to attach individual event-listeners to the placemarks at all.
e.g.
window.google.earth.addEventListener(ge.getWindow(), 'mousedown', onWindowMouseDown);
var onWindowMouseDown = function(event) {
if (event.getTarget().getType() == 'KmlPlacemark') {
// get the placemark that was clicked
var placemark = event.getTarget();
// do something with it, or one of its relative objects...
var document = placemark.getOwnerDocument();
var parent = placemark.getParentNode();
// etc...
}
}
Not sure if this is quite what you want but there is a kmltree api that will:
build out the kml tree for you based on the kml given
allow you to have a 'kmlloaded' event handler
http://code.google.com/p/kmltree/
function initCB(instance){
ge = instance;
ge.getWindow().setVisibility(true);
var gex = gex = new GEarthExtensions(ge);
var tree = kmltree({
url: 'http://foo.com/regionatedRoot.kml',
gex: gex,
mapElement: $('#map3d'),
element: $('#tree'),
});
$(tree).bind('kmlLoaded', function(event, kmlObject){ //do something here });
tree.load();
}
it does require you to bring in another js api but it works pretty good and gives you some good built in functionality.
So far I haven't found anything just from the plug-in that will fire an event when the kml is loaded...
you might be able to try using fetchKml() especially if you are hardcoding that url for the link in there?
google.earth.fetchKml(ge, 'http://foo.com/regionatedRoot.kml', function(kmlObject){
//do logic here
});

How to list and edit html of all web part in sharepoint 2007?

I am new in sharepoint and I have to do a very simple modification in all web part. We have lots of web part containing very simple html. The html only contain a link and an image.
Web developers had put full links to pages and images and it cause some problems. I want to scan all of the web parts html and replace full links by relative links.
Is it possible ? We have tons of pages and links. Doing it manually will take 2 weeks!!!
Thanks!
EDIT #2:
Now the question is: Is it possible to list all aspx files in my website?
I know how to access the web parts content with a url :
using (SPLimitedWebPartManager manager = web.GetLimitedWebPartManager(
"ca/Pages/Home.aspx", PersonalizationScope.Shared))
{
foreach (System.Web.UI.WebControls.WebParts.WebPart wp in manager.WebParts)
{
System.Console.WriteLine(wp.Title);
if (wp.GetType().Equals(typeof(Microsoft.SharePoint.WebPartPages.ContentEditorWebPart)))
{
Microsoft.SharePoint.WebPartPages.ContentEditorWebPart thisWebPart = wp as Microsoft.SharePoint.WebPartPages.ContentEditorWebPart;
System.Console.WriteLine(thisWebPart.Content.InnerText );
System.Console.WriteLine(thisWebPart.Content.InnerXml);
}
}
}
EDIT #1:
As requested their is an example:
I want to remove "http://www.mywebsite.com" from all shared webparts with code like this:
<A title="" href="http://www.mywebsite.com/Pages/Career.aspx" target=""><IMG style="BORDER-RIGHT: 0px solid; BORDER-TOP: 0px solid; BORDER-LEFT: 0px solid; BORDER-BOTTOM: 0px solid" src="http://www.mywebsite.com/images/Career.jpg" border=0></A>
In content editor web part the content is stored under content tag
<Content xmlns="http://schemas.microsoft.com/WebPart/v2/ContentEditor"><![CDATA[<p>test document test document</p>]]></Content>
what i can suggest here is to open the site in sharepoint desginer and use the find and replace option for all pages
I am not sure if I got what's required exactly. What about writing a program that do that? Detect the links by regex and replace them.
If you want to actually change the content in Sharepoint, it could be difficult to do this in code. Every webpart works differently, so there's no standard solution for all web parts. For example, a CQWP can pull data from various lists, so the way to make the change for that webpart would be to change the data in the lists it pulls from. Other webparts might pull data from SQL Server, Reports, have IFrames in them, etc. Some webparts might even have the URLs hardcoded in a custom DLL, which you could only change by modifying the solution/feature that the DLL is a part of and redeploying the updated version.
However, an alternate solution is to write a Response Filter, which will take the output of Sharepoint and dynamically do a find/replace every single time a page is requested from Sharepoint. See http://aspnetresources.com/articles/HttpFilters for more information on how to do that.
Two parts to this, the first is to loop through all web part pages in your site - quite a few examples out there so not going to muddy things by repeating that here.
The second part is to update the Content property and save - seem like this is the missing part of your puzzle for updating the Content Editor Web Part (CEWP) programatically so :-
using System.Xml;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;
private void updateContentEditor(SPWeb web, string pageUrl)
{
using (SPLimitedWebPartManager manager =
web.GetLimitedWebPartManager(pageUrl, PersonalizationScope.Shared))
{
foreach (WebPart wp in manager.WebParts)
{
if (wp.GetType() == typeof(ContentEditorWebPart))
{
ContentEditorWebPart cewp = wp as ContentEditorWebPart;
cewp.Content.InnerXml;
// See http://justgeeks.blogspot.com/2009/02/i-found-to-be-bit-tricky-to-update.html
XmlDocument xmlDoc = new XmlDocument();
XmlElement xmlElement = xmlDoc.CreateElement("MyElement");
// Do you change logic here
xmlElement.InnerText =
contentEditor.Content.InnerText.Replace(BEFORE, AFTER);
// Save changes
contentEditor.Content = xmlElement;
manager.SaveChanges(cewp);
}
}
}
}

By Clicking an html link i want to open that url in browse?

I am opening an html page in web view and By Clicking an html link i want to open the given link in to web browser and my application should close.
implement UIWebView's shouldStartLoadWithRequest delegete method and inside it write
-(BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request
navigationType:(UIWebViewNavigationType)navigationType {
if (navigationType == UIWebViewNavigationTypeLinkClicked) {
[[UIApplication sharedApplication] openURL:[request URL]];
}
}

Resources