123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761 |
- function jQueryEventProxy(debug) {
- this.m_debug = debug;
- }
- jQueryEventProxy.prototype = {
- eventHandler: function(event) {
- try {
- var proxy = event.data.proxy;
- if(proxy.checkIfEventDataContainsHandler(event.data)) {
- proxy.callEventHandler($(this),
- event);
- }
- }
- catch(e) {
- alert("jQueryEventProxy.eventHandler: Event handling malfunctioned: " + e);
- }
- },
- checkIfEventDataContainsHandler: function(data) {
- var contains = false;
- if(data &&
- data.proxy &&
- data.handler &&
- data.handler.that &&
- data.handler.handler) {
- contains = true;
- }
- return contains;
- },
- callEventHandler: function(target,
- event) {
- var handler = event.data.handler;
- try {
- handler.handler.call(handler.that,
- target,
- event);
- }
- catch(e) {
- if(this.m_debug) {
- this.m_debug.error(e);
- alert(e);
- }
- }
- },
- buildEventData: function(handler) {
- var data = { proxy: this,
- handler: handler};
- if(!this.checkIfEventDataContainsHandler(data)) {
- throw "jQueryEventProxy.buildEventData: event handler invalid.";
- }
- return data;
- },
- bind: function(object, eventName, handler) {
- try {
- var eventData = this.buildEventData(handler);
- object.bind(eventName,
- eventData,
- this.eventHandler);
- }
- catch(e) {
- alert("jQueryEventProxy.bind: Couldn't bind event to object because: " + e);
- }
- }
- };
- function DnDHelper() {
- }
- DnDHelper.prototype = {
- disableDragging: function(elements) {
- elements.attr("draggable", false);
- elements.bind("mousedown",
- function(event) {
- event.preventDefault();
- return false;
- });
- }
- };
- function CartoonParser() {
- this.m_callbackObject= undefined;
- }
- CartoonParser.prototype = {
- parseCartoonsFromFeed: function(feed,
- callbackObject) {
- this.m_callbackObject = callbackObject;
- var cartoons = undefined;
- if(feed.status == "ok") {
- cartoons = this.parseCartoons(feed);
- }
- else {
- this.forwardError(feed.URL);
- }
- if(cartoons !== undefined &&
- cartoons.cartoons.length > 0) {
- this.forwardCartoons(cartoons);
- }
- else {
- this.forwardError(feed.URL);
- }
- },
- parseCartoons: function(feed) {
- var cartoons = {URL: feed.URL,
- title: '',
- lastModified: '',
- cartoons: []};
- if(feed &&
- feed.status == "ok") {
- cartoons.lastModified = feed.lastModified;
- cartoons.title = feed.title;
- for(var i =0; i < feed.items.length; i++) {
- var cartoon = this.parseCartoon(feed.items[i]);
- if(cartoon !== undefined) {
- cartoons.cartoons.push(cartoon);
- }
- }
- }
- return cartoons;
- },
- parseCartoon: function(feedItem) {
- var cartoon = undefined;
- var cartoonImage = this.determineTheActualCartoon(feedItem);
- if(cartoonImage.imageURL !== '') {
- cartoon = { title: feedItem.title,
- URL: feedItem.url,
- date: feedItem.date,
- imageURL: cartoonImage.imageURL,
- altText: cartoonImage.altText,
- titleText: cartoonImage.titleText};
- }
- return cartoon;
- },
- determineTheActualCartoon: function(item){
- // Let's check if there are any images in description
- var cartoonImage = {imageURL: '',
- altText: '',
- titleText: ''};
- var images = this.getItemContent(item);
- var imageTag = this.findImageTag(images);
- if(imageTag !== undefined) {
- cartoonImage.imageURL = imageTag.attr("src");
- cartoonImage.altText = imageTag.attr("alt");
- cartoonImage.titleText = imageTag.attr("title");
- }
- if(cartoonImage.imageURL !== '' &&
- item.url.search(/\.(png|jpe?g|gif)/i) != -1) {
- cartoonImage.imageURL = item.url;
- }
- return cartoonImage;
- },
- getItemContent: function(item) {
- var images = $();
- try {
- images = $(item.description, document).filter("img");
- }
- catch(e) { /* Swallow exception */}
- if(images.length === 0) {
- try {
- images = $(item.content, document).find("img");
- }
- catch(e) { /* Swallow exception */}
- }
- if(images.length === 0) {
- try {
- images = $(item.description, document).find("img");
- }
- catch(e) { /* Swallow exception */}
- }
- return images;
- },
- findImageTag: function(images) {
- var imageTag = undefined;
- if(images.length > 0) {
- tempImageTag = $(images.get(0));
- if(tempImageTag.attr("src") !== undefined) {
- imageTag = tempImageTag;
- }
- }
- return imageTag;
- },
- forwardCartoons: function(cartoons) {
- var that = this.m_callbackObject.that;
- var callback = this.m_callbackObject.callback;
- callback.call(that, cartoons);
- },
- forwardError: function(url) {
- var that = this.m_callbackObject.that;
- var callback = this.m_callbackObject.errorCallback;
- callback.call(that, url, "Couldn't find cartoons from this URL. Check internet connectivity.");
- }
- };
- function MaemoHelper(window,
- jQueryEventProxy,
- dndHelper) {
- this.C_IMAGE_URL = "qrc:/images/maemo-task-switcher.png";
- this.m_window = window;
- this.m_jQueryEventProxy = jQueryEventProxy;
- this.m_dndHelper = dndHelper;
- }
- MaemoHelper.prototype = {
- createTaskSwitcher: function(to) {
- var element = this.createTaskSwitcherElement(this.C_IMAGE_URL,
- this.m_window.document);
- var clickHandler = {that: this,
- handler: this.taskSwitcherClicked};
- this.m_jQueryEventProxy.bind(element,
- "click",
- clickHandler);
- this.m_jQueryEventProxy.bind(to,
- "click",
- clickHandler);
- to.prepend(element);
- },
- createTaskSwitcherElement: function(imageURL,
- document) {
- var html = "<button id=\"maemoTaskSwitcher\">" +
- "<img id=\"maemoTaskSwitcherIcon\" src=\"\" />" +
- "</button>";
- var element = $(html, document);
- var image = element.find("#maemoTaskSwitcherIcon");
- this.m_dndHelper.disableDragging(image);
- image.attr("src", imageURL);
- return element;
- },
- taskSwitcherClicked: function(target, event) {
- this.m_window.minimize();
- },
- setFontSizeTo: function(elements, fontSize) {
- elements.css("font-size", fontSize);
- }
- };
- function CartoonSource(url,
- name,
- id,
- active) {
- this.setUrl(url);
- this.setName(name);
- this.setId(id);
- this.setActive(active);
- }
- CartoonSource.prototype = {
- setId: function(id) {
- this.m_id = id;
- },
- getId: function() {
- return this.m_id;
- },
- setUrl: function(url) {
- this.m_url = url;
- },
- getUrl: function() {
- return this.m_url;
- },
- setName: function(name) {
- this.m_name = name;
- },
- getName: function() {
- return this.m_name;
- },
- setActive: function(active) {
- if(!active) {
- active = false;
- }
- if(active === true ||
- active === 1) {
- this.m_active = 1;
- }
- if(active === false ||
- active === 0) {
- this.m_active = 0;
- }
- },
- getActive: function() {
- return this.m_active;
- },
- getActiveBoolean: function() {
- return (this.m_active ? true : false);
- }
- };
- function CartoonSourceResultFiller() {
- }
- CartoonSourceResultFiller.prototype = {
- createCartoonSource: function(row) {
- var cartoonSource = new CartoonSource();
- cartoonSource.setId(row['id']);
- cartoonSource.setUrl(row['url']);
- cartoonSource.setName(row['name']);
- cartoonSource.setActive(row['active']);
- return cartoonSource;
- }
- };
- function CartoonSourceResultAdapter(receiver) {
- this.m_receiver = receiver;
- this.m_cartoonSourceResultFiller = new CartoonSourceResultFiller();
- }
- CartoonSourceResultAdapter.prototype = {
- receiveResults: function(tx, results) {
- var cartoonSources = [];
- for (var i = 0; i < results.rows.length; ++i) {
- var row = results.rows.item(i);
- var cartoonSource = this.m_cartoonSourceResultFiller.createCartoonSource(row);
- cartoonSources.push(cartoonSource);
- }
- this.sendToReceiver(cartoonSources);
- },
- sendToReceiver: function(cartoonSources) {
- this.m_receiver.callback.call(this.m_receiver.that,
- cartoonSources);
- },
- getReceiver: function() {
- var callbackObject = { that: this,
- callback: this.receiveResults};
- return callbackObject;
- }
- };
- function CartoonAdditionAdapter(backend,
- receiver) {
- this.m_backend = backend;
- this.m_receiver = receiver;
- this.m_cartoonSourceResultFiller = new CartoonSourceResultFiller();
- }
- CartoonAdditionAdapter.prototype = {
- receiveIdResult: function(tx,
- results) {
- var id = results.insertId;
- this.m_backend.getCartoonSource(id,
- this.cartoonSourceReceiverCallback());
- },
- receiveCartoonSource: function(tx,
- results) {
- var row = results.rows.item(0);
- var cartoonSource = this.m_cartoonSourceResultFiller.createCartoonSource(row);
- this.sendToReceiver(cartoonSource);
- },
- sendToReceiver: function(cartoonSource) {
- this.m_receiver.callback.call(this.m_receiver.that,
- cartoonSource);
- },
- getReceiver: function() {
- var callbackObject = { that: this,
- callback: this.receiveIdResult};
- return callbackObject;
- },
- cartoonSourceReceiverCallback: function() {
- var callbackObject = { that: this,
- callback: this.receiveCartoonSource};
- return callbackObject;
- }
- };
- function CartoonDataFetcher(feedUpdateBroker,
- cartoonParser,
- feedResolver) {
- this.m_feedUpdateBroker = feedUpdateBroker;
- this.m_cartoonParser = cartoonParser;
- this.m_feedResolver = feedResolver;
- this.m_case = undefined;
- this.C_MAX_WAIT_TIME = 60000;
- }
- CartoonDataFetcher.prototype = {
- abort: function() {
- if(this.m_case !== undefined &&
- "xhr" in this.m_case) {
- this.m_case.xhr.abort();
- }
- },
- getDataFromURL: function(URL,
- receivers,
- feedDiscover) {
- if(feedDiscover === undefined) {
- feedDiscover = true;
- }
- this.m_case = this.createCase(URL,
- receivers,
- feedDiscover);
- this.createXHR(URL);
- },
- createCase: function(URL,
- receivers,
- feedDiscover) {
- var xhr = this.createXHR(this,
- URL,
- this.C_MAX_WAIT_TIME);
- var caseData = { URL: URL,
- receivers: receivers,
- feedDiscover: feedDiscover,
- xhr: xhr.xhr,
- timeoutID: xhr.timeoutID
- };
- return caseData;
- },
- createXHR: function(that,
- URL,
- timeout) {
- var receiver = that;
- var log = console;
- var xhr = new XMLHttpRequest();
- xhr.onreadystatechange = function() {
- log.debug(receiver);
- if(xhr.readyState === 4 &&
- receiver.receiveResponse) {
- receiver.receiveResponse(xhr,
- xhr.statusText);
- }
- };
- xhr.overrideMimeType("text/xml");
- xhr.open("GET", URL, true);
- xhr.send(null);
- var timeoutID = setTimeout(function() {xhr.abort();}, timeout);
- return { timeoutID: timeoutID, xhr: xhr };
- },
- receiveResponse: function(request,
- textStatus) {
- clearTimeout(this.m_case.timeoutID);
- var feedInfos = [];
- this.m_case.status = textStatus;
- if(this.m_case.feedDiscover &&
- this.m_feedResolver !== undefined) {
- feedInfos = this.m_feedResolver.findFeedInfos(request);
- }
- if(feedInfos.length > 0) {
- this.getDataFromURL(feedInfos[0].href,
- this.m_case.receivers,
- false);
- return;
- }
- else if(feedInfos.length == 0 &&
- request.responseXML) {
- this.processFeed(request,
- this.m_case.receivers.cartoonReceiver);
- }
- else {
- this.reportError(this.m_case);
- }
- },
- processFeed: function(request,
- receiver) {
- var feed = this.m_feedUpdateBroker.handleResponse(request,
- request.status,
- request.responseXML);
- this.m_cartoonParser.parseCartoonsFromFeed(feed, receiver);
- },
- reportError: function(errorCase) {
- try {
- var errorReceiver = errorCase.receivers.errorReceiver;
- errorReceiver.callback.call(errorReceiver.that,
- errorCase.URL,
- "Couldn't find cartoons for URL " +
- errorCase.URL +
- "(because of " + errorCase.status +
- ").");
- }
- catch(e) {
- alert("CartoonDataFetcher.reportError: Error callback threw an exception: " + e);
- }
- }
- };
- function FeedResolver() {
- /*
- * https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp
- * <link (whitespace|rel="alternate"|type="application/(atom|rss)+xml"|title="*"|href="*") />
- */
- this.LINK_MATCH_REGEX = /<link(?:\s+|(?:rel=[\"\']alternate[\"\']){1}|(?:(type)=[\"\']application\/(atom|rss)\+xml[\"\']){1}|(?:(title){1}=[\"\']([^<&\"]*)[\"\'])?|(href){1}=[\"\']([^<&\"]*)[\"\'])*\s*\/>/i;
- }
- FeedResolver.prototype = {
- findFeedInfos: function(response) {
- var feedInfos = [];
- if(response.responseXML) {
- feedInfos = this.findFeedInfosFromDOM(response.responseXML);
- }
- if(!response.responseXML &&
- response.responseText) {
- feedInfos = this.findFeedInfosFromText(response.responseText);
- }
- return feedInfos;
- },
- findFeedInfosFromDOM: function(xmlDoc) {
- var feedInfos = [];
- if(xmlDoc.getElementsByTagName("html").length > 0) {
- var elements = xmlDoc.getElementsByTagName("link");
- var baseURL = xmlDoc.baseURI;
- for(var i = 0; i < elements.length; i++) {
- var attributes = { rel: elements[i].rel.toLowerCase(),
- title: elements[i].title,
- type: elements[i].type.toLowerCase()
- .replace(/application\/([a-z]+)\+xml/g,
- "$1"),
- href: elements[i].href};
- if(attributes.rel === 'alternate' &&
- (attributes.type === 'atom' ||
- attributes.type === 'rss') &&
- attributes.href !== '') {
- delete attributes.rel;
- feedInfos.push(attributes);
- }
- }
- }
- return feedInfos;
- },
- findFeedInfosFromText: function(htmlText) {
- var feedInfos = [];
- if(htmlText.search(/<html.*?>/i) != -1) {
- var beforeHead = htmlText.split(/<\/head>/i)[0];
- var textArray = beforeHead.replace(/\/?>/g, "/>\n").split(/\n\r?/);
- for(var i=0; i<textArray.length; i++) {
- var feedInfo = this.findSingleFeedInfoFromText(textArray[i]);
- if(feedInfo) {
- feedInfos.push(feedInfo);
- }
- }
- }
- return feedInfos;
- },
- findSingleFeedInfoFromText: function(text) {
- var matches = this.LINK_MATCH_REGEX.exec(text);
- var feedInfo = undefined;
- if(matches) {
- feedInfo = {};
- for(var i=0; i<matches.length; i++) {
- if(matches[i] !== undefined &&
- (matches[i].toLowerCase() === 'type' ||
- matches[i].toLowerCase() === 'href' ||
- matches[i].toLowerCase() === 'title')) {
- feedInfo[matches[i]] = matches[i+1];
- i = i+2;
- continue;
- }
- }
- }
- return feedInfo;
- }
- };
- function CartoonManagerBackend(db) {
- this.m_db = db;
- this.m_txId = 0;
- this.m_resultReceivers = {};
- this.C_TABLE_NAME = "CartoonReaderSources";
- this.C_DEFAULT_FEED_NAME = "xkcd";
- this.C_DEFAULT_FEED = "http://xkcd.com/atom.xml";
- this.C_CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS " + this.C_TABLE_NAME + " " +
- "(id INTEGER PRIMARY KEY AUTOINCREMENT," +
- " url TEXT, " +
- " name TEXT, " +
- " active INTEGER NOT NULL DEFAULT 0);";
- this.setup();
- }
- CartoonManagerBackend.prototype = {
- setup: function() {
- this.executeSQL(this.C_CREATE_TABLE_SQL,
- [],
- this.getEmptyHandler());
- },
- getEmptyHandler: function() {
- var handler = {that: this,
- callback: this.emptyHandler};
- return handler;
- },
- emptyHandler: function(tx, result) {
- console.log("CartoonManagerBackend.emptyHandler called.");
- },
- registerAddCartoonSourceAdapter: function(adapter) {
- this.m_addCartoonSourceAdapter = adapter;
- },
- registerGetCartoonSourcesAdapter: function(adapter) {
- this.m_getCartoonSourcesAdapter = adapter;
- },
- registerGetCartoonSourceAdapter: function(adapter) {
- this.m_getCartoonSourceAdapter = adapter;
- },
- registerUpdateCartoonSourceAdapter: function(adapter) {
- this.m_updateCartoonSourceAdapter = adapter;
- },
- getCartoonSources: function(receiver) {
- if(receiver === undefined &&
- this.m_getCartoonSourcesAdapter !== undefined) {
- receiver = this.m_getCartoonSourcesAdapter.getReceiver();
- }
- if(receiver === undefined) {
- receiver = this.getEmptyHandler();
- }
- var cartoonSourceSQL = "SELECT * FROM " + this.C_TABLE_NAME + ";";
- this.executeSQL(cartoonSourceSQL,
- [],
- receiver);
- },
- getCartoonSource: function(id,
- receiver) {
- if(receiver === undefined &&
- this.m_getCartoonSourceAdapter !== undefined) {
- receiver = this.m_getCartoonSourceAdapter.getReceiver();
- }
- if(receiver === undefined) {
- receiver = this.getEmptyHandler();
- }
- var cartoonSourceForIdSQL = "SELECT * FROM " + this.C_TABLE_NAME + " " +
- "WHERE id = ?;";
- this.executeSQL(cartoonSourceForIdSQL,
- [id],
- receiver);
- },
- getActiveCartoonSource: function(receiver) {
- if(receiver === undefined &&
- this.m_getCartoonSourceAdapter !== undefined) {
- receiver = this.m_getCartoonSourceAdapter.getReceiver();
- }
- if(receiver === undefined) {
- receiver = this.getEmptyHandler();
- }
- var activeCartoonSourceSQL = "SELECT * FROM " + this.C_TABLE_NAME + " " +
- "WHERE active = 1;";
- this.executeSQL(activeCartoonSourceSQL,
- [],
- receiver);
- },
- addCartoonSource: function(cartoonSource,
- receiver) {
- if(receiver === undefined &&
- this.m_addCartoonSourceAdapter !== undefined) {
- receiver = this.m_addCartoonSourceAdapter.getReceiver();
- }
- if(receiver === undefined) {
- receiver = this.getEmptyHandler();
- }
- var createSQL = "INSERT INTO " + this.C_TABLE_NAME + " " +
- "(url, name, active) VALUES (?, ?, 0);";
- this.executeSQL(createSQL,
- [cartoonSource.getUrl(),
- cartoonSource.getName()],
- receiver);
- },
- receiveModelChanges: function(changes) {
- if("toBeAdded" in changes) {
- this.handleAdded(changes.toBeAdded);
- }
- if("updated" in changes) {
- this.handleUpdated(changes.updated);
- }
- if("removed" in changes) {
- this.handleRemoved(changes.removed);
- }
- },
- handleAdded: function(added) {
- this.addCartoonSource(added.cartoonSource);
- },
- handleUpdated: function(updated) {
- if("cartoonSources" in updated) {
- for(var i = 0; i < updated.cartoonSources.length; i++) {
- this.updateCartoonSource(updated.cartoonSources[i]);
- }
- }
- },
- updateCartoonSource: function(cartoonSource) {
- var receiver = this.getEmptyHandler();
- if(this.m_updateCartoonSourceAdapter !== undefined) {
- receiver = this.m_updateCartoonSourceAdapter.getReceiver();
- }
- var updateSQL = "UPDATE " + this.C_TABLE_NAME + " " +
- "SET url = ?, " +
- "name = ?, " +
- "active = ? " +
- "WHERE id = ?;";
- this.executeSQL(updateSQL,
- [cartoonSource.getUrl(),
- cartoonSource.getName(),
- cartoonSource.getActive(),
- cartoonSource.getId()],
- receiver);
- },
- handleRemoved: function(removed) {
- var removeSQL = "DELETE FROM " + this.C_TABLE_NAME + " "+
- "WHERE id = ?;";
- this.executeSQL(removeSQL,
- [removed.getId()],
- this.getEmptyHandler());
- },
- executeSQL: function(SQL,
- params,
- resultReceiver) {
- var txId = this.m_txId;
- this.m_txId++;
- var self = this;
- this.m_resultReceivers[txId] = resultReceiver;
- this.m_db.transaction(function(tx) {
- tx.txId = txId;
- tx.SQL = SQL;
- tx.executeSql(SQL,
- params,
- function(tx, result) {self.generalResultReceiver(tx, result);},
- function(tx, error) {self.generalErrorReceiver(tx, error);});
- });
- },
- generalResultReceiver: function(tx, result) {
- /** Let's cheat a bit and insert default if none was
- was returned... */
- if(tx.SQL.search(/SELECT/) != -1 &&
- result.rows.length == 0) {
- // Insert default
- var insertDefault = "INSERT INTO " + this.C_TABLE_NAME + " " +
- "(url, name, active) VALUES(?, ?, ?);";
- this.executeSQL(insertDefault,
- [this.C_DEFAULT_FEED, this.C_DEFAULT_FEED_NAME, 1],
- this.getEmptyHandler());
- this.executeSQL(tx.SQL,
- [],
- this.m_resultReceivers[tx.txId]);
- delete this.m_resultReceivers[tx.txId];
- return;
- }
- var receiver = this.m_resultReceivers[tx.txId];
- try {
- receiver.callback.call(receiver.that, tx, result);
- }
- catch(e) {
- alert("CartoonManagerBackend failed to call the result receiver because: " + e);
- }
- },
- generalErrorReceiver: function(tx, error) {
- alert("CartoonManagerBackend received error when trying to execute SQL: " + error.message);
- }
- };
- function ObjectSpiller(recurse) {
- //var m_recursionDepth = 0;
- this.m_recurseOn = recurse;
- }
- ObjectSpiller.prototype = {
- getRecurseOn: function() {
- return this.m_recurseOn;
- },
- setRecurseOn: function(recurseOn) {
- this.m_recurseOn = recurseOn;
- },
- vomit: function(object) {
- for(var name in object) {
- alert(name + " : " + object[name]);
- if(typeof(object[name]) == "object" &&
- this.m_recurseOn) {
- alert("Recursing on " + name);
- this.vomit(object[name]);
- }
- }
- }
- };
|