Changeset 24:056ef2be1351

Show
Ignore:
Timestamp:
12/03/11 22:21:56 (19 months ago)
Author:
Dave Raggett <dsr@…>
Branch:
default
Tags:
tip
Message:

overhauled cookie blocking and p3p policy formatting, support for Firefox 10

Location:
dashboard
Files:
12 modified

Legend:

Unmodified
Added
Removed
  • dashboard/build.sh

    r22 r24  
    88touch $TARGET.xpi 
    99rm $TARGET.xpi 
    10 zip -r ../$TARGET.xpi install.rdf chrome.manifest chrome defaults readme.txt 
     10zip -r ../$TARGET.xpi install.rdf chrome.manifest chrome defaults readme.txt build.sh 
    1111mv ../$TARGET.xpi . 
  • dashboard/chrome/content/assess.js

    r0 r24  
    5454    }, false); 
    5555 
    56     let norton_button = document.getElementById("exec_norton_button"); 
    57     norton_button.addEventListener("command", function () 
    58     { 
    59       assess.check_norton(); 
    60     }, false); 
    61  
    62     let freetrust_button = document.getElementById("exec_freetrust_button"); 
    63     freetrust_button.addEventListener("command", function () 
    64     { 
    65       assess.check_freetrust(); 
    66     }, false); 
    67  
    68     let truste_button = document.getElementById("exec_truste_button"); 
    69     freetrust_button.addEventListener("command", function () 
    70     { 
    71       assess.check_truste(); 
    72     }, false); 
    73  
    7456    let simplify = document.getElementById("simplify_choices"); 
    7557    simplify.addEventListener("command", function () 
     
    213195  }, 
    214196 
    215   check_norton: function () 
    216   { 
    217     window.open("http://safeweb.norton.com/report/show?url="+this.host); 
    218   }, 
    219  
    220   check_freetrust: function () 
    221   { 
    222     window.open("http://freetrustseal.com/trust.php?site="+this.host); 
    223   }, 
    224  
    225   check_truste: function () 
    226   { 
    227     window.open("http://clicktoverify.truste.com/pvr.php?page=validate&url="+this.host); 
    228   }, 
    229  
    230197  record_prefs: function (evt) 
    231198  { 
    232     assess.save_prefs(assess.host); 
     199    // special effort to clear cookies 
     200    // when setting preferences 
     201    let id = this.getAttribute("id"); 
     202    let checked = this.getAttribute("checked"); 
     203    let host = assess.host; 
     204 
     205    if (id == "prefs_all_lasting_cookies") 
     206    { 
     207      if (checked == "true") 
     208         assess.query_3rd_parties(host, 
     209           function (host, parties, offsite) 
     210           { 
     211             assess.purge_cookies(host, 1<<5, parties, offsite); 
     212           }); 
     213    } 
     214    else if (id == "prefs_ext_3rd_cookies" || id == "thoughtful") 
     215    { 
     216      if (checked == "true") 
     217         assess.query_3rd_parties(host, 
     218           function (host, parties, offsite) 
     219           { 
     220             assess.purge_cookies(host, 1<<4, parties, offsite); 
     221           }); 
     222    } 
     223    else if (id == "paranoid") 
     224    { 
     225      if (checked == "true") 
     226         assess.query_3rd_parties(host, 
     227           function (host, parties, offsite) 
     228           { 
     229             assess.purge_cookies(host, (1<<4 | 1<<5), parties, offsite); 
     230           }); 
     231    } 
     232 
     233    assess.save_prefs(host); 
     234  }, 
     235 
     236  // query for list of 3rd parties for this site, assumes that 
     237  // database.log_3rd_parties(status); has already taken effect 
     238  query_3rd_parties: function (host, action) 
     239  { 
     240    let database = window.database; 
     241    let query = "SELECT DISTINCT third_party, offsite FROM  parties " + 
     242                "WHERE page_host = " + database.quote(host); 
     243 
     244    let handler =  
     245    { 
     246      parties: [], 
     247      offsite: [], 
     248 
     249      process_row: function (row) 
     250      { 
     251        this.parties.push(row.getResultByName("third_party")); 
     252        this.offsite.push(row.getResultByName("offsite"));         
     253      }, 
     254 
     255      finalize: function ()  
     256      { 
     257        action(host, this.parties, this.offsite); 
     258      } 
     259    }; 
     260 
     261    database.select(query, database.db, handler); 
     262  }, 
     263 
     264  // code copied from misc.rate_cookies() 
     265  purge_cookies: function (host, prefs, parties, offsite) 
     266  { 
     267    let cm = Components.classes['@mozilla.org/cookiemanager;1']. 
     268      getService(Components.interfaces.nsICookieManager2); 
     269 
     270    let cookies = cm.enumerator; 
     271    let lasting_cookies = []; 
     272    let session_cookies = []; 
     273    let int_3rd_lasting_cookies = []; 
     274    let int_3rd_session_cookies = []; 
     275    let ext_3rd_lasting_cookies = []; 
     276    let ext_3rd_session_cookies = []; 
     277 
     278    // iterate through cookiemanager's list of current cookies 
     279    // and check against first and all third party sites, this 
     280    // would require *many* database queries using SQLite 
     281    while (cookies.hasMoreElements()) 
     282    { 
     283      let cookie = cookies.getNext(); 
     284      cookie.QueryInterface(Components.interfaces.nsICookie2); 
     285 
     286      // cookie matching web page host 
     287      if (host.indexOf(cookie.host) >= 0) 
     288      { 
     289        if (cookie.isSession) 
     290          session_cookies.push(cookie); 
     291        else 
     292          lasting_cookies.push(cookie); 
     293      } 
     294      else  // check for 3rd party cookies 
     295      { 
     296        // pump up the cost! 
     297        for (let i in parties) 
     298        { 
     299          if (parties[i].indexOf(cookie.host) >= 0) 
     300          { 
     301            if (offsite[i] == 2) 
     302            { 
     303              if (cookie.isSession) 
     304                ext_3rd_session_cookies.push(cookie); 
     305              else 
     306                ext_3rd_lasting_cookies.push(cookie); 
     307            } 
     308            else 
     309            { 
     310              if (cookie.isSession) 
     311                int_3rd_session_cookies.push(cookie); 
     312              else 
     313                int_3rd_lasting_cookies.push(cookie); 
     314            } 
     315          } 
     316        } 
     317      } 
     318    } 
     319 
     320    let int_3rd_parties = 0; 
     321    let ext_3rd_parties = 0; 
     322 
     323    for (let i = 0; i < offsite.length; ++i) 
     324    { 
     325      if (offsite[i] == 2) 
     326        ++ext_3rd_parties; 
     327      else 
     328        ++int_3rd_parties; 
     329    } 
     330 
     331    if (prefs & (1<<5))  // purge all lasting cookies 
     332    { 
     333      for (let i = 0; i < lasting_cookies.length; ++i) 
     334      { 
     335        cookie = lasting_cookies[i]; 
     336        cm.remove(cookie.host, cookie.name, cookie.path, false); 
     337      } 
     338 
     339      for (let i = 0; i < int_3rd_lasting_cookies.length; ++i) 
     340      { 
     341        cookie = int_3rd_lasting_cookies[i]; 
     342        cm.remove(cookie.host, cookie.name, cookie.path, false); 
     343      } 
     344 
     345      for (let i = 0; i < ext_3rd_lasting_cookies.length; ++i) 
     346      { 
     347        cookie = ext_3rd_lasting_cookies[i]; 
     348        cm.remove(cookie.host, cookie.name, cookie.path, false); 
     349      } 
     350    } 
     351    else 
     352    { 
     353      if (prefs & (1<<4))  // purge all 3rd party cookies 
     354      { 
     355        for (let i = 0; i < ext_3rd_session_cookies.length; ++i) 
     356        { 
     357          cookie = ext_3rd_session_cookies[i]; 
     358          cm.remove(cookie.host, cookie.name, cookie.path, false); 
     359        } 
     360 
     361        for (let i = 0; i < ext_3rd_lasting_cookies.length; ++i) 
     362        { 
     363          cookie = ext_3rd_lasting_cookies[i]; 
     364          cm.remove(cookie.host, cookie.name, cookie.path, false); 
     365        } 
     366      } 
     367    } 
    233368  }, 
    234369 
  • dashboard/chrome/content/dashboard.js

    r2 r24  
    335335  // which is obtained from the onLocationChange event 
    336336  update_current_site: function (status) { 
    337     this.assess.update_current_site(status); 
     337    console.log("dashboard.update_current_site: " + status.page_host); 
     338    assess.update_current_site(status); 
    338339  }, 
    339340 
  • dashboard/chrome/content/dashboard.xul

    r16 r24  
    153153        <vbox flex="1" style="overflow:auto; padding:10px"> 
    154154        <html:div id="p3p_policy"/> 
     155        <vbox  id="site_info"> 
    155156        <html:h3>&dashboard.dialog.current.heading;</html:h3> 
    156         <vbox  id="site_info"> 
    157157        <description> 
    158158        <html:p>&dashboard.dialog.cursite.descr;</html:p> 
     
    246246        </panel> 
    247247        </description> 
    248         <html:hr/> 
    249         <html:p>&dashboard.dialog.cursite.test;</html:p> 
    250         <hbox> 
    251         <button id="exec_norton_button" label="&dashboard.dialog.cursite.test.norton.label;"/> 
    252         <button id="exec_freetrust_button" label="&dashboard.dialog.cursite.test.freetrust.label;"/> 
    253         <button id="exec_truste_button" label="&dashboard.dialog.cursite.test.truste.label;"/> 
    254         </hbox> 
    255248        </vbox> 
    256249        </vbox> 
  • dashboard/chrome/content/database.js

    r1 r24  
    824824    var prefs; 
    825825 
    826     var sql = "SELECT prefs FROM site_info WHERE host = '" + 
     826    let sql = "SELECT prefs FROM site_info WHERE host = '" + 
    827827              host + "'"; 
    828828 
    829     var dataset = this.sync_get(sql, db); 
     829    let dataset = this.sync_get(sql, db); 
    830830 
    831831    if (dataset && dataset.length > 0) 
  • dashboard/chrome/content/misc.js

    r0 r24  
    401401  rate_site: function (browser) 
    402402  { 
    403     var uri = browser.currentURI; 
    404     var status = browser.dashboard_status; 
     403    let uri = browser.currentURI; 
     404    let status = browser.dashboard_status; 
    405405 
    406406    // status is null for about:* pages 
    407     var host = (status ? status.page_host : null); 
     407    let host = (status ? status.page_host : null); 
     408    console.log("misc.rate_site: " + host); 
    408409     
    409410    if (host) 
    410411    { 
    411       this.query_3rd_parties(browser, host); 
    412       this.query_p3p(browser, host); 
    413       this.query_geo(browser, host); 
     412      // synchronous functions 
    414413      this.html5_ping(browser); 
    415       this.query_dom_storage(browser); 
    416  
    417       // allow page scripts to do their evil work before check 
    418       setTimeout( function () 
    419       { 
    420         dashboard_overlay.misc.spot_web_bugs(browser); 
    421       }, 10 ); 
     414      this.spot_web_bugs(browser); 
     415 
     416      // prepare continuation, count is number of processes  
     417      // before calling misc.update_dashboard(browser); 
     418      let counter = { "count": 4 }; 
     419 
     420      // asynchronous involving db access 
     421      this.query_3rd_parties(browser, host, counter); 
     422      this.query_p3p(browser, host, counter); 
     423      this.query_geo(browser, host, counter); 
     424      this.query_dom_storage(browser, counter); 
    422425    } 
    423426    else // treat non-http pages as cool 
     
    426429      primelife_button.style.listStyleImage =  
    427430             'url("chrome://dashboard-common/skin/glasses-cool.png")'; 
    428     } 
    429  
    430     let context = dashboard_overlay.context; 
    431     let dialog = context.dashboard_dialog; 
    432  
    433     // check if this is the current browser to avoid changing dashboard if it's not 
    434     if (dialog && dialog.dashboard && browser == dashboard_overlay.current_browser()) 
    435     { 
    436       dialog.dashboard_overlay = dashboard_overlay; 
    437       var update = dialog.dashboard.update_current_site; 
    438  
    439       // some of the above database operations are asynchronous 
    440       // and need time to complete before we display the results 
    441       // query p3p has its own means to refresh dashboard display 
    442       // since it involves external network traffic for policies 
    443       // 200mS should be plenty for SQLite database operations. 
    444       setTimeout(function () 
    445       { 
    446         if (status) 
    447           update(status); 
    448       }, 200); 
    449     } 
     431 
     432      this.update_dashboard(browser); 
     433    } 
     434  }, 
     435 
     436  // update dashboard current site user interface 
     437  // introduce delay to allow change in browser to take effect 
     438  update_dashboard: function (browser) 
     439  { 
     440    setTimeout(function () 
     441    { 
     442      dashboard_overlay.misc.check_rating(browser); 
     443 
     444      let status = browser.dashboard_status; 
     445      let context = dashboard_overlay.context; 
     446      let dialog = context.dashboard_dialog; 
     447      console.log("update_dashboard: " + status.page_host); 
     448 
     449      // check if this is the current browser to avoid changing dashboard if it's not 
     450      if (dialog && dialog.dashboard && browser == dashboard_overlay.current_browser()) 
     451      { 
     452        dialog.dashboard_overlay = dashboard_overlay; 
     453        dialog.dashboard.update_current_site(status); 
     454      } 
     455    }, 10); 
    450456  }, 
    451457 
     
    489495  }, 
    490496 
    491   // query for list of 3rd parties for this site 
    492   query_3rd_parties: function (browser, host) 
     497  // query for list of 3rd parties for this site, assumes that 
     498  // database.log_3rd_parties(status); has already taken effect 
     499  query_3rd_parties: function (browser, host, counter) 
    493500  { 
    494501    let database = dashboard_overlay.database; 
     
    498505    let handler =  
    499506    { 
    500       browser: browser, 
    501507      parties: [], 
    502508      offsite: [], 
     
    511517      { 
    512518        dashboard_overlay.misc.rate_cookies(browser, this.parties, this.offsite); 
     519 
     520        if (--counter.count <= 0) 
     521          dashboard_overlay.misc.update_dashboard(browser); 
    513522      } 
    514523    }; 
     
    517526  }, 
    518527 
    519   query_dom_storage: function (browser) 
     528  query_dom_storage: function (browser, counter) 
    520529  { 
    521530    let database = dashboard_overlay.database; 
     
    550559      { 
    551560        status.dom_storage = this.keys.length; 
     561 
     562        if (--counter.count <= 0) 
     563          dashboard_overlay.misc.update_dashboard(browser); 
    552564      } 
    553565    }; 
     
    560572  // then do same check for flash supercookies 
    561573  // linear in *total* number of cookies for all hosts 
     574  // it may be faster(?) to scan separately for cookies 
     575  // for the host and for each 3rd party 
    562576  rate_cookies: function (browser, parties, offsite)  
    563577  { 
     
    583597      cookie.QueryInterface(Components.interfaces.nsICookie2); 
    584598 
     599      // cookie matching web page host 
    585600      if (host.indexOf(cookie.host) >= 0) 
    586601      { 
     
    590605          lasting_cookies.push(cookie); 
    591606      } 
    592       else 
     607      else  // check for 3rd party cookies 
    593608      { 
    594609        // pump up the cost! 
     
    661676    status.ext_3rd_party_flash_cookies = ext_3rd_fso.length; 
    662677 
    663     this.check_rating(browser); 
    664   }, 
    665  
    666   query_p3p: function (browser, host) 
     678    // get prefs and purge unwanted cookies 
     679    let database = dashboard_overlay.database; 
     680    let prefs = database.get_prefs(host, database.db); 
     681    let cookie = null; 
     682    console.log("rate_cookies: prefs = " + prefs); 
     683 
     684    if (prefs & (1<<5))  // purge all lasting cookies 
     685    { 
     686      for (let i = 0; i < lasting_cookies.length; ++i) 
     687      { 
     688        cookie = lasting_cookies[i]; 
     689        cm.remove(cookie.host, cookie.name, cookie.path, false); 
     690      } 
     691 
     692      for (let i = 0; i < int_3rd_lasting_cookies.length; ++i) 
     693      { 
     694        cookie = int_3rd_lasting_cookies[i]; 
     695        cm.remove(cookie.host, cookie.name, cookie.path, false); 
     696      } 
     697 
     698      for (let i = 0; i < ext_3rd_lasting_cookies.length; ++i) 
     699      { 
     700        cookie = ext_3rd_lasting_cookies[i]; 
     701        cm.remove(cookie.host, cookie.name, cookie.path, false); 
     702      } 
     703 
     704      if (prefs & (1<<4))  // purge all 3rd party cookies 
     705      { 
     706        for (let i = 0; i < ext_3rd_session_cookies.length; ++i) 
     707        { 
     708          cookie = ext_3rd_session_cookies[i]; 
     709          cm.remove(cookie.host, cookie.name, cookie.path, false); 
     710        } 
     711      } 
     712    } 
     713    else 
     714    { 
     715      if (prefs & (1<<4))  // purge all 3rd party cookies 
     716      { 
     717        for (let i = 0; i < ext_3rd_session_cookies.length; ++i) 
     718        { 
     719          cookie = ext_3rd_session_cookies[i]; 
     720          cm.remove(cookie.host, cookie.name, cookie.path, false); 
     721        } 
     722 
     723        for (let i = 0; i < ext_3rd_lasting_cookies.length; ++i) 
     724        { 
     725          cookie = ext_3rd_lasting_cookies[i]; 
     726          cm.remove(cookie.host, cookie.name, cookie.path, false); 
     727        } 
     728      } 
     729    } 
     730  }, 
     731 
     732  query_p3p: function (browser, host, counter) 
    667733  { 
    668734    let database = dashboard_overlay.database; 
     
    680746      { 
    681747        dashboard_overlay.misc.rate_p3p(browser, this.data); 
     748 
     749        if (--counter.count <= 0) 
     750          dashboard_overlay.misc.update_dashboard(browser); 
    682751      } 
    683752    }; 
     
    692761  }, 
    693762 
    694   query_geo: function (browser, host) 
     763  query_geo: function (browser, host, counter) 
    695764  { 
    696765    let database = dashboard_overlay.database; 
     
    710779      { 
    711780        dashboard_overlay.misc.rate_geo(this.browser, this.data); 
     781 
     782        if (--counter.count <= 0) 
     783          dashboard_overlay.misc.update_dashboard(browser); 
    712784      } 
    713785    }; 
  • dashboard/chrome/content/observer.js

    r0 r24  
    6060      observerService.addObserver(this, "http-on-modify-request", false); 
    6161      observerService.addObserver(this, "http-on-examine-response", false); 
     62      observerService.addObserver(this, "cookie-changed", false); 
    6263 
    6364      // register content policy 
     
    9697      observerService.removeObserver(this, "http-on-examine-response"); 
    9798      observerService.removeObserver(this, "http-on-modify-request"); 
     99      observerService.addObserver(this, "cookie-changed", false); 
    98100 
    99101      // is it sensible to delete the category entry here? 
     
    219221      let offsite = 0; 
    220222      let block_3rd_party_cookie = false; 
    221       let block_lasting_cookies = false; 
    222223      let block_3rd_parties = false; 
    223224 
    224       // the experimental "do not track" headers, as explained in 
    225       // http://paranoia.dubfire.net/2011/01/history-of-do-not-track-header.html 
     225      // the "do not track" header, as defined in 
     226      // http://www.w3.org/Submission/web-tracking-protection/ 
    226227      if (prefs & (1 << 15)) 
    227228      { 
    228         httpChannel.setRequestHeader("X-Behavioral-Ad-Opt-Out", "1", false); 
    229         httpChannel.setRequestHeader("X-Do-Not-Track", "1", false); 
    230       } 
    231  
    232       block_lasting_cookies = prefs & (1<<5); 
     229        httpChannel.setRequestHeader("DNT", "1", false); 
     230      } 
     231 
     232      // unwanted cookies are purged after page has loaded 
    233233 
    234234      // 3 from bit position in assess:save_prefs    
     
    401401      let httpChannel = subject.QueryInterface(Components.interfaces.nsIHttpChannel); 
    402402 
    403     let type = ""; 
    404     try { 
    405       type = httpChannel.getResponseHeader("Content-Type"); 
    406     } catch (e) { 
    407       type = "undefined"; 
    408     }  
     403      let type = ""; 
     404      try { 
     405        type = httpChannel.getResponseHeader("Content-Type"); 
     406      } catch (e) { 
     407        type = "undefined"; 
     408      }  
    409409 
    410410      console.log("loading (" + httpChannel.responseStatus +  ") " + type + " from " + httpChannel.URI.spec); 
     
    424424          let never = rp ? rp & (1 <<2) : false ; // never block content from this site 
    425425 
     426          let block_lasting_cookies = status.prefs & (1<<5); 
    426427          let block_3rd_parties = status.prefs & (1<<3); 
    427428          let block_flash = status.prefs & (1<<12); 
    428429          let block_java = status.prefs & (1<<13); 
     430 
     431          // always block cookies set on P3P policy! 
     432          if (target.path == "/w3c/p3p.xml") 
     433            observer.block_p3p_cookies(httpChannel); 
    429434 
    430435          if (block_3rd_parties & !never) 
     
    470475      } 
    471476    } 
     477    else if (topic == "cookie-changed")  // only used for logging purposes 
     478    { 
     479      // subject is nsICookie2 or nsIArray of nsICookie2 objects 
     480      // data  is "deleted", "added", "changed", "batch-deleted", "cleared or "reload" 
     481      let cookies = null; 
     482 
     483      try { 
     484        cookies = subject.QueryInterface(Components.interfaces.nsIArray); 
     485      } catch (e) { 
     486        cookies = null; 
     487      } 
     488 
     489      if (!cookies) 
     490      { 
     491        let cookie = subject ? subject.QueryInterface(Components.interfaces.nsICookie2) : null; 
     492 
     493        if (cookie) 
     494          cookies = [ cookie ]; 
     495      } 
     496 
     497      let i = 0; 
     498      while (i < cookies.length) 
     499      { 
     500        let cookie = cookies[i++]; 
     501        console.log("cookie " + cookie.name + " for " + cookie.host + " " + data); 
     502      } 
     503    } 
    472504  }, 
    473505 
     
    496528      } 
    497529 
     530      console.log("get_tab_index_from_channel: notificationCallbacks is null"); 
    498531      return -2; 
    499532    } 
    500533    catch (e) 
    501534    { 
     535      console.log("get_tab_index_from_channel: " + e); 
    502536      if (aChannel.loadGroup) 
    503537      { 
     
    518552          catch (e) 
    519553          { 
     554            console.log("get_tab_index_from_channel: " + e); 
    520555            return -4; 
    521556          } 
    522557        } 
    523558      } 
     559 
     560      console.log("get_tab_index_from_channel: notificationCallbacks is null or loadGroup is null"); 
    524561      return -3; 
    525562    } 
     563  }, 
     564 
     565  block_p3p_cookies: function (httpChannel) 
     566  { 
     567    console.log("observer.block_p3p_cookies on " + httpChannel.URI.host); 
     568 
     569    let visitor = { 
     570      "channel": httpChannel, 
     571      "host": httpChannel.URI.host, 
     572 
     573      "visitHeader": function (header, value) 
     574      { 
     575        if (header == "Set-Cookie") 
     576          this.channel.setResponseHeader(header, null, false); 
     577      } 
     578    }; 
     579 
     580    httpChannel.visitResponseHeaders(visitor); 
    526581  }, 
    527582 
  • dashboard/chrome/content/overlay.js

    r1 r24  
    302302    catch (e) 
    303303    { 
    304       alert("couldn't get localized string for " + key); 
     304      alert("couldn't get localized string for " + key + "\n " + e); 
    305305      return key; 
    306306    } 
     
    705705  }, 
    706706   
     707  // clear tab's dashboard status 
    707708  on_page_unload: function(aEvent) 
    708709  {   
    709710    var doc = aEvent.originalTarget; 
    710     // doc is document that triggered "onunload" event   
    711     // do something with the unloaded page. 
    712  
    713     //gBrowser.removeProgressListener(this.progressListener); 
     711 
     712    if (doc instanceof HTMLDocument) 
     713    { 
     714      let win = doc.defaultView; 
     715 
     716      if (win.frameElement) 
     717        return; 
     718 
     719      console.log("on page unload event - " + doc.location.href); 
     720 
     721      // find browser for this document 
     722      var browser = this.find_browser_from_doc(doc); 
     723 
     724      if (browser) 
     725        browser.dashboard_status = null; 
     726    }  
    714727  }, 
    715728 
  • dashboard/chrome/content/p3p.js

    r0 r24  
    4444      return alert("couldn't find correct policy for path: " + path); 
    4545 
     46    console.log("render_policy: uri = " + uri + " path = " + path); 
     47 
    4648    var req = new XMLHttpRequest(); 
    4749 
     
    5456        if (req.status == 200) 
    5557        { 
    56           if (req.responseXML) 
     58          if (req.responseXML && req.responseXML.documentElement.nodeName != "parsererror") 
    5759            dashboard_p3p.find_applicable_policy(path, req.responseXML, depth); 
    5860          else 
     
    6668            } 
    6769*/ 
    68             alert("malformed P3P policy for url: " + uri + 
     70            console.log("trimming leading space before re-parse"); 
     71            // trim leading whitespace before XML declaration 
     72            // so that we can view the policy for a common error 
     73            let s = req.responseText; 
     74            let i = 0; 
     75            for (i = 0; i < s.length && s.charCodeAt(i) < 33; ++i); 
     76            s = s.substr(i); 
     77 
     78            let parser = new DOMParser(); 
     79            let dom = parser.parseFromString(s, "text/xml"); 
     80 
     81            if (dom.documentElement.nodeName != "parsererror") 
     82              dashboard_p3p.find_applicable_policy(path, dom, depth); 
     83            else 
     84              alert("malformed P3P policy for url: " + uri + 
    6985                  "\nmedia type is " + req.channel.contentType); 
    7086          } 
     
    103119  find_applicable_policy: function (path, doc, depth) 
    104120  { 
     121    let serializer = new XMLSerializer(); 
     122    let xml = serializer.serializeToString(doc); 
     123    //alert(xml); 
     124 
    105125    let uri = null, el, pattern; 
    106126    let root = doc.documentElement; 
     127    console.log("p3p root element is " + root.nodeName); 
    107128    let includes = root.getElementsByTagName("INCLUDE"); 
    108129 
     
    121142    if (!uri) 
    122143    { 
     144      console.log("p3p: checking POLICY-REF element"); 
    123145      let pr = root.getElementsByTagName("POLICY-REF"); 
    124146 
    125147      if (pr && pr.length > 0) 
    126148        uri = pr[0].getAttribute("about"); 
     149      else 
     150        console.log("p3p: can't find any POLICY-REF elements"); 
     151 
     152      console.log("p3p policy-ref: " + uri); 
    127153    } 
    128154 
     
    168194  }, 
    169195 
    170   show_policy: function (path, root) { 
     196  show_policy: function (path, root) 
     197  { 
    171198    let p3p = dashboard_p3p; 
     199    console.log("show_policy: path = " + path); 
    172200 
    173201    if (!p3p.description) 
     
    181209    p3p.description.appendChild(el); 
    182210 
    183     el.innerHTML = dashboard.localize("p3p_render.comment"); 
     211    el.innerHTML = dashboard.localize("p3p_render.comment") + "<html:br />\n"; 
    184212 
    185213    let policies = root.getElementsByTagName("POLICY"); 
     
    246274  { 
    247275    let obj = {}; 
     276    console.log("p3p dump_contact: " + discuri); 
    248277 
    249278    for (let data = contact.firstChild; data; data = data.nextSibling) 
     
    263292    s += "<html:h2>"+obj.business.name+" P3P Privacy Policy</html:h2>\n"; 
    264293 
    265     s += "<html:p><html:em>See also site's <html:a id='shrp'>" + 
    266          "human readable policy</html:a></html:em></html:p>\n"; 
     294    if (discuri) 
     295    { 
     296      s += "<html:p><html:em>See also site's <html:a id='shrp' title='" + discuri + "'>" + 
     297           "human readable policy</html:a></html:em></html:p>\n"; 
     298    } 
    267299 
    268300    s += "<html:p>\n"; 
    269301 
    270     s += obj.business.contact_info.postal.street + "<html:br />\n"; 
    271     s += obj.business.contact_info.postal.city + ", "; 
    272  
    273     if (obj.business.contact_info.postal.stateprov) 
    274       s += obj.business.contact_info.postal.stateprov + " "; 
     302    if (typeof(obj.business.contact_info.postal) != "undefined") 
     303    { 
     304      try 
     305      { 
     306        let info = obj.business.contact_info; 
     307 
     308        s += info.postal.street + "<html:br />\n"; 
     309        s += info.postal.city + ", "; 
     310 
     311        if (info.postal.stateprov) 
     312        s += info.postal.stateprov + " "; 
    275313   
    276     if (obj.business.contact_info.postal.postalcode) 
    277       s += obj.business.contact_info.postal.postalcode + "<html:br />\n"; 
    278  
    279     s += obj.business.contact_info.postal.country + "<html:br />\n"; 
    280  
    281     if (obj.business.contact_info.online.email) 
    282     { 
    283       s += "<html:br />email: \n"; 
    284       s += obj.business.contact_info.online.email; 
    285     } 
    286  
    287     if (obj.business.contact_info.telecom && 
    288            obj.business.contact_info.telecom.telephone) 
    289     { 
    290       s += "<html:br />phone: \n"; 
    291       if (obj.business.contact_info.telecom.telephone.intcode) 
    292       { 
    293         s += "+"  + obj.business.contact_info.telecom.telephone.intcode; 
    294         s += "."  + obj.business.contact_info.telecom.telephone.loccode; 
    295         s += "."  + obj.business.contact_info.telecom.telephone.number; 
    296       } 
    297       else if (obj.business.contact_info.telecom.telephone.number) 
    298       { 
    299          if (obj.business.contact_info.telecom.telephone.number.substr(0,2) == "00") 
    300            s += "+" + obj.business.contact_info.telecom.telephone.substr(2); 
    301          else 
    302            s += obj.business.contact_info.telecom.telephone.number; 
    303       } 
    304       else if (typeof (obj.business.contact_info.telecom.telephone) == "string") 
    305       { 
    306          if (obj.business.contact_info.telecom.telephone.substr(0,2) == "00") 
    307            s += "+" + obj.business.contact_info.telecom.telephone.substr(2); 
    308          else 
    309            s += obj.business.contact_info.telecom.telephone; 
     314        if (info.postal.postalcode) 
     315          s += info.postal.postalcode + "<html:br />\n"; 
     316 
     317        s += info.postal.country + "<html:br />\n"; 
     318 
     319        if (info.online.email) 
     320        { 
     321          s += "<html:br />email: \n"; 
     322          s += info.online.email; 
     323        } 
     324 
     325        if (info.telecom && info.telecom.telephone) 
     326        { 
     327          s += "<html:br />phone: \n"; 
     328 
     329          if (info.telecom.telephone.intcode) 
     330          { 
     331            s += "+"  + info.telecom.telephone.intcode; 
     332            s += "."  + info.telecom.telephone.loccode; 
     333            s += "."  + info.telecom.telephone.number; 
     334          } 
     335          else if (info.telecom.telephone.number) 
     336          { 
     337            if (info.telecom.telephone.number.substr(0,2) == "00") 
     338              s += "+" + info.telecom.telephone.substr(2); 
     339            else 
     340              s += info.telecom.telephone.number; 
     341          } 
     342          else if (typeof (info.telecom.telephone) == "string") 
     343          { 
     344            if (info.telecom.telephone.substr(0,2) == "00") 
     345              s += "+" + info.telecom.telephone.substr(2); 
     346            else 
     347            s += info.telecom.telephone; 
     348          } 
     349        } 
     350      } 
     351      catch (e) 
     352      { 
     353        console.log("p3p: couldn't format address for "  + obj.business.name); 
    310354      } 
    311355    } 
    312356 
    313357    s += "\n</html:p>\n"; 
    314  
    315358    this.description.appendChild(div); 
    316359    div.innerHTML += s; 
     
    321364    var parent_window = window.arguments ? window.arguments[1] : null; 
    322365    let link = document.getElementById("shrp"); 
    323     link.addEventListener("click", function (e) { 
    324        let browser = parent_window.gBrowser; 
    325        browser.selectedTab =  browser.addTab(discuri); 
    326        e.cancel = true; 
    327        e.stopPropagation(); 
    328        e.preventDefault(); 
    329        return false; 
    330     }, false); 
     366 
     367    if (discuri) 
     368    { 
     369      link.addEventListener("click", function (e) { 
     370         let browser = parent_window.gBrowser; 
     371         browser.selectedTab =  browser.addTab(discuri); 
     372         e.cancel = true; 
     373         e.stopPropagation(); 
     374         e.preventDefault(); 
     375         return false; 
     376      }, false); 
     377    } 
    331378  }, 
    332379 
     
    351398 
    352399    name = ref[ref.length - 1]; 
    353     part[name] = value; 
     400 
     401    if (!part[name]) 
     402      part[name] = value; 
    354403  }, 
    355404 
     
    383432        let desc = this.get_description(ref); 
    384433        if (!desc) desc = ref; 
     434 
     435        // special case as details are given separately 
     436        if (ref == "dynamic.miscdata") 
     437          continue; 
     438 
    385439        li = document.createElementNS("http://www.w3.org/1999/xhtml", "li"); 
    386440        ul.appendChild(li); 
     
    407461 
    408462        let purpose = this.purposes[el.nodeName]; 
    409         if (!purpose) purpose = el.nodeName; 
     463        if (!purpose) 
     464          break; 
    410465 
    411466        let li = document.createElementNS("http://www.w3.org/1999/xhtml", "li"); 
     
    467522 
    468523        let retention = this.retention[el.nodeName]; 
    469         if (!retention) purpose = el.nodeName; 
     524 
     525        if (!retention) 
     526        { 
     527          purpose = el.nodeName; 
     528          retention = this.retention["undefined"]; 
     529        } 
    470530 
    471531        let li = document.createElementNS("http://www.w3.org/1999/xhtml", "li"); 
     
    686746      "period of time. The absence of a retention policy would be " + 
    687747      "reflected under this option. Where the recipient is a public " + 
    688       "fora, this is the appropriate retention policy.</html:span>" 
     748      "fora, this is the appropriate retention policy.</html:span>", 
     749    "undefined" : 
     750      "<html:span>A site specific retention policy.</html:span>" 
    689751  }, 
    690752 
     
    699761  { 
    700762    "user.name" : "user's name", 
     763    "user.home-info" : "user's home contact information", 
     764    "user.home-info.postal" : "user's address", 
     765    "user.home-info.telecom" : "user's phone number", 
     766    "user.home-info.online.email" : "user's email", 
    701767    "user.employer" : "user's employer", 
    702768    "dynamic.clickstream" : "information typically found in Web " + 
  • dashboard/chrome/locale/en-US/dashboard.dtd

    r21 r24  
    164164 "sets the default preferences for sites for which you haven't set overrides"> 
    165165 
    166 <!ENTITY dashboard.dialog.cursite.test 
    167  "You can use the following buttons to check the current website in various ways. These use external websites and open in a new window."> 
    168  
    169 <!ENTITY dashboard.dialog.cursite.test.norton.label 
    170  "Check site with Norton SafeWeb..."> 
    171 <!ENTITY dashboard.dialog.cursite.test.freetrust.label 
    172  "Check site with Free Trust Seal..."> 
    173 <!ENTITY dashboard.dialog.cursite.test.truste.label 
    174  "Check site with TRUSTe..."> 
    175  
    176166<!-- share table info --> 
    177167 
  • dashboard/install.rdf

    r23 r24  
    44  <Description about="urn:mozilla:install-manifest"> 
    55    <em:id>dashboard@dave.raggett</em:id> 
    6     <em:version>0.9.6</em:version> 
     6    <em:version>0.9.8</em:version> 
    77    <em:localized> 
    88      <Description> <!-- example localization via google translate --> 
     
    2626        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!-- firefox --> 
    2727        <em:minVersion>3.0.9</em:minVersion> 
    28         <em:maxVersion>6.1</em:maxVersion> 
     28        <em:maxVersion>10.0</em:maxVersion> 
    2929      </Description> 
    3030    </em:targetApplication>