diff -r f3521a11d878 -r 918767a9c8d3 Wikipedia/Wiki.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Wikipedia/Wiki.js Tue Mar 09 10:34:58 2010 +0000 @@ -0,0 +1,632 @@ +// //////////////////////////////////////////////////////////////////////////// +// Symbian Foundation Example Code +// +// This software is in the public domain. No copyright is claimed, and you +// may use it for any purpose without license from the Symbian Foundation. +// No warranty for any purpose is expressed or implied by the authors or +// the Symbian Foundation. +// //////////////////////////////////////////////////////////////////////////// + + +var baseUrl = "http://en.wikipedia.org"; + +var wikiSearchBaseUrl = "/w/api.php?format=xml&action=query&list=search&srsearch="; +var wikiSearchOffsetQueryPart = "&sroffset="; +var wikiSearchLimitQueryPart = "&srlimit="; +var wikiSearchWhatQueryPart = "&srwhat="; + +var wikiViewPageUrlBase = baseUrl + "/w/index.php?title="; +var wikiPrintableParam = "&printable=yes"; + +var MENU_ITEM_READER_SEARCH = 1; +var MENU_ITEM_HISTORY_CLEAR = 1; +var MENU_ITEM_BOOKMARKS_CLEAR = 1; +var MENU_ITEM_MAIN_BACK = 4; +var MENU_ITEM_MAIN_NEXT = 5; +var MENU_ITEM_MAIN_ADD_BOOKMARK = 6; +var MENU_ITEM_MAIN_NAVIGATION = 7; +var MENU_ITEM_MAIN_SEARCH = 8; +var MENU_ITEM_MAIN_BOOKMARKS = 9; +var MENU_ITEM_MAIN_HISTORY = 10; +var MENU_ITEM_MAIN_LANGUAGE =11; +var MENU_ITEM_MAIN_UPDATES =12; +var MENU_ITEM_MAIN_HELP = 13; + +var PREDICTIVE_RESULT_COUNT = 0; + +//var wapediaArticleBase = "http://wapedia.mobi/en/"; + + +//var wikiListCategoriesUrl = symbianOrgBaseUrl + "/wiki/api.php?format=xml&action=query&list=allcategories&aclimit=500&acprop=size"; +//var wikiWatchListUrl = "http://en.wikipedia.org/w/api.php?action=query&list=watchlist&wlallrev&wlprop=ids|title|timestamp|user|comment"; +//var wikiWatchListFeed = "/wiki/api.php?action=feedwatchlist&feedformat=rss"; + +var wikiSearchOptions = [ + { value: "title", text: "Search in title only" }, + { value: "text", text: "Full text search" }, +]; + +function WikiHome () { + RssReader.prototype.init.call(this,"Wikipedia", null /*url*/, new WikiFeedPresenter(null), null, wikiResponseParser); + + this.wikiSearchButton = new FormButton(null, "Search"); + this.wikiSearchString = new TextField('wikiSearchString', null, ""); + + var bookmarksButton = new NavigationButton(null, "next.png", "Bookmarks"); + var historyButton = new NavigationButton(null, "next.png", "History"); + var languageButton = new NavigationButton(null, "next.png", "Language"); + + var self = this; + bookmarksButton.addEventListener("ActionPerformed", function(){wikiBookmarksView.previousView = self; wikiBookmarksView.show();}); + historyButton.addEventListener("ActionPerformed", function(){wikiHistoryView.previousView = self; wikiHistoryView.show();}); + languageButton.addEventListener("ActionPerformed", function(){languageSelectView.previousView = self; languageSelectView.show();}); + +// this.wikiSearchString.addEventListener("KeyPressed", function(){self.predictiveSearch(0);}); + this.wikiSearchButton.addEventListener("ActionPerformed", function(){self.search(0);}); + + this.addControl(new Label(null, "Search Wiki", null)); + this.addControl(this.wikiSearchString); + this.addControl(this.wikiSearchButton); + this.addControl(bookmarksButton); + this.addControl(historyButton); + this.addControl(languageButton); + k.known(); +} + + +WikiHome.prototype = new RssReader(); +WikiHome.prototype.wikiMainPageButton = null; +WikiHome.prototype.wikiSearchButton = null; +WikiHome.prototype.wikiSearchString = null; +WikiHome.prototype.wikiSearchSelection = null; +WikiHome.prototype.predictiveTimer = null; + +var lastWikiSearchWasFrom = 0; +var lastWikiSearchResultCountWas = 0; + +WikiHome.prototype.search = function(from) { + try { + lastWikiSearchWasFrom = from; + var srstring = this.wikiSearchString.getText(); + var url = this.formSearchUrl(srstring, from, resultsPerPage); + var reader = new RssReader("Wiki: " + srstring, url, new WikiFeedPresenter(null), this, wikiResponseParser); + reader.show(); + }catch (X) { alert(X);} +} + +WikiHome.prototype.predictiveSearch = function(from){ + if ( this.predictiveTimer != null ) { + clearInterval(this.predictiveTimer); + } + var self = this; + this.predictiveTimer = setInterval(function() {self.doPredictiveSearch(from), 1000}); +} + +WikiHome.prototype.doPredictiveSearch = function(from) { + if ( this.feedUpdateBroker != undefined && this.feedUpdateBroker != null ) { + this.feedUpdateBroker.cancel(); + } + lastWikiSearchWasFrom = from; + var srstring = this.wikiSearchString.getText(); + if (srstring.length <= 1) { + return; + } + var url = this.formSearchUrl( srstring , from, resultsPerPage ); + this.feedURL = url; + this.update(true, false); +} + + +WikiHome.prototype.formSearchUrl = function(query, offset, limit) { + var buf = baseUrl + wikiSearchBaseUrl + query + if (offset > 0) { + buf += wikiSearchOffsetQueryPart + offset; + } + buf += wikiSearchLimitQueryPart + limit; + return buf; +} + +// abstract function for updating per-view menu +// only called if window.widget is defined +WikiHome.prototype.setupMenu = function(){ + if ( window.widget ) { + menu.clear(); + var self = this; + var searchMenuItem = new MenuItem("Search", MENU_ITEM_MAIN_SEARCH); + searchMenuItem.onSelect = function(){wikiHomeView.show();}; + menu.append(searchMenuItem); + var historyMenuItem = new MenuItem("History", MENU_ITEM_MAIN_HISTORY); + historyMenuItem.onSelect = function(){wikiHistoryView.previousView = self; wikiHistoryView.show();}; + menu.append(historyMenuItem); + var bookmarksMenuItem = new MenuItem("Bookmarks", MENU_ITEM_MAIN_BOOKMARKS); + bookmarksMenuItem.onSelect = function(){wikiBookmarksView.previousView = self; wikiBookmarksView.show();}; + menu.append(bookmarksMenuItem); + + addHelpMenuItems(); + } +} + +WikiHome.prototype.focusFirst = function(){ + // don't change focus - this is predictive search so stick with text field +} + +WikiHome.prototype.show = function(){ + View.prototype.show.call(this); + if (window.widget) { + widget.setNavigationEnabled(true); + } +} + + +// force right soft key to display "Exit" command +//WikiHome.prototype.setupSoftKeys = function() { +// if (window.widget) { +// alert("WikiHome.prototype.setupSoftKeys"); +// menu.setRightSoftkeyLabel(); +// } +//} + + +// ////////////////////////////////////////////////////////////// +// Article view +function WikiListView(caption){ + ListView.prototype.init.call(this, null, null); + caption = uniDecode(caption); // can be encoded unicode + var caption = new NavigationButton(1, "titlebar.png", shorten(caption, 30), true); + caption.addEventListener("ActionPerformed", function(){wikiHomeView.show();}); + this.addControl(caption); + this.useHistoryForBackButton = 1; // used internally to identify the type +} + +WikiListView.prototype = new ListView(null,null); + + +WikiListView.prototype.setupMenu = function () { + if ( window.widget ) { + menu.clear(); + var self = this; + + var searchMenuItem = new MenuItem("Search", MENU_ITEM_READER_SEARCH); + searchMenuItem.onSelect = function(){wikiHomeView.show();}; + menu.append(searchMenuItem); + + var bookmarkMenuItem = new MenuItem("Add bookmark", MENU_ITEM_MAIN_ADD_BOOKMARK); + bookmarkMenuItem.onSelect = function(){wikiBookmarksView.addItem(pageBeingShown, pageBeingShownContent, pageBeingShownBase);}; + menu.append(bookmarkMenuItem); + + var backMenuItem = new MenuItem("Back", MENU_ITEM_MAIN_BACK); + backMenuItem.onSelect = function(){self.goBack();}; + menu.append(backMenuItem); + + if (wikiHistoryView.hasNext()) { + var forwardMenuItem = new MenuItem("Forward", MENU_ITEM_MAIN_NEXT); + forwardMenuItem.onSelect = function(){wikiHistoryView.go(1);}; + menu.append(forwardMenuItem); + } + + var historyMenuItem = new MenuItem("History", MENU_ITEM_MAIN_HISTORY); + historyMenuItem.onSelect = function(){wikiHistoryView.previousView = self; wikiHistoryView.show();}; + menu.append(historyMenuItem); + + var bookmarksMenuItem = new MenuItem("Bookmarks", MENU_ITEM_MAIN_BOOKMARKS); + bookmarksMenuItem.onSelect = function(){wikiBookmarksView.previousView = self; wikiBookmarksView.show();}; + menu.append(bookmarksMenuItem); + + addHelpMenuItems(); + + } + +} + +WikiListView.prototype.show = function(){ + View.prototype.show.call(this); + if (window.widget) { + widget.setNavigationEnabled(true); + } +} + +WikiListView.prototype.setupPreviousView = function() { + if ( uiManager.currentView.useHistoryForBackButton != undefined ) { + this.useHistoryForBackButton = true; + // this signals to uiManager that we want a back button. + // actual value is not used because useHistoryForBackButton = true + this.previousView = wikiHistoryView; + } else { + this.useHistoryForBackButton = false; + this.previousView = uiManager.currentView; + } +} + +WikiListView.prototype.goBack = function() { + if (this.useHistoryForBackButton) { + wikiHistoryView.go(-1); + } else { + View.prototype.goBack.call(this); + } +} + + +// ///////////////////////////////////////////////////////////////////////////// +// RssReader customisations + +// response parser for forum groups +function wikiResponseParser(broker, responseStatus, xmlDoc) { + if (responseStatus == 200 && xmlDoc != null) { + // for compatibility with rss + var lastModified = new Date(); + + // init result items array + var items = []; + + var elements = xmlDoc.getElementsByTagName("p"); + + for (var i = 0; i < elements.length; i++) { + var pagetitle = elements[i].getAttribute("title"); + items.push({ id: ""+i, title: pagetitle}); + } + + lastWikiSearchResultCountWas = elements.length; + // update was completed successfully + return { status: "ok", lastModified: lastModified, items: items }; + } else { + // update failed + return { status: "error" }; + } +} + + + +// //////////////////////////////////////////////////////////////////////////// +// FeedPresenter implementation for full search results view +function WikiFeedPresenter(rssreader){ + if (rssreader) { + this.init(rssreader); + } +} + +// WikiFeedPresenter is a subclass of ButtonFeedPresenter +WikiFeedPresenter.prototype = new ButtonFeedPresenter(null); + +// WikiFeedPresenter "Constructor" +WikiFeedPresenter.prototype.init = function(rssreader) { + ButtonFeedPresenter.prototype.init.call(this, rssreader); +} + +// Handle the click on a specific item +WikiFeedPresenter.prototype.feedClicked = function(event){ + var buttonid = event.source.id; + + if (buttonid == "Next page") { + wikiHomeView.search(lastWikiSearchWasFrom + resultsPerPage); + } + else if (buttonid == "Previous page") { + var from = lastWikiSearchWasFrom - resultsPerPage; + if ( from < 0 ) from = 0; + wikiHomeView.search(from); + } + else { + // show article + var title = this.items[buttonid].title; + wikiBrowse(title); + } +} + +// Create and add controls to be shown before items list. +WikiFeedPresenter.prototype.addFooterItems = function(){ + var self = this; + if (lastWikiSearchResultCountWas == resultsPerPage) { + var nextPageButton = new NavigationButton("Next page", "next.png", "Next page"); + nextPageButton.addEventListener("ActionPerformed", function(event){ self.feedClicked(event); }); + this.rssreader.addFeedItemControl(nextPageButton); + } + if (lastWikiSearchWasFrom > 0) { + var prevPageButton = new NavigationButton("Previous page", "prev.png", "Previous page"); + prevPageButton.addEventListener("ActionPerformed", function(event) { self.feedClicked(event); }); + this.rssreader.addFeedItemControl(prevPageButton); + } +} + + +// ///////////////////////////////////////////////////////////////////////////////// +// Browse / view wiki pages in 'printable format' +var wikiAjax; +var pageBeingShown; +var pageBeingShownBase; +var pageBeingShownContent; +var gDontAddToHistory; +var wikiBrowseCancelled = false; +var gViewCache = new ViewCache(10); + +function wikiBrowse(page, dontAddToHistory, baseUrl) { + pageBeingShown = page; + if ( baseUrl != undefined && baseUrl != null ){ + pageBeingShownBase = baseUrl; + } else { + pageBeingShownBase = wikiViewPageUrlBase; + } + //alert("page=" + pageBeingShown + ", baseUrl=" + pageBeingShownBase); + if ( dontAddToHistory != undefined || dontAddToHistory == true) { + gDontAddToHistory = true; + } else { + gDontAddToHistory = false; + } + wikiBrowseCancelled = false; + var t = page.replace(/_/g, ' '); + var v = gViewCache.getView(t); + if ( v != undefined && v != null ) { + v.setupPreviousView(); + v.show(); + return; + } + try { + pageBeingShownContent = null; + uiManager.showNotification(-1, "wait", "Loading page...", -1); + if (page) { + + wikiAjax = new Ajax(); + + wikiAjax.onreadystatechange = function(){ + wikiPageDownloadStateChanged(); + }; + + // var url = wikiViewPageUrlBase + encodeURIComponent(page) + wikiPrintableParam; + var url = pageBeingShownBase + encodeURIComponent(page) + wikiPrintableParam; + //alert("url: " + url); + // var url = wapediaArticleBase + page + // initiate the request + wikiAjax.open("GET", url, true); + wikiAjax.send(null); + + if (window.widget) { + menu.setRightSoftkeyLabel("Cancel", function(){ + wikiBrowseCancel(); + }); + } + + } + } catch(xx) { alert(xx);} +} + +function wikiBrowseCancel() { + wikiBrowseCancelled = true; + wikiAjax.abort(); +} + +function wikiPageDownloadStateChanged() { + if ( wikiBrowseCancelled ) { + return; + } + if (wikiAjax.readyState == 4) { + uiManager.hideNotification(); + try { + showWikiPage(pageBeingShown, wikiAjax.responseText); + }catch(xx) { alert(xx);} + } +} + +function showWikiPage(title, html){ + // ensure no underscores + title = title.replace(/_/g, ' '); + title = uniDecode(title); + pageBeingShown = title; + pageBeingShownContent = html; + if (false == gDontAddToHistory) { + wikiHistoryView.addItem(title, html, pageBeingShownBase); + } + var start = html.indexOf('
'); + var end = findDivEnd(html, start); + var pageView = new WikiListView(pageBeingShown); + var text = html.substring(start, end); +// text = stripExtStyle(text); +// text = modWikiBox(text, 'class="box"'); +// text = modWikiBox(text, 'class="vertical-navbox'); +// text = modWikiBox(text, 'class="infobox"'); + text = stripStylesFromTag(text, "table", "box"); + text = stripStylesFromTag(text, "table", "infobox"); + text = stripStylesFromTag(text, "table", "navbox"); + text = stripStylesFromTag(text, "table", "vertical-navbox"); + text = stripStylesFromTag(text, "div", "thumbinner"); + // replace inline float: right; + text = text.replace(/float: right|float:right/g, "clear:both; width: 95%; display:block"); + text = text.replace(/clear:right|clear: right/g, ""); + text = modWikiLinks(text); + + var docModel = ParseIntoDocModel(text); + var preamble = new ContentPanel(null, "Overview", docModel.preface, true, true); + pageView.addControl(preamble); + for (var i = 0; i < docModel.sections.length; i++) { + if ( docModel.sections[i].caption == "Contents" ) { + continue; + } + var control = new ContentPanel( + null, + docModel.sections[i].caption, + docModel.sections[i].content, + true, false); // foldable & expanded + pageView.addControl(control); + } + pageView.setupPreviousView(); + gViewCache.addView(title,pageView); + pageView.show(); +} + +// /////////////////////////////////////////////////////////////////////// +// Parsing and modding HTML to fit + +function modWikiLinks(text) { +// var tmp = text;//.replace(/ src="/g, ' src="http://www.wikipedia.org'); + // images sorted. now links + var tmp = text.replace(/65em/g, '100%'); + var strToLookFor = ' href="/wiki/'; //index.php/'; + +// var tmp = text.replace(/ src="/g, ' src="http://wapedia.mobi'); +// // images sorted. now links +// var strToLookFor = ' href="/en/'; + + var from = 0; + var ind = tmp.indexOf(strToLookFor); + var buf =""; + while ( ind > 0 ) { + buf = buf + tmp.substring(from, ind); + // extract page name + var ind2 = tmp.indexOf('"', ind + strToLookFor.length); + var pageName = tmp.substring(ind + strToLookFor.length, ind2); + buf += " style=\"text-decoration: underline;\"" + buf += " href=\"JavaScript:void(0)\""; + buf += " onclick=\"event.stopPropagation();wikiBrowse(uniDecode('" + pageName.replace(/'/g, "\'") + "')); return false;\""; + from = ind2; + ind = tmp.indexOf(strToLookFor, from); + } + buf = buf + tmp.substring(from); + return buf; +} + +function stripExtStyle(text) { + var ret = text.replace(/style=\".+?\"/g, ""); + return ret; +} + +function stripStylesFromTag(text, tag, style) { + var key = "<" + tag + " "; + var ind = text.indexOf(key); + if ( ind == -1 ) return text; + var buf = ""; + var prevind = 0; + while(ind != -1 ) { + var ind2 = text.indexOf(">", ind); + if ( ind2 == -1 ) { + // something's wrong, return unedited + return text; + } + var tag = text.substring(ind, ind2+1); + if ( style != undefined ) { + if ( tag.indexOf(style) != -1 ) { + tag = stripExtStyle(tag); + } + } else { + tag = stripExtStyle(tag); + } + buf += text.substring(prevind, ind); + buf += tag; + prevind = ind2+1; + ind = text.indexOf(key, prevind ); + } + buf += text.substring(prevind); + return buf; +} + +function findDivEnd(text, from) { + var openDivCount = 1; + var divind = text.indexOf(" 0 && divind > 0 && cdivind > 0 ) { + pos = Math.min(divind, cdivind); + if ( pos == divind ) { + openDivCount ++; + } + if ( pos == cdivind ) { + openDivCount --; + } + divind = text.indexOf(" 0) { + text = text.substring(ind); + ind = 0; + var ind2 = text.indexOf(""); + var caption = text.substring(ind+4, ind2); + text = text.substring(ind2+5); + ind = text.indexOf("") == -1 && substr.indexOf("<") == -1 ) { +// // got it +// buf += text.substring(prevind, ind2 + 7); +// } else { +// // not it +// buf += text.substring(prevind, ind); +// } +// prevind = ind; +// ind = text.indexOf(clx, prevind + 1); +// } +// buf += text.substring(prevind); +// return buf; +//} +// +//function modDivs(text, clx) { +// var key = "
", ind); +// if ( ind2 == -1 ) { +// // something's wrong, return unedited +// return text; +// } +// buf += text.substring(prevind, ind + key.length); +// prevind = ind2; +// ind = text.indexOf(key, prevind ); +// } +// buf += text.substring(prevind); +// return buf; +//} +// +