try { var medialib; var mquery; var albumremote; var artistremote; var filepath; var timeout; var onalbumchange; var frame; var firefoxClassLoaderURL; var policy; var tracingClassLoaderClass; var bootstraped; var albumArtClass; var traceFlag = true; var firefoxClassLoaderURL var applet = null; var currentArtist=""; var currentAlbum=""; var downloadImage=false; var writeMp3Tag=false; var prefs; var splitter; var box=null; var oldframe=null; var framebox; var removespacer; var firefoxClassLoaderPackages; var packages; var playlist; var loaded = false; function loadAlbums() { var url; var javaInstance var album = albumremote.stringValue; var artist = artistremote.stringValue; downloadImage = this.prefs.getBoolPref("downloadImages"); writeMp3Tag = this.prefs.getBoolPref("writeMp3tag"); var doc = frame.contentDocument; if (doc.wrappedJSObject) doc = doc.wrappedJSObject; applet = doc.applets[0]; if (applet == null){ alert("Applet not loaded. Please ensure that java 1.6 (1.5 for Mac OS) is installed on Songbird"); } else { if (((currentAlbum != album) || (currentArtist != artist)) && (album!="" || artist!="")) { currentAlbum = album; currentArtist = artist; } var file = filepath.stringValue; applet.setDownloadImage(downloadImage); applet.setWriteMP3Tag(writeMp3Tag); addAlbumsByArtist(); applet.loadingDone(); } } function initAlbumApplet() { initmedialib(); givePermission(); albumremote = SB_NewDataRemote("metadata.album", null); artistremote = SB_NewDataRemote("metadata.artist", null); filepath = SB_NewDataRemote("metadata.url",null); /* function onPlaylistCellClick( aEvent ) { // we can get the property that was clicked on... alert(aEvent.property); // or the <MediaItem> alert(aEvent.item.guid); // as well as key states from MouseEvent alert(aEvent.ctrlKey); } songbird; */ var albumExtension = { albumListener: function(evt) { setAlbumFilter(evt.target.getAttribute("album")); } } var loadedExtension = { loadedListener: function(evt) { loadAlbums(); } } var playExtension = { playListener : function(evt) { setAlbumFilter(evt.target.getAttribute("album")); playFilter(); } } var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShellTreeItem) .rootTreeItem .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindow); mainWindow.document.addEventListener("albumChangeEvent", function(e) { albumExtension.albumListener(e); }, false, true); mainWindow.document.addEventListener("appletLoadedEvent", function(e) { loadedExtension.loadedListener(e); }, false, true); mainWindow.document.addEventListener("AlbumAppletPlayEvent", function(e) { playExtension.playListener(e); }, false, true); //mainWindow.document.addEventListener("PlaylistCellClick", onPlaylistCellClick, false, true); var onalbumchange = { observe: function( aSubject, aTopic, aData ) { syncSelectedAlbum(); } }; albumremote.bindObserver(onalbumchange, true); var firefoxClassLoaderURL = new java.net.URL(getPath("albumapplet") + "components/firefoxClassLoader.jar"); var extensionPath = getPath("albumapplet"); /* * Enumerate URLs to our JARs and class directories */ var libPath = extensionPath + "components/lib/"; var jarFilenames = [ "classes/", "albumjava/", //the albumJava classes, "albumjava/ascrblr-1.0-alpha2.jar", "albumjava/jdom.jar", "albumjava/swingx-2007_10_14.jar", "albumjava/sqlitejdbc-v037-nested.jar", "albumjava/JID3.jar", "albumjava/TimingFramework-1.0.jar" ]; var jarFilepaths = []; for (var i = 0; i < jarFilenames.length; i++) { jarFilepaths.push(libPath + jarFilenames[i]); } /* * Load them up! */ packages = loadJava(jarFilepaths); /* * Create a sample Java object */ placeApplet(); } function syncSelectedAlbum() { var album = albumremote.stringValue; var artist = artistremote.stringValue; if (((currentAlbum != album) || (currentArtist != artist)) && (album!="" || artist!="") && applet!=null) { applet.setSelectedAlbum(album,artist); } } function setAlbumFilter( aAlbum ) { try { // Crack out the variables we'll need var playlist = document.getElementById("sb-library-page-playlist"); var mediaListView = playlist.mediaListView; var cascadeFilterSet = mediaListView.cascadeFilterSet; // Find which filter index is the album filter var albumIndex = -1; for ( albumIndex = 0; albumIndex < cascadeFilterSet.length; albumIndex++ ) { if ( cascadeFilterSet.getProperty( albumIndex ) == SBProperties.albumName ) break; } // If we found the albumIndex if ( albumIndex < cascadeFilterSet.length ) { // Get all the valid albums var albums = cascadeFilterSet.getValues( albumIndex ); // Find the requested album while ( albums.hasMore() ) { var album = albums.getNext(); if ( album == aAlbum ) { // And set a single filter value and return cascadeFilterSet.set( albumIndex, [ aAlbum ], 1 ); return; } } // OTHERWISE, I guess you meant to clear the filter, right? cascadeFilterSet.set( albumIndex, [ ], 0 ); } } catch ( err ) { alert( "setAlbumFilter( '" + aAlbum + "' )\n\n" + err ); } } function playFilter(){ try { var playlist = document.getElementById("sb-library-page-playlist"); playlist.sendPlayEvent(); } catch( err) { alert("playFilter error. Someone messed up. I swear, it wasn't me! \n" + err); } } function resetalbumArt() { medialib = null; mquery = null; albumremote.unbind(); albumremote = null; onalbumchange = null; button = null; } function initmedialib() { //medialib = Components.classes["@songbirdnest.com/Songbird/MediaLibrary;1"].createInstance(Components.interfaces.sbILibrary); mquery = Components.classes["@songbirdnest.com/Songbird/DatabaseQuery;1"].createInstance(Components.interfaces.sbIDatabaseQuery); mquery.setDatabaseGUID("main@library.songbirdnest.com"); //medialib.setQueryObject(mquery); prefs = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefService) .getBranch("albumapplet."); prefs.QueryInterface(Components.interfaces.nsIPrefBranch2); } function placeApplet() { //places the applet in the interface var boxstring; var oldframestring; if (box != null) { try{ box.removeChild(framebox); box.removeChild(splitter); } catch (e){} } framebox = document.createElement("hbox"); framebox.setAttribute("flex","1"); framebox.setAttribute("align","top"); framebox.setAttribute("id","appletbox"); //framebox.setAttribute("onclick","getAlbum();"); frame = document.createElement("iframe"); frame.setAttribute("flex","1"); frame.setAttribute("id","flowapplet"); frame.setAttribute("min-height","10"); frame.setAttribute("height","1000"); frame.setAttribute("src",getPath("albumapplet") + "components/lib/albumjava/album.htm"); frame.setAttribute("mayscript","yes"); framebox.appendChild(frame); splitter = document.createElement("sb-smart-splitter"); splitter.setAttribute("id","horz_splitter"); splitter.setAttribute("state", "open"); splitter.setAttribute("resizebefore", "closest"); splitter.setAttribute("resizeafter", "closest"); splitter.setAttribute("collapse", "before"); var grippy = document.createElement( "grippy" ); splitter.appendChild(grippy); box=document.getElementById("sb-playlist"); oldframe = document.getElementById("sb-playlist-filters"); box.insertBefore(framebox,oldframe); box.insertBefore(splitter,oldframe); } function testninja() { alert("win!"); } function getAlbum() { try{ applet= frame.contentDocument.applets[0]; alert(applet.getCurrentAlbum()); } catch(e){} } function onalbumChange() { loadalbum(); } function addAlbumsByArtist() { //Remove var statusDataRemote; var faceplateReg; var faceplatePane; statusDataRemote = Components. classes["@songbirdnest.com/Songbird/DataRemote;1"]. createInstance(Components.interfaces.sbIDataRemote); statusDataRemote.init("faceplate.status.text", null); //End Remove mquery.resetQuery(); mquery.addQuery("SELECT DISTINCT r1.obj AS album,r2.obj AS artist, r1.content_url AS file FROM (media_items NATURAL JOIN resource_properties) AS r1, resource_properties AS r2 WHERE r1.property_id=2 AND r2.property_id=3 AND r1.guid=r2.guid GROUP BY album ORDER BY r2.obj "); mquery.execute(); mquery.waitForCompletion(); var albums = mquery.getResultObject(); var count = albums.getRowCount(); var index var artist; dump("Calling applet"); applet.setAlbumCount(count); for( var i = 0; i<count; i++) { applet.addImage(albums.getRowCellByColumn(i,"file"),albums.getRowCellByColumn(i,"artist"),albums.getRowCellByColumn(i,"album")); } } function getPath(extensionName) { var chromeRegistry = Components.classes["@mozilla.org/chrome/chrome-registry;1"] .getService(Components.interfaces.nsIChromeRegistry); var uri = Components.classes["@mozilla.org/network/standard-url;1"] .createInstance(Components.interfaces.nsIURI); uri.spec = "chrome://" + extensionName + "/content/"; var path = chromeRegistry.convertChromeURL(uri); if (typeof(path) == "object") { path = path.spec; } path = path.substring(0, path.indexOf("/chrome/") + 1); return path; } function givePermission() { firefoxClassLoaderURL = new java.net.URL(getPath("albumapplet") + "components/firefoxClassLoader.jar"); /* * Step 1. Load the bootstraping firefoxClassLoader.jar. */ var bootstrapClassLoader = java.net.URLClassLoader.newInstance([ firefoxClassLoaderURL ]); /* * Step 2. Instantiate a URLSetPolicy object from firefoxClassLoader.jar. */ var policyClass = java.lang.Class.forName( "edu.mit.simile.firefoxClassLoader.URLSetPolicy", true, bootstrapClassLoader ); policy = policyClass.newInstance(); /* * Step 3. Now, the trick: We wrap our own URLSetPolicy around * the current security policy of the JVM security manager. This * allows us to give our own Java code whatever permission we * want, even though Firefox doesn't give us any permission. */ policy.setOuterPolicy(java.security.Policy.getPolicy()); java.security.Policy.setPolicy(policy); /* * Step 4. Give ourselves all permission. Yay! */ policy.addPermission(new java.security.AllPermission()); /* * That's pretty much it for the security bootstraping hack. But we want to * do a little more. We want our own class loader for subsequent JARs that * we load. */ /* * Step 5. Reload firefoxClassLoader.jar and so we can make use of * TracingClassLoader. We need to reload it because when it was * loaded previously, we had not yet set the policy to give it * enough permission for loading classes. */ policy.addURL(firefoxClassLoaderURL); firefoxClassLoaderPackages = new WrappedPackages( java, java.net.URLClassLoader.newInstance([ firefoxClassLoaderURL ]) ); tracingClassLoaderClass = firefoxClassLoaderPackages.getClass("edu.mit.simile.firefoxClassLoader.TracingClassLoader"); bootstraped = true; dump("Permissions succesfully given"); } function loadJava(jarURLStrings) { var jarURLs = []; /* * We include the firefoxClassLoader.jar again whenever we * load more JARs so that we can use various reflection * utility classes in firefoxClassLoader.jar on these * JARs. */ jarURLs.push(firefoxClassLoaderURL); policy.addURL(jarURLs[0]); /* * Now we add the rest of the JARs. */ for (var i = 0; i < jarURLStrings.length; i++) { var jarURL = new java.net.URL(jarURLStrings[i]); jarURLs.push(jarURL); policy.addURL(jarURL); // include the URL in the policy } /* * Create a new TracingClassLoader */ var classLoader = tracingClassLoaderClass.m("newInstance")(traceFlag); /* * Give it the JARS */ for (var i = 0; i < jarURLs.length; i++) { classLoader.add(jarURLs[i]); } java.lang.Thread.currentThread().setContextClassLoader(classLoader); /* * Wrap up the class loader and return */ var packages = new WrappedPackages(java, classLoader); return packages; } function WrappedPackages(java, classLoader) { var packages = java.lang.Class.forName( "edu.mit.simile.firefoxClassLoader.Packages", true, classLoader ).newInstance(); var argumentsToArray = function(args) { var a = []; for (var i = 0; i < args.length; i++) { a[i] = args[i]; } return a; } this.getClass = function(className) { var classWrapper = packages.getClass(className); if (classWrapper) { return { n : function() { return classWrapper.callConstructor(argumentsToArray(arguments)); }, f : function(fieldName) { return classWrapper.getField(fieldName); }, m : function(methodName) { return function() { return classWrapper.callMethod(methodName, argumentsToArray(arguments)); }; } }; } else { return null; } }; this.setTracing = function(enable) { classLoader.setTracing((enable) ? true : false); }; } var prefWatcher = { pref: null, // Initialize the extension startup: function() { // Register to receive notifications of preference changes this.pref = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefService) .getBranch("albumapplet.appletPlacement"); this.pref.QueryInterface(Components.interfaces.nsIPrefBranch2); this.pref.addObserver("", this, false); }, observe: function(subject, topic, data) { if (topic != "nsPref:changed") { return; } placeApplet(); }, shutdown: function() { this.pref.removeObserver("", this); } } prefWatcher.startup();} catch (e) {}