From 951906dcecb1d3c7bcf751976a03e0c196ca6db0 Mon Sep 17 00:00:00 2001 From: Andrew Dolgov Date: Sun, 14 Nov 2010 23:46:49 +0300 Subject: [PATCH] use Modalbox library for popup dialogs --- backend.php | 2 +- functions.js | 96 +++--- infobox.css | 121 -------- lib/modalbox/license.txt | 1 + lib/modalbox/modalbox.css | 122 ++++++++ lib/modalbox/modalbox.js | 577 +++++++++++++++++++++++++++++++++++ lib/modalbox/spinner.gif | Bin 0 -> 7823 bytes lib/scriptaculous/builder.js | 136 +++++++++ modules/popup-dialog.php | 119 ++++---- modules/pref-feeds.php | 140 ++------- modules/pref-filters.php | 12 +- modules/pref-users.php | 21 +- prefs.js | 4 +- prefs.php | 15 +- tt-rss.css | 12 +- tt-rss.php | 17 +- 16 files changed, 1003 insertions(+), 392 deletions(-) delete mode 100644 infobox.css create mode 100644 lib/modalbox/license.txt create mode 100644 lib/modalbox/modalbox.css create mode 100644 lib/modalbox/modalbox.js create mode 100644 lib/modalbox/spinner.gif create mode 100644 lib/scriptaculous/builder.js diff --git a/backend.php b/backend.php index 13e7b934..e03e6a27 100644 --- a/backend.php +++ b/backend.php @@ -50,7 +50,7 @@ if ((!$op || $op == "rpc" || $op == "rss" || ($op == "view" && $mode != "zoom") || - $op == "digestSend" || $op == "viewfeed" || $op == "publish" || + $op == "digestSend" || $op == "dlg" || $op == "viewfeed" || $op == "publish" || $op == "globalUpdateFeeds") && !$_REQUEST["noxml"]) { header("Content-Type: application/xml; charset=utf-8"); diff --git a/functions.js b/functions.js index 56fafad9..1c21adf0 100644 --- a/functions.js +++ b/functions.js @@ -27,38 +27,34 @@ function exception_error(location, e, ext_info) { try { - var ebc = $("xebContent"); - - if (ebc) { - - Element.show("dialog_overlay"); - Element.show("errorBoxShadow"); - - if (ext_info) { - if (ext_info.responseText) { - ext_info = ext_info.responseText; - } + if (ext_info) { + if (ext_info.responseText) { + ext_info = ext_info.responseText; } - - ebc.innerHTML = - "
Error message:
" + - "
" + msg + "
"; + } - if (ext_info) { - ebc.innerHTML += "
Additional information:
" + - ""; - } + var content = "
" + + "
" + msg + "
"; - ebc.innerHTML += "
Stack trace:
" + - ""; - - } else { - alert(msg); + if (ext_info) { + content += "
Additional information:
" + + ""; } + content += "
Stack trace:
" + + ""; + + content += "
" + + "
"; + + // TODO: add code to automatically report errors to tt-rss.org + + Modalbox.show(content, {title: "Unhandled exception", width: 600, + resizeDuration: 0, transitions: false}); + } catch (e) { alert(msg); - } } @@ -322,7 +318,10 @@ function toggleSelectRow(sender, row) { function checkboxToggleElement(elem, id) { if (elem.checked) { - Effect.Appear(id, {duration : 0.5}); + Effect.Appear(id, {duration : 0.5, + afterSetup: function() { + Modalbox.resizeToContent(); + }}); } else { Effect.Fade(id, {duration : 0.5}); } @@ -391,26 +390,19 @@ function closeInfoBox(cleanup) { try { enableHotkeys(); + Modalbox.hide(); - if (Element.visible("infoBoxShadow")) { - Element.hide("dialog_overlay"); - Element.hide("infoBoxShadow"); - - if (cleanup) $("infoBox").innerHTML = " "; - } } catch (e) { - exception_error("closeInfoBox", e); + //exception_error("closeInfoBox", e); } - return false; } function displayDlg(id, param, callback) { - notify_progress("Loading, please wait...", true); - disableHotkeys(); + notify_progress("Loading, please wait...", true); var query = "?op=dlg&id=" + param_escape(id) + "¶m=" + param_escape(param); @@ -443,23 +435,30 @@ function infobox_submit_callback2(transport) { function infobox_callback2(transport) { try { - console.log("infobox_callback2"); + //console.log("infobox_callback2"); + notify(''); - var box = $('infoBox'); - - if (box) { + var content; + var dtitle = "Dialog"; - if (!getInitParam("infobox_disable_overlay")) { - Element.show("dialog_overlay"); - } + if (transport.responseXML) { + var dlg = transport.responseXML.getElementsByTagName("dlg")[0]; - box.innerHTML=transport.responseText; - Element.show("infoBoxShadow"); - //Effect.SlideDown("infoBoxShadow", {duration : 1.0}); + var title = transport.responseXML.getElementsByTagName("title")[0]; + if (title) + dtitle = title.firstChild.nodeValue; + var content = transport.responseXML.getElementsByTagName("content")[0]; + + content = content.firstChild.nodeValue; + } else { + content = transport.responseText; } + Modalbox.show(content, {title: dtitle, width: 600, + transitions: true, resizeDuration: 0 }); + disableHotkeys(); notify(""); @@ -604,7 +603,10 @@ function subscribeToFeed() { if (count > 5) count = 5; select.size = count; - Effect.Appear('fadd_feeds_container', {duration : 0.5}); + Effect.Appear('fadd_feeds_container', {duration : 0.5, + afterSetup: function() { + Modalbox.resizeToContent() + }}); } }); break; diff --git a/infobox.css b/infobox.css deleted file mode 100644 index 53f95a3f..00000000 --- a/infobox.css +++ /dev/null @@ -1,121 +0,0 @@ -#infoBoxTitle { - border-width : 0px 0px 1px 0px; - border-style : solid; - border-color : #659a4c; - background-color : #99d67a; - padding : 4px 2px 4px 10px; - color : white; - font-weight : bold; - font-size : 16px; - text-shadow : #659a4c 0px 1px 0px; -} - -/* shadow stuff from http://www.sixapart.com/pronet/articles/ydsf_-_robust_c.html */ - -#infoBox { - border-width : 1px 1px 1px 1px; - border-style : solid; - border-color : #659a4c; - background-color : #f8fcf5; - position: relative; - overflow : hidden; - left : -4px; - top : -4px; -} - -div#errorBox { - background-color : #ffcccc; - border : 1px solid #ff0000; - font-size : 12px; - position: relative; - overflow : hidden; - left : -4px; - top : -4px; -} - -html>body #infoBox, html>body #errorBox { - left : -10px; - top : -10px; - margin : 0; -} - -#infoBoxShadow:before, #infoBoxShadow:after, -#errorBoxShadow:before, #errorBoxShadow:after { - content : " "; - display : block; - background : inherit; - width : 10px; - height : 10px; -} - -#infoBoxShadow:before, #errorBoxShadow:before { - position : absolute; - top : 0; - right : 0; - margin : -10px 0 0 auto; - background-position : right top; -} - -#infoBoxShadow:after, #errorBoxShadow:after { - margin : -10px 0 0 -10px; - background-position : left bottom; -} - -#infoBoxShadow, #errorBoxShadow { - background-image : url("images/shadow.png"); - background-position : bottom right; - left : 25%; - top : 50px; - width : 50%; - position : absolute; - min-width : 600px; -} - -#infoBoxShadow { - z-index : 5; -} - -#errorBoxShadow { - z-index : 400; -} - -div.infoBoxContents { - padding : 10px; - margin-bottom : 5px; - font-size : 12px; -} - -div.infoBoxContents td { - font-size : 12px; -} - -div.infoBoxContents a { - color : #527040; -} - -div.infoBoxContents a:hover { - color : black; -} - -div#errorBox div#xebTitle { - background-color : #ff0000; - color : white; - padding : 4px 2px 4px 10px; - color : white; - font-weight : bold; - font-size : 12px; -} - -div#errorBox div#xebContent { - font-size : 12px; - padding : 10px; -} - -div#errorBox textarea { - width : 100%; - height : 100px; -} - -div#errorBox button { - margin-bottom : 10px; -} diff --git a/lib/modalbox/license.txt b/lib/modalbox/license.txt new file mode 100644 index 00000000..7ae2f892 --- /dev/null +++ b/lib/modalbox/license.txt @@ -0,0 +1 @@ +Copyright (c) 2006-2007 Andrey Okonetchnikov Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/lib/modalbox/modalbox.css b/lib/modalbox/modalbox.css new file mode 100644 index 00000000..60c30508 --- /dev/null +++ b/lib/modalbox/modalbox.css @@ -0,0 +1,122 @@ +/* + modalbox.css + + Modalbox project + + Created by Andrew Okonetchnikov. + Copyright 2006-2010 okonet.ru. All rights reserved. + + Licensed under MIT license. +*/ + +#MB_overlay { + position: absolute; + margin: auto; + top: 0; left: 0; + width: 100%; height: 100%; + z-index: 9999; + border: 0; + background-color: #000!important; +} +#MB_overlay[id] { position: fixed; } + +#MB_windowwrapper { + position:absolute; + top:0; + width:100%; +} + +#MB_window { + position:relative; + margin-left:auto; + margin-right:auto; + top:0; + left:0; + border: 0 solid; + text-align: left; + z-index: 10000; +} +#MB_window[id] { position: relative; } + +#MB_frame { + position: relative; + background-color: #EFEFEF; + height: 100%; +} + +#MB_header { + margin: 0; + padding: 0; +} + +#MB_content { + position: relative; + padding: 6px .75em; + overflow: auto; +} + +#MB_caption { + font: bold 100% "Lucida Grande", Arial, sans-serif; + text-shadow: #FFF 0 1px 0; + padding: .5em 2em .5em .75em; + margin: 0; + text-align: left; +} + +#MB_close { + display: block; + position: absolute; + right: 5px; top: 4px; + padding: 2px 3px; + font-weight: bold; + text-decoration: none; + font-size: 13px; +} +#MB_close:hover { + background: transparent; +} + +#MB_loading { + padding: 1.5em; + text-indent: -10000px; + background: transparent url(spinner.gif) 50% 0 no-repeat; +} + +/* Color scheme */ +#MB_window { + background-color: #EFEFEF; + color: #000; + + -webkit-box-shadow: 0 0 64px #000; + -moz-box-shadow: #000 0 0 64px; + box-shadow: 0 0 64px #000; +} + #MB_frame { + padding-bottom: 4px; + + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-bottomright: 4px; + + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + } + + #MB_content { border-top: 1px solid #F9F9F9; } + + #MB_header { + background-color: #DDD; + border-bottom: 1px solid #CCC; + } + #MB_caption { color: #000 } + #MB_close { color: #777 } + #MB_close:hover { color: #000 } + + +/* Alert message */ +.MB_alert { + margin: 10px 0; + text-align: center; +} \ No newline at end of file diff --git a/lib/modalbox/modalbox.js b/lib/modalbox/modalbox.js new file mode 100644 index 00000000..f338ec43 --- /dev/null +++ b/lib/modalbox/modalbox.js @@ -0,0 +1,577 @@ +// +// ModalBox - The pop-up window thingie with AJAX, based on Prototype JS framework. +// +// Created by Andrew Okonetchnikov +// Copyright 2006-2010 okonet.ru. All rights reserved. +// +// Licensed under MIT license. +// + +if (!window.Modalbox) + var Modalbox = new Object(); + +Modalbox.Methods = { + overrideAlert: false, // Override standard browser alert message with ModalBox + focusableElements: new Array, + currFocused: 0, + initialized: false, + active: true, + options: { + title: "ModalBox Window", // Title of the ModalBox window + overlayClose: true, // Close modal box by clicking on overlay + width: 500, // Default width in px + height: 90, // Default height in px + overlayOpacity: .65, // Default overlay opacity + overlayDuration: .25, // Default overlay fade in/out duration in seconds + slideDownDuration: .5, // Default Modalbox appear slide down effect in seconds + slideUpDuration: .5, // Default Modalbox hiding slide up effect in seconds + resizeDuration: .25, // Default resize duration seconds + inactiveFade: true, // Fades MB window on inactive state + transitions: true, // Toggles transition effects. Transitions are enabled by default + loadingString: "Please wait. Loading...", // Default loading string message + closeString: "Close window", // Default title attribute for close window link + closeValue: "×", // Default string for close link in the header + params: {}, + method: 'get', // Default Ajax request method + autoFocusing: true, // Toggles auto-focusing for form elements. Disable for long text pages. + aspnet: false, // Should be use then using with ASP.NET costrols. Then true Modalbox window will be injected into the first form element. + resizeCSSID: '' + }, + _options: new Object, + + setOptions: function(options) { + Object.extend(this.options, options || {}); + }, + + _init: function(options) { + // Setting up original options with default options + Object.extend(this._options, this.options); + this.setOptions(options); + + //Creating the overlay + this.MBoverlay = new Element("div", { id: "MB_overlay", style: "opacity: 0" }); + + //Creating the modal window + this.MBwindowwrapper = new Element("div", {id: "MB_windowwrapper"}).update( + this.MBwindow = new Element("div", {id: "MB_window", style: "display: none"}).update( + this.MBframe = new Element("div", {id: "MB_frame"}).update( + this.MBheader = new Element("div", {id: "MB_header"}).update( + this.MBcaption = new Element("div", {id: "MB_caption"}) + ) + ) + ) + ); + + this.MBclose = new Element("a", {id: "MB_close", title: this.options.closeString, href: "#"}).update("" + this.options.closeValue + ""); + this.MBheader.insert({'bottom':this.MBclose}); + + this.MBcontent = new Element("div", {id: "MB_content"}).update( + this.MBloading = new Element("div", {id: "MB_loading"}).update(this.options.loadingString) + ); + this.MBframe.insert({'bottom':this.MBcontent}); + + // Inserting into DOM. If parameter set and form element have been found will inject into it. Otherwise will inject into body as topmost element. + // Be sure to set padding and marging to null via CSS for both body and (in case of asp.net) form elements. + var injectToEl = this.options.aspnet ? $(document.body).down('form') : $(document.body); + injectToEl.insert({'top':this.MBwindowwrapper}); + injectToEl.insert({'top':this.MBoverlay}); + + var scrollOffsets = document.viewport.getScrollOffsets(); + if (scrollOffsets[1] > 0) { + $('MB_window').setStyle({top:scrollOffsets[1] + 'px'}); + } + + Event.observe(window, 'scroll', function() { + scrollOffsets = document.viewport.getScrollOffsets(); + $('MB_window').setStyle({top:scrollOffsets[1] + 'px'}); + }); + + // Initial scrolling position of the window. To be used for remove scrolling effect during ModalBox appearing + this.initScrollX = window.pageXOffset || document.body.scrollLeft || document.documentElement.scrollLeft; + this.initScrollY = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop; + + //Adding event observers + this.hideObserver = this._hide.bindAsEventListener(this); + this.kbdObserver = this._kbdHandler.bindAsEventListener(this); + this._initObservers(); + + this.initialized = true; // Mark as initialized + }, + + show: function(content, options) { + if(!this.initialized) this._init(options); // Check for is already initialized + + this.content = content; + this.setOptions(options); + + if(this.options.title) // Updating title of the MB + $(this.MBcaption).update(this.options.title); + else { // If title isn't given, the header will not displayed + $(this.MBheader).hide(); + $(this.MBcaption).hide(); + } + + if(this.MBwindow.style.display == "none") { // First modal box appearing + this._appear(); + this.event("onShow"); // Passing onShow callback + } + else { // If MB already on the screen, update it + this._update(); + this.event("onUpdate"); // Passing onUpdate callback + } + }, + + hide: function(options) { // External hide method to use from external HTML and JS + if(this.initialized) { + // Reading for options/callbacks except if event given as a pararmeter + if(options && typeof options.element != 'function') Object.extend(this.options, options); + // Passing beforeHide callback + this.event("beforeHide"); + if(this.options.transitions) + Effect.SlideUp(this.MBwindow, { duration: this.options.slideUpDuration, transition: Effect.Transitions.sinoidal, afterFinish: this._deinit.bind(this) } ); + else { + $(this.MBwindow).hide(); + this._deinit(); + } + Event.stopObserving(window, 'scroll'); + } else throw("Modalbox is not initialized."); + }, + + _hide: function(event) { // Internal hide method to use with overlay and close link + event.stop(); // Stop event propaganation for link elements + /* Then clicked on overlay we'll check the option and in case of overlayClose == false we'll break hiding execution [Fix for #139] */ + if(event.element().id == 'MB_overlay' && !this.options.overlayClose) return false; + this.hide(); + }, + + alert: function(message){ + var html = '

' + message + '

'; + Modalbox.show(html, {title: 'Alert: ' + document.title, width: 300}); + }, + + _appear: function() { // First appearing of MB + if(Prototype.Browser.IE && !navigator.appVersion.match(/\b7.0\b/)) { // Preparing IE 6 for showing modalbox + window.scrollTo(0,0); + this._prepareIE("100%", "hidden"); + } + this._setWidth(); + if(this.options.transitions) { + $(this.MBoverlay).setStyle({opacity: 0}); + new Effect.Fade(this.MBoverlay, { + from: 0, + to: this.options.overlayOpacity, + duration: this.options.overlayDuration, + afterFinish: function() { + new Effect.SlideDown(this.MBwindow, { + duration: this.options.slideDownDuration, + transition: Effect.Transitions.sinoidal, + afterFinish: function(){ + this.loadContent(); + }.bind(this) + }); + }.bind(this) + }); + } else { + $(this.MBoverlay).setStyle({opacity: this.options.overlayOpacity}); + $(this.MBwindow).show(); + this.loadContent(); + } + this._setWidthAndPosition = this._setWidthAndPosition.bindAsEventListener(this); + Event.observe(window, "resize", this._setWidthAndPosition); + }, + + resize: function(byWidth, byHeight, options) { // Change size of MB without loading content + var oWidth = $(this.MBoverlay).getWidth(); + var wHeight = $(this.MBwindow).getHeight(); + var wWidth = $(this.MBwindow).getWidth(); + var hHeight = $(this.MBheader).getHeight(); + var cHeight = $(this.MBcontent).getHeight(); + var newHeight = ((wHeight - hHeight + byHeight) < cHeight) ? (cHeight + hHeight) : (wHeight + byHeight); + + var el = $(this.MBwindow); + var contentEl = $(this.MBcontent); + var windowBottomMargin = 10; + var windowOffset = (parseInt(el.getStyle('margin-top'), 0) + parseInt(el.getStyle('margin-bottom'), 0) + parseInt(el.getStyle('border-top-width'), 0) + parseInt(el.getStyle('border-bottom-width'), 0)) + windowBottomMargin; + var contentPadding = (parseInt(contentEl.getStyle('padding-top')) + parseInt(contentEl.getStyle('padding-bottom'))); + + if ((newHeight + windowOffset + contentPadding) > document.viewport.getHeight()) { + // adjust window height to account for margins and border widths + newHeight = document.viewport.getHeight() - windowOffset - windowBottomMargin; + // calculate content height including header height and padding values + newcHeight = newHeight - hHeight - parseInt($(this.MBframe).getStyle('padding-bottom'), 0) - parseInt($(this.MBcontent).getStyle('padding-bottom'), 0); + $(this.MBcontent).setStyle({height:newcHeight + 'px'}); + } + else if ($(this.MBcontent).getStyle('height')) { + // release any MB_content height set prior to establish scrollbars in content area + $(this.MBcontent).setStyle({height:''}); + } + + var newWidth = wWidth + byWidth; + this.options.width = newWidth; + if(options) this.setOptions(options); // Passing callbacks + if(this.options.transitions && !Modalbox.animating) { + Modalbox.animating = true; + new Effect.Morph(this.MBwindow, { + style: "width:" + newWidth + "px; height:" + newHeight + "px;", + duration: this.options.resizeDuration, + beforeStart: function(fx){ + fx.element.setStyle({overflow:"hidden"}); // Fix for MSIE 6 to resize correctly + }, + afterFinish: function(fx) { + fx.element.setStyle({overflow:"visible"}); + this.event("_afterResize"); // Passing internal callback + this.event("afterResize"); // Passing callback + Modalbox.animating = false; + }.bind(this) + }); + } else { + this.MBwindow.setStyle({width: newWidth + "px", height: newHeight + "px"}); + setTimeout(function() { + this.event("_afterResize"); // Passing internal callback + this.event("afterResize"); // Passing callback + }.bind(this), 1); + } + + }, + + resizeToContent: function(options){ + // Resizes the modalbox window to the actual content height. + // This might be useful to resize modalbox after some content modifications which were changed ccontent height. + + if (typeof options == "undefined") { + options = new Object(); + } + + // check to see if MB_content includes any images + var mbimages = $('MB_content').select('img'); + var totalimages = mbimages.length; + if (mbimages[0]) { + if (typeof options.imagesloaded == "undefined") { + + var loadedImages = $A(); + var loadedImageTotal = 0; + mbimages.each(function(o,idx) { + loadedImages[idx] = new Image(); + loadedImages[idx].src = o.src; + loadedImages[idx].onload = function() { + loadedImageTotal++; + if (loadedImageTotal == totalimages) { + // make sure all images have been rendered by checking their height + var imageincomplete = false; + mbimages.each(function(i) { + if (i.height == 0) { + imageincomplete = true; + } + }); + if (imageincomplete || Modalbox.animating) { + // some image hasn't been rendered yet, trigger resize loop until it is + Modalbox.resizeToContent(); + } + else { + // trigger one final resize, but set imagesloaded option to skip inspection of images + options.imagesloaded = true; + Modalbox.resizeToContent(options); + } + } + } + }) + } + } + + var byHeight = this.options.height - $(this.MBwindow).getHeight(); + if (options.resizeCSSID && $(options.resizeCSSID)) { + // byWidth is the amount of pixels needed to increase/decrease window to meet width of options.resizeCSSID + // plus a 10 pixel margin to accommodate scrollbars + var byWidth = $(options.resizeCSSID).getWidth() - $(this.MBwindow).getWidth() + (parseInt($(this.MBcontent).getStyle('padding-left'), 0) + parseInt($(this.MBcontent).getStyle('padding-right'), 0)) + 15; + } + else { + // don't change width + var byWidth = 0; + } + if(byHeight != 0) { + if(options) this.setOptions(options); // Passing callbacks + Modalbox.resize(byWidth, byHeight); + } + }, + + resizeToInclude: function(element, options){ + + // Resizes the modalbox window to the camulative height of element. Calculations are using CSS properties for margins and border. + // This method might be useful to resize modalbox before including or updating content. + + var el = $(element); + var elHeight = el.getHeight() + parseInt(el.getStyle('margin-top'), 0) + parseInt(el.getStyle('margin-bottom'), 0) + parseInt(el.getStyle('border-top-width'), 0) + parseInt(el.getStyle('border-bottom-width'), 0); + if(elHeight > 0) { + if(options) this.setOptions(options); // Passing callbacks + Modalbox.resize(0, elHeight); + } + }, + + _update: function() { // Updating MB in case of wizards + $(this.MBcontent).update($(this.MBloading).update(this.options.loadingString)); + this.loadContent(); + }, + + loadContent: function () { + if(this.event("beforeLoad") != false) { // If callback passed false, skip loading of the content + if(typeof this.content == 'string') { + var htmlRegExp = new RegExp(/<\/?[^>]+>/gi); + if(htmlRegExp.test(this.content)) { // Plain HTML given as a parameter + this._insertContent(this.content.stripScripts(), function(){ + this.content.extractScripts().map(function(script) { + return eval(script.replace("", "")); + }.bind(window)); + }.bind(this)); + } else // URL given as a parameter. We'll request it via Ajax + new Ajax.Request( this.content, { method: this.options.method.toLowerCase(), parameters: this.options.params, + onComplete: function(transport) { + var response = new String(transport.responseText); + this._insertContent(transport.responseText.stripScripts(), function(){ + response.extractScripts().map(function(script) { + return eval(script.replace("", "")); + }.bind(window)); + }); + }.bind(this), + onException: function(instance, exception){ + Modalbox.hide(); + throw('Modalbox Loading Error: ' + exception); + } + }); + + } else if (typeof this.content == 'object') {// HTML Object is given + this._insertContent(this.content); + } else { + Modalbox.hide(); + throw('Modalbox Parameters Error: Please specify correct URL or HTML element (plain HTML or object)'); + } + } + }, + + _insertContent: function(content, callback){ + $(this.MBcontent).hide().update(""); + if(typeof content == 'string') { // Plain HTML is given + this.MBcontent.update(new Element("div", { style: "display: none" }).update(content)).down().show(); + } else if (typeof content == 'object') { // HTML Object is given + var _htmlObj = content.cloneNode(true); // If node already a part of DOM we'll clone it + // If clonable element has ID attribute defined, modifying it to prevent duplicates + if(content.id) content.id = "MB_" + content.id; + /* Add prefix for IDs on all elements inside the DOM node */ + $(content).select('*[id]').each(function(el){ el.id = "MB_" + el.id; }); + this.MBcontent.update(_htmlObj).down('div').show(); + if(Prototype.Browser.IE) // Toggling back visibility for hidden selects in IE + $$("#MB_content select").invoke('setStyle', {'visibility': ''}); + } + + // Prepare and resize modal box for content + if(this.options.height == this._options.height) { + Modalbox.resize((this.options.width - $(this.MBwindow).getWidth()), $(this.MBcontent).getHeight() - $(this.MBwindow).getHeight() + $(this.MBheader).getHeight(), { + afterResize: function(){ + setTimeout(function(){ // MSIE fix + this._putContent(callback); + }.bind(this),1); + }.bind(this) + }); + } else { // Height is defined. Creating a scrollable window + this._setWidth(); + this.MBcontent.setStyle({overflow: 'auto', height: $(this.MBwindow).getHeight() - $(this.MBheader).getHeight() - 13 + 'px'}); + setTimeout(function(){ // MSIE fix + this._putContent(callback); + }.bind(this),1); + } + }, + + _putContent: function(callback){ + this.MBcontent.show(); + this.focusableElements = this._findFocusableElements(); + this._setFocus(); // Setting focus on first 'focusable' element in content (input, select, textarea, link or button) + if(callback != undefined) + callback(); // Executing internal JS from loaded content + this.event("afterLoad"); // Passing callback + }, + + activate: function(options){ + this.setOptions(options); + this.active = true; + $(this.MBclose).observe("click", this.hideObserver); + if(this.options.overlayClose) + $(this.MBoverlay).observe("click", this.hideObserver); + $(this.MBclose).show(); + if(this.options.transitions && this.options.inactiveFade) + new Effect.Appear(this.MBwindow, {duration: this.options.slideUpDuration}); + }, + + deactivate: function(options) { + this.setOptions(options); + this.active = false; + $(this.MBclose).stopObserving("click", this.hideObserver); + if(this.options.overlayClose) + $(this.MBoverlay).stopObserving("click", this.hideObserver); + $(this.MBclose).hide(); + if(this.options.transitions && this.options.inactiveFade) + new Effect.Fade(this.MBwindow, {duration: this.options.slideUpDuration, to: .75}); + }, + + _initObservers: function(){ + $(this.MBclose).observe("click", this.hideObserver); + if(this.options.overlayClose) + $(this.MBoverlay).observe("click", this.hideObserver); + if(Prototype.Browser.Gecko) + Event.observe(document, "keypress", this.kbdObserver); // Gecko is moving focus a way too fast + else + Event.observe(document, "keydown", this.kbdObserver); // All other browsers are okay with keydown + }, + + _removeObservers: function(){ + $(this.MBclose).stopObserving("click", this.hideObserver); + if(this.options.overlayClose) + $(this.MBoverlay).stopObserving("click", this.hideObserver); + if(Prototype.Browser.Gecko) + Event.stopObserving(document, "keypress", this.kbdObserver); + else + Event.stopObserving(document, "keydown", this.kbdObserver); + }, + + _setFocus: function() { + /* Setting focus to the first 'focusable' element which is one with tabindex = 1 or the first in the form loaded. */ + if(this.focusableElements.length > 0 && this.options.autoFocusing == true) { + var firstEl = this.focusableElements.find(function (el){ + return el.tabIndex == 1; + }) || this.focusableElements.first(); + this.currFocused = this.focusableElements.toArray().indexOf(firstEl); + firstEl.focus(); // Focus on first focusable element except close button + } else if($(this.MBclose).visible()) + $(this.MBclose).focus(); // If no focusable elements exist focus on close button + }, + + _findFocusableElements: function(){ // Collect form elements or links from MB content + this.MBcontent.select('input:not([type~=hidden]), select, textarea, button, a[href]').invoke('addClassName', 'MB_focusable'); + return this.MBcontent.select('.MB_focusable'); + }, + + _kbdHandler: function(event) { + var node = event.element(); + switch(event.keyCode) { + case Event.KEY_TAB: + event.stop(); + + /* Switching currFocused to the element which was focused by mouse instead of TAB-key. Fix for #134 */ + if(node != this.focusableElements[this.currFocused]) + this.currFocused = this.focusableElements.toArray().indexOf(node); + + if(!event.shiftKey) { //Focusing in direct order + if(this.currFocused == this.focusableElements.length - 1) { + this.focusableElements.first().focus(); + this.currFocused = 0; + } else { + this.currFocused++; + this.focusableElements[this.currFocused].focus(); + } + } else { // Shift key is pressed. Focusing in reverse order + if(this.currFocused == 0) { + this.focusableElements.last().focus(); + this.currFocused = this.focusableElements.length - 1; + } else { + this.currFocused--; + this.focusableElements[this.currFocused].focus(); + } + } + break; + case Event.KEY_ESC: + if(this.active) this._hide(event); + break; + case 32: + this._preventScroll(event); + break; + case 0: // For Gecko browsers compatibility + if(event.which == 32) this._preventScroll(event); + break; + case Event.KEY_UP: + case Event.KEY_DOWN: + case Event.KEY_PAGEDOWN: + case Event.KEY_PAGEUP: + case Event.KEY_HOME: + case Event.KEY_END: + // Safari operates in slightly different way. This realization is still buggy in Safari. + if(Prototype.Browser.WebKit && !["textarea", "select"].include(node.tagName.toLowerCase())) + event.stop(); + else if( (node.tagName.toLowerCase() == "input" && ["submit", "button"].include(node.type)) || (node.tagName.toLowerCase() == "a") ) + event.stop(); + break; + } + }, + + _preventScroll: function(event) { // Disabling scrolling by "space" key + if(!["input", "textarea", "select", "button"].include(event.element().tagName.toLowerCase())) + event.stop(); + }, + + _deinit: function() + { + this._removeObservers(); + Event.stopObserving(window, "resize", this._setWidthAndPosition ); + if(this.options.transitions) { + Effect.toggle(this.MBoverlay, 'appear', {duration: this.options.overlayDuration, afterFinish: this._removeElements.bind(this) }); + } else { + this.MBoverlay.hide(); + this._removeElements(); + } + $(this.MBcontent).setStyle({overflow: '', height: ''}); + }, + + _removeElements: function () { + $(this.MBoverlay).remove(); + $(this.MBwindow).remove(); + if(Prototype.Browser.IE && !navigator.appVersion.match(/\b7.0\b/)) { + this._prepareIE("", ""); // If set to auto MSIE will show horizontal scrolling + window.scrollTo(this.initScrollX, this.initScrollY); + } + + /* Replacing prefixes 'MB_' in IDs for the original content */ + if(typeof this.content == 'object') { + if(this.content.id && this.content.id.match(/MB_/)) { + this.content.id = this.content.id.replace(/MB_/, ""); + } + this.content.select('*[id]').each(function(el){ el.id = el.id.replace(/MB_/, ""); }); + } + /* Initialized will be set to false */ + this.initialized = false; + this.event("afterHide"); // Passing afterHide callback + this.setOptions(this._options); //Settings options object into intial state + }, + + _setWidth: function () { //Set size + $(this.MBwindow).setStyle({width: this.options.width + "px", height: this.options.height + "px"}); + }, + + _setWidthAndPosition: function () { + $(this.MBwindow).setStyle({width: this.options.width + "px"}); + }, + + _getScrollTop: function () { //From: http://www.quirksmode.org/js/doctypes.html + var theTop; + if (document.documentElement && document.documentElement.scrollTop) + theTop = document.documentElement.scrollTop; + else if (document.body) + theTop = document.body.scrollTop; + return theTop; + }, + _prepareIE: function(height, overflow){ + $$('html, body').invoke('setStyle', {width: height, height: height, overflow: overflow}); // IE requires width and height set to 100% and overflow hidden + $$("select").invoke('setStyle', {'visibility': overflow}); // Toggle visibility for all selects in the common document + }, + event: function(eventName) { + if(this.options[eventName]) { + var returnValue = this.options[eventName](); // Executing callback + this.options[eventName] = null; // Removing callback after execution + if(returnValue != undefined) + return returnValue; + else + return true; + } + return true; + } +}; + +Object.extend(Modalbox, Modalbox.Methods); + +if(Modalbox.overrideAlert) window.alert = Modalbox.alert; \ No newline at end of file diff --git a/lib/modalbox/spinner.gif b/lib/modalbox/spinner.gif new file mode 100644 index 0000000000000000000000000000000000000000..39615c89252d05f980b2cda99be6b153b26b20c1 GIT binary patch literal 7823 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 literal 0 HcmV?d00001 diff --git a/lib/scriptaculous/builder.js b/lib/scriptaculous/builder.js new file mode 100644 index 00000000..f1f42b9a --- /dev/null +++ b/lib/scriptaculous/builder.js @@ -0,0 +1,136 @@ +// script.aculo.us builder.js v1.8.3, Thu Oct 08 11:23:33 +0200 2009 + +// Copyright (c) 2005-2009 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// +// script.aculo.us is freely distributable under the terms of an MIT-style license. +// For details, see the script.aculo.us web site: http://script.aculo.us/ + +var Builder = { + NODEMAP: { + AREA: 'map', + CAPTION: 'table', + COL: 'table', + COLGROUP: 'table', + LEGEND: 'fieldset', + OPTGROUP: 'select', + OPTION: 'select', + PARAM: 'object', + TBODY: 'table', + TD: 'table', + TFOOT: 'table', + TH: 'table', + THEAD: 'table', + TR: 'table' + }, + // note: For Firefox < 1.5, OPTION and OPTGROUP tags are currently broken, + // due to a Firefox bug + node: function(elementName) { + elementName = elementName.toUpperCase(); + + // try innerHTML approach + var parentTag = this.NODEMAP[elementName] || 'div'; + var parentElement = document.createElement(parentTag); + try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707 + parentElement.innerHTML = "<" + elementName + ">"; + } catch(e) {} + var element = parentElement.firstChild || null; + + // see if browser added wrapping tags + if(element && (element.tagName.toUpperCase() != elementName)) + element = element.getElementsByTagName(elementName)[0]; + + // fallback to createElement approach + if(!element) element = document.createElement(elementName); + + // abort if nothing could be created + if(!element) return; + + // attributes (or text) + if(arguments[1]) + if(this._isStringOrNumber(arguments[1]) || + (arguments[1] instanceof Array) || + arguments[1].tagName) { + this._children(element, arguments[1]); + } else { + var attrs = this._attributes(arguments[1]); + if(attrs.length) { + try { // prevent IE "feature": http://dev.rubyonrails.org/ticket/2707 + parentElement.innerHTML = "<" +elementName + " " + + attrs + ">"; + } catch(e) {} + element = parentElement.firstChild || null; + // workaround firefox 1.0.X bug + if(!element) { + element = document.createElement(elementName); + for(attr in arguments[1]) + element[attr == 'class' ? 'className' : attr] = arguments[1][attr]; + } + if(element.tagName.toUpperCase() != elementName) + element = parentElement.getElementsByTagName(elementName)[0]; + } + } + + // text, or array of children + if(arguments[2]) + this._children(element, arguments[2]); + + return $(element); + }, + _text: function(text) { + return document.createTextNode(text); + }, + + ATTR_MAP: { + 'className': 'class', + 'htmlFor': 'for' + }, + + _attributes: function(attributes) { + var attrs = []; + for(attribute in attributes) + attrs.push((attribute in this.ATTR_MAP ? this.ATTR_MAP[attribute] : attribute) + + '="' + attributes[attribute].toString().escapeHTML().gsub(/"/,'"') + '"'); + return attrs.join(" "); + }, + _children: function(element, children) { + if(children.tagName) { + element.appendChild(children); + return; + } + if(typeof children=='object') { // array can hold nodes and text + children.flatten().each( function(e) { + if(typeof e=='object') + element.appendChild(e); + else + if(Builder._isStringOrNumber(e)) + element.appendChild(Builder._text(e)); + }); + } else + if(Builder._isStringOrNumber(children)) + element.appendChild(Builder._text(children)); + }, + _isStringOrNumber: function(param) { + return(typeof param=='string' || typeof param=='number'); + }, + build: function(html) { + var element = this.node('div'); + $(element).update(html.strip()); + return element.down(); + }, + dump: function(scope) { + if(typeof scope != 'object' && typeof scope != 'function') scope = window; //global scope + + var tags = ("A ABBR ACRONYM ADDRESS APPLET AREA B BASE BASEFONT BDO BIG BLOCKQUOTE BODY " + + "BR BUTTON CAPTION CENTER CITE CODE COL COLGROUP DD DEL DFN DIR DIV DL DT EM FIELDSET " + + "FONT FORM FRAME FRAMESET H1 H2 H3 H4 H5 H6 HEAD HR HTML I IFRAME IMG INPUT INS ISINDEX "+ + "KBD LABEL LEGEND LI LINK MAP MENU META NOFRAMES NOSCRIPT OBJECT OL OPTGROUP OPTION P "+ + "PARAM PRE Q S SAMP SCRIPT SELECT SMALL SPAN STRIKE STRONG STYLE SUB SUP TABLE TBODY TD "+ + "TEXTAREA TFOOT TH THEAD TITLE TR TT U UL VAR").split(/\s+/); + + tags.each( function(tag){ + scope[tag] = function() { + return Builder.node.apply(Builder, [tag].concat($A(arguments))); + }; + }); + } +}; \ No newline at end of file diff --git a/modules/popup-dialog.php b/modules/popup-dialog.php index 8d3c2cee..c018acbd 100644 --- a/modules/popup-dialog.php +++ b/modules/popup-dialog.php @@ -3,9 +3,11 @@ $id = $_REQUEST["id"]; $param = db_escape_string($_REQUEST["param"]); + print ""; + if ($id == "importOpml") { - print "
".__('OPML Import')."
"; - print "
"; + print "".__('OPML Import').""; + print ""; @@ -58,15 +60,16 @@ print "parent.opmlImportHandler(this)"; print ""; - print "
"; + print ""; + print "]]>"; - return; + //return; } if ($id == "editPrefProfiles") { - print "
".__('Settings Profiles')."
"; - print "
"; + print "".__('Settings Profiles').""; + print "". __('Close this window').""; - print "
"; + print ""; + print "]]>"; - return; + //return; } if ($id == "pubOPMLUrl") { - print "
".__('Public OPML URL')."
"; - print "
"; + print "".__('Public OPML URL').""; + print "". __('Close this window').""; - print "
"; + print ""; + print "]]>"; - return; + //return; } if ($id == "explainError") { - print "
".__('Notice')."
"; - print "
"; + print "".__('Notice').""; + print ""; @@ -227,15 +232,16 @@ print "
"; + print ""; + print "]]>"; - return; + //return; } if ($id == "quickAddFeed") { - print "
".__('Subscribe to Feed')."
"; - print "
"; + print "".__('Subscribe to Feed').""; + print ""; @@ -295,15 +301,17 @@ onclick=\"return subscribeToFeed()\">".__('Subscribe')."
"; - - return; + + print "]]>"; + + //return; } if ($id == "feedBrowser") { - print "
".__('Feed Browser')."
"; + print "".__('Feed Browser').""; - print "
"; + print "".__('Remove')."
"; - print ""; - return; + print "]]>"; + //return; } if ($id == "search") { - print "
".__('Search')."
"; - print "
"; + print "".__('Search').""; + print ""; @@ -433,9 +441,9 @@
"; - print ""; + print "]]>"; - return; + //return; } @@ -443,8 +451,8 @@ $active_feed_id = db_escape_string($_REQUEST["param"]); - print "
".__('Create Filter')."
"; - print "
"; + print "".__('Create Filter').""; + print ""; @@ -550,17 +558,17 @@ print ""; - print "
"; + print "]]>"; // print ""; - return; + //return; } if ($id == "feedUpdateErrors") { - print "
".__('Update Errors')."
"; - print "
"; + print "".__('Update Errors').""; + print "". __('Close this window').""; - print "
"; + print "]]>"; - return; + //return; } if ($id == "editArticleTags") { - print "
".__('Edit Tags')."
"; - print "
"; + print "".__('Edit Tags').""; + print ""; @@ -618,14 +626,14 @@ print " "; print ""; - print "
"; + print "]]>"; - return; + //return; } if ($id == "printTagCloud") { - print "
".__('Tag Cloud')."
"; - print "
"; + print "".__('Tag Cloud').""; + print "".__('more tags')."):
"; @@ -641,15 +649,15 @@ __('Close this window').""; print "
"; - print ""; + print "]]>"; - return; + //return; } if ($id == "emailArticle") { - print "
".__('Forward article by email')."
"; - print "
"; + print "".__('Forward article by email').""; + print ""; @@ -754,15 +762,15 @@ print " "; print ""; - print "
"; + print "]]>"; - return; + //return; } if ($id == "generatedFeed") { - print "
".__('View as RSS')."
"; - print "
"; + print "".__('View as RSS').""; + print "". __('Close this window').""; - print "
"; + print ""; + print "]]>"; - return; + //return; } - print "
Internal Error
-
-

Unknown dialog $id

-
"; - + print ""; } ?> diff --git a/modules/pref-feeds.php b/modules/pref-feeds.php index b2ca96fb..38f7b577 100644 --- a/modules/pref-feeds.php +++ b/modules/pref-feeds.php @@ -58,114 +58,13 @@ return; } -/* if ($subop == "massSubscribe") { - $ids = split(",", db_escape_string($_REQUEST["ids"])); - - $subscribed = array(); - - foreach ($ids as $id) { - - if ($mode == 1) { - $result = db_query($link, "SELECT feed_url,title FROM ttrss_feeds - WHERE id = '$id'"); - } else if ($mode == 2) { - $result = db_query($link, "SELECT * FROM ttrss_archived_feeds - WHERE id = '$id' AND owner_uid = " . $_SESSION["uid"]); - $orig_id = db_escape_string(db_fetch_result($result, 0, "id")); - $site_url = db_escape_string(db_fetch_result($result, 0, "site_url")); - } - - $feed_url = db_escape_string(db_fetch_result($result, 0, "feed_url")); - $title = db_escape_string(db_fetch_result($result, 0, "title")); - - $title_orig = db_fetch_result($result, 0, "title"); - - $result = db_query($link, "SELECT id FROM ttrss_feeds WHERE - feed_url = '$feed_url' AND owner_uid = " . $_SESSION["uid"]); - - if (db_num_rows($result) == 0) { - if ($mode == 1) { - $result = db_query($link, - "INSERT INTO ttrss_feeds (owner_uid,feed_url,title,cat_id) - VALUES ('".$_SESSION["uid"]."', '$feed_url', '$title', NULL)"); - } else if ($mode == 2) { - $result = db_query($link, - "INSERT INTO ttrss_feeds (id,owner_uid,feed_url,title,cat_id,site_url) - VALUES ('$orig_id','".$_SESSION["uid"]."', '$feed_url', '$title', NULL, '$site_url')"); - } - array_push($subscribed, $title_orig); - } - } - - if (count($subscribed) > 0) { - $msg = "".__('Subscribed to feeds:')."". - ""; - - print format_notice($msg); - } - - return; - } */ - -/* if ($subop == "browse") { - - print "
".__('Feed Browser')."
"; - - print "
"; - - $browser_search = db_escape_string($_REQUEST["search"]); - - //print "

".__("Showing top 25 registered feeds, sorted by popularity:")."

"; - - print "
"; - - print " -
- - - -
"; - - print " "; - - print __("limit:"); - - print " "; - - print "

"; - - $owner_uid = $_SESSION["uid"]; - - print "

    "; - print_feed_browser($link, $search, 25); - print "
"; + if ($subop == "editfeed") { + header("Content-Type: text/xml"); - print "
- -
"; + print ""; + print "".__('Feed Editor').""; + print ""; - return; - } */ - - if ($subop == "editfeed") { $feed_id = db_escape_string($_REQUEST["id"]); $result = db_query($link, @@ -184,10 +83,6 @@ $feed_icon = ""; } - print "
".__('Feed Editor')."
"; - - print "
"; - print ""; print ""; @@ -402,16 +297,19 @@
"; + print "]]>
"; + return; } if ($subop == "editfeeds") { $feed_ids = db_escape_string($_REQUEST["ids"]); - - print "
".__('Multiple Feed Editor')."
"; - - print "
"; + + header("Content-Type: text/xml"); + print ""; + print "".__('Multiple Feed Editor').""; + print ""; @@ -555,6 +453,8 @@ onclick=\"return feedEditCancel()\" value=\"".__('Cancel')."\">
"; + print "]]>"; + return; } @@ -954,10 +854,10 @@ } - print "
".__('Category editor')."
"; - - print "
"; - + header("Content-Type: text/xml"); + print ""; + print "".__('Category editor').""; + print "". __('Close this window')."
"; - print "
"; + print "]]>"; return; @@ -1189,8 +1089,6 @@ if (db_num_rows($result) != 0) { -// print "
PLACEHOLDER
"; - print "

"; print "
". diff --git a/modules/pref-filters.php b/modules/pref-filters.php index d11d0eb7..b50b0410 100644 --- a/modules/pref-filters.php +++ b/modules/pref-filters.php @@ -7,6 +7,11 @@ $filter_id = db_escape_string($_REQUEST["id"]); + header("Content-Type: text/xml"); + print ""; + print "".__('Filter Editor').""; + print "".__('Filter Editor').""; - print "
"; - print ""; print ""; @@ -158,7 +160,7 @@ print ""; - print "
"; + print "]]>
"; return; } @@ -278,8 +280,6 @@ $sort = "reg_exp"; } -// print "
PLACEHOLDER
"; - $result = db_query($link, "SELECT id,description FROM ttrss_filter_types ORDER BY description"); diff --git a/modules/pref-users.php b/modules/pref-users.php index 754eb7b6..f1f25c66 100644 --- a/modules/pref-users.php +++ b/modules/pref-users.php @@ -12,11 +12,14 @@ if ($subop == "user-details") { + header("Content-Type: text/xml"); + print ""; + $uid = sprintf("%d", $_REQUEST["id"]); - print "
".__('User details')."
"; + print "".__('User details').""; - print "
"; + print "".__("Close this window"). "
"; - print ""; + print "]]>
"; return; } if ($subop == "edit") { + header("Content-Type: text/xml"); + $id = db_escape_string($_REQUEST["id"]); - print "
".__('User Editor')."
"; - - print "
"; + print ""; + print "".__('User Editor').""; + print ""; @@ -180,7 +185,7 @@
"; - print ""; + print "]]>"; return; } @@ -410,8 +415,6 @@ if (db_num_rows($result) > 0) { -// print "
PLACEHOLDER
"; - print "

"; diff --git a/prefs.js b/prefs.js index c5b49f5c..e6af5660 100644 --- a/prefs.js +++ b/prefs.js @@ -157,7 +157,6 @@ function infobox_feed_cat_callback2(transport) { try { infobox_callback2(transport); init_cat_inline_editor(); - $('fadd_cat').focus(); } catch (e) { exception_error("infobox_feed_cat_callback2", e); } @@ -327,7 +326,6 @@ function addUser() { function editUser(id, event) { try { - if (!event || !event.ctrlKey) { disableHotkeys(); @@ -946,7 +944,7 @@ function editSelectedFeed() { notify(""); - editFeed(rows[0]); + editFeed(rows[0], {}); } diff --git a/prefs.php b/prefs.php index 01f0b3ff..898840e3 100644 --- a/prefs.php +++ b/prefs.php @@ -25,7 +25,7 @@ Tiny Tiny RSS : Preferences - + @@ -42,6 +42,7 @@ + @@ -133,20 +134,8 @@
 
-
BAH
- - - -
Tiny Tiny RSS diff --git a/tt-rss.css b/tt-rss.css index 130b0e37..171bb94f 100644 --- a/tt-rss.css +++ b/tt-rss.css @@ -799,7 +799,7 @@ span.groupPrompt { } div.tagCloudContainer { - border : 1px solid #99d67a; + border : 1px solid gray; background-color : white; margin : 5px 0px 5px 0px; padding : 5px; @@ -1749,3 +1749,13 @@ div.hlUpdPic { div.hlUpdPic img { max-width : 16px; } + + +div.fatalError button { + margin-top : 5px; +} + +div.fatalError textarea { + width : 100%; + height : 100px; +} diff --git a/tt-rss.php b/tt-rss.php index 251a2a8d..53e8036f 100644 --- a/tt-rss.php +++ b/tt-rss.php @@ -26,9 +26,10 @@ Tiny Tiny RSS - + + @@ -42,7 +43,8 @@ - + + @@ -84,20 +86,9 @@
 
- - - -