itextsharp add annotation to existing pdf c# : Add a link to a pdf application SDK tool html .net asp.net online 14814-part1761

CHAPTER 7
The Past, Present, and Future of Local
Storage for Web Applications
Diving In
Persistent local storage is one of the areas where native client applications have tradi-
tionally held an advantage over web applications. For native applications, the operating
system typically provides an abstraction layer for storing and retrieving application-
specific data like preferences or runtime state. These values may be stored in the reg-
istry, INI files, XML files, or some other place, according to platform convention. If
your native client application needs local storage beyond key/value pairs, you can em-
bed your own database, invent your own file format, or implement any number of other
solutions.
Historically, web applications have had none of these luxuries. Cookies were invented
early in the Web’s history, and indeed they can be used for persistent local storage of
small amounts of data. But they have several potentially dealbreaking downsides:
• Cookies are included with every HTTP request, thereby slowing down your web
application by needlessly transmitting the same data over and over.
• Cookies are included with every HTTP request, thereby sending data unencrypted
over the Internet (unless your entire web application is served over SSL).
• Cookies are limited to about 4 KB of data—enough to slow down your application
(see above), but not enough to be terribly useful.
What we really want is:
• A lot of storage space...
• on the client...
• that persists beyond a page refresh...
• and isn’t transmitted to the server.
127
Download from Library of Wow! eBook <www.wowebook.com>
Add a link to a pdf - insert, remove PDF links in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Free C# example code is offered for users to edit PDF document hyperlink (url), like inserting and deleting
adding hyperlinks to pdf files; add a link to a pdf
Add a link to a pdf - VB.NET PDF url edit library: insert, remove PDF links in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Help to Insert a Hyperlink to Specified PDF Document Page
adding hyperlinks to pdf documents; add hyperlink to pdf in
There have been a number of attempts to achieve this, all ultimately unsatisfactory in
different ways.
A Brief History of Local Storage Hacks Before HTML5
In the beginning, there was only Internet Explorer. Or at least, that’s what Microsoft
wanted the world to think. To that end, during the first of the Great Browser Wars,
Microsoft invented a great many things and included them in its browser-to-end-all-
browser-wars, Internet Explorer. One of these things was called DHTML Behaviors,
and one of these behaviors was called 
userData
.
userData
allows web pages to store up to 64 KB of data per domain, in a hierarchical
XML-based structure. (Trusted domains, such as intranet sites, can store 10 times that
amount. And hey, 640 KB ought to be enough for anybody!) IE does not present any
form of permissions dialog, and there is no allowance for increasing the amount of
storage available.
In 2002, Adobe introduced a feature in Flash 6 that gained the unfortunate and mis-
leading name of “Flash cookies.” Within the Flash environment, the feature is properly
known as Local Shared Objects, or LSOs. Briefly, it allows Flash objects to store up to
100 KB of data per domain. In 2005 Brad Neuberg developed an early prototype of a
Flash-to-JavaScript  bridge  called  the  AJAX  Massive  Storage  System,  or AMASS,
but it was limited by some of Flash’s design quirks. By 2006, with the advent of
ExternalInterface in Flash 8, accessing LSOs from JavaScript became an order of mag-
nitude easier and faster. Brad rewrote AMASS and integrated it into the popular Dojo
Toolkit under the moniker 
dojox.storage
. With this solution, each domain is given the
usual 100 KB of storage “for free.” Beyond that, it prompts the user for each order of
magnitude increase in data storage (1 MB, 10 MB, and so on).
Then, in 2007, Google launched Gears, an open source browser plug-in aimed at pro-
viding additional capabilities in browsers. (We’ve previously discussed Gears in the
context  of  providing  a  geolocation  API  in  Internet  Explorer  (see “What About
IE?” on page 123). Gears provides an API to an embedded SQL database based on
SQLite. After obtaining permission from the user once, Gears can store unlimited
amounts of data per domain in SQL database tables.
In the meantime, Brad Neuberg and others continued to hack away on 
dojox.storage
to provide  a  unified  interface to all  these different  plug-ins  and  APIs. By 2009,
dojox.storage
could autodetect (and provide a unified interface on top of) Adobe Flash,
Gears, Adobe AIR, and an early prototype of HTML5 Storage that was only imple-
mented in older versions of Firefox.
As you survey these solutions, a pattern emerges: all of them are either specific to a
single browser, or reliant on a third-party plug-in. Despite heroic efforts to paper over
the differences (in 
dojox.storage
), they all expose radically different interfaces, have
different storage limitations, and present different user experiences. So this is the
128 | Chapter 7: The Past, Present, and Future of Local Storage for Web Applications
Download from Library of Wow! eBook <www.wowebook.com>
RasterEdge .NET Document Imaging Trial Package Download Link.
Extract; C# Read: PDF Image Extract; C# Write: Insert text into PDF; C# Write: Add Image to PDF; C# Protect: Add Password to PDF; C#
add links to pdf acrobat; convert excel to pdf with hyperlinks
C# PDF Library SDK to view, edit, convert, process PDF file for C#
editing PDF document hyperlink (url) and quick navigation link in PDF bookmark. C#.NET: Edit PDF Metadata. PDF SDK for .NET allows you to read, add, edit, update
add hyperlink pdf file; add links to pdf in acrobat
problem that HTML5 set out to solve: to provide a standardized API, implemented
natively and consistently in multiple browsers, without having to rely on third-party
plug-ins.
Introducing HTML5 Storage
What I refer to as “HTML5 Storage” is actually a specification named Web Storage.
This was at one time part of the HTML5 specification proper, but was split out into its
own specification for uninteresting political reasons. Certain browser vendors also refer
to it as “Local Storage” or “DOM Storage.” The naming situation is made even more
complicated by some related, similarly named, emerging standards that I’ll discuss later
in this chapter.
So what is HTML5 Storage? Simply put, it’s a way for web pages to store named key/
value pairs locally, within the client web browser. Like the data stored in cookies, this
data persists even after you navigate away from the website, close your browser tab,
exit your browser, or what have you. But unlike with cookies, this data is never trans-
mitted to the remote web server (unless you go out of your way to send it manually).
And unlike all previous attempts at providing persistent local storage (described in the
preceding section), it is implemented natively in web browsers, so it is available even
when third-party browser plug-ins are not.
Which browsers? As Table 7-1 shows, HTML5 is supported by the latest versions of
pretty much all browsers...even Internet Explorer!
Table 7-1. HTML5 Storage support
IE
Firefox
Safari
Chrome
Opera
iPhone
Android
8.0+
3.5+
4.0+
4.0+
10.5+
2.0+
2.0+
From your JavaScript code, you’ll access HTML5 Storage through the 
localStorage
object on the global 
window
object. Before you can use it, you should detect whether
the browser supports it (see “Local Storage” on page 21):
function supports_html5_storage() {
return ('localStorage' in window) && window['localStorage'] !== null;
}
Or, instead of writing this function yourself, you can use Modernizr (see “Modernizr:
An HTML5 Detection Library” on page 16) to detect support for HTML5 Storage:
if (Modernizr.localstorage) {
// window.localStorage is available!
} else {
// no native support for HTML5 Storage :(
// maybe try dojox.storage or a third-party solution
}
Introducing HTML5 Storage | 129
Download from Library of Wow! eBook <www.wowebook.com>
C# PDF insert image Library: insert images into PDF in C#.net, ASP
C#.NET PDF SDK - Add Image to PDF Page in C#.NET. How to Insert & Add Image, Picture or Logo on PDF Page Using C#.NET. Add Image to PDF Page Using C#.NET.
adding links to pdf document; pdf link open in new window
VB.NET PDF insert image library: insert images into PDF in vb.net
VB.NET PDF - Add Image to PDF Page in VB.NET. Guide VB.NET Programmers How to Add Images in PDF Document Using XDoc.PDF SDK for VB.NET.
add link to pdf file; check links in pdf
Using HTML5 Storage
HTML5 Storage is based on named key/value pairs. You store data based on a named
key, and then you can retrieve that data with the same key:
interface Storage {
getter any getItem(in DOMString key);
setter creator void setItem(in DOMString key, in any data);
};
The named key is a string. The data can be any type supported by JavaScript, including
strings, Booleans, integers, or floats. However, the data is actually stored as a string. If
you are storing and retrieving anything other than strings, you will need to use functions
like 
parseInt()
or 
parseFloat()
to coerce your retrieved data into the expected Java-
Script datatype.
Calling 
setItem()
with a named key that already exists will silently overwrite the pre-
vious value. Calling 
getItem()
with a nonexistent key will return 
null
rather than
throwing an exception.
Like other JavaScript objects, you can treat the 
localStorage
object as an associative
array. Instead of using the 
getItem()
and 
setItem()
methods, you can simply use square
brackets. For example, this snippet of code:
var foo = localStorage.getItem("bar");
// ...
localStorage.setItem("bar", foo);
could be rewritten to use square-bracket syntax instead:
var foo = localStorage["bar"];
// ...
localStorage["bar"] = foo;
There are also methods for removing the value for a given named key and clearing the
entire storage area (that is, deleting all the keys and values at once):
interface Storage {
deleter void removeItem(in DOMString key);
void clear();
};
Calling 
removeItem()
with a nonexistent key will do nothing.
Finally, there is a property to get the total number of values in the storage area, and to
iterate through all of the keys by index (to get the name of each key):
interface Storage {
readonly attribute unsigned long length;
getter DOMString key(in unsigned long index);
};
If you call 
key()
with an index that is not between 0 and (
length
–1), the function will
return 
null
.
130 | Chapter 7: The Past, Present, and Future of Local Storage for Web Applications
Download from Library of Wow! eBook <www.wowebook.com>
VB.NET PDF Password Library: add, remove, edit PDF file password
VB: Add Password to PDF with Permission Settings Applied. This VB.NET example shows how to add PDF file password with access permission setting.
adding links to pdf in preview; add hyperlinks pdf file
C# PDF Password Library: add, remove, edit PDF file password in C#
C# Sample Code: Add Password to PDF with Permission Settings Applied in C#.NET. This example shows how to add PDF file password with access permission setting.
add url to pdf; adding hyperlinks to a pdf
Tracking Changes to the HTML5 Storage Area
If you want to keep track programmatically of when the storage area changes, you can
trap the 
storage
event. The 
storage
event is fired on the 
window
object whenever
setItem()
removeItem()
, or 
clear()
is called and actually changes something. For ex-
ample, if you set an item to its existing value or call 
clear()
when there are no named
keys, the 
storage
event will not fire because nothing actually changed in the storage
area.
The 
storage
event is supported everywhere the 
localStorage
object is supported,
which  includes  Internet  Explorer  8.  IE  8  does  not  support  the  W3C  standard
addEventListener
(although that will finally be added in IE 9). Therefore, to hook the
storage
event, you’ll need to check which event mechanism the browser supports. (If
you’ve done this before with other events, you can skip to the end of this section.
Trapping the 
storage
event works the same way as trapping any other event. If you
prefer to use jQuery or some other JavaScript library to register your event handlers,
you can do that with the 
storage
event, too.) Here’s how:
if (window.addEventListener) {
window.addEventListener("storage", handle_storage, false);
} else {
window.attachEvent("onstorage", handle_storage);
};
The 
handle_storage()
callback function will be called with a 
StorageEvent
object, ex-
cept in Internet Explorer, where the event object is stored in 
window.event
:
function handle_storage(e) {
if (!e) { e = window.event; }
}
At this point, the variable 
e
will be a 
StorageEvent
object, which has the useful prop-
erties listed in Table 7-2.
Table 7-2. StorageEvent object properties
Property
Type
Description
key
String The named key that was added, removed, or modified
oldValue
Any
The previous value (now overwritten), or 
null
if a new item was added
newValue
Any
The new value, or 
null
if an item was removed
url
a
String
The page that called the method that triggered this change
a
The 
url
property was originally called 
uri
. Some browsers shipped with that property before the specification changed. For maximum
compatibility, you should check whether the 
url
property exists and, if not, check for the 
uri
property instead.
The 
storage
event is not cancelable. From within the 
handle_storage()
callback func-
tion, there is no way to stop the change from occurring. It’s simply a way for the browser
to tell you, “Hey, this just happened. There’s nothing you can do about it now; I just
wanted to let you know.”
Using HTML5 Storage | 131
Download from Library of Wow! eBook <www.wowebook.com>
How to C#: Basic SDK Concept of XDoc.PDF for .NET
You may add PDF document protection functionality into your C# of PDF document, including editing PDF url links and quick navigation link in bookmark
c# read pdf from url; add hyperlinks to pdf
VB.NET PDF: Basic SDK Concept of XDoc.PDF
You may add PDF document protection functionality into your VB.NET of PDF document, including editing PDF url links and quick navigation link in bookmark
add a link to a pdf in acrobat; adding a link to a pdf in preview
Limitations in Current Browsers
In talking about the history of local storage hacks using third-party plug-ins (see “A
Brief History of Local Storage Hacks Before HTML5” on page 128), I made a point of
mentioning the limitations of each technique, such as storage limits. However, I haven’t
mentioned anything about the limitations of the now-standardized HTML5 Storage.
By default, each origin gets 5 MB of storage space. This is surprisingly consistent across
browsers, although it is phrased as no more than a suggestion in the HTML5 Storage
specification. One thing to keep in mind is that you’re storing strings, not data in its
original format. If you’re storing a lot of integers or floats, the difference in represen-
tation can really add up: each digit in that float is being stored as a character, not in the
usual representation of a floating-point number.
If you exceed your storage quota, a 
QUOTA_EXCEEDED_ERR
exception will be thrown. “No”
is the answer to the next obvious question, “Can I ask the user for more storage space?”
At the time of writing, no browser supports any mechanism for web developers to
request more storage space. Some browsers, such as Opera, allow the user to control
each site’s storage quota, but it is purely a user-initiated action, not something that you
as a web developer can build into your web application.
HTML5 Storage in Action
Let’s look at an example of HTML5 Storage in action. Think back to the Halma game
we constructed in Chapter 4 (see “A Complete Example” on page 75). There’s a small
problem with the game: if you close the browser window mid-game, you’ll lose your
progress. But with HTML5 Storage, we can save the progress locally, within the browser
itself. You can see a live demonstration at http://diveintohtml5.org/examples/localstor
age-halma.html. Make a few moves, close the browser tab, and then reopen it. If your
browser supports HTML5 Storage, the demonstration page should magically remem-
ber your exact position within the game, including the number of moves you’ve made,
the positions of each of the pieces on the board, and even whether a particular piece is
selected.
How does it work? Every time a change occurs within the game, we call this function:
function saveGameState() {
if (!supportsLocalStorage()) { return false; }
localStorage["halma.game.in.progress"] = gGameInProgress;
for (var i = 0; i < kNumPieces; i++) {
localStorage["halma.piece." + i + ".row"] = gPieces[i].row;
localStorage["halma.piece." + i + ".column"] = gPieces[i].column;
}
localStorage["halma.selectedpiece"] = gSelectedPieceIndex;
localStorage["halma.selectedpiecehasmoved"] gSelectedPieceHasMoved;
localStorage["halma.movecount"] = gMoveCount;
return true;
}
132 | Chapter 7: The Past, Present, and Future of Local Storage for Web Applications
Download from Library of Wow! eBook <www.wowebook.com>
As you can see, it uses the 
localStorage
object to save whether there is a game in
progress (
gGameInProgress
, a Boolean). If so, it iterates through the pieces (
gPieces
, a
JavaScript 
Array
) and saves the row and column number of each piece. Then it saves
some additional game state, including which piece is selected (
gSelectedPieceIndex
,
an integer), whether the piece is in the middle of a potentially long series of hops
(
gSelectedPieceHasMoved
, a Boolean), and the total number of moves made so far
(
gMoveCount
, an integer).
On page load, instead of automatically calling a 
newGame()
function that would reset
these variables to hardcoded values, we call a 
resumeGame()
function. Using HTML5
Storage, the 
resumeGame()
function checks whether any state about a game in progress
is stored locally. If so, it restores those values using the 
localStorage
object:
function resumeGame() {
if (!supportsLocalStorage()) { return false; }
gGameInProgress = (localStorage["halma.game.in.progress"] == "true");
if (!gGameInProgress) { return false; }
gPieces = new Array(kNumPieces);
for (var i = 0; i < kNumPieces; i++) {
var row = parseInt(localStorage["halma.piece." + i + ".row"]);
var column = parseInt(localStorage["halma.piece." + i + ".column"]);
gPieces[i] = new Cell(row, column);
}
gNumPieces = kNumPieces;
gSelectedPieceIndex = parseInt(localStorage["halma.selectedpiece"]);
gSelectedPieceHasMoved = localStorage["halma.selectedpiecehasmoved"] == "true";
gMoveCount = parseInt(localStorage["halma.movecount"]);
drawBoard();
return true;
}
The most important part of this function is the caveat that I mentioned earlier in this
chapter, which I’ll repeat here: Data is stored as strings. If you are storing something
other than a string, you’ll need to coerce it yourself when you retrieve it. For example,
the flag for whether there is a game in progress (
gGameInProgress
) is a Boolean. In the
saveGameState()
function, we just stored it and didn’t worry about the datatype:
localStorage["halma.game.in.progress"] = gGameInProgress;
But in the 
resumeGame()
function, we need to treat the value we got from the local storage
area as a string and manually construct the proper Boolean value ourselves:
gGameInProgress = (localStorage["halma.game.in.progress"] == "true");
Similarly,  the  number  of  moves  is  stored  in 
gMoveCount
as  an  integer.  In  the
saveGameState()
function, we just stored it:
localStorage["halma.movecount"] = gMoveCount;
But in the 
resumeGame()
function, we need to coerce the value to an integer, using the
parseInt()
function built into JavaScript:
gMoveCount = parseInt(localStorage["halma.movecount"]);
HTML5 Storage in Action | 133
Download from Library of Wow! eBook <www.wowebook.com>
Beyond Named Key/Value Pairs: Competing Visions
While the past is littered with hacks and workarounds (see “A Brief History of Local
Storage Hacks Before HTML5” on page 128), the present condition of HTML5 Storage
is surprisingly rosy. A new API has been standardized and implemented across all major
browsers, platforms, and devices. As a web developer, that’s just not something you
see every day, is it? But there is more to life than 5 MB of named key/value pairs, and
the future of persistent local storage is...how shall I put it? Well, there are a number of
competing visions.
One vision is an acronym that you probably know already: SQL. In 2007, Google
launched Gears, an open source cross-browser plug-in that included an embedded da-
tabase based on SQLite. This early prototype later influenced the creation of the Web
SQL Database specification. Web SQL Database (formerly known as “WebDB”) pro-
vides a thin wrapper around a SQL database, allowing you to do things like this from
JavaScript:
openDatabase('documents', '1.0', 'Local document storage', 5*1024*1024, 
function (db) {
db.changeVersion('', '1.0', function (t) {
t.executeSql('CREATE TABLE docids (id, name)');
}, error);
});
As you can see, most of the action resides in the string you pass to the 
executeSql()
method. This string can be any supported SQL statement, including 
SELECT
UPDATE
,
INSERT
, and 
DELETE
. It’s just like backend database programming, except you’re doing
it from JavaScript! Oh joy!
Table  7-3 shows which browsers have implemented the Web SQL Database
specification.
Table 7-3. Web SQL Database support
IE
Firefox
Safari
Chrome
Opera
iPhone
Android
·
·
4.0+
4.0+
10.5+
3.0+
·
Of course, if you’ve used more than one database product in your life, you are aware
that “SQL” is more of a marketing term than a hard-and-fast standard. (Some would
say the  same of  “HTML5,”  but never mind  that.)  Sure, there is  an  actual  SQL
specification—it’s called SQL-92—but there is no database server in the world that
conforms to that and only that specification. There’s Oracle’s SQL, Microsoft’s SQL,
MySQL’s SQL, PostgreSQL’s SQL, and SQLite’s SQL. And each of these products adds
new SQL features over time, so even saying “SQLite’s SQL” is not sufficient to pin
down exactly what you’re talking about—you need to say “the version of SQL that
shipped with SQLite Version X.Y.Z.”
134 | Chapter 7: The Past, Present, and Future of Local Storage for Web Applications
Download from Library of Wow! eBook <www.wowebook.com>
All of which brings us to the following disclaimer, currently residing at the top of the
Web SQL Database specification:
This specification has reached an impasse: all interested implementors have used the
same SQL backend (Sqlite), but we need multiple independent implementations to pro-
ceed along a standardisation path. Until another implementor is interested in imple-
menting this spec, the description of the SQL dialect has been left as simply a reference
to Sqlite, which isn’t acceptable for a standard.
It is against this backdrop that I will introduce you to another competing vision for
advanced, persistent, local storage for web applications: the Indexed Database API,
formerly known as “WebSimpleDB,” now affectionately known as “IndexedDB.”
The Indexed Database API exposes what’s called an object store. An object store shares
many concepts with a SQL database. There are “databases” with “records,” and each
record has a set number of “fields.” Each field has a specific datatype, which is defined
when the database is created. You can select a subset of records, then enumerate them
with a “cursor.” Changes to the object store are handled within “transactions.”
If you’ve done any SQL database programming, these terms probably sound familiar.
The primary difference is that the object store has no structured query language. You
don’t construct a statement like 
"SELECT * from USERS where ACTIVE = 'Y'"
. Instead,
you use methods provided by the object store to open a cursor on the database named
USERS
, enumerate through the records, filter out records for inactive users, and use
accessor methods to get the values of each field in the remaining records. The early
walk-through of IndexedDB is a good tutorial on how IndexedDB works, giving side-
by-side comparisons of IndexedDB and Web SQL Database.
At the time of writing, IndexedDB hasn’t been implemented in any major browser. In
early June 2010, Mozilla said that it would “have some test builds in the next few
weeks”, but there is no word yet on whether it will even ship in Firefox 4. (By contrast,
Mozilla has stated that it will never implement Web SQL Database.) Google has stated
that it is considering IndexedDB support, and even Microsoft has said that IndexedDB
“is a great solution for the Web”.
So what can you, as a web developer, do with IndexedDB? At the moment, absolutely
nothing. A year from now? Maybe something. Check the “Further Reading” section
for links to some good tutorials to get you started.
Further Reading
HTML5 Storage:
• HTML5 Storage specification
• “Introduction to DOM Storage” on MSDN
• “Web Storage: easier, more powerful client-side data storage”, by Shwetank Dixit
Further Reading | 135
Download from Library of Wow! eBook <www.wowebook.com>
• “Introduction to DOM Storage” on the Mozilla Developer Center. (Note: most of
this page is devoted to Firefox’s prototype implementation of a 
globalStorage
ob-
ject, a nonstandard precursor to 
localStorage
. Mozilla added support for the
standard 
localStorage
interface in Firefox 3.5.)
• “Unlock local storage for mobile Web applications with HTML 5”, a tutorial on
IBM DeveloperWorks
Early work by Brad Neuberg et al. (pre-HTML5):
• “Internet Explorer Has Native Support for Persistence?!?!”, about the 
userData
object in IE
• Dojo Storage, part of a larger tutorial about the (now-defunct) Dojo Offline library
dojox.storage.manager
API reference
dojox.storage
Subversion repository
Web SQL Database:
• Web SQL Database specification
• “Introducing Web SQL Databases”, by Remy Sharp
• Web Database demonstration
• persistence.js, an “asynchronous JavaScript ORM” built on top of Web SQL Da-
tabase and Gears
IndexedDB:
• Indexed Database API specification
• “Beyond HTML5: Database APIs and the Road to IndexedDB”, by Arun Ranga-
nathan and Shawn Wilsher
• “Firefox 4: An early walk-through of IndexedDB”, by Arun Ranganathan
136 | Chapter 7: The Past, Present, and Future of Local Storage for Web Applications
Download from Library of Wow! eBook <www.wowebook.com>
Documents you may be interested
Documents you may be interested