Changeset 1044 for trunk/plugins/Linker


Ignore:
Timestamp:
10/02/08 17:07:26 (11 years ago)
Author:
douglas
Message:

FIXED Ticket #1176 Merging new dialogs branch back to trunk.

Location:
trunk/plugins/Linker
Files:
1 added
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/plugins/Linker/linker.js

    r1027 r1044  
    5151}; 
    5252 
    53 Linker.prototype._createLink = function(a) 
    54 { 
    55   if(!a && this.editor.selectionEmpty(this.editor.getSelection())) 
    56   {        
    57     alert(this._lc("You must select some text before making a new link.")); 
    58     return false; 
    59   } 
    60  
    61   var inputs = 
    62   { 
    63     type:     'url', 
    64     href:     'http://www.example.com/', 
    65     target:   '', 
    66     p_width:  '', 
    67     p_height: '', 
    68     p_options: ['menubar=no','toolbar=yes','location=no','status=no','scrollbars=yes','resizeable=yes'], 
    69     to:       'alice@example.com', 
    70     subject:  '', 
    71     body:     '', 
    72     anchor:   '' 
    73   }; 
    74  
    75   if(a && a.tagName.toLowerCase() == 'a') 
    76   { 
    77     var href =this.editor.fixRelativeLinks(a.getAttribute('href')); 
    78     var m = href.match(/^mailto:(.*@[^?&]*)(\?(.*))?$/); 
    79     var anchor = href.match(/^#(.*)$/); 
    80  
    81     if(m) 
    82     { 
    83       // Mailto 
    84       inputs.type = 'mailto'; 
    85       inputs.to = m[1]; 
    86       if(m[3]) 
    87       { 
    88         var args  = m[3].split('&'); 
    89         for(var x = 0; x<args.length; x++) 
    90         { 
    91           var j = args[x].match(/(subject|body)=(.*)/); 
    92           if(j) 
    93           { 
    94             inputs[j[1]] = decodeURIComponent(j[2]); 
    95           } 
    96         } 
    97       } 
    98     } 
    99     else if (anchor) 
    100     { 
    101       //Anchor-Link 
    102       inputs.type = 'anchor'; 
    103       inputs.anchor = anchor[1]; 
    104        
    105     } 
    106     else 
    107     { 
    108  
    109  
    110       if(a.getAttribute('onclick')) 
    111       { 
    112         var m = a.getAttribute('onclick').match(/window\.open\(\s*this\.href\s*,\s*'([a-z0-9_]*)'\s*,\s*'([a-z0-9_=,]*)'\s*\)/i); 
    113  
    114         // Popup Window 
    115         inputs.href   = href ? href : ''; 
    116         inputs.target = 'popup'; 
    117         inputs.p_name = m[1]; 
    118         inputs.p_options = [ ]; 
    119  
    120  
    121         var args = m[2].split(','); 
    122         for(var x = 0; x < args.length; x++) 
    123         { 
    124           var i = args[x].match(/(width|height)=([0-9]+)/); 
    125           if(i) 
    126           { 
    127             inputs['p_' + i[1]] = parseInt(i[2]); 
    128           } 
    129           else 
    130           { 
    131             inputs.p_options.push(args[x]); 
    132           } 
    133         } 
    134       } 
    135       else 
    136       { 
    137         // Normal 
    138         inputs.href   = href; 
    139         inputs.target = a.target; 
    140       } 
    141     } 
    142   } 
    143  
    144   var linker = this; 
    145  
    146   // If we are not editing a link, then we need to insert links now using execCommand 
    147   // because for some reason IE is losing the selection between now and when doOK is 
    148   // complete.  I guess because we are defocusing the iframe when we click stuff in the 
    149   // linker dialog. 
    150  
    151   this.a = a; // Why doesn't a get into the closure below, but if I set it as a property then it's fine? 
    152  
    153   var doOK = function() 
    154   { 
    155     //if(linker.a) alert(linker.a.tagName); 
    156     var a = linker.a; 
    157  
    158     var values = linker._dialog.hide(); 
    159     var atr = 
    160     { 
    161       href: '', 
    162       target:'', 
    163       title:'', 
    164       onclick:'' 
    165     }; 
    166  
    167     if(values.type == 'url') 
    168     { 
    169      if(values.href) 
    170      { 
    171        atr.href = values.href; 
    172        atr.target = values.target; 
    173        if(values.target == 'popup') 
    174        { 
    175  
    176          if(values.p_width) 
    177          { 
    178            values.p_options.push('width=' + values.p_width); 
    179          } 
    180          if(values.p_height) 
    181          { 
    182            values.p_options.push('height=' + values.p_height); 
    183          } 
    184          atr.onclick = 'if(window.top && window.top.Xinha){return false}window.open(this.href, \'' + (values.p_name.replace(/[^a-z0-9_]/i, '_')) + '\', \'' + values.p_options.join(',') + '\');return false;'; 
    185        } 
    186      } 
    187     } 
    188     else if(values.type == 'anchor') 
    189     { 
    190       if(values.anchor) 
    191       { 
    192         atr.href = values.anchor.value; 
    193       } 
    194     } 
    195     else 
    196     { 
    197       if(values.to) 
    198       { 
    199         atr.href = 'mailto:' + values.to; 
    200         if(values.subject) atr.href += '?subject=' + encodeURIComponent(values.subject); 
    201         if(values.body)    atr.href += (values.subject ? '&' : '?') + 'body=' + encodeURIComponent(values.body); 
    202       } 
    203     } 
    204  
    205     if (atr.href) atr.href = atr.href.trim(); 
    206  
    207     if(a && a.tagName.toLowerCase() == 'a') 
    208     { 
    209       if(!atr.href) 
    210       { 
    211         if(confirm(linker._dialog._lc('Are you sure you wish to remove this link?'))) 
    212         { 
    213           var p = a.parentNode; 
    214           while(a.hasChildNodes()) 
    215           { 
    216             p.insertBefore(a.removeChild(a.childNodes[0]), a); 
    217           } 
    218           p.removeChild(a); 
    219           linker.editor.updateToolbar(); 
    220           return; 
    221         } 
    222       } 
    223       else 
    224       { 
    225         // Update the link 
    226         for(var i in atr) 
    227         { 
    228           a.setAttribute(i, atr[i]); 
    229         } 
    230          
    231         // If we change a mailto link in IE for some hitherto unknown 
    232         // reason it sets the innerHTML of the link to be the  
    233         // href of the link.  Stupid IE. 
    234         if(Xinha.is_ie) 
    235         { 
    236           if(/mailto:([^?<>]*)(\?[^<]*)?$/i.test(a.innerHTML)) 
    237           { 
    238             a.innerHTML = RegExp.$1; 
    239           } 
    240         } 
    241       } 
    242     } 
    243     else 
    244     { 
    245       if(!atr.href) return true; 
    246  
    247       // Insert a link, we let the browser do this, we figure it knows best 
    248       var tmp = Xinha.uniq('http://www.example.com/Link'); 
    249       linker.editor._doc.execCommand('createlink', false, tmp); 
    250  
    251       // Fix them up 
    252       var anchors = linker.editor._doc.getElementsByTagName('a'); 
    253       for(var i = 0; i < anchors.length; i++) 
    254       { 
    255         var anchor = anchors[i]; 
    256         if(anchor.href == tmp) 
    257         { 
    258           // Found one. 
    259           if (!a) a = anchor; 
    260           for(var j in atr) 
    261           { 
    262             anchor.setAttribute(j, atr[j]); 
    263           } 
    264         } 
    265       } 
    266     } 
    267     linker.editor.selectNodeContents(a); 
    268     linker.editor.updateToolbar(); 
    269   }; 
    270  
    271   this._dialog.show(inputs, doOK); 
    272  
    273 }; 
    274  
    275 Linker.prototype._getSelectedAnchor = function() 
    276 { 
    277   var sel  = this.editor.getSelection(); 
    278   var rng  = this.editor.createRange(sel); 
    279   var a    = this.editor.activeElement(sel); 
    280   if(a != null && a.tagName.toLowerCase() == 'a') 
    281   { 
    282     return a; 
    283   } 
    284   else 
    285   { 
    286     a = this.editor._getFirstAncestor(sel, 'a'); 
    287     if(a != null) 
    288     { 
    289       return a; 
    290     } 
    291   } 
    292   return null; 
    293 }; 
    29453 
    29554Linker.prototype.onGenerateOnce = function() 
    29655{ 
    297   this._dialog = new Linker.Dialog(this); 
     56  Linker.loadAssets(); 
     57  this.loadFiles(); 
    29858}; 
    299 // Inline Dialog for Linker 
     59 
     60Linker.prototype.onUpdateToolbar = function() 
     61{  
     62  if (typeof dTree == 'undefined' || !Linker.methodsReady || !Linker.html || !this.files) 
     63  { 
     64    this.editor._toolbarObjects.createlink.state("enabled", false); 
     65  } 
     66  else this.onUpdateToolbar = null; 
     67}; 
    30068 
    30169Linker.Dialog_dTrees = [ ]; 
    30270 
     71Linker.loadAssets = function() 
     72{ 
     73  var self = Linker; 
     74  if (self.loading) return; 
     75  self.loading = true; 
     76  Xinha._getback(Xinha.getPluginDir("Linker") + '/pluginMethods.js', function(getback) { eval(getback); self.methodsReady = true; }); 
     77  Xinha._loadback( Xinha.getPluginDir("Linker") + '/dTree/dtree.js', function() {Linker.dTreeReady = true; } ); 
     78  Xinha._getback( Xinha.getPluginDir("Linker") + '/dialog.html', function(getback) { self.html = getback; } ); 
     79} 
    30380 
    304 Linker.Dialog = function (linker) 
     81Linker.prototype.loadFiles = function() 
    30582{ 
    306   var  lDialog = this; 
    307   this.Dialog_nxtid = 0; 
    308   this.linker = linker; 
    309   this.id = { }; // This will be filled below with a replace, nifty 
    310  
    311   this.ready = false; 
    312   this.files  = false; 
    313   this.html   = false; 
    314   this.dialog = false; 
    315  
    316   // load the dTree script 
    317   this._prepareDialog(); 
    318  
    319 }; 
    320  
    321 Linker.Dialog.prototype._prepareDialog = function() 
    322 { 
    323   var lDialog = this; 
    324   var linker = this.linker; 
    325  
    326   // We load some stuff up int he background, recalling this function 
    327   // when they have loaded.  This is to keep the editor responsive while 
    328   // we prepare the dialog. 
    329   if(typeof dTree == 'undefined') 
    330   { 
    331     Xinha._loadback(Xinha.getPluginDir("Linker") + '/dTree/dtree.js', 
    332                        function() {lDialog._prepareDialog(); } 
    333                       ); 
    334     return; 
    335   } 
    336  
    337   if(this.files === false) 
    338   { 
     83    var linker = this; 
    33984    if(linker.lConfig.backend) 
    34085    { 
    341       //get files from backend 
    342       Xinha._postback(linker.lConfig.backend, 
    343                       linker.lConfig.backend_data,  
     86        //get files from backend 
     87        Xinha._postback(linker.lConfig.backend, 
     88                          linker.lConfig.backend_data, 
    34489                          function(txt) { 
    34590                            try { 
    346                                 lDialog.files = eval(txt); 
     91                                linker.files = eval(txt); 
    34792                            } catch(Error) { 
    348                                 lDialog.files = [ {url:'',title:Error.toString()} ]; 
     93                                linker.files = [ {url:'',title:Error.toString()} ]; 
    34994                            } 
    350                             lDialog._prepareDialog(); }); 
     95                            }); 
    35196    } 
    35297    else if(linker.lConfig.files != null) 
    35398    { 
    35499        //get files from plugin-config 
    355         lDialog.files = linker.lConfig.files; 
    356         lDialog._prepareDialog(); 
     100        linker.files = linker.lConfig.files; 
    357101    } 
    358     return; 
    359   } 
    360   var files = this.files; 
    361  
    362   if(this.html == false) 
    363   { 
    364     Xinha._getback(Xinha.getPluginDir("Linker") + '/dialog.html', function(txt) { lDialog.html = txt; lDialog._prepareDialog(); }); 
    365     return; 
    366   } 
    367   var html = this.html; 
    368  
    369   // Now we have everything we need, so we can build the dialog. 
    370   var dialog = this.dialog = new Xinha.Dialog(linker.editor, this.html, 'Linker'); 
    371   var dTreeName = Xinha.uniq('dTree_'); 
    372  
    373   this.dTree = new dTree(dTreeName, Xinha.getPluginDir("Linker") + '/dTree/'); 
    374   eval(dTreeName + ' = this.dTree'); 
    375  
    376   this.dTree.add(this.Dialog_nxtid++, -1, linker.lConfig.treeCaption , null, linker.lConfig.treeCaption); 
    377   this.makeNodes(files, 0); 
    378  
    379   // Put it in 
    380   var ddTree = this.dialog.getElementById('dTree'); 
    381   //ddTree.innerHTML = this.dTree.toString(); 
    382   ddTree.innerHTML = ''; 
    383   ddTree.style.position = 'absolute'; 
    384   ddTree.style.left = 1 + 'px'; 
    385   ddTree.style.top =  0 + 'px'; 
    386   ddTree.style.overflow = 'auto'; 
    387   ddTree.style.backgroundColor = 'white'; 
    388   this.ddTree = ddTree; 
    389   this.dTree._linker_premade = this.dTree.toString(); 
    390  
    391   var options = this.dialog.getElementById('options'); 
    392   options.style.position = 'absolute'; 
    393   options.style.top      = 0   + 'px'; 
    394   options.style.right    = 0   + 'px'; 
    395   options.style.width    = 320 + 'px'; 
    396   options.style.overflow = 'auto'; 
    397  
    398   // Hookup the resizer 
    399   this.dialog.onresize = function() 
    400     { 
    401       var h = parseInt(dialog.height) - dialog.getElementById('h1').offsetHeight; 
    402       var w = parseInt(dialog.width)  - 322 ; 
    403       // An error is thrown with IE when trying to set a negative width or a negative height 
    404       // But perhaps a width / height of 0 is not the minimum required we need to set 
    405       if (w<0) w = 0; 
    406       if (h<0) h = 0; 
    407       options.style.height = ddTree.style.height = h + 'px'; 
    408       ddTree.style.width  = w + 'px'; 
    409     } 
    410  
    411   this.ready = true; 
    412 }; 
    413  
    414 Linker.Dialog.prototype.makeNodes = function(files, parent) 
    415 { 
    416   for(var i = 0; i < files.length; i++) 
    417   { 
    418     if(typeof files[i] == 'string') 
    419     { 
    420       this.dTree.add(Linker.nxtid++, parent, 
    421                      files[i].replace(/^.*\//, ''), 
    422                      'javascript:document.getElementsByName(\'' + this.dialog.id.href + '\')[0].value=decodeURIComponent(\'' + encodeURIComponent(files[i]) + '\');document.getElementsByName(\'' + this.dialog.id.type + '\')[0].click();document.getElementsByName(\'' + this.dialog.id.href + '\')[0].focus();void(0);', 
    423                      files[i]); 
    424     } 
    425     else if(typeof files[i]=="object" && files[i] && typeof files[i].length==="number") // there seems to be a strange bug in IE that requires this complicated check, see #1197 
    426     { 
    427       var id = this.Dialog_nxtid++; 
    428       this.dTree.add(id, parent, files[i][0].replace(/^.*\//, ''), null, files[i][0]); 
    429       this.makeNodes(files[i][1], id); 
    430     } 
    431     else if(typeof files[i] == 'object') 
    432     { 
    433       if(files[i].children) { 
    434         var id = this.Dialog_nxtid++; 
    435       } else { 
    436         var id = Linker.nxtid++; 
    437       } 
    438  
    439       if(files[i].title) var title = files[i].title; 
    440       else if(files[i].url) var title = files[i].url.replace(/^.*\//, ''); 
    441       else var title = "no title defined"; 
    442       if(files[i].url) var link = 'javascript:document.getElementsByName(\'' + this.dialog.id.href + '\')[0].value=decodeURIComponent(\'' + encodeURIComponent(files[i].url) + '\');document.getElementsByName(\'' + this.dialog.id.type + '\')[0].click();document.getElementsByName(\'' + this.dialog.id.href + '\')[0].focus();void(0);'; 
    443       else var link = ''; 
    444        
    445       this.dTree.add(id, parent, title, link, title); 
    446       if(files[i].children) { 
    447         this.makeNodes(files[i].children, id); 
    448       } 
    449     } 
    450   } 
    451 }; 
    452  
    453 Linker.Dialog.prototype._lc = Linker.prototype._lc; 
    454  
    455 Linker.Dialog.prototype.show = function(inputs, ok, cancel) 
    456 { 
    457   if(!this.ready) 
    458   { 
    459     var lDialog = this; 
    460     window.setTimeout(function() {lDialog.show(inputs,ok,cancel);},100); 
    461     return; 
    462   } 
    463  
    464   if(this.ddTree.innerHTML == '') 
    465   { 
    466     this.ddTree.innerHTML = this.dTree._linker_premade; 
    467   } 
    468  
    469   if(inputs.type=='url') 
    470   { 
    471     this.dialog.getElementById('urltable').style.display = ''; 
    472     this.dialog.getElementById('mailtable').style.display = 'none'; 
    473     this.dialog.getElementById('anchortable').style.display = 'none'; 
    474   } 
    475   else if(inputs.type=='anchor') 
    476   { 
    477     this.dialog.getElementById('urltable').style.display = 'none'; 
    478     this.dialog.getElementById('mailtable').style.display = 'none'; 
    479     this.dialog.getElementById('anchortable').style.display = ''; 
    480   } 
    481   else 
    482   { 
    483     this.dialog.getElementById('urltable').style.display = 'none'; 
    484     this.dialog.getElementById('mailtable').style.display = ''; 
    485     this.dialog.getElementById('anchortable').style.display = 'none'; 
    486   } 
    487  
    488   if(inputs.target=='popup') 
    489   { 
    490     this.dialog.getElementById('popuptable').style.display = ''; 
    491   } 
    492   else 
    493   { 
    494     this.dialog.getElementById('popuptable').style.display = 'none'; 
    495   } 
    496    
    497   var anchor = this.dialog.getElementById('anchor'); 
    498   for(var i=anchor.length;i>=0;i--) { 
    499     anchor[i] = null; 
    500   } 
    501  
    502   var html = this.linker.editor.getHTML();   
    503   var anchors = new Array(); 
    504  
    505   var m = html.match(/<a[^>]+name="([^"]+)"/gi); 
    506   if(m) 
    507   { 
    508     for(i=0;i<m.length;i++) 
    509     { 
    510         var n = m[i].match(/name="([^"]+)"/i); 
    511         if(!anchors.contains(n[1])) anchors.push(n[1]); 
    512     } 
    513   } 
    514   m = html.match(/id="([^"]+)"/gi); 
    515   if(m) 
    516   { 
    517     for(i=0;i<m.length;i++) 
    518     { 
    519         n = m[i].match(/id="([^"]+)"/i); 
    520         if(!anchors.contains(n[1])) anchors.push(n[1]); 
    521     } 
    522   } 
    523    
    524   for(i=0;i<anchors.length;i++) 
    525   { 
    526     var opt = new Option(anchors[i],'#'+anchors[i],false,(inputs.anchor == anchors[i])); 
    527     anchor[anchor.length] = opt; 
    528   } 
    529  
    530   //if no anchors found completely hide Anchor-Link 
    531   if(anchor.length==0) { 
    532     this.dialog.getElementById('anchorfieldset').style.display = "none"; 
    533   } 
    534    
    535   // if we're not editing an existing link, hide the remove link button 
    536   if (inputs.href == 'http://www.example.com/' && inputs.to == 'alice@example.com') {  
    537     this.dialog.getElementById('clear').style.display = "none"; 
    538   } 
    539   else { 
    540     this.dialog.getElementById('clear').style.display = ""; 
    541   } 
    542   // Connect the OK and Cancel buttons 
    543   var dialog = this.dialog; 
    544   var lDialog = this; 
    545   if(ok) 
    546   { 
    547     this.dialog.getElementById('ok').onclick = ok; 
    548   } 
    549   else 
    550   { 
    551     this.dialog.getElementById('ok').onclick = function() {lDialog.hide();}; 
    552   } 
    553  
    554   if(cancel) 
    555   { 
    556     this.dialog.getElementById('cancel').onclick = cancel; 
    557   } 
    558   else 
    559   { 
    560     this.dialog.getElementById('cancel').onclick = function() { lDialog.hide()}; 
    561   } 
    562  
    563   // Show the dialog 
    564   this.linker.editor.disableToolbar(['fullscreen','linker']); 
    565  
    566   this.dialog.show(inputs); 
    567  
    568   // Init the sizes 
    569   this.dialog.onresize(); 
    570 }; 
    571  
    572 Linker.Dialog.prototype.hide = function() 
    573 { 
    574   this.linker.editor.enableToolbar(); 
    575   return this.dialog.hide(); 
    576 }; 
     102} 
Note: See TracChangeset for help on using the changeset viewer.