PK9default/PKb8a~~default/details.css/* Copyright (C) 2007 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ body { font-family: arial,sans-serif; font-size: 12px; color: black; } PKb8 default/entry_item.xml
PKb8Rdefault/frame_BottomLeft.pngPNG  IHDR IDATx^104*D\$x(zIz%> >h7,Gp6[u]I4?C;wgRk֘IYyH)7cɬ(v,K1ӄU 0cPd@FdL=IHHi#$P?D2YH$ Ϟ`A(6oI IENDB`PKb8%default/frame_BottomMiddleStretch.pngPNG  IHDRR ڤIDATx^T11 kn'xb`g1=+ JvuU\7z*e| %B%I*?J-¼i5{:?yKSGb]Z֊@cBE`&vvsg&> '}sFG1s9eoe 2 k2 *m?i )IENDB`PKb8=GGdefault/frame_BottomRight.pngPNG  IHDR IDATx^1JQEaJ+[k q6.J`) LcH,H8q{|\8ZtF>H0B D@z`&eM$T E\2+SK,d2.ci~r?3 Z$d`aK`Bf>>LFw7 } a{By*_e#E,쥫0iŲDqR(-:KŒU6r|-/5IENDB`PKb8Yɟ\\default/frame_MiddleLeft.pngPNG  IHDR #IDATx^ @c6K5HpzԏW'IENDB`PKb8ʈlldefault/frame_MiddleRight.pngPNG  IHDR 7T@3IDATx^ñ OjXv$ZWRܾMQxqb]> _H_[^ЦyW= Ylȶa7uhy8}Ǒֺ"3L0 r,BicP6 Z Vh;Z%IY[5c<ec|3#bIdžXeSZIY*M*R.@\\ņ'.O^=/Ul JIENDB`PKb8$$"default/frame_TopMiddleStretch.pngPNG  IHDRR9";"IDATx^ @ /EؑM@A8 ۯ6AmsQzk)[q]/)M%r'nujq_HДRE-rvs_O]OLm-?2了nq5nW,E=z;W H@$  H@$  H@$  H@rU8 @xm.y*$ IENDB`PKb8P'idefault/frame_TopRight.pngPNG  IHDR[HIDATx^OSWǧ̽%:qDel 2q0"ctuq@M@e;2xQZZؖB3ew_\b*u1_x9<= >dٛ dy5$)V>3?P.3 wBd7L c?_ᝊblbY`v诟s:}K';:$=\<9&XH%HR2#(c p^l`y< \nwCC6j-Wl}p1yx < &0E|{?轥|8SPE^&YHkr`I~IxK2N/n|p o!;Te$ VQݓdel`Ѕ-Ro w-3G.wKL 2%FW,dzF6jVG{]ߴ;pQV5I 9Y;%FLjkA6ӋdVhBj4t͢DKSk7^Į +dd;y$Ǔq\Bʫ.(AɝR#O,t+׉x>}ؚ93n p&XF\Dgʜ0ZOw"=E8{k((iYQX'x FvSKY.$/CWn y͑`<d{ǑWewH^伱c*- +4K"pр~U=OÍn xKr.Fe]B2 v#eZThjYmjm?\ū0 {D,2W,h2ǟ_>۬଱ٱͧQeK5{'R❕\O5K{==)iN vTRq`S*D #q?ӏ.)cHտG]5yIENDB`PKb8kxdefault/scrollbar_thumb.pngPNG  IHDR &~IDATx^; 0DG-0!M`]1m'jc|T,TDUBlx&˃:{ X.Z1&m?0ќ}P P KcN C<ykHIENDB`PKb8jݜ:ccdefault/scrollbar_track.pngPNG  IHDR  P*IDATx^ʱ @@?o5R j{$IС®!D[IENDB`PKb8 ssdefault/theme_config.xml #EEEEEE PKb8sdefault/title.xml PKb8Dzzdefault/frame_TopLogo.pngPNG  IHDRg1lAIDATx^1!~[x $` 9r9ȑA Gr 9r#9 GrXZIENDB`PK9editme/PKQ9"==editme/config_constants.js/* Copyright (C) 2007 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // ---------------------- Configuration ------------------------ // Feed URL. var CONFIG_FEED_URL = 'http://pozirk.com/rss.xml'; // Set to true to add cache-buster (a random URL query parameter) // to HTTP requests URLs. // // Some servers will not like this and your request shall fail. var CONFIG_CACHE_BUSTER = false; // Feed refresh interval in ms. var CONFIG_REFRESH_FEED_MS = 60 * 60 * 1000; // Maximum feed entries to parse and display. var CONFIG_MAX_ENTRIES = 10; // Timeout length for HTTP requests in ms. var CONFIG_HTTP_REQUEST_TIMEOUT_MS = 5 * 1000; // Offline mode retry interval in ms. // // The gadget enters offline mode when an HTTP request fails. // When in offline mode, the gadget will retry requests to the server // more frequently, as set by this configuration value. // // Highly recommended this value not be too small. One minute is probably // the least it should be. var CONFIG_RETRY_DELAY_MS = 5 * 60 * 1000; // The directory that contains the theme to be used. var CONFIG_THEME_DIR = 'default'; PKb8(Z  editme/entry_item_impl.js/* Copyright (C) 2007 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // ---------------------- Custom Code ------------------------ // There are three functions defined here that can be modified to implement // custom entry items. // // 1) parseFeed: Responsible for parsing the feed. // Called with the response data after a feed is retrieved. // Parses the response text and returns an array of data objects. // The data objects will be the contents of the entry list. // // 2) EntryList.prototype.fillItem: // Responsible for filling in the entry item. // // For example: if your 'listitem.xml' looks like this: //
//
// // Then "fillItem" should set the value of the label: // listitem.children('foo').innerText = 'some value'; // // 3) EntryList.prototype.afterResize: Called after an entry item is added. // Typically used to manage layout of entry items. // // These functions and "listitem.xml" allow customization of the // entry list items. // Parses the feed into an array of data objects. // Executes callback when finished. function parseFeed(responseText, callback) { debug.trace('Parsing feed.'); // Call default parsing function that will parse most ATOM and RSS feeds. // If you wish to parse manually, remove this line and replace with // your own code. You may be able to copy and modify the code from // "parseAtom" or "parseRSS" from utils_js/parsers.js parseFeedDefault(responseText, callback); } // Fills in the contents of an entry item. // // Modify this function if you have entry items with non-standard // UI elements or custom entry data. EntryList.prototype.fillItem = function(listitem, item) { var title = listitem.children('title'); var published = listitem.children('published'); title.innerText = item.title; published.innerText = formatDate(item.published); }; // Called after the EntryList is resized. // Commonly used to layout entry items. // // For example, if you have elements that need to stretch or be positioned // in a specific manner, you would adjust those elements according to // the provided width and height. // // - width: EntryList width. // - height: EntryList height. EntryList.prototype.afterResize = function(width, height) { }; PK9en/PK902%%en/strings.xml Pozirk Games RSS Download and Online Games Pozirk Games RSS Copyright 2008 Pozirk Games. http://www.pozirk.com Pozirk Games - Download and Online Games! Free and shareware games. Logic puzzle arcade action word jigsaw and card games. Computer and Online games. 2D and 3D games. New and old games. Hints tips and tricks. min ago mins ago hr ago hrs ago day ago days ago Trying to connect... Pozirk Games RSS PK9 utils_js/PK8x0\F\Futils_js/entry_list.js/* Copyright (C) 2007 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ EntryList.FRAME_TOP_LEFT_IMAGE = 'frame_TopLeft.png'; EntryList.FRAME_TOP_MIDDLE_IMAGE = 'frame_TopMiddle.png'; EntryList.FRAME_TOP_RIGHT_IMAGE = 'frame_TopRight.png'; EntryList.FRAME_TOP_LOGO_IMAGE = 'frame_TopLogo.png'; EntryList.FRAME_MIDDLE_LEFT_IMAGE = 'frame_MiddleLeft.png'; EntryList.FRAME_MIDDLE_RIGHT_IMAGE = 'frame_MiddleRight.png'; // Filenames of alternative "stretch" images. If exists, gadget will use // these instead and stretch instead of tiling. // Other option was to introduce new parameter in config_constants to // control stretching vs. tiling. // Decided this would be better since it requires no code modifications on // the designer's part. EntryList.FRAME_TOP_MIDDLE_STRETCH_IMAGE = 'frame_TopMiddleStretch.png'; EntryList.FRAME_BOTTOM_MIDDLE_STRETCH_IMAGE = 'frame_BottomMiddleStretch.png'; EntryList.FRAME_MIDDLE_LEFT_STRETCH_IMAGE = 'frame_MiddleLeftStretch.png'; EntryList.FRAME_MIDDLE_RIGHT_STRETCH_IMAGE = 'frame_MiddleRightStretch.png'; EntryList.FRAME_BOTTOM_LEFT_IMAGE = 'frame_BottomLeft.png'; EntryList.FRAME_BOTTOM_MIDDLE_IMAGE = 'frame_BottomMiddle.png'; EntryList.FRAME_BOTTOM_RIGHT_IMAGE = 'frame_BottomRight.png'; EntryList.SCROLLBAR_TRACK_IMAGE = 'scrollbar_track.png'; EntryList.SCROLLBAR_THUMB_IMAGE = 'scrollbar_thumb.png'; // Default entry hover background, if none specified in config. EntryList.DEFAULT_ENTRY_HOVER_BKG = '#FFFFFF'; // XML file that describes title. The title is the area above content where // arbritrary elements can be specified. EntryList.TITLE_FILE = 'title.xml'; // The theme file that contains the XML template for an entry item. EntryList.ITEM_TEMPLATE_FILE = 'entry_item.xml'; // Configuration values for this theme. EntryList.CONFIG_FILE = 'theme_config.xml'; // Encapsulates the UI that displays feed entries. // Also manages sizing of scrollbar and frame. // - container: Container div, inner elements are defined in "main.xml". // - themeDir: directory path containing the desired "theme". function EntryList(container, themeDir) { this.container = container; this.content = this.container.children('content'); // The title area. this.title = this.container.children('title'); // The div that wraps the entries (for clipping purposes). this.entryListViewport = this.content.children('entriesViewport'); // The actual div that will contain the entries. this.entryList = this.entryListViewport.children('entries'); // The label that will contain text content. this.statusLabel = this.content.children('statusLabel'); this.scrollbar = this.container.children('scrollbar'); // The actual scrollbar is implemented with a progressbar. this.scrollProgressBar = this.scrollbar.children('bar'); // Setup handlers for the progress bar events. var me = this; this.scrollProgressBar.onchange = function() { me.onScroll(); }; this.scrollProgressBar.onmousewheel = function() { me.onMouseWheel(); }; this.header = new HorizStretchImage(header); this.footer = new HorizStretchImage(footer); this.borderLeft = this.container.children('borderLeft'); this.borderRight = this.container.children('borderRight'); this.logo = this.container.children('logo'); this.logoImage = this.logo.children('image'); themeDir = themeDir || EntryList.DEFAULT_THEME_DIR; this.loadTheme(themeDir); // The current number of entries. this.numItems = 0; // The height of the displayable content. // Will be calculated in the resize method. this.contentHeight = 0; } // Loads theme in the given directory. EntryList.prototype.loadTheme = function(themeDir) { // Read in the entry item template. this.itemXml = gadget.storage.openText( pathify(themeDir, EntryList.ITEM_TEMPLATE_FILE)); // Read in header title XML. this.titleXml = gadget.storage.openText( pathify(themeDir, EntryList.TITLE_FILE)); // Read in config XML. var configXml = gadget.storage.openText( pathify(themeDir, EntryList.CONFIG_FILE)); // Parse config and extract values. var xmlDoc = makeDomDocument(); xmlDoc.async = false; xmlDoc.loadXML(configXml); var parser = new SimpleXmlParser(xmlDoc); var parsedItems = parser.getItems('config'); // Set the entry hover background color. if (parsedItems.length > 0 && parsedItems[0]['entryHoverBkg']) { this.entryHoverBkg = parsedItems[0]['entryHoverBkg']; } else { // Use the default. this.entryHoverBkg = EntryList.DEFAULT_ENTRY_HOVER_BKG; } // Insert title content into title area. if (this.titleXml) { this.title.appendElement(this.titleXml); } var headerMiddleImage; if (isFilePresent( pathify(themeDir, EntryList.FRAME_TOP_MIDDLE_STRETCH_IMAGE))) { this.header.setStretchMode(true); headerMiddleImage = pathify(themeDir, EntryList.FRAME_TOP_MIDDLE_STRETCH_IMAGE); } else { this.header.setStretchMode(false); headerMiddleImage = pathify(themeDir, EntryList.FRAME_TOP_MIDDLE_IMAGE); } this.header.setImages(pathify(themeDir, EntryList.FRAME_TOP_LEFT_IMAGE), headerMiddleImage, pathify(themeDir, EntryList.FRAME_TOP_RIGHT_IMAGE)); this.logoImage.src = pathify(themeDir, EntryList.FRAME_TOP_LOGO_IMAGE); this.logoImage.width = this.logoImage.srcWidth; this.logo.height = this.logoImage.srcHeight; var footerMiddleImage; if (isFilePresent(pathify(themeDir, EntryList.FRAME_BOTTOM_MIDDLE_STRETCH_IMAGE))) { this.footer.setStretchMode(true); footerMiddleImage = pathify(themeDir, EntryList.FRAME_BOTTOM_MIDDLE_STRETCH_IMAGE); } else { this.footer.setStretchMode(false); footerMiddleImage = pathify(themeDir, EntryList.FRAME_BOTTOM_MIDDLE_IMAGE); } this.footer.setImages( pathify(themeDir, EntryList.FRAME_BOTTOM_LEFT_IMAGE), footerMiddleImage, pathify(themeDir, EntryList.FRAME_BOTTOM_RIGHT_IMAGE)); // Setup left border. if (isFilePresent( pathify(themeDir, EntryList.FRAME_MIDDLE_LEFT_STRETCH_IMAGE))) { this.setupVerticalBorder(this.borderLeft, pathify(themeDir, EntryList.FRAME_MIDDLE_LEFT_STRETCH_IMAGE), true); } else { this.setupVerticalBorder(this.borderLeft, pathify(themeDir, EntryList.FRAME_MIDDLE_LEFT_IMAGE), false); } // Setup right border. if (isFilePresent( pathify(themeDir, EntryList.FRAME_MIDDLE_RIGHT_STRETCH_IMAGE))) { this.setupVerticalBorder(this.borderRight, pathify(themeDir, EntryList.FRAME_MIDDLE_RIGHT_STRETCH_IMAGE), true); } else { this.setupVerticalBorder(this.borderRight, pathify(themeDir, EntryList.FRAME_MIDDLE_RIGHT_IMAGE), false); } this.scrollbar.background = pathify(themeDir, EntryList.SCROLLBAR_TRACK_IMAGE); this.scrollProgressBar.thumbImage = pathify(themeDir, EntryList.SCROLLBAR_THUMB_IMAGE); this.scrollProgressBar.emptyImage = pathify(themeDir, EntryList.SCROLLBAR_TRACK_IMAGE); this.scrollProgressBar.fullImage = pathify(themeDir, EntryList.SCROLLBAR_TRACK_IMAGE); this.scrollbar.width = getImageDimensions(this.scrollbar.background)[0]; this.scrollProgressBar.width = this.scrollbar.width; this.resize(view.width, view.height); }; // Loads an image into either left or right border. // - border: The div representing the border. // - imagePath: The path to the image. // - isStretch: Whether to setup the border to stretch or tile when resized. EntryList.prototype.setupVerticalBorder = function( border, imagePath, isStretch) { if (isStretch) { border.children('stretchImage').src = imagePath; border.width = border.children('stretchImage').srcWidth; border.background = ''; } else { border.background = imagePath; border.width = getImageDimensions(border.background)[0]; border.children('stretchImage').src = ''; } }; // Resizes border to specified height. // - border: The div representing the border. // - height: The new height. EntryList.prototype.resizeVerticalBorder = function(border, height) { border.height = height; // Determine if it's stretch mode. if (border.children('stretchImage').src) { var stretchImageHeight = border.children('stretchImage').srcHeight; if (height > stretchImageHeight) { // When image is stretched beyond original size, edge of image fades. // Need to extend the image slightly. border.children('stretchImage').height = height + Math.sqrt(height - stretchImageHeight); } else { border.children('stretchImage').height = height; } } }; // Handles scrolling event (scrollbar changed value). EntryList.prototype.onScroll = function() { // Bounds checks. if (this.scrollProgressBar.value < 0) { this.scrollProgressBar.value = 0; } else if (this.scrollProgressBar.value > 100) { this.scrollProgressBar.value = 100; } var percentage = (this.scrollProgressBar.max - this.scrollProgressBar.value); // Calculate the content scroll offset. var offset = (percentage / 100) * (this.entryList.height - this.entryListViewport.height); // Offset the entry list. this.entryList.y = -offset; }; // Handles mousewheel event. EntryList.prototype.onMouseWheel = function() { if (event.wheelDelta > 0) { // Up. this.scrollProgressBar.value += this.getPageStep(); } else { // Down. this.scrollProgressBar.value -= this.getPageStep(); } // No bounds checks here, onScroll will do it. // Refresh scrolling. this.onScroll(); }; // Calculates the percentage (represented by an int between 0 and 100) // of total content height that is in one visible page. EntryList.prototype.getPageStep = function() { if (this.entryList.height <= 0) { return 0; } return 100 * (this.entryListViewport.height / this.entryList.height); }; // Clears entry list and displays a status message. EntryList.prototype.displayMessage = function(message) { this.clearItems(); // Ensure status message is visible. this.statusLabel.visible = true; this.statusLabel.innerText = message; }; // Adds an item to the entry list. EntryList.prototype.addItem = function(item) { debug.trace('Adding entry item.'); // When there any items, hide status message. this.statusLabel.visible = false; var listitem = this.entryList.appendElement(this.itemXml); var itemHeight = listitem.height; listitem.y = itemHeight * this.numItems; listitem.onclick = function() { itemOnClick(item); }; listitem.ondblclick = function() { openEntryInBrowser(item.link); }; var entryHoverBkg = this.entryHoverBkg; listitem.onmouseover = function() { listitem.background = entryHoverBkg; }; listitem.onmouseout = function() { listitem.background = ''; }; var me = this; listitem.onmousewheel = function() { me.onMouseWheel(); }; this.fillItem(listitem, item); ++this.numItems; this.entryList.height = itemHeight * this.numItems; }; // Resize entry list to the given width and height. EntryList.prototype.resize = function(width, height) { this.container.width = width; this.container.height = height; // Resize the header. this.header.resize(width); var headerHeight = this.header.getHeight(); // Set title to same height as header. this.title.height = headerHeight; // Resize and position the footer. this.footer.resize(width); var footerHeight = this.footer.getHeight(); var footerY = height - footerHeight; this.footer.setY(footerY); // Check if footer is overlapping header. if (footerY < headerHeight) { // It is overlapping, hide the footer. this.footer.hide(); } else { this.footer.show(); } // Calculate and store height of content. this.contentHeight = height - headerHeight - footerHeight; // Width of area that consists of content and scrollbar (if present). var contentAndScrollWidth = width - this.borderRight.width - this.borderLeft.width; this.contentWidth = contentAndScrollWidth; // Set height of entry list viewport. // Subtracting 2 to account for vertical padding. this.entryListViewport.height = this.contentHeight - 2; this.entryListViewport.y = 1; // If the entry list viewport is bigger than the actual entry list. if (this.entryListViewport.height > this.entryList.height) { // Hide and reset the scrollbar. this.scrollbar.visible = false; this.scrollProgressBar.value = 100; } else { this.scrollbar.visible = true; // Shorten the content width to account for the visible scrollbar. this.contentWidth -= this.scrollbar.width; // Resize and position the scrollbar container. this.scrollbar.height = this.contentHeight; this.scrollbar.x = width - this.borderRight.width - this.scrollProgressBar.width; this.scrollbar.y = headerHeight; // Resize the progress bar. this.scrollProgressBar.height = this.contentHeight; } // Resize and position the content. this.content.height = this.contentHeight; this.content.width = this.contentWidth; this.content.x = this.borderLeft.width; this.content.y = headerHeight; // Align the title area to the content. this.title.x = this.content.x; this.title.width = this.content.width; if (this.logo) { // Center the logo. var logoImageWidth = this.logoImage.width; var logoX = this.borderLeft.width + ((contentAndScrollWidth - logoImageWidth) / 2); // Check if logo overlaps left border. if (logoX < this.borderLeft.width) { logoX = this.borderLeft.width; } this.logo.x = logoX; // Match the logo width to that of the content (for clipping purposes). this.logo.width = contentAndScrollWidth; } // Padding for entries viewport. // Same as content container less four for left & right padding. // Don't have to set width of the inner entryList since it is width 100%. this.entryListViewport.width = this.content.width - 4; this.entryListViewport.x = 2; // Position the left border. this.borderLeft.x = 0; this.borderLeft.y = headerHeight; // Resize the left border. this.resizeVerticalBorder(this.borderLeft, this.contentHeight); // Position the right border. this.borderRight.x = width - this.borderRight.width; this.borderRight.y = headerHeight; // Resize the right border. this.resizeVerticalBorder(this.borderRight, this.contentHeight); this.afterResize(); // Refresh the scrolling. this.onScroll(); }; // Removes all items. EntryList.prototype.clearItems = function() { this.numItems = 0; this.entryList.removeAllElements(); }; // Combination of images that will fit a given width. // // Consists of 3 images: // // [ ][ ][ ] // ^left ^middle ^right // // The middle image will be tiled or stretched to ensure all 3 images fill out // the specified width. // // By default the middle image will tile, but can set to stretch with // "setStretchMode". function HorizStretchImage(container) { // The container div. this.container = container; // The left-side image. this.left = this.container.children('left'); // The middle image that will be tiled. this.middle = this.container.children('middle'); this.middle.x = this.left.width; // The right-side image. this.right = this.container.children('right'); // Whether to tile or stretch the middle. this.isStretch = false; } HorizStretchImage.prototype.setStretchMode = function(isStretch) { this.isStretch = isStretch; this.middle.children('stretchImage').visible = this.isStretch; }; // Set image sources with provided image paths. HorizStretchImage.prototype.setImages = function(left, middle, right) { this.left.src = left; this.left.width = this.left.srcWidth; this.container.height = this.left.srcHeight; if (this.isStretch) { this.middle.children('stretchImage').src = middle; } else { this.middle.background = middle; } this.right.src = right; this.right.width = this.right.srcWidth; // Images have changed, need to resize. this.resize(this.container.width); }; // Resize and stretch to specified width. HorizStretchImage.prototype.resize = function(width) { // Set the width of the container. this.container.width = width; // Set the width of the middle (background will tile). this.middle.width = this.container.width - this.left.width - this.right.width; if (this.isStretch) { var newStretchWidth = this.middle.width; var stretchImg = this.middle.children('stretchImage'); // When image is stretched beyond original size, right edge of image fades. // Need to enlarge the image slightly. if (newStretchWidth > stretchImg.srcWidth) { newStretchWidth += Math.sqrt(newStretchWidth - stretchImg.srcWidth); } stretchImg.width = newStretchWidth; } this.middle.x = this.left.width; // Position the right-side image. this.right.x = this.container.width - this.right.width; }; // Returns the height. HorizStretchImage.prototype.getHeight = function() { return this.container.height; }; // Set the Y position. HorizStretchImage.prototype.setY = function(y) { this.container.y = y; }; // Hides the images. HorizStretchImage.prototype.hide = function() { this.container.visible = false; }; // Unhides the images. HorizStretchImage.prototype.show = function() { this.container.visible = true; }; PK8R{utils_js/parsers.js/* Copyright (C) 2007 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // ---------------------- Default Parsers ------------------------ // Generates sequential IDs. // // Some feeds do not provide entry IDs, however the gadget needs each entry // to have a unique ID. When parsing a feed and encountering an ID-less entry, // use this to create an ID. var IdGenerator = new function() { this.nextId = 0; this.getNextId = function() { return ++this.nextId; }; }; // Attempts to automatically parse feed. // So far can detect and parse basic ATOM and RSS. // // A parsed entry is a JS object and contains these fields: // // title - The entry title. // content - The description or summary. // link - The link to the entry. // // And may contain values for these fields: // // published - Published date. // id - Unique identifier for the entry. // // When finished, executes callback with array of parsed entries. function parseFeedDefault(responseText, callback) { debug.trace('Default feed parsing.'); var doc; try { doc = makeDomDocument(); doc.loadXML(responseText); } catch(e) { debug.error('Could not load XML.'); return; } // Get the top-level tag name. var rootTagName = doc.documentElement.tagName; var entries; if (rootTagName == 'rss' || rootTagName =='channel') { entries = parseRSS20(doc, CONFIG_MAX_ENTRIES); } else if (rootTagName == 'rdf:RDF') { entries = parseRSS10(doc, CONFIG_MAX_ENTRIES); } else if (rootTagName == 'feed') { // ATOM has top level "feed" element. entries = parseATOM(doc, CONFIG_MAX_ENTRIES); } else { debug.error('Unrecognized feed type.'); return; } callback(entries); } // Generic RSS 1.0 parser. // Returns array of data objects. function parseRSS10(doc, maxEntries) { debug.trace('Parsing RSS 1.0 feed.'); var entries = []; try { var entryElements = doc.getElementsByTagName('item'); for (var i = 0; i < entryElements.length && i < maxEntries; ++i) { var entry = entryElements[i]; var entryData = {}; // ID. entryData['id'] = entry.getAttribute('rdf:about'); // Entry title. entryData['title'] = entry.getElementsByTagName('title')[0].text; // Strip any possible HTML from title. entryData['title'] = stripHtml(entryData['title']); // Publish date. if (entry.getElementsByTagName('dc:date').length > 0) { var pubDate = entry.getElementsByTagName('dc:date')[0].text; entryData['published'] = parseRFC3339(pubDate); } // Entry content (optional). if (entry.getElementsByTagName('description').length > 0) { entryData['content'] = entry.getElementsByTagName('description')[0].text; } else { entryData['content'] = entryData['title']; } // Link. entryData['link'] = entry.getElementsByTagName('link')[0].text; entries.push(entryData); } } catch(e) { debug.error('Error parsing RSS 1.0 feed: ' + e.message); return; } debug.trace('Successfully parsed ' + entries.length + ' entries.'); return entries; } // Generic RSS 2.0 parser. // Returns array of data objects. function parseRSS20(doc, maxEntries) { debug.trace('Parsing RSS 2.0 feed.'); var entries = []; try { var entryElements = doc.getElementsByTagName('item'); for (var i = 0; i < entryElements.length && i < maxEntries; ++i) { var entry = entryElements[i]; var entryData = {}; // ID. if (entry.getElementsByTagName('guid').length > 0) { entryData['id'] = entry.getElementsByTagName('guid')[0].text; } else { entryData['id'] = IdGenerator.getNextId(); } // Entry title. entryData['title'] = entry.getElementsByTagName('title')[0].text; // Strip any possible HTML from title. entryData['title'] = stripHtml(entryData['title']); // Publish date. if (entry.getElementsByTagName('pubDate').length > 0) { var pubDate = entry.getElementsByTagName('pubDate')[0].text; entryData['published'] = new Date(pubDate); } // Entry content. entryData['content'] = entry.getElementsByTagName('description')[0].text; // Link. entryData['link'] = entry.getElementsByTagName('link')[0].text; entries.push(entryData); } } catch(e) { debug.error('Error parsing RSS 2.0 feed: ' + e.message); return; } debug.trace('Successfully parsed ' + entries.length + ' entries.'); return entries; } // Generic ATOM parser. // Returns array of data objects. function parseATOM(doc, maxEntries) { debug.trace('Parsing ATOM feed.'); var entries = []; try { var entryElements = doc.getElementsByTagName('entry'); for (var i = 0; i < entryElements.length && i < maxEntries; ++i) { var entry = entryElements[i]; var entryData = {}; // ID. entryData['id'] = entry.getElementsByTagName('id')[0].text; // Entry title. entryData['title'] = entry.getElementsByTagName('title')[0].text; // Strip any possible HTML from title. entryData['title'] = stripHtml(entryData['title']); // Published. if (entry.getElementsByTagName('published').length > 0) { var published = entry.getElementsByTagName('published')[0].text; entryData['published'] = parseRFC3339(published); } else if (entry.getElementsByTagName('updated').length > 0) { var updated = entry.getElementsByTagName('updated')[0].text; entryData['published'] = parseRFC3339(updated); } // Entry content (optional). if (entry.getElementsByTagName('content').length > 0) { entryData['content'] = entry.getElementsByTagName('content')[0].text; } else if (entry.getElementsByTagName('summary').length > 0) { entryData['content'] = entry.getElementsByTagName('summary')[0].text; } else { // Set content to the title. entryData['content'] = entryData['title']; } // Get the alt link. var linkElements = entry.getElementsByTagName('link'); for (var j = 0; j < linkElements.length; ++j) { var link = linkElements[j]; var rel = link.getAttribute('rel'); if (rel == 'alternate') { entryData['link'] = link.getAttribute('href'); } } entries.push(entryData); } } catch(e) { debug.error('Error parsing ATOM feed: ' + e.message); return; } debug.trace('Successfully parsed ' + entries.length + ' entries.'); return entries; } PKv8Ӗutils_js/utils.js/* Copyright (C) 2007 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // ---------------------- Utilities ------------------------ // Converts an RFC3339 date time into local time JS Date. // Returns null on error. function parseRFC3339(date) { var newDate = new Date(); // Parse date portion. // first 10 chars 'XXXX-XX-XX' var datePart = date.substring(0, 10); datePart = datePart.split("-"); if (datePart.length != 3) { return null; } newDate.setUTCFullYear(datePart[0]); newDate.setUTCMonth(datePart[1] - 1); newDate.setUTCDate(datePart[2]); // Check for 'T'. var tPart = date.substring(10, 11); if (tPart != 'T' && tPart != 't') { return null; } // Parse time portion. // 'XX:XX:XX' var timePart = date.substring(11, 19); timePart = timePart.split(":"); if (timePart.length != 3) { return null; } newDate.setUTCHours(timePart[0]); newDate.setUTCMinutes(timePart[1]); newDate.setUTCSeconds(timePart[2]); var index = 19; var dateLen = date.length; if (date.charAt(index) == '.') { // Consume fractional sec. do { ++index; } while (date.charAt(index) >= '0' && date.charAt(index) <= '9' && index < date.length); } if (index >= date.length) { // No zone to parse; return newDate; } if (date.charAt(index) == 'Z') { // No offset. return newDate; } var offsetSign = date.charAt(index); if (offsetSign != '+' && offsetSign != '-') { return null; } ++index; // Parse offset. var offsetPart = date.substring(index, index + 5); if (offsetPart.length == 4) { // Assume colon-less format. var tempOffsetPart = []; tempOffsetPart[0] = offsetPart.substr(0, 2); tempOffsetPart[1] = offsetPart.substr(2, 2); offsetPart = tempOffsetPart; } else { offsetPart = offsetPart.split(":"); } if (offsetPart.length != 2) { return null; } var offsetSeconds = (Number(offsetPart[0]) * 60) + Number(offsetPart[1]); var offsetMs = offsetSeconds * 60 * 1000; // Adjust for offset. if (offsetSign == '+') { newDate.setTime(newDate.getTime() - offsetMs); } else { newDate.setTime(newDate.getTime() + offsetMs); } return newDate; } // Formats date object similar to how contentarea displays dates, i.e.: // - 15 min ago // - 3 hrs ago // - 5 days ago // // Returns empty string on error. function formatDate(date) { if (!date) { return ''; } var now = new Date(); var value; // Difference between now and supplied date in ms. var diff = now.getTime() - date.getTime(); // Convert to min. diff = diff / (60 * 1000); // Less than an hour. if (diff < 60) { value = Math.floor(diff); return value + ' ' + (value > 1 ? strings.MINS_AGO : strings.MIN_AGO); } // Convert to hours. diff = Math.floor(diff / 60); // Less than a day. if (diff < 24) { value = Math.floor(diff); return value + ' ' + (value > 1 ? strings.HRS_AGO : strings.HR_AGO); } // Convert to days. value = Math.floor(diff / 24); // Default unit is day. return value + ' ' + (value > 1 ? strings.DAYS_AGO : strings.DAY_AGO); } // Retrieves an online image and executes callback with the response datastream // as an argument. function retrieveImage(url, callback) { if (!url) { debug.warning('Invalid image url: ' + url); return; } debug.trace('Retrieving image: ' + url); try { var request = new XMLHttpRequest(); request.open('GET', url, true); request.onreadystatechange = onReadyStateChange; request.send(); } catch (e) { debug.warn('Can\'t retrieve image: ' + url); return; } function onReadyStateChange() { if (request.readyState != 4) { return; } if (request.status == 200) { callback(request.responseStream); } } } // A shameful way to determine the dimensions (width/height) of an image. // - path: Path to image. // // Returns an array with [width, height]. function getImageDimensions(path) { // NOTE: Uses a hidden "img" element defined in "main.xml". imgSizer.src = path; return [imgSizer.srcWidth, imgSizer.srcHeight]; } // Strips HTML and decodes common entities. function stripHtml(s) { s = s.replace(/(<([^>]*)>)/ig, ''); return s; } // Determines whether file is present in gadget package. function isFilePresent(path) { var result = gadget.storage.extract(path); return result !== ''; } // "Pathify"s filename with given path. function pathify(path, filename) { return path + '\\' + filename; } function SimpleXmlParser(xmlDoc) { this.xmlDoc = xmlDoc; this.parseError = xmlDoc.parseError; if (this.parseError.errorCode !== 0) { debug.error("SimpleXmlParser ERROR: " + this.parseError.reason); } } SimpleXmlParser.prototype.getItems = function(key) { var xmlDoc = this.xmlDoc; var items = []; if (this.parseError.errorCode !== 0) { debug.error("SimpleXmlParser ERROR: " + this.parseError.reason); } else { var objNodeList = xmlDoc.getElementsByTagName(key); for (var i = 0; i < objNodeList.length; ++i) { var xmlItem = objNodeList.item(i); var item = {}; var added = false; for (var j = 0; j < xmlItem.childNodes.length; ++j) { var child = xmlItem.childNodes.item(j); if (child.childNodes.length > 0) { var name = child.nodeName; var value = child.childNodes[0].nodeValue; item[name] = value; added = true; } } if (added) { items.push(item); } } } return items; }; function makeDomDocument() { var doc = new DOMDocument(); doc.resolveExternals = false; doc.validateOnParse = false; doc.setProperty('ProhibitDTD', false); return doc; } PKt9.cgadget.gmanifest &GADGET_NAME; &GADGET_DESCRIPTION; &GADGET_ABOUT_TEXT; icon_small.png icon_large.png 1.0.0.0 Pozirk Games http://www.pozirk.com/ C1B7BF2A-1485-13A6-566C-3AACB6C589E8 Copyright (c) 2008 Pozirk Games. All Rights Reserved contact@pozirk.com PKb8(mmain.js/* Copyright (C) 2007 Google Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // ---------------------- Global variables/objects ------------------------ // EntryList object. // Manages the UI: // - The frame // - The content // - Adding entry items to the list // - Scrolling var entryList; // Entries received from the feed. var lastEntries; // The theme file that contains the CSS for the details view. var DETAILS_CSS_FILE = 'details.css'; // The CSS styles to use in the details view. var detailsCss; // The current entry displayed in the details view. var currentEntry = null; // ---------------------- Gadget events ------------------------ function onOpen() { // Read in the details view CSS. detailsCss = gadget.storage.openText( pathify(CONFIG_THEME_DIR, DETAILS_CSS_FILE)); // Create the EntryList. entryList = new EntryList(container, CONFIG_THEME_DIR); // Call draw with no data to display default error message. draw(null); // Refresh (request feed and then re-draw). refresh(); // Run-forever timer that refreshes the feed. view.setInterval(refresh, CONFIG_REFRESH_FEED_MS); } // Entry item onclick handler. function itemOnClick(entry) { debug.trace('Entry item onclick event.'); // Is a details view already open? if (currentEntry !== null) { var previousEntry = currentEntry; // We explicitly close so we know for sure that "currentEntry" is // null at this point. pluginHelper.closeDetailsView(); // Same entry as before, no need to open it again. if (previousEntry == entry) { return; } } currentEntry = entry; var htmlDetailsView = new DetailsView(); htmlDetailsView.html_content = true; var htmlContent = ''; htmlContent += entry.content; htmlDetailsView.setContent('', undefined, htmlContent, false, 0); // Show the details view pluginHelper.showDetailsView(htmlDetailsView, entry.title, gddDetailsViewFlagToolbarOpen, function(flags) { detailsViewOnFeedback(flags, entry.link); }); } function openEntryInBrowser(url) { var winShell = new ActiveXObject('Shell.Application'); winShell.ShellExecute(url); } // Handles when details view is closed. // Here we want to open a link to the entry if the title bar is clicked. function detailsViewOnFeedback(flags, url) { currentEntry = null; debug.trace('detailsViewOnFeedback event.'); // User clicked on the title bar link. if (flags == gddDetailsViewFlagToolbarOpen) { openEntryInBrowser(url); } } function onSize() { entryList.resize(view.width, view.height); } // ---------------------- Feed retrieval and parsing ------------------------ function refresh() { debug.trace('Refreshing feed.'); retrieveFeed(CONFIG_FEED_URL, draw); } // Requests a feed and executes 'callback' when finished. function retrieveFeed(url, callback) { var request = new XMLHttpRequest(); request.onreadystatechange = onReadyStateChange; if (CONFIG_CACHE_BUSTER) { url += '?cache_buster_xyz=' + Math.random(); } debug.trace('Opening request to: ' + url); function onRequestError() { if (request) { request.abort(); // Prevent leak. request = null; } debug.warning('Request error, will retry later.'); // Retry again later. view.setTimeout(refresh, getRetryDelay()); } var timeoutTimer = null; if (!lastEntries) { // Want to set a timeout since no data is available. // If request times out, call onRequestError to retry. timeoutTimer = view.setTimeout( onRequestError, CONFIG_HTTP_REQUEST_TIMEOUT_MS); } try { request.open('GET', url, true); request.send(); } catch(e) { debug.warn('Could not retrieve feed: ' + e.message); // If there are no entries, we want to call the retry function. if (!lastEntries) { onRequestError(); } return; } function onReadyStateChange() { if (request.readyState != 4) { return; } if (request.status == 200) { if (timeoutTimer) { debug.trace('Cancelling request timeout timer.'); view.clearTimeout(timeoutTimer); } debug.trace('Retrieve succeeded.'); parseFeed(request.responseText, callback); } // Prevent leak. request = null; } } // Extracted to a function: in the future we may want more intelligent // delay (i.e. backoff). function getRetryDelay() { return CONFIG_RETRY_DELAY_MS; } // ---------------------- Drawing code ------------------------ function draw(entries) { entryList.clearItems(); debug.trace('Adding entries.'); // If no entry data, indicate error. if (!entries) { debug.trace('No entries data, displaying default error.'); entryList.displayMessage(strings.TRYING_TO_CONNECT); } else { for (var i = 0; i < entries.length && i < CONFIG_MAX_ENTRIES; ++i) { entryList.addItem(entries[i]); } lastEntries = entries; } entryList.resize(view.width, view.height); } PKp9  icon_large.pngPNG  IHDR@0-gAMA7tEXtSoftwareAdobe ImageReadyqe<PLTEkD_Q'zSڄdOhlʋx2I2ˉRjoŨD\2-c֮ͯVi@ԪF]E-iIDATxb ` nvD\VlM?@T7:@3 Ap3  hR!JP bbY(: $F@M* XBJ?@| 悘# Cjjif&gi$)@M`@ Hjjr<Ia\`P#E`` 7  *P J  K 4PLBPj&. (ho* A&Us0ebZ/ˠ Ri @8 kiɠ  Lp04N >AKKvv0`ЅŢnP47@ | 0  `JD+s2A\h;?)*J1@_ԌIWUe@2P4k0I)+BM}aa}XhjXjBd@1KC("?;r># h4ijjJL Al8 egW+" KMe Me#} )o45~` `ҢLJJFTՕSb`ReRR>%R'r Ġhdʯ* LUª86b0bd@! Da E&p{BJ"fJ xVfPfg)bీ4v9&HbUg5(  DH,Hˁ 'ga`hh#IZ\NMUaaQ~k!&8&4-yrR"RRb` %''4@ #7bgU'9qvva)PJ)s+A7e Ġ ha ʪFƺfjjj```A@4 bb`'<##H @10p0h: c,, 5Z&&lBBl2 0EQ ԵM`YـM؀9@A XXM=($1V M^j@ Dh6+!(KEJ x!yF d L!$,PXP*:SW@@ x2 ! / @ `8@lX H;0Q @ *`ded@⠴p H?^^ 4h pyYv~bQ6b2*+b TV]EG u@F & Ԯcm @ # @MA(U @@L @:bYIENDB`PKb8#ֈicon_small.pngPNG  IHDRw=OIDATx^kHW/"baPʨ0 &QZJQYat͢,5i(؛5m/E{Р h.1FIc.ZLLI& {zcm/><?S/ $0a0g0bqq,/`aX/z5) +F /ӧu_SK_6$9v;,qzv'ǡB5`8jrtv!jD uʝD"D0WWW199ek*5 س?ک' pOG|·8_}:<р8`T"fCZ~&~cEOkAaFM%a|^{?zkؐۍ2l<yaϢn5H#maH3W$\L1&6~w"DNCoxt+l@ *z# VVVpWi}76؆G7": U!G&z}،ăq.OLAXӳk!9ýKK˘ϠߥσK I4tw!\0@3BQ:3-:j3[ ( v9ȕnJ@nre#?Hüd%wt~ݟy%7=. u44: cP C#3 s**"r9#ktUPTJ).:,'\0؁÷km"Dba䇳/wAt)AIENDB`PKb8lmain.xml