Changeset 1192


Ignore:
Timestamp:
11/07/09 15:15:47 (9 years ago)
Author:
gogo
Message:

Discussion in ticket #1478

Creating Sub Classes

Addition of method Xinha.extend. This method provides a means for more "classical" sub classing within javascript. Short story,

    var Vehicle = function() { }
    Vehicle.prototype.horn = function() { alert('Toot'); }

    var Car = function() 
	{ 
		Car.parentConstructor.call(this); // If you want to call it.
	}
    Xinha.extend(Car, Vehicle);
    
    Car.prototype.horn = function() 
	{ 
		alert('Toot'); 
		Car.superClass.horn.call(this);  // If you want to call it.
	}

remember the "call" method of javascript is .call(<on-this-object>, arg, arg, arg ..) and that you can also use the "apply" method to pass in arguments as an array which is .apply(<on this object>, [arg, arg, arg]), and that the arguments to your method are in the "arguments" array.

Dialog Modification

Split out the setting of the localizer from the translation of HTML in source:trunk/modules/Dialogs/XinhaDialog.js by introducing a new method Xinha.Dialog::setLocalizer(), Xinha.Dialog::translateHtml() remains compatible, the localizer is optional to it.

.htaccess Security

Further additions to the .htaccess files for the demo_images in ExtendedFileManager? and ImageManager?. I think we should give consideration to just deleting these folders totally, over the last year I've had a number of instances of people coming to me with these folders filled with various malware.

File-Picker on arbitrary fields outside Xinha (ExtendedFileManager?)

Addition of a source:trunk/plugins/ExtendedFileManager/file-picker.js hijacking of the ExtendedFileManager? in the same manner as the existing source:trunk/plugins/ImageManager/image-picker.js within ImageManager?. I'm putting this n there incase somebody finds it useful, but it may need some work as I don't use it myself any more. I am likely to come up with a way to replace both ExtendedFileManager? and ImageManager? with the "Mootools FileManager", this is a very nice file manager with a similar dialog "look" to our new dialogs, and the very VERY important bonus of it being easy to upload multiple files at once with a progress indicator (using a hidden flash component to do the hard work).

ImageManager? to use hspace and vspace attributes instead of margin.

The addition of a config option to ImageManager? "UseHSpaceVSpace" which swaps out the "margin" settings for the hspace and vspace attributes. The reason for this apparent "old fashioned-ness" is that margin is less reliably honoured when the HTML is put into an email.

YouTube and Flickr added to the ImageManager?

The addition of additional data sources (aka backends or choosers) to ImageManager?, specifically "YouTube" and "Flickr".

When one or both is enabled the user can use a selector in the image manager popup to choose from images on the local server, or search for videos on YouTube, or images on Flickr.

YouTube is enabled by setting $IMConfig['YouTube'] = TRUE; when the user selects a video the large format video still is inserted into the Xinha area, with extra information on the query string.

Flickr is enabled by setting $IMConfig['Flickr']['Key'] = 'your flickr api key here';, when the user selects an image, the image is inserted into the Xinha area.

For videos especially there needs to be some extra processing to turn that into a video when the end user sees this HTML, this is done by the "smart-image.js" script in combination with the (included) swfobject. In short, on the page WHERE YOU USE THE HTML (not where you are running Xinha to edit it) you will put this

   <script type="text/javascript" src="/path/to/xinha/plugins/ImageManager/smart-image.js"></script>
   <body onload="SmartImages.replace_all();">

it will replace the still image with the video (provided javascript is on).

Smart-image will also add a little hover attribution to Flickr sourced images (ie, hover over the image an attribution link appears). If you are going to use the Flickr source, then you must make sure you are legally permitted to do so, for one, your site can not be commercial. I've provided you with the tools, just try not to shoot yourself.

New Dialog Types

Added a new Dialog type "DetachedDialog?". This "faked" dialog extends the Xinha.Dialog and is a "drop in" replacement for it, the difference is the DetachedDialog? is not associated to any instance of Xinha. No Xinha needs to be instantiated for a "plugin" to use a DetachedDialog?. Where this is useful is in leveraging off plugins to provide functionality outside of Xinha, see link-picker.js below (in Linker).

Also added a new Dialog type "DivDialog?". Similar to the DetachedDialog?, except the dialog HTML is written directly into an html element supplied to the dialog. The use of this is similar to the above, providing a means for getting a plugin "away" from Xinha to provide it's services for other things. This Dialog may need some work since it was written before the new Xinha.Dialog was created, in brief test it worked mostly. Worth keeping around as it's a pretty simple example of how a new Dialog type can be constructed by extending the existing one.

Added a "Link Picker" to leverage the Linker plugin for providing a "Browse" button next to normal input fields in order to select a link which is written into the field.

This is the initial usage of the DetachedDialog?, the basic usage of this is described in the comments in that file source:trunk/plugins/Linker/link-picker.js

Hid all dotfiles from the Linker scanner, the linker shouldn't be showing "hidden" files.

CSS fix to dTree in linker, just to make sure it's styles were not getting clobbered.

Stylist Duplicate Stylesheet Fix

Stop the Stylist from possibly adding a duplicate stylesheet into pageStyleSheets, this was creating a subtle problem in certain circumstances.

New Plugin: WysiwygWrap?

Added a new plugin WysiwygWrap, basically this wraps the content of your Xinha with some specific elements you tell it, when in Wysiwyg mode, and strips them out again when you go back to code (or submit). The idea is to make it so that, combined with an appropriate pageStyleSheet(s) you can more easily simulate in Xinha what it will "look like" when that HTML is "published" wherever it's getting published.

It takes a simple configuration of xinha.config.WysiwygWrap = { elements: [ list of the ancestor elements to insert, in order top down ] }
Example:

  xinha.config.WysiwygWrap = { elements: ['div#outer', 'div.inner'] }

will produce this in your Xinha Wysiwyg mode html

	<div id="outer">
		<div class="inner">
			** Original Xinha Content For Editing Here **
		</div>
	</div>

so your pageStyleSheet would just make nice CSS for those outer and inner to make the html in the Wysiwyg mode look closer to how it would look "on the site".

In practice, I'm not sure this works that well, it seemed a good idea at the time, but it can be a bit fragile.

Location:
trunk
Files:
19 added
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/XinhaCore.js

    r1188 r1192  
    57305730}; 
    57315731 
     5732 
     5733/** Extend one class from another, that is, make a sub class. 
     5734 *  This manner of doing it was probably first devised by Kevin Lindsey 
     5735 * 
     5736 *  http://kevlindev.com/tutorials/javascript/inheritance/index.htm 
     5737 * 
     5738 *  It has subsequently been used in one form or another by various toolkits  
     5739 *  such as the YUI. 
     5740 * 
     5741 *  I make no claim as to understanding it really, but it works. 
     5742 *  
     5743 *  Example Usage: 
     5744 *  {{{ 
     5745 *  ------------------------------------------------------------------------- 
     5746  
     5747    // =========  MAKING THE INITIAL SUPER CLASS =========== 
     5748     
     5749        document.write("<h1>Superclass Creation And Test</h1>"); 
     5750     
     5751        function Vehicle(name, sound) 
     5752        {     
     5753          this.name  = name; 
     5754          this.sound = sound 
     5755        } 
     5756       
     5757        Vehicle.prototype.pressHorn = function() 
     5758        { 
     5759          document.write(this.name + ': ' + this.sound + '<br/>'); 
     5760        } 
     5761         
     5762        var Bedford  = new Vehicle('Bedford Van', 'Honk Honk'); 
     5763        Bedford.pressHorn(); // Vehicle::pressHorn() is defined 
     5764     
     5765     
     5766    // ========= MAKING A SUBCLASS OF A SUPER CLASS ========= 
     5767     
     5768        document.write("<h1>Subclass Creation And Test</h1>"); 
     5769         
     5770        // Make the sub class constructor first 
     5771        Car = function(name) 
     5772        { 
     5773          // This is how we call the parent's constructor, note that 
     5774          // we are using Car.parent.... not "this", we can't use this. 
     5775          Car.parentConstructor.call(this, name, 'Toot Toot'); 
     5776        } 
     5777         
     5778        // Remember the subclass comes first, then the base class, you are extending 
     5779        // Car with the methods and properties of Vehicle. 
     5780        Xinha.extend(Car, Vehicle); 
     5781         
     5782        var MazdaMx5 = new Car('Mazda MX5');   
     5783        MazdaMx5.pressHorn(); // Car::pressHorn() is inherited from Vehicle::pressHorn() 
     5784     
     5785    // =========  ADDING METHODS TO THE SUB CLASS =========== 
     5786 
     5787        document.write("<h1>Add Method to Sub Class And Test</h1>"); 
     5788         
     5789        Car.prototype.isACar = function() 
     5790        { 
     5791          document.write(this.name + ": Car::isACar() is implemented, this is a car! <br/>"); 
     5792          this.pressHorn(); 
     5793        } 
     5794        
     5795        MazdaMx5.isACar(); // Car::isACar() is defined as above 
     5796        try      { Bedford.isACar(); } // Vehicle::isACar() is not defined, will throw this exception 
     5797        catch(e) { document.write("Bedford: Vehicle::onGettingCutOff() not implemented, this is not a car!<br/>"); } 
     5798     
     5799    // =========  EXTENDING A METHOD (CALLING MASKED PARENT METHODS) =========== 
     5800     
     5801        document.write("<h1>Extend/Override Inherited Method in Sub Class And Test</h1>"); 
     5802         
     5803        Car.prototype.pressHorn = function() 
     5804        {  
     5805          document.write(this.name + ': I am going to press the horn... <br/>'); 
     5806          Car.superClass.pressHorn.call(this);         
     5807        } 
     5808        MazdaMx5.pressHorn(); // Car::pressHorn() 
     5809        Bedford.pressHorn();  // Vehicle::pressHorn() 
     5810         
     5811    // =========  MODIFYING THE SUPERCLASS AFTER SUBCLASSING =========== 
     5812     
     5813        document.write("<h1>Add New Method to Superclass And Test In Subclass</h1>");   
     5814         
     5815        Vehicle.prototype.startUp = function() { document.write(this.name + ": Vroooom <br/>"); }   
     5816        MazdaMx5.startUp(); // Cars get the prototype'd startUp() also. 
     5817         
     5818 *  ------------------------------------------------------------------------- 
     5819 *  }}}   
     5820 * 
     5821 *  @param subclass_constructor (optional)  Constructor function for the subclass 
     5822 *  @param superclass Constructor function for the superclass  
     5823 */ 
     5824 
     5825Xinha.extend = function(subClass, baseClass) { 
     5826   function inheritance() {} 
     5827   inheritance.prototype = baseClass.prototype; 
     5828 
     5829   subClass.prototype = new inheritance(); 
     5830   subClass.prototype.constructor = subClass; 
     5831   subClass.parentConstructor = baseClass; 
     5832   subClass.superClass = baseClass.prototype; 
     5833} 
     5834 
    57325835/** Event Flushing 
    57335836 *  To try and work around memory leaks in the rather broken 
  • trunk/modules/Dialogs/XinhaDialog.js

    r1166 r1192  
    702702Xinha.Dialog.prototype.getElementById = function(id) 
    703703{ 
     704  if(!this.rootElem.parentNode) 
     705  {      
     706    this.document.body.appendChild(this.rootElem); 
     707  } 
     708   
    704709  return this.document.getElementById(this.id[id] ? this.id[id] : id); 
    705710}; 
     
    710715Xinha.Dialog.prototype.getElementsByName = function(name) 
    711716{ 
     717  if(!this.rootElem.parentNode) 
     718  {      
     719    this.document.body.appendChild(this.rootElem); 
     720  } 
     721     
    712722  var els = this.document.getElementsByName(this.id[name] ? this.id[name] : name);  
    713723  return Xinha.collectionToArray(els); 
     
    12871297  return values; 
    12881298}; 
     1299 
     1300/** Sets the localizer to use for the dialog 
     1301 *  @param function|string Either a function which takes a string as a parameter and returns  
     1302 *    a localized string, or the name of a contact to pass to the standard Xinha localizer 
     1303 *    the "context" usually means the name of a plugin. 
     1304 */ 
     1305  
     1306Xinha.Dialog.prototype.setLocalizer = function(localizer) 
     1307 
     1308  var dialog = this; 
     1309  if(typeof localizer == 'function') 
     1310  { 
     1311    dialog._lc = localizer; 
     1312  } 
     1313  else if(localizer) 
     1314  { 
     1315    this._lc = function(string) 
     1316    { 
     1317      return Xinha._lc(string,localizer); 
     1318    }; 
     1319  } 
     1320  else 
     1321  { 
     1322    this._lc = function(string) 
     1323    { 
     1324      return string; 
     1325    }; 
     1326  } 
     1327} 
     1328 
    12891329/** Localizes strings in the dialog. 
    12901330 * @private 
    12911331 * @param {String} html The HTML to translate 
    1292  * @param {String} localizer Context for translation, usually plugin's name 
    1293  */ 
    1294 Xinha.Dialog.prototype.translateHtml = function(html, localizer) 
    1295 { 
     1332 * @param {String} localizer Context for translation, usually plugin's name (optional if setLocalizer() has been used)  
     1333 */ 
     1334  
     1335Xinha.Dialog.prototype.translateHtml = function(html,localizer) 
     1336 
    12961337  var dialog = this; 
    1297   if(typeof localizer == 'function') 
    1298   { 
    1299     dialog._lc = localizer; 
    1300   } 
    1301   else if(localizer) 
    1302   { 
    1303     this._lc = function(string) 
    1304     { 
    1305       return Xinha._lc(string,localizer); 
    1306     }; 
    1307   } 
    1308   else 
    1309   { 
    1310     this._lc = function(string) 
    1311     { 
    1312       return string; 
    1313     }; 
    1314   } 
    1315  
     1338  if(localizer) this.setLocalizer(localizer); 
     1339   
    13161340  // looking for strings of the form name='[foo]' or id="[bar]" 
    13171341  html = html.replace(/((?:name)|(?:id))=(['"])\[([a-z0-9_]+)\]\2/ig, 
  • trunk/plugins/ExtendedFileManager/demo_images/.htaccess

    r1143 r1192  
    11<IfModule mod_php.c> 
    2   php_flag engine off 
     2 php_flag engine off 
    33</IfModule> 
    4 AddType text/html .html .htm .shtml .php .php3 .phtml .phtm .pl .py .cgi 
     4AddType text/html .html .htm .shtml .php .php3 .php4 .php5 .php6 .php7 .php8 .phtml .phtm .pl .py .cgi 
     5RemoveHandler .php 
     6RemoveHandler .php8 
     7RemoveHandler .php7 
     8RemoveHandler .php6 
     9RemoveHandler .php5 
     10RemoveHandler .php4 
     11RemoveHandler .php3 
  • trunk/plugins/ImageManager/ImageManager.js

    r1067 r1192  
    110110                        f_height  : image.height, 
    111111      f_backgroundColor: image.style.backgroundColor, 
    112       f_borderColor: image.style.borderColor 
     112      f_borderColor: image.style.borderColor, 
     113      f_hspace:  image.hspace && image.hspace != '-1' ? parseInt(image.hspace) : '', 
     114      f_vspace: image.vspace && image.vspace != '-1' ? parseInt(image.vspace) : '' 
    113115                        }; 
    114116 
     
    269271          } 
    270272          break; 
     273           
     274          case "f_hspace" :  
     275          { 
     276            if(!isNaN(parseInt(value))) { img.hspace  = parseInt(value); } else { img.hspace = ''; } 
     277          } 
     278          break; 
     279           
     280          case "f_vspace" :  
     281          { 
     282            if(!isNaN(parseInt(value))) { img.vspace  = parseInt(value); } else { img.vspace = ''; } 
     283          } 
     284          break; 
    271285                        } 
    272286 
  • trunk/plugins/ImageManager/assets/imagelist.css

    r677 r1192  
    4545.listview td.actions { text-align:right; } 
    4646.listview td.actions img { border:0px; } 
     47 
     48.flk-license { font-size: xx-small; text-align:center; } 
  • trunk/plugins/ImageManager/assets/images.js

    r999 r1192  
    5757                var obj = topDoc.getElementById('orginal_height'); obj.value = height;           
    5858    // Set preview for the selected 
    59     topDoc.getElementById('f_preview').src = window.parent._backend_url + '__function=thumbs&img=' + filename; 
     59    topDoc.getElementById('f_preview').src = window.parent._backend_url + '__function=thumbs&img=' + encodeURIComponent(filename); 
    6060     
    6161    update_selected(); 
  • trunk/plugins/ImageManager/assets/manager.css

    r770 r1192  
    1010.dirs { padding: 1em;   } 
    1111.imageFrame { width: 100%; height: 145px; margin: 0 auto; margin-top: 1em; background-color: White;} 
     12#youtubeChooser .imageFrame { height: 155px; } 
    1213.smallWidth{ width: 4em; } 
    1314.largelWidth{ width: 22em; } 
  • trunk/plugins/ImageManager/assets/manager.js

    r999 r1192  
    9494        } 
    9595      } 
    96       document.getElementById('f_preview').src = _backend_url + '__function=thumbs&img=' + param.f_url;       
     96      document.getElementById('f_preview').src = _backend_url + '__function=thumbs&img=' + encodeURIComponent(param.f_url);       
    9797                } 
    9898                 
     
    114114        { 
    115115                // pass data back to the calling window 
    116                 var fields = ["f_url", "f_alt", "f_align", "f_width", "f_height", "f_padding", "f_margin", "f_border", "f_borderColor", "f_backgroundColor"]; 
     116                var fields = ["f_url", "f_alt", "f_align", "f_width", "f_height", "f_padding", "f_margin", "f_border", "f_borderColor", "f_backgroundColor", 'f_hspace', 'f_vspace']; 
    117117                var param = new Object(); 
    118118                for (var i in fields)  
     
    133133                        else if (el) 
    134134                                param[id] = el.value; 
    135       else alert("Missing " + fields[i]); 
     135      // else alert("Missing " + fields[i]); <-- Not useful to tell people this, maybe for debugging. 
    136136 
    137137                } 
  • trunk/plugins/ImageManager/backend.php

    r677 r1192  
    140140                break; 
    141141 
     142     
     143        case "youtube": 
     144 
     145                include_once( $IMConfig['base_dir'] . "/youtube.php" ); 
     146                exit(); 
     147 
     148                break; 
     149     
     150     
     151        case "flickr": 
     152 
     153                include_once( $IMConfig['base_dir'] . "/flickr.php" ); 
     154                exit(); 
     155 
     156                break; 
     157     
    142158        default: 
    143159 
  • trunk/plugins/ImageManager/config.inc.php

    r1143 r1192  
    284284$IMConfig['ViewMode'] = 'thumbs'; 
    285285 
    286  
     286// ------------------------------------------------------------------------- 
     287 
     288/** Margin Types  
     289 *  If your HTML will be used in an email, then using CSS type "margin" 
     290 *  is not so reliable and you should set UseHSpaceVSpace to be true 
     291 *  to go back to the old fashioned hspace="" and vspace="" attributes on 
     292 *  images. 
     293 */ 
     294$IMConfig['UseHSpaceVSpace'] = false; 
     295 
     296// ------------------------------------------------------------------------- 
     297 
     298/** 
     299 * ImageManager/Picker can provide selection interfaces for more than just  
     300 * images on the server ("Pictures"). 
     301 * 
     302 *  Local - the classical ImageManager for images stored on this server. 
     303 * 
     304 *  YouTube  - provides selection (but not upload etc) of videos on YouTube 
     305 *    see smart-image.js for how to make the videos work as videos instead of 
     306 *    static images. 
     307 * 
     308 *  Flickr   - provides selection (but not upload etc) of public images on Flickr 
     309 *    Set  
     310 *       $IMConfig['Flickr'] = array('Key' => 'yourkeyhere'); 
     311 *    to turn on Flickr support. 
     312 *  
     313 *    To get a key: http://www.flickr.com/services/api/keys/ 
     314 * 
     315 *    WARNING: Flickr restricts commercial use of the API.  If your site is in any way even  
     316 *     remotely commercial you need to ask for a commercial key from flickr. 
     317 * 
     318 *    ADDITIONAL WARNING: Flickr requires that you provide a link back to them, preferably 
     319 *     on the image itself (linking to the image) - you can use smart-image.js to do 
     320 *     something like this.  
     321 * 
     322 *    ADDITIONAL ADDITIONAL WARNING: It's up to you to comply with the image's license!!  
     323 */ 
     324  
     325$IMConfig['Local'] = TRUE; 
     326$IMConfig['YouTube']  = FALSE; 
     327$IMConfig['Flickr']   = FALSE; 
     328 
     329// These are some configurable defaults for Flickr, to override 
     330//  $IMConfig['Flickr'] = array('Whatever' => 'You Want'); 
     331$FlickrDefaults = array 
     332( 
     333  // This is the URL as flickr provides it for the licence which you wish  
     334  // to search on by default.  The default here is the least restrictive one. 
     335  'Default License' => 'http://creativecommons.org/licenses/by/2.0/', 
     336     
     337);   
    287338 
    288339 
     
    300351  $IMConfig = array_merge($IMConfig, $passed_data); 
    301352  $IMConfig['backend_url'] .= xinha_passed_data_querystring() . '&'; 
     353   
     354  if($IMConfig['Flickr']) 
     355  { 
     356    foreach($FlickrDefaults as $k => $v) 
     357    { 
     358      if(!isset($IMConfig['Flickr'][$k])) 
     359      { 
     360        $IMConfig['Flickr'][$k] = $v; 
     361      } 
     362    } 
     363  } 
    302364} 
    303365// Deprecated config passing, don't use this way any more! 
  • trunk/plugins/ImageManager/demo_images/.htaccess

    r1143 r1192  
    11<IfModule mod_php.c> 
    2   php_flag engine off 
     2 php_flag engine off 
    33</IfModule> 
    4 AddType text/html .html .htm .shtml .php .php3 .phtml .phtm .pl .py .cgi 
     4AddType text/html .html .htm .shtml .php .php3 .php4 .php5 .php6 .php7 .php8 .phtml .phtm .pl .py .cgi 
     5RemoveHandler .php 
     6RemoveHandler .php8 
     7RemoveHandler .php7 
     8RemoveHandler .php6 
     9RemoveHandler .php5 
     10RemoveHandler .php4 
     11RemoveHandler .php3 
  • trunk/plugins/ImageManager/image-picker.js

    r1045 r1192  
    5555ImagePicker.prototype.backend             = Xinha.getPluginDir('ImageManager') + '/backend.php?__plugin=ImageManager&'; 
    5656ImagePicker.prototype.backend_data        = null; 
     57 
     58ImagePicker.prototype.append_query_string = true; 
    5759 
    5860ImagePicker.prototype.popup_picker = function() 
     
    8082      f_margin: null 
    8183    }; 
     84     
     85    while(outparam.f_url.match(/[?&]((f_[a-z0-9]+)=([^&#]+))/i)) 
     86    { 
     87      outparam[RegExp.$2] = decodeURIComponent(RegExp.$3); 
     88      outparam.f_url = outparam.f_url.replace(RegExp.$1, ''); 
     89    } 
     90     
     91    outparam.f_url = outparam.f_url.replace(/&{2,}/g, '&'); 
     92    outparam.f_url = outparam.f_url.replace(/\?&*(#.*)?$/, '');  
    8293  } 
    8394 
     
    105116                        return false; 
    106117                } 
     118     
    107119    picker.field.value = param.f_url; 
     120    if(picker.append_query_string) 
     121    { 
     122      if(picker.field.value.match(/[?&](.*)$/)) 
     123      { 
     124        if(RegExp.$1.length) 
     125        { 
     126          picker.field.value += '&'; 
     127        } 
     128      } 
     129      else 
     130      { 
     131        picker.field.value += '?'; 
     132      } 
     133       
     134      for(var i in param) 
     135      {         
     136        if(i == 'f_url' || param[i] == null || param[i] == 'null' || param[i] == '') continue;                 
     137        if(typeof param[i] == 'function') continue; 
     138        if(param[i].length = 0) continue; 
     139         
     140        picker.field.value += i + '=' + encodeURIComponent(param[i]) + '&'; 
     141      } 
     142    } 
     143     
    108144                }, outparam); 
    109145} 
  • trunk/plugins/ImageManager/manager.php

    r1165 r1192  
    5252  } 
    5353?> 
     54 
     55<script type="text/javascript"> 
     56  function switchChooser(toChooserPanel) 
     57  { 
     58    var ourPanel =  document.getElementById(toChooserPanel); 
     59    if(!ourPanel) return false; // Can't change, doesn't exist. 
     60     
     61    // hide all panels 
     62    var d = document.getElementById('chooserFieldset').getElementsByTagName('div'); 
     63    for(i = 0; i < d.length; i++) 
     64    { 
     65      if(d[i].className.match(/chooserPanel/)) 
     66        d[i].style.display = 'none';       
     67    } 
     68     
     69    // show ours 
     70    ourPanel.style.display = 'block'; 
     71  } 
     72</script> 
    5473</head> 
    5574<body> 
     
    6079<input type="hidden" name="__function" value="images" /> 
    6180 
    62 <fieldset> 
    63   <legend>Image Manager</legend> 
     81<fieldset id="chooserFieldset"> 
     82  <legend> 
     83    Choose From:  
     84    <select onchange="switchChooser(this.options[this.selectedIndex].value)"> 
     85    <?php 
     86      if($IMConfig['Local']) 
     87      { 
     88        ?> 
     89        <option value="picturesChooser">This Server</option> 
     90        <?php 
     91      } 
     92    ?> 
     93     
     94    <?php 
     95      if($IMConfig['YouTube']) 
     96      { 
     97        ?> 
     98        <option value="youtubeChooser">YouTube Videos</option> 
     99        <?php 
     100      } 
     101    ?> 
     102     
     103    <?php 
     104      if($IMConfig['Flickr']) 
     105      { 
     106        ?> 
     107        <option value="flickrChooser">Flickr Pictures</option> 
     108        <?php 
     109      } 
     110    ?> 
     111    </select> 
     112  </legend> 
     113     
     114  <?php 
     115    if($IMConfig['Local']) 
     116    { 
     117      ?> 
     118  <div id="picturesChooser" class="chooserPanel"> 
    64119  <table width="100%"> 
    65120    <tr> 
     
    111166 
    112167  <iframe src="<?php print $IMConfig['backend_url']; ?>__function=images" name="imgManager" id="imgManager" class="imageFrame" scrolling="auto" title="Image Selection" frameborder="0"></iframe> 
    113  
     168  </div> 
     169  <?php 
     170    } 
     171  ?> 
     172   
     173  <?php 
     174    if($IMConfig['YouTube']) 
     175    { 
     176      ?> 
     177      <div id="youtubeChooser" style="display:none" class="chooserPanel"> 
     178             
     179        <table width="100%"> 
     180          <tr> 
     181            <th><labelfor="ytUsername">YouTube Username</label></th> 
     182            <td> 
     183              <input type="text" name="ytUsername" id="ytUsername" /> 
     184            </td> 
     185             
     186            <th><labelfor="ytSearch">Keyword</label></th> 
     187            <td> 
     188              <input type="text" name="ytSearch" id="ytSearch" /> 
     189            </td>      
     190            <td> 
     191              <input type="button" value="Search" onclick="document.getElementById('ytManager').src='<?php print $IMConfig['backend_url']; ?>__function=youtube&ytSearch='+document.getElementById('ytSearch').value+'&ytUsername='+document.getElementById('ytUsername').value;" /> 
     192            </td> 
     193          </tr>     
     194        </table> 
     195       
     196        <div id="messages" style="display: none;"><span id="message"></span><img SRC="<?php print $IMConfig['base_url']; ?>img/dots.gif" width="22" height="12" alt="..." /></div> 
     197       
     198        <iframe src="<?php print $IMConfig['backend_url']; ?>__function=youtube" name="ytManager" id="ytManager" class="imageFrame" scrolling="auto" title="YouTube Selection" frameborder="0"></iframe> 
     199     
     200      </div> 
     201      <?php 
     202    } 
     203  ?> 
     204     
     205  <?php 
     206    if($IMConfig['Flickr']) 
     207    { 
     208      require_once('Classes/Flickr.php'); 
     209      $lics = flickr_get_license_id_by_usage();  
     210      ?> 
     211      <div id="flickrChooser" style="display:none" class="chooserPanel"> 
     212        <script type="text/javascript"> 
     213          function flickr_go() 
     214          { 
     215            var u = '<?php print $IMConfig['backend_url']; ?>__function=flickr'; 
     216            u += '&flkSearch='  + encodeURIComponent(document.getElementById('flkSearch').value); 
     217            u += '&flkUsername='+ encodeURIComponent(document.getElementById('flkUsername').value); 
     218            u += '&flkLicense=' + encodeURIComponent( document.getElementById('flkLicense').options[document.getElementById('flkLicense').selectedIndex].value ); 
     219             
     220            document.getElementById('flkManager').src= u;             
     221          } 
     222        </script> 
     223        <table width="100%"> 
     224          <tr> 
     225            <th><labelfor="ytUsername">Flickr Username/Email</label></th> 
     226            <td> 
     227              <input type="text" name="flkUsername" id="flkUsername" /> 
     228            </td> 
     229             
     230            <th><labelfor="ytSearch">Keyword</label></th> 
     231            <td> 
     232              <input type="text" name="flkSearch" id="flkSearch" /> 
     233            </td>      
     234            <td> 
     235              <input type="button" value="Search" onclick="flickr_go();" /> 
     236            </td> 
     237          </tr>     
     238          <tr> 
     239            <th>Usage Restriction:</th> 
     240            <td colspan="3"> 
     241              <select name="flkLicense" id="flkLicense"  onchange="flickr_go();"> 
     242                <?php 
     243                  foreach($lics as $usage => $licid) 
     244                  { 
     245                    ?> 
     246                    <option value="<?php echo $licid ?>" <?php if(flickr_is_default_license($licid)) echo 'selected="selected"' ?>> <?php echo $licid ?> <?php echo htmlspecialchars($usage) ?></li> 
     247                    <?php 
     248                  } 
     249                ?> 
     250              </select> 
     251            </td>          
     252            <td><a href="http://flickr.com/" target="_blank">flickr.com</a></td> 
     253          </tr> 
     254        </table> 
     255       
     256        <div id="messages" style="display: none;"><span id="message"></span><img SRC="<?php print $IMConfig['base_url']; ?>img/dots.gif" width="22" height="12" alt="..." /></div> 
     257       
     258        <iframe src="<?php print $IMConfig['backend_url']; ?>__function=flickr" name="flkManager" id="flkManager" class="imageFrame" scrolling="auto" title="Flickr Selection" frameborder="0"></iframe> 
     259     
     260      </div> 
     261      <?php 
     262    } 
     263  ?> 
    114264</fieldset> 
    115265 
     
    139289    <th style="text-align: left;" class="fullOptions">Margin:</th> 
    140290    <td colspan="3" class="fullOptions"> 
    141       <input name="f_margin" type="text" id="f_margin" size="3" /> 
     291    <?php 
     292      if(@$IMConfig['UseHSpaceVSpace']) 
     293      { 
     294        ?> 
     295          <input name="f_hspace" type="text" id="f_hspace" size="3" /> 
     296        x <input name="f_vspace" type="text" id="f_vspace" size="3" />  
     297        <?php 
     298      } 
     299      else 
     300      { 
     301        ?> 
     302        <input name="f_margin" type="text" id="f_margin" size="3" /> 
     303        <?php 
     304      } 
     305    ?>       
    142306      px </td> 
    143307  </tr> 
  • trunk/plugins/ImageManager/thumbs.php

    r999 r1192  
    2424//get the image and the full path to the image 
    2525$image = rawurldecode($_GET['img']); 
     26 
     27// If the image is a URL, see if there is an x-thumbnail x-thumb or x-tn param on it 
     28//  probably best to use x-tn to save space on the URL 
     29if(preg_match('/^[a-z]+:\/\/.*[?&]x-(thumbnail|thumb|tn)=([^&]+)/i', $image, $Matches)) 
     30{ 
     31  // In which case, we will use the thumbnail 
     32  header('location: ' . rawurldecode($Matches[2])); 
     33  exit; 
     34} 
     35 
    2636$fullpath = Files::makeFile($manager->getImagesDir(),$image); 
    2737 
  • trunk/plugins/Linker/Linker.js

    r1067 r1192  
    1919  'backend' : Xinha.getPluginDir("Linker") + '/scan.php', 
    2020  'backend_data' : null, 
    21   'files' : null 
     21  'files' : null,  
     22  'dialog': null, 
     23  'canSetTarget': true, 
     24  'canRemoveLink': true 
    2225}; 
    2326 
  • trunk/plugins/Linker/dTree/dtree.css

    r582 r1192  
    1212} 
    1313.dtree img { 
    14   border: 0px; 
    15   vertical-align: middle; 
     14  border: 0px !important; 
     15  margin:0px  !important; 
     16  display:inline !important; 
     17  vertical-align: middle !important; 
    1618} 
    1719.dtree a,.dtree a:visited { 
  • trunk/plugins/Linker/pluginMethods.js

    r1118 r1192  
    270270 
    271271  // Now we have everything we need, so we can build the dialog. 
    272   var dialog = this.dialog = new Xinha.Dialog(linker.editor, Linker.html, 'Linker',{width:600,height:400}); 
     272  if(!linker.lConfig.dialog && Xinha.Dialog) linker.lConfig.dialog = Xinha.Dialog; 
     273   
     274  var dialog = this.dialog = new linker.lConfig.dialog(linker.editor, Linker.html, 'Linker',{width:600,height:400}); 
    273275  var dTreeName = Xinha.uniq('dTree_'); 
    274276 
     
    353355 
    354356Linker.Dialog.prototype.makeNodes = function(files, parent) 
    355 { 
     357{  
    356358  for(var i = 0; i < files.length; i++) 
    357359  { 
     
    406408    this.ddTree.innerHTML = this.dTree._linker_premade; 
    407409  } 
    408  
     410   
     411  if(!this.linker.lConfig.canSetTarget) 
     412  { 
     413    this.dialog.getElementById('target_options').style.display = 'none';     
     414  } 
     415   
    409416  this.showOptionsForType(inputs.type); 
    410417  this.showOptionsForTarget(inputs.target); 
     
    522529    } 
    523530  } 
     531   
     532  // It could be forced not be able to be removed, as is the case with link-picker.js 
     533  if(!this.linker.lConfig.canRemoveLink) 
     534  { 
     535    this.dialog.getElementById('clear').style.display = 'none'; 
     536  } 
     537   
    524538  // Connect the OK and Cancel buttons 
    525539  var dialog = this.dialog; 
  • trunk/plugins/Linker/scan.php

    r926 r1192  
    7272      while($dh && ($file = readdir($dh))) 
    7373      { 
    74         if($file !== '.' && $file !== '..') 
     74        if($file[0] !== '.') 
    7575        { 
    7676          $path = realpath($dir . '/' . $file); 
  • trunk/plugins/Stylist/Stylist.js

    r1135 r1192  
    2323      this.css_style[i] = newStyles[i]; 
    2424    } 
     25  } 
     26   
     27  for(var x = 0; x < this.pageStyleSheets.length; x++) 
     28  { 
     29    if(this.pageStyleSheets[x] == url) return; 
    2530  } 
    2631  this.pageStyleSheets[this.pageStyleSheets.length] = url; 
Note: See TracChangeset for help on using the changeset viewer.