From d0bd3f44f6034b5ab9a8ac3f36987d3af8d4f07c Mon Sep 17 00:00:00 2001 From: Samuel Clay Date: Thu, 23 Jul 2009 02:39:13 +0000 Subject: [PATCH] Whew, fixed all oddball menu-fade and menu-close issues. Now it looks pretty good with its drop-shadow and auto-close behavior. --- media/css/reader.css | 15 +- media/js/jquery.dropshadow.js | 304 +++++++++++++++ media/js/jquery.simplemodal-1.3.js | 592 +++++++++++++++++++++++++++++ media/js/newsblur/reader.js | 61 ++- templates/base.html | 4 +- templates/reader/feeds.xhtml | 7 +- 6 files changed, 962 insertions(+), 21 deletions(-) create mode 100644 media/js/jquery.dropshadow.js create mode 100644 media/js/jquery.simplemodal-1.3.js diff --git a/media/css/reader.css b/media/css/reader.css index c3b907ef5..64f5bf63b 100644 --- a/media/css/reader.css +++ b/media/css/reader.css @@ -428,7 +428,6 @@ a img { #taskbar .taskbar_leftnav .task_button .taskbar_menu li { margin: 0; padding: 4px; - cursor: pointer; } #taskbar .taskbar_leftnav .task_button .taskbar_menu li span { @@ -436,6 +435,7 @@ a img { margin: 0; display: block; color: #203060; + cursor: pointer; } #taskbar .taskbar_leftnav .task_button .taskbar_menu li:hover span { @@ -451,6 +451,19 @@ a img { background: transparent url(../img/icons/silk/user.png) no-repeat center center; } +/* ================ */ +/* = Modal Dialog = */ +/* ================ */ + +#simplemodal-overlay { + background-color: #101030; +} + +#simplemodal-container { + width: 500px; + background-color: white; + padding: 8px; +} /* ==================== */ /* = OPML Import Form = */ diff --git a/media/js/jquery.dropshadow.js b/media/js/jquery.dropshadow.js new file mode 100644 index 000000000..9eb9d7c7c --- /dev/null +++ b/media/js/jquery.dropshadow.js @@ -0,0 +1,304 @@ +/* + VERSION: Drop Shadow jQuery Plugin 1.6 12-13-2007 + + REQUIRES: jquery.js (1.2.6 or later) + + SYNTAX: $(selector).dropShadow(options); // Creates new drop shadows + $(selector).redrawShadow(); // Redraws shadows on elements + $(selector).removeShadow(); // Removes shadows from elements + $(selector).shadowId(); // Returns an existing shadow's ID + + OPTIONS: + + left : integer (default = 4) + top : integer (default = 4) + blur : integer (default = 2) + opacity : decimal (default = 0.5) + color : string (default = "black") + swap : boolean (default = false) + + The left and top parameters specify the distance and direction, in pixels, to + offset the shadow. Zero values position the shadow directly behind the element. + Positive values shift the shadow to the right and down, while negative values + shift the shadow to the left and up. + + The blur parameter specifies the spread, or dispersion, of the shadow. Zero + produces a sharp shadow, one or two produces a normal shadow, and three or four + produces a softer shadow. Higher values increase the processing load. + + The opacity parameter should be a decimal value, usually less than one. You can + use a value higher than one in special situations, e.g. with extreme blurring. + + Color is specified in the usual manner, with a color name or hex value. The + color parameter does not apply with transparent images. + + The swap parameter reverses the stacking order of the original and the shadow. + This can be used for special effects, like an embossed or engraved look. + + EXPLANATION: + + This jQuery plug-in adds soft drop shadows behind page elements. It is only + intended for adding a few drop shadows to mostly stationary objects, like a + page heading, a photo, or content containers. + + The shadows it creates are not bound to the original elements, so they won't + move or change size automatically if the original elements change. A window + resize event listener is assigned, which should re-align the shadows in many + cases, but if the elements otherwise move or resize you will have to handle + those events manually. Shadows can be redrawn with the redrawShadow() method + or removed with the removeShadow() method. The redrawShadow() method uses the + same options used to create the original shadow. If you want to change the + options, you should remove the shadow first and then create a new shadow. + + The dropShadow method returns a jQuery collection of the new shadow(s). If + further manipulation is required, you can store it in a variable like this: + + var myShadow = $("#myElement").dropShadow(); + + You can also read the ID of the shadow from the original element at a later + time. To get a shadow's ID, either read the shadowId attribute of the + original element or call the shadowId() method. For example: + + var myShadowId = $("#myElement").attr("shadowId"); or + var myShadowId = $("#myElement").shadowId(); + + If the original element does not already have an ID assigned, a random ID will + be generated for the shadow. However, if the original does have an ID, the + shadow's ID will be the original ID and "_dropShadow". For example, if the + element's ID is "myElement", the shadow's ID would be "myElement_dropShadow". + + If you have a long piece of text and the user resizes the window so that the + text wraps or unwraps, the shape of the text changes and the words are no + longer in the same positions. In that case, you can either preset the height + and width, so that it becomes a fixed box, or you can shadow each word + separately, like this: + +

Your Page Title

+ + $("h1 span").dropShadow(); + + The dropShadow method attempts to determine whether the selected elements have + transparent backgrounds. If you want to shadow the content inside an element, + like text or a transparent image, it must not have a background-color or + background-image style. If the element has a solid background it will create a + rectangular shadow around the outside box. + + The shadow elements are positioned absolutely one layer below the original + element, which is positioned relatively (unless it's already absolute). + + *** All shadows have the "dropShadow" class, for selecting with CSS or jQuery. + + ISSUES: + + 1) Limited styling of shadowed elements by ID. Because IDs must be unique, + and the shadows have their own ID, styles applied by ID won't transfer + to the shadows. Instead, style elements by class or use inline styles. + 2) Sometimes shadows don't align properly. Elements may need to be wrapped + in container elements, margins or floats changed, etc. or you may just + have to tweak the left and top offsets to get them to align. For example, + with draggable objects, you have to wrap them inside two divs. Make the + outer div draggable and set the inner div's position to relative. Then + you can create a shadow on the element inside the inner div. + 3) If the user changes font sizes it will throw the shadows off. Browsers + do not expose an event for font size changes. The only known way to + detect a user font size change is to embed an invisible text element and + then continuously poll for changes in size. + 4) Safari support is shaky, and may require even more tweaks/wrappers, etc. + + The bottom line is that this is a gimick effect, not PFM, and if you push it + too hard or expect it to work in every possible situation on every browser, + you will be disappointed. Use it sparingly, and don't use it for anything + critical. Otherwise, have fun with it! + + AUTHOR: Larry Stevens (McLars@eyebulb.com) This work is in the public domain, + and it is not supported in any way. Use it at your own risk. +*/ + + +(function($){ + + var dropShadowZindex = 1; //z-index counter + + $.fn.dropShadow = function(options) + { + // Default options + var opt = $.extend({ + left: 4, + top: 4, + blur: 2, + opacity: .5, + color: "black", + swap: false + }, options); + var jShadows = $([]); //empty jQuery collection + + // Loop through original elements + this.not(".dropShadow").each(function() + { + var jthis = $(this); + var shadows = []; + var blur = (opt.blur <= 0) ? 0 : opt.blur; + var opacity = (blur == 0) ? opt.opacity : opt.opacity / (blur * 8); + var zOriginal = (opt.swap) ? dropShadowZindex : dropShadowZindex + 1; + var zShadow = (opt.swap) ? dropShadowZindex + 1 : dropShadowZindex; + + // Create ID for shadow + var shadowId; + if (this.id) { + shadowId = this.id + "_dropShadow"; + } + else { + shadowId = "ds" + (1 + Math.floor(9999 * Math.random())); + } + + // Modify original element + $.data(this, "shadowId", shadowId); //store id in expando + $.data(this, "shadowOptions", options); //store options in expando + jthis + .attr("shadowId", shadowId) + .css("zIndex", zOriginal); + if (jthis.css("position") != "absolute") { + jthis.css({ + position: "relative", + zoom: 1 //for IE layout + }); + } + + // Create first shadow layer + bgColor = jthis.css("backgroundColor"); + if (bgColor == "rgba(0, 0, 0, 0)") bgColor = "transparent"; //Safari + if (bgColor != "transparent" || jthis.css("backgroundImage") != "none" + || this.nodeName == "SELECT" + || this.nodeName == "INPUT" + || this.nodeName == "TEXTAREA") { + shadows[0] = $("
") + .css("background", opt.color); + } + else { + shadows[0] = jthis + .clone() + .removeAttr("id") + .removeAttr("name") + .removeAttr("shadowId") + .css("color", opt.color); + } + shadows[0] + .addClass("dropShadow") + .css({ + height: jthis.outerHeight(), + left: blur, + opacity: opacity, + position: "absolute", + top: blur, + width: jthis.outerWidth(), + zIndex: zShadow + }); + + // Create other shadow layers + var layers = (8 * blur) + 1; + for (i = 1; i < layers; i++) { + shadows[i] = shadows[0].clone(); + } + + // Position layers + var i = 1; + var j = blur; + while (j > 0) { + shadows[i].css({left: j * 2, top: 0}); //top + shadows[i + 1].css({left: j * 4, top: j * 2}); //right + shadows[i + 2].css({left: j * 2, top: j * 4}); //bottom + shadows[i + 3].css({left: 0, top: j * 2}); //left + shadows[i + 4].css({left: j * 3, top: j}); //top-right + shadows[i + 5].css({left: j * 3, top: j * 3}); //bottom-right + shadows[i + 6].css({left: j, top: j * 3}); //bottom-left + shadows[i + 7].css({left: j, top: j}); //top-left + i += 8; + j--; + } + + // Create container + var divShadow = $("
") + .attr("id", shadowId) + .addClass("dropShadow") + .css({ + left: jthis.position().left + opt.left - blur, + marginTop: jthis.css("marginTop"), + marginRight: jthis.css("marginRight"), + marginBottom: jthis.css("marginBottom"), + marginLeft: jthis.css("marginLeft"), + position: "absolute", + top: jthis.position().top + opt.top - blur, + zIndex: zShadow + }); + + // Add layers to container + for (i = 0; i < layers; i++) { + divShadow.append(shadows[i]); + } + + // Add container to DOM + jthis.after(divShadow); + + // Add shadow to return set + jShadows = jShadows.add(divShadow); + + // Re-align shadow on window resize + $(window).resize(function() + { + try { + divShadow.css({ + left: jthis.position().left + opt.left - blur, + top: jthis.position().top + opt.top - blur + }); + } + catch(e){} + }); + + // Increment z-index counter + dropShadowZindex += 2; + + }); //end each + + return this.pushStack(jShadows); + }; + + + $.fn.redrawShadow = function() + { + // Remove existing shadows + this.removeShadow(); + + // Draw new shadows + return this.each(function() + { + var shadowOptions = $.data(this, "shadowOptions"); + $(this).dropShadow(shadowOptions); + }); + }; + + + $.fn.removeShadow = function() + { + return this.each(function() + { + var shadowId = $(this).shadowId(); + $("div#" + shadowId).remove(); + }); + }; + + + $.fn.shadowId = function() + { + return $.data(this[0], "shadowId"); + }; + + + $(function() + { + // Suppress printing of shadows + var noPrint = ""; + $("head").append(noPrint); + }); + +})(jQuery); \ No newline at end of file diff --git a/media/js/jquery.simplemodal-1.3.js b/media/js/jquery.simplemodal-1.3.js new file mode 100644 index 000000000..0096bb6fa --- /dev/null +++ b/media/js/jquery.simplemodal-1.3.js @@ -0,0 +1,592 @@ +/* + * SimpleModal 1.3 - jQuery Plugin + * http://www.ericmmartin.com/projects/simplemodal/ + * Copyright (c) 2009 Eric Martin + * Dual licensed under the MIT and GPL licenses + * Revision: $Id: jquery.simplemodal.js 205 2009-06-12 13:29:21Z emartin24 $ + */ + +/** + * SimpleModal is a lightweight jQuery plugin that provides a simple + * interface to create a modal dialog. + * + * The goal of SimpleModal is to provide developers with a cross-browser + * overlay and container that will be populated with data provided to + * SimpleModal. + * + * There are two ways to call SimpleModal: + * 1) As a chained function on a jQuery object, like $('#myDiv').modal();. + * This call would place the DOM object, #myDiv, inside a modal dialog. + * Chaining requires a jQuery object. An optional options object can be + * passed as a parameter. + * + * @example $('
my data
').modal({options}); + * @example $('#myDiv').modal({options}); + * @example jQueryObject.modal({options}); + * + * 2) As a stand-alone function, like $.modal(data). The data parameter + * is required and an optional options object can be passed as a second + * parameter. This method provides more flexibility in the types of data + * that are allowed. The data could be a DOM object, a jQuery object, HTML + * or a string. + * + * @example $.modal('
my data
', {options}); + * @example $.modal('my data', {options}); + * @example $.modal($('#myDiv'), {options}); + * @example $.modal(jQueryObject, {options}); + * @example $.modal(document.getElementById('myDiv'), {options}); + * + * A SimpleModal call can contain multiple elements, but only one modal + * dialog can be created at a time. Which means that all of the matched + * elements will be displayed within the modal container. + * + * SimpleModal internally sets the CSS needed to display the modal dialog + * properly in all browsers, yet provides the developer with the flexibility + * to easily control the look and feel. The styling for SimpleModal can be + * done through external stylesheets, or through SimpleModal, using the + * overlayCss and/or containerCss options. + * + * SimpleModal has been tested in the following browsers: + * - IE 6, 7, 8 + * - Firefox 2, 3 + * - Opera 9 + * - Safari 3 + * - Chrome 1, 2 + * + * @name SimpleModal + * @type jQuery + * @requires jQuery v1.2.2 + * @cat Plugins/Windows and Overlays + * @author Eric Martin (http://ericmmartin.com) + * @version 1.3 + */ +;(function ($) { + var ie6 = $.browser.msie && parseInt($.browser.version) == 6 && typeof window['XMLHttpRequest'] != "object", + ieQuirks = null, + w = []; + + /* + * Stand-alone function to create a modal dialog. + * + * @param {string, object} data A string, jQuery object or DOM object + * @param {object} [options] An optional object containing options overrides + */ + $.modal = function (data, options) { + return $.modal.impl.init(data, options); + }; + + /* + * Stand-alone close function to close the modal dialog + */ + $.modal.close = function () { + $.modal.impl.close(); + }; + + /* + * Chained function to create a modal dialog. + * + * @param {object} [options] An optional object containing options overrides + */ + $.fn.modal = function (options) { + return $.modal.impl.init(this, options); + }; + + /* + * SimpleModal default options + * + * appendTo: (String:'body') The jQuery selector to append the elements to. For ASP.NET, use 'form'. + * focus: (Boolean:true) Forces focus to remain on the modal dialog + * opacity: (Number:50) The opacity value for the overlay div, from 0 - 100 + * overlayId: (String:'simplemodal-overlay') The DOM element id for the overlay div + * overlayCss: (Object:{}) The CSS styling for the overlay div + * containerId: (String:'simplemodal-container') The DOM element id for the container div + * containerCss: (Object:{}) The CSS styling for the container div + * dataId: (String:'simplemodal-data') The DOM element id for the data div + * dataCss: (Object:{}) The CSS styling for the data div + * minHeight: (Number:200) The minimum height for the container + * minWidth: (Number:200) The minimum width for the container + * maxHeight: (Number:null) The maximum height for the container. If not specified, the window height is used. + * maxWidth: (Number:null) The maximum width for the container. If not specified, the window width is used. + * autoResize: (Boolean:false) Resize container on window resize? Use with caution - this may have undesirable side-effects. + * zIndex: (Number: 1000) Starting z-index value + * close: (Boolean:true) If true, closeHTML, escClose and overClose will be used if set. + If false, none of them will be used. + * closeHTML: (String:'') The HTML for the + default close link. SimpleModal will automatically add the closeClass to this element. + * closeClass: (String:'simplemodal-close') The CSS class used to bind to the close event + * escClose: (Boolean:true) Allow Esc keypress to close the dialog? + * overlayClose: (Boolean:false) Allow click on overlay to close the dialog? + * position: (Array:null) Position of container [top, left]. Can be number of pixels or percentage + * persist: (Boolean:false) Persist the data across modal calls? Only used for existing + DOM elements. If true, the data will be maintained across modal calls, if false, + the data will be reverted to its original state. + * onOpen: (Function:null) The callback function used in place of SimpleModal's open + * onShow: (Function:null) The callback function used after the modal dialog has opened + * onClose: (Function:null) The callback function used in place of SimpleModal's close + */ + $.modal.defaults = { + appendTo: 'body', + focus: true, + opacity: 50, + overlayId: 'simplemodal-overlay', + overlayCss: {}, + containerId: 'simplemodal-container', + containerCss: {}, + dataId: 'simplemodal-data', + dataCss: {}, + minHeight: 200, + minWidth: 300, + maxHeight: null, + maxWidth: null, + autoResize: false, + zIndex: 1000, + close: true, + closeHTML: '', + closeClass: 'simplemodal-close', + escClose: true, + overlayClose: false, + position: null, + persist: false, + onOpen: null, + onShow: null, + onClose: null + }; + + /* + * Main modal object + */ + $.modal.impl = { + /* + * Modal dialog options + */ + opts: null, + /* + * Contains the modal dialog elements and is the object passed + * back to the callback (onOpen, onShow, onClose) functions + */ + dialog: {}, + /* + * Initialize the modal dialog + */ + init: function (data, options) { + // don't allow multiple calls + if (this.dialog.data) { + return false; + } + + // $.boxModel is undefined if checked earlier + ieQuirks = $.browser.msie && !$.boxModel; + + // merge defaults and user options + this.opts = $.extend({}, $.modal.defaults, options); + + // keep track of z-index + this.zIndex = this.opts.zIndex; + + // set the onClose callback flag + this.occb = false; + + // determine how to handle the data based on its type + if (typeof data == 'object') { + // convert DOM object to a jQuery object + data = data instanceof jQuery ? data : $(data); + + // if the object came from the DOM, keep track of its parent + if (data.parent().parent().size() > 0) { + this.dialog.parentNode = data.parent(); + + // persist changes? if not, make a clone of the element + if (!this.opts.persist) { + this.dialog.orig = data.clone(true); + } + } + } + else if (typeof data == 'string' || typeof data == 'number') { + // just insert the data as innerHTML + data = $('
').html(data); + } + else { + // unsupported data type! + alert('SimpleModal Error: Unsupported data type: ' + typeof data); + return false; + } + + // create the modal overlay, container and, if necessary, iframe + this.create(data); + data = null; + + // display the modal dialog + this.open(); + + // useful for adding events/manipulating data in the modal dialog + if ($.isFunction(this.opts.onShow)) { + this.opts.onShow.apply(this, [this.dialog]); + } + + // don't break the chain =) + return this; + }, + /* + * Create and add the modal overlay and container to the page + */ + create: function (data) { + // get the window properties + w = this.getDimensions(); + + // add an iframe to prevent select options from bleeding through + if (ie6) { + this.dialog.iframe = $('