Commits

ryanackley committed a94bab9

initial import

  • Participants

Comments (0)

Files changed (17)

+#/**********************************************************\ 
+# 
+# Auto-generated CMakeLists.txt for the NPAPI File IO for Chrome project
+#
+#\**********************************************************/
+
+# Written to work with cmake 2.6
+cmake_minimum_required (VERSION 2.6)
+set (CMAKE_BACKWARDS_COMPATIBILITY 2.6)
+
+Project(${PLUGIN_NAME})
+
+file (GLOB GENERAL RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+    [^.]*.cpp
+    [^.]*.h
+    [^.]*.cmake
+    )
+
+include_directories(${PLUGIN_INCLUDE_DIRS})
+
+# Generated files are stored in ${GENERATED} by the project configuration
+SET_SOURCE_FILES_PROPERTIES(
+    ${GENERATED}
+    PROPERTIES
+        GENERATED 1
+    )
+
+SOURCE_GROUP(Generated FILES
+    ${GENERATED}
+    )
+
+SET( SOURCES
+    ${GENERAL}
+    ${GENERATED}
+    )
+
+# This will include Win/projectDef.cmake, X11/projectDef.cmake, Mac/projectDef 
+# depending on the platform
+include_platform()
+//
+//  DialogManager.h
+//  FireBreath
+//
+//  Created by Ryan Ackley on 4/10/12.
+//  Copyright (c) 2012 Benryan Software Inc. All rights reserved.
+//
+#ifndef DialogManager_h__
+#define DialogManager_h__
+
+#include <boost/noncopyable.hpp>
+#include <boost/function.hpp>
+#include "BrowserHost.h"
+
+typedef boost::function<void (const std::string&)> PathCallback;
+
+namespace FB { class PluginWindow; }
+
+class DialogManager
+{
+public:
+    static DialogManager* get();
+    virtual void OpenFolderDialog(const FB::BrowserHostPtr& host, FB::PluginWindow* win, const PathCallback& cb) = 0;
+    
+protected:
+    DialogManager() {}
+    virtual ~DialogManager() {}
+};
+
+#endif // DialogManager_h__
+/**********************************************************\ 
+ 
+ Auto-generated Factory.cpp
+ 
+ This file contains the auto-generated factory methods 
+ for the NPAPIFileIOforChrome project
+ 
+\**********************************************************/
+
+#include "FactoryBase.h"
+#include "NPAPIFileIOforChrome.h"
+#include <boost/make_shared.hpp>
+
+class PluginFactory : public FB::FactoryBase
+{
+public:
+    ///////////////////////////////////////////////////////////////////////////////
+    /// @fn FB::PluginCorePtr createPlugin(const std::string& mimetype)
+    ///
+    /// @brief  Creates a plugin object matching the provided mimetype
+    ///         If mimetype is empty, returns the default plugin
+    ///////////////////////////////////////////////////////////////////////////////
+    FB::PluginCorePtr createPlugin(const std::string& mimetype)
+    {
+        return boost::make_shared<NPAPIFileIOforChrome>();
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////////
+    /// @see FB::FactoryBase::globalPluginInitialize
+    ///////////////////////////////////////////////////////////////////////////////
+    void globalPluginInitialize()
+    {
+        NPAPIFileIOforChrome::StaticInitialize();
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////////
+    /// @see FB::FactoryBase::globalPluginDeinitialize
+    ///////////////////////////////////////////////////////////////////////////////
+    void globalPluginDeinitialize()
+    {
+        NPAPIFileIOforChrome::StaticDeinitialize();
+    }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+/// @fn getFactoryInstance()
+///
+/// @brief  Returns the factory instance for this plugin module
+///////////////////////////////////////////////////////////////////////////////
+FB::FactoryBasePtr getFactoryInstance()
+{
+    static boost::shared_ptr<PluginFactory> factory = boost::make_shared<PluginFactory>();
+    return factory;
+}
+

Mac/DialogManagerMac.h

+//
+//  DialogManagerMac.h
+//  FireBreath
+//
+//  Created by Ryan Ackley on 4/10/12.
+//  Copyright (c) 2012 Benryan Software Inc. All rights reserved.
+//
+
+#ifndef DialogManagerMac_h__
+#define DialogManagerMac_h__
+
+#include <boost/noncopyable.hpp>
+#include <string>
+
+#include "../DialogManager.h"
+
+class DialogManagerMac : public DialogManager
+{
+public:
+    void OpenFolderDialog(const FB::BrowserHostPtr& host, FB::PluginWindow* win, const PathCallback& cb);
+    void _showFolderDialog(FB::PluginWindow* win, const PathCallback& cb);
+    
+protected:
+    DialogManagerMac() {};
+    ~DialogManagerMac() {};
+    friend class DialogManager;
+};
+#endif // DialogManagerMac_h__

Mac/DialogManagerMac.mm

+//
+//  DialogManagerMac.mm
+//  FireBreath
+//
+//  Created by Ryan Ackley on 4/10/12.
+//  Copyright (c) 2012 Benryan Software Inc. All rights reserved.
+//
+
+#include <string>
+#include <boost/thread.hpp>
+#include <AppKit/AppKit.h>
+#include <Cocoa/Cocoa.h>
+#include "logging.h"
+
+#include "DialogManagerMac.h"
+#include "BrowserHost.h"
+
+DialogManager* DialogManager::get()
+{
+    static DialogManagerMac inst;
+    return &inst;
+}
+
+
+void DialogManagerMac::OpenFolderDialog(const FB::BrowserHostPtr& host, FB::PluginWindow* win, const PathCallback& cb)
+{
+    host->ScheduleOnMainThread(boost::shared_ptr<DialogManagerMac>(), boost::bind(&DialogManagerMac::_showFolderDialog, this, win, cb));
+}
+
+void DialogManagerMac::_showFolderDialog(FB::PluginWindow* win, const PathCallback& cb)
+{
+    FBLOG_INFO("DialogManagerMac", "Showing folder dialog");
+    std::string out;
+    int result;
+    NSAutoreleasePool* pool = [NSAutoreleasePool new];
+    NSOpenPanel *oPanel = [NSOpenPanel openPanel];
+    
+    [oPanel setAllowsMultipleSelection:NO];
+    [oPanel setCanChooseFiles:NO];
+    [oPanel setCanChooseDirectories:YES];
+    result = [oPanel runModalForDirectory:nil
+                                     file:nil types:nil];
+    
+    if (result == NSOKButton) {
+        NSArray *filesToOpen = [oPanel filenames];
+        NSString *aFile = [filesToOpen objectAtIndex:0];
+        out = [aFile cStringUsingEncoding:[NSString defaultCStringEncoding]];
+        FBLOG_INFO("DialogManagerMac", "Folder selected: " << out);
+    }
+    [pool release];
+    cb(out);
+}

Mac/bundle_template/Info.plist

+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>${PLUGIN_NAME}</string>
+	<key>CFBundleGetInfoString</key>
+    <string>${PLUGIN_NAME} ${FBSTRING_PLUGIN_VERSION}, ${FBSTRING_LegalCopyright}</string>
+	<key>CFBundleIdentifier</key>
+    <string>com.${FBTYPELIB_NAME}.${FBSTRING_PluginName}</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundlePackageType</key>
+	<string>BRPL</string>
+	<key>CFBundleShortVersionString</key>
+    <string>${PLUGIN_NAME} ${FBSTRING_PLUGIN_VERSION}</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleVersion</key>
+    <string>${FBSTRING_PLUGIN_VERSION}</string>
+	<key>CFPlugInDynamicRegisterFunction</key>
+	<string></string>
+	<key>CFPlugInDynamicRegistration</key>
+	<string>NO</string>
+	<key>CFPlugInFactories</key>
+	<dict>
+		<key>00000000-0000-0000-0000-000000000000</key>
+		<string>MyFactoryFunction</string>
+	</dict>
+	<key>CFPlugInTypes</key>
+	<dict>
+		<key>00000000-0000-0000-0000-000000000000</key>
+		<array>
+			<string>00000000-0000-0000-0000-000000000000</string>
+		</array>
+	</dict>
+	<key>CFPlugInUnloadFunction</key>
+	<string></string>
+	<key>WebPluginName</key>
+	<string>${FBSTRING_ProductName}</string>
+	<key>WebPluginDescription</key>
+	<string>${FBSTRING_FileDescription}</string>
+	<key>WebPluginMIMETypes</key>
+	<dict>
+@foreach (FBSTRING_MIMEType CUR_MIMETYPE FBSTRING_FileDescription CUR_DESC)
+		<key>${CUR_MIMETYPE}</key>
+		<dict>
+            <key>WebPluginExtensions</key>
+            <array>
+                <string></string>
+            </array>
+			<key>WebPluginTypeDescription</key>
+			<string>${CUR_DESC}</string>
+		</dict>
+@endforeach
+	</dict>
+</dict>
+</plist>

Mac/bundle_template/InfoPlist.strings

+/* Localized versions of Info.plist keys */
+
+CFBundleName = "${PLUGIN_NAME}.plugin";
+NSHumanReadableCopyright = "${FBSTRING_LegalCopyright}";

Mac/bundle_template/Localized.r

+#include <CoreServices/CoreServices.r>
+
+resource 'STR#' (126) 
+{ {
+    "${FBSTRING_LegalCopyright}",
+    "${FBSTRING_ProductName}"
+} };
+
+resource 'STR#' (127) 
+{ {
+    "",
+} };
+
+resource 'STR#' (128) 
+{ {
+@foreach (FBSTRING_MIMEType CUR_MIMETYPE FBSTRING_FileExtents CUR_EXTENT)
+    "${CUR_MIMETYPE}",
+    "${CUR_EXTENT}",
+@endforeach
+} };

Mac/projectDef.cmake

+#/**********************************************************\ 
+# Auto-generated Mac project definition file for the
+# NPAPI File IO for Chrome project
+#\**********************************************************/
+
+# Mac template platform definition CMake file
+# Included from ../CMakeLists.txt
+
+# remember that the current source dir is the project root; this file is in Mac/
+file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+    Mac/[^.]*.cpp
+    Mac/[^.]*.h
+    Mac/[^.]*.mm
+    Mac/[^.]*.cmake
+    )
+
+# use this to add preprocessor definitions
+add_definitions(
+    
+)
+
+
+SOURCE_GROUP(Mac FILES ${PLATFORM})
+
+set (SOURCES
+    ${SOURCES}
+    ${PLATFORM}
+    )
+
+set(PLIST "Mac/bundle_template/Info.plist")
+set(STRINGS "Mac/bundle_template/InfoPlist.strings")
+set(LOCALIZED "Mac/bundle_template/Localized.r")
+
+add_mac_plugin(${PROJECT_NAME} ${PLIST} ${STRINGS} ${LOCALIZED} SOURCES)
+
+# add library dependencies here; leave ${PLUGIN_INTERNAL_DEPS} there unless you know what you're doing!
+target_link_libraries(${PROJECT_NAME}
+    ${PLUGIN_INTERNAL_DEPS}
+    )

NPAPIFileIOforChrome.cpp

+/**********************************************************\
+
+  Auto-generated NPAPIFileIOforChrome.cpp
+
+  This file contains the auto-generated main plugin object
+  implementation for the NPAPI File IO for Chrome project
+
+\**********************************************************/
+
+#include "NPAPIFileIOforChromeAPI.h"
+
+#include "NPAPIFileIOforChrome.h"
+
+///////////////////////////////////////////////////////////////////////////////
+/// @fn NPAPIFileIOforChrome::StaticInitialize()
+///
+/// @brief  Called from PluginFactory::globalPluginInitialize()
+///
+/// @see FB::FactoryBase::globalPluginInitialize
+///////////////////////////////////////////////////////////////////////////////
+void NPAPIFileIOforChrome::StaticInitialize()
+{
+    // Place one-time initialization stuff here; As of FireBreath 1.4 this should only
+    // be called once per process
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// @fn NPAPIFileIOforChrome::StaticInitialize()
+///
+/// @brief  Called from PluginFactory::globalPluginDeinitialize()
+///
+/// @see FB::FactoryBase::globalPluginDeinitialize
+///////////////////////////////////////////////////////////////////////////////
+void NPAPIFileIOforChrome::StaticDeinitialize()
+{
+    // Place one-time deinitialization stuff here. As of FireBreath 1.4 this should
+    // always be called just before the plugin library is unloaded
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// @brief  NPAPIFileIOforChrome constructor.  Note that your API is not available
+///         at this point, nor the window.  For best results wait to use
+///         the JSAPI object until the onPluginReady method is called
+///////////////////////////////////////////////////////////////////////////////
+NPAPIFileIOforChrome::NPAPIFileIOforChrome()
+{
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// @brief  NPAPIFileIOforChrome destructor.
+///////////////////////////////////////////////////////////////////////////////
+NPAPIFileIOforChrome::~NPAPIFileIOforChrome()
+{
+    // This is optional, but if you reset m_api (the shared_ptr to your JSAPI
+    // root object) and tell the host to free the retained JSAPI objects then
+    // unless you are holding another shared_ptr reference to your JSAPI object
+    // they will be released here.
+    releaseRootJSAPI();
+    m_host->freeRetainedObjects();
+}
+
+void NPAPIFileIOforChrome::onPluginReady()
+{
+    // When this is called, the BrowserHost is attached, the JSAPI object is
+    // created, and we are ready to interact with the page and such.  The
+    // PluginWindow may or may not have already fire the AttachedEvent at
+    // this point.
+}
+
+void NPAPIFileIOforChrome::shutdown()
+{
+    // This will be called when it is time for the plugin to shut down;
+    // any threads or anything else that may hold a shared_ptr to this
+    // object should be released here so that this object can be safely
+    // destroyed. This is the last point that shared_from_this and weak_ptr
+    // references to this object will be valid
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// @brief  Creates an instance of the JSAPI object that provides your main
+///         Javascript interface.
+///
+/// Note that m_host is your BrowserHost and shared_ptr returns a
+/// FB::PluginCorePtr, which can be used to provide a
+/// boost::weak_ptr<NPAPIFileIOforChrome> for your JSAPI class.
+///
+/// Be very careful where you hold a shared_ptr to your plugin class from,
+/// as it could prevent your plugin class from getting destroyed properly.
+///////////////////////////////////////////////////////////////////////////////
+FB::JSAPIPtr NPAPIFileIOforChrome::createJSAPI()
+{
+    // m_host is the BrowserHost
+    return boost::make_shared<NPAPIFileIOforChromeAPI>(FB::ptr_cast<NPAPIFileIOforChrome>(shared_from_this()), m_host);
+}
+
+bool NPAPIFileIOforChrome::onMouseDown(FB::MouseDownEvent *evt, FB::PluginWindow *)
+{
+    //printf("Mouse down at: %d, %d\n", evt->m_x, evt->m_y);
+    return false;
+}
+
+bool NPAPIFileIOforChrome::onMouseUp(FB::MouseUpEvent *evt, FB::PluginWindow *)
+{
+    //printf("Mouse up at: %d, %d\n", evt->m_x, evt->m_y);
+    return false;
+}
+
+bool NPAPIFileIOforChrome::onMouseMove(FB::MouseMoveEvent *evt, FB::PluginWindow *)
+{
+    //printf("Mouse move at: %d, %d\n", evt->m_x, evt->m_y);
+    return false;
+}
+bool NPAPIFileIOforChrome::onWindowAttached(FB::AttachedEvent *evt, FB::PluginWindow *)
+{
+    // The window is attached; act appropriately
+    return false;
+}
+
+bool NPAPIFileIOforChrome::onWindowDetached(FB::DetachedEvent *evt, FB::PluginWindow *)
+{
+    // The window is about to be detached; act appropriately
+    return false;
+}
+

NPAPIFileIOforChrome.h

+/**********************************************************\
+
+  Auto-generated NPAPIFileIOforChrome.h
+
+  This file contains the auto-generated main plugin object
+  implementation for the NPAPI File IO for Chrome project
+
+\**********************************************************/
+#ifndef H_NPAPIFileIOforChromePLUGIN
+#define H_NPAPIFileIOforChromePLUGIN
+
+#include "PluginWindow.h"
+#include "PluginEvents/MouseEvents.h"
+#include "PluginEvents/AttachedEvent.h"
+
+#include "PluginCore.h"
+
+
+FB_FORWARD_PTR(NPAPIFileIOforChrome)
+class NPAPIFileIOforChrome : public FB::PluginCore
+{
+public:
+    static void StaticInitialize();
+    static void StaticDeinitialize();
+
+public:
+    NPAPIFileIOforChrome();
+    virtual ~NPAPIFileIOforChrome();
+
+public:
+    void onPluginReady();
+    void shutdown();
+    virtual FB::JSAPIPtr createJSAPI();
+    // If you want your plugin to always be windowless, set this to true
+    // If you want your plugin to be optionally windowless based on the
+    // value of the "windowless" param tag, remove this method or return
+    // FB::PluginCore::isWindowless()
+    virtual bool isWindowless() { return true; }
+
+    BEGIN_PLUGIN_EVENT_MAP()
+        EVENTTYPE_CASE(FB::MouseDownEvent, onMouseDown, FB::PluginWindow)
+        EVENTTYPE_CASE(FB::MouseUpEvent, onMouseUp, FB::PluginWindow)
+        EVENTTYPE_CASE(FB::MouseMoveEvent, onMouseMove, FB::PluginWindow)
+        EVENTTYPE_CASE(FB::MouseMoveEvent, onMouseMove, FB::PluginWindow)
+        EVENTTYPE_CASE(FB::AttachedEvent, onWindowAttached, FB::PluginWindow)
+        EVENTTYPE_CASE(FB::DetachedEvent, onWindowDetached, FB::PluginWindow)
+    END_PLUGIN_EVENT_MAP()
+
+    /** BEGIN EVENTDEF -- DON'T CHANGE THIS LINE **/
+    virtual bool onMouseDown(FB::MouseDownEvent *evt, FB::PluginWindow *);
+    virtual bool onMouseUp(FB::MouseUpEvent *evt, FB::PluginWindow *);
+    virtual bool onMouseMove(FB::MouseMoveEvent *evt, FB::PluginWindow *);
+    virtual bool onWindowAttached(FB::AttachedEvent *evt, FB::PluginWindow *);
+    virtual bool onWindowDetached(FB::DetachedEvent *evt, FB::PluginWindow *);
+    /** END EVENTDEF -- DON'T CHANGE THIS LINE **/
+};
+
+
+#endif
+

NPAPIFileIOforChromeAPI.cpp

+/**********************************************************\
+
+  Auto-generated NPAPIFileIOforChromeAPI.cpp
+
+\**********************************************************/
+
+#define BOOST_FILESYSTEM_VERSION 3
+
+#include "JSObject.h"
+#include "variant_list.h"
+#include "DOM/Document.h"
+#include "global/config.h"
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
+#include "NPAPIFileIOforChromeAPI.h"
+#include "BinaryArray.h"
+#include "DOM/Window.h"
+#include "NPObjectAPI.h"
+#include "NpapiBrowserHost.h"
+#include "DialogManager.h"
+
+using namespace boost::filesystem;
+using namespace FB;
+using namespace FB::Npapi;
+
+
+///////////////////////////////////////////////////////////////////////////////
+/// @fn FB::variant NPAPIFileIOforChromeAPI::echo(const FB::variant& msg)
+///
+/// @brief  Echos whatever is passed from Javascript.
+///         Go ahead and change it. See what happens!
+///////////////////////////////////////////////////////////////////////////////
+FB::variant NPAPIFileIOforChromeAPI::echo(const FB::variant& msg)
+{
+    static int n(0);
+    fire_echo("So far, you clicked this many times: ", n++);
+
+    // return "foobar";
+    return msg;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+/// @fn NPAPIFileIOforChromePtr NPAPIFileIOforChromeAPI::getPlugin()
+///
+/// @brief  Gets a reference to the plugin that was passed in when the object
+///         was created.  If the plugin has already been released then this
+///         will throw a FB::script_error that will be translated into a
+///         javascript exception in the page.
+///////////////////////////////////////////////////////////////////////////////
+NPAPIFileIOforChromePtr NPAPIFileIOforChromeAPI::getPlugin()
+{
+    NPAPIFileIOforChromePtr plugin(m_plugin.lock());
+    if (!plugin) {
+        throw FB::script_error("The plugin is invalid");
+    }
+    return plugin;
+}
+
+// Read/Write property testString
+std::string NPAPIFileIOforChromeAPI::get_testString()
+{
+    return m_testString;
+}
+
+void NPAPIFileIOforChromeAPI::set_testString(const std::string& val)
+{
+    m_testString = val;
+}
+
+// Read-only property version
+std::string NPAPIFileIOforChromeAPI::get_version()
+{
+    return FBSTRING_PLUGIN_VERSION;
+}
+
+void NPAPIFileIOforChromeAPI::testEvent()
+{
+    fire_test();
+}
+
+
+/*void NPAPIFileIOforChromeAPI::saveToFileUrl(std::string url, std::string content)
+{
+    
+}*/
+bool NPAPIFileIOforChromeAPI::createDirectory(std::string strPath)
+{
+    if (!strPath.length())
+    {
+        return true;
+    }
+    path p(strPath);
+    
+    create_directory(p);
+    return is_directory(p);
+}
+bool NPAPIFileIOforChromeAPI::saveBlobToFile(std::string strPath, JSObjectPtr dataArray)
+{
+    variant lenProp = dataArray->GetProperty("length");
+    int arrayLength = (int)lenProp.cast<double>();
+    
+    DOM::WindowPtr window = m_host->getDOMWindow();
+    JSObjectPtr obj = window->getProperty<FB::JSObjectPtr>("JSON");
+    variant v = obj->Invoke("stringify", FB::variant_list_of(dataArray));
+    
+    std::string jsonArray = v.cast<std::string>();
+    
+    std::ostringstream currentNum("");
+    //std::vector<char> buffer;
+    //buffer.reserve(arrayLength);
+    char buffer[arrayLength];
+    int idx = 0;
+    
+    int size = jsonArray.length();
+    for (int x = 0; x < size; x++)
+    {
+        char next = jsonArray[x];
+        switch(next)
+        {
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+                currentNum << next;
+                break;
+            default:
+                if (currentNum.str().length())
+                {
+                    int ch;
+                    std::istringstream in(currentNum.str());
+                    in >> ch;
+                    if (idx < arrayLength)
+                    {
+                        buffer[idx++] = (char)ch;
+                    }
+                    currentNum.str("");
+                }
+                break;
+        }
+    }
+    
+    
+    //int fileLen = buffer.size();
+       
+    path p(strPath);
+   
+    /*int fileLen = (int)lenProp.cast<double>();
+    char buffer[fileLen];
+    
+    path p(strPath);
+    
+    for (int x = 0; x < fileLen; x++)
+    {
+        buffer[x] = (char)dataArray->GetProperty(x).cast<double>();
+    }*/
+    
+    boost::filesystem::ofstream out(p, std::ios::out | std::ios::binary);
+    out.write(buffer, arrayLength);
+    out.close();
+    return true;
+   
+}
+FB::VariantList NPAPIFileIOforChromeAPI::getDirEntries(std::string strPath)
+{
+    path p(strPath);
+    
+    VariantList entries;
+    if (is_directory(p))
+    {
+        directory_iterator di(p);
+        directory_iterator eos;
+        
+        while(di != eos)
+        {
+            directory_entry de = *di;
+           // variant entry;
+            //entry.assign<std::string>();
+            entries.push_back(de.path().filename().generic_string());
+            di++;
+        }
+    }
+    return entries;
+    
+}
+FB::JSAPIPtr NPAPIFileIOforChromeAPI::contentsAtPath(std::string strPath)
+{
+    path p(strPath);
+    
+    
+    //VariantList jsBytes;
+    if (is_regular_file(p))
+    {
+        int size = file_size(p);
+        char buffer[size];
+        
+        boost::filesystem::ifstream in(p, std::ios::in | std::ios::binary);
+    
+        in.read(buffer, size);
+        in.close();
+        
+        std::ostringstream json;
+        
+        json << "[";
+        for (int x = 0; x < size; x++)
+        {
+            json << (int)buffer[x] << ",";
+        }
+        json << "]";
+        
+        DOM::WindowPtr win = m_host->getDOMWindow();
+        JSObjectPtr jsObj = win->getJSObject();
+        
+        NPObjectAPIPtr bridgeObj = boost::static_pointer_cast<NPObjectAPI>(jsObj);
+        NpapiBrowserHostPtr npapiHost = boost::static_pointer_cast<NpapiBrowserHost>(m_host); 
+        
+        NPVariant retVal;
+        NPVariant tmp;
+        
+        npapiHost->getNPVariant(&tmp, FB::variant(json.str()));
+        
+        if (npapiHost->Evaluate(bridgeObj->getNPObject(),
+                           &tmp.value.stringValue, &retVal)) {
+            if (retVal.type != NPVariantType_Object)
+            {
+                npapiHost->ReleaseVariantValue(&retVal);
+            }
+            else
+            {
+                JSAPIPtr array(new NPObjectAPI(retVal.value.objectValue, npapiHost));
+                return array;
+            }
+            
+        } else {
+            throw script_error("Error executing JavaScript code");
+        }
+
+        
+        //return boost::make_shared<BinaryArray>(buffer, size);
+        /*jsBytes.reserve(size);
+        for (int x = 0; x < size; x++)
+        {
+            variant ch = buffer[x];
+            jsBytes.push_back(ch);
+        }*/
+    }
+    return JSObjectPtr();
+    //return ;
+    
+}
+int NPAPIFileIOforChromeAPI::getFileSize(std::string strPath)
+{
+    path p(strPath);
+    return file_size(p);
+}
+bool NPAPIFileIOforChromeAPI::isDirectory(std::string strPath)
+{
+    path p(strPath);
+    return is_directory(p);
+}
+bool NPAPIFileIOforChromeAPI::fileExists(std::string strPath)
+{
+    path p(strPath);
+    return exists(p);
+}
+bool NPAPIFileIOforChromeAPI::removeRecursively(std::string strPath)
+{
+    path p(strPath);
+    return remove_all(p) != 0;
+}
+void NPAPIFileIOforChromeAPI::launchFileSelect(JSObjectPtr callback)
+{
+    DialogManager* dlgMgr = DialogManager::get();
+    dlgMgr->OpenFolderDialog(m_host, NULL, boost::bind(&NPAPIFileIOforChromeAPI::fileSelectCallback, this, _1, callback));
+}
+void NPAPIFileIOforChromeAPI::fileSelectCallback(const std::string &path, JSObjectPtr callback)
+{
+    callback->Invoke("",FB::variant_list_of(path));
+}
+std::string NPAPIFileIOforChromeAPI::getChromeDataDir(std::string version)
+{
+#if defined __MACH__ && defined __APPLE__
+    path apps("/Applications");
+    
+    directory_iterator di(apps);
+    directory_iterator eos;
+    
+    std::string userHome = getenv("HOME");
+    while(di != eos)
+    {
+        directory_entry de = *di;
+        std::string appPath = de.path().filename().generic_string();
+        size_t index = appPath.find("Google Chrom");
+        if (index != appPath.npos)
+        {
+            path vpath = de.path();
+            vpath /= ("Contents/Versions/" + version);
+            if (exists(vpath))
+            {
+                std::string dirName = appPath.substr(7, appPath.length() - 11);
+                path retVal(userHome);
+                retVal /= ("Library/Application Support/Google/" + dirName);
+                return retVal.generic_string();
+            }
+        }
+        di++;
+    }
+    return "";
+    
+   // pid_t pid = getppid();
+    
+    
+#endif
+}
+

NPAPIFileIOforChromeAPI.h

+/**********************************************************\
+
+  Auto-generated NPAPIFileIOforChromeAPI.h
+
+\**********************************************************/
+
+#include <string>
+#include <sstream>
+#include <boost/weak_ptr.hpp>
+#include "JSAPIAuto.h"
+#include "BrowserHost.h"
+#include "NPAPIFileIOforChrome.h"
+
+#ifndef H_NPAPIFileIOforChromeAPI
+#define H_NPAPIFileIOforChromeAPI
+
+class NPAPIFileIOforChromeAPI : public FB::JSAPIAuto
+{
+public:
+    ////////////////////////////////////////////////////////////////////////////
+    /// @fn NPAPIFileIOforChromeAPI::NPAPIFileIOforChromeAPI(const NPAPIFileIOforChromePtr& plugin, const FB::BrowserHostPtr host)
+    ///
+    /// @brief  Constructor for your JSAPI object.
+    ///         You should register your methods, properties, and events
+    ///         that should be accessible to Javascript from here.
+    ///
+    /// @see FB::JSAPIAuto::registerMethod
+    /// @see FB::JSAPIAuto::registerProperty
+    /// @see FB::JSAPIAuto::registerEvent
+    ////////////////////////////////////////////////////////////////////////////
+    NPAPIFileIOforChromeAPI(const NPAPIFileIOforChromePtr& plugin, const FB::BrowserHostPtr& host) :
+        m_plugin(plugin), m_host(host)
+    {
+        registerMethod("echo",      make_method(this, &NPAPIFileIOforChromeAPI::echo));
+        registerMethod("testEvent", make_method(this, &NPAPIFileIOforChromeAPI::testEvent));
+        //registerMethod("saveToFileUrl",      make_method(this, &NPAPIFileIOforChromeAPI::saveToFileUrl));
+        registerMethod("launchFileSelect",     make_method(this, &NPAPIFileIOforChromeAPI::launchFileSelect));
+        registerMethod("createDirectory",      make_method(this, &NPAPIFileIOforChromeAPI::createDirectory));
+        registerMethod("saveBlobToFile",      make_method(this, &NPAPIFileIOforChromeAPI::saveBlobToFile));
+        registerMethod("getDirEntries",      make_method(this, &NPAPIFileIOforChromeAPI::getDirEntries));
+        registerMethod("contentsAtPath",      make_method(this, &NPAPIFileIOforChromeAPI::contentsAtPath));
+        registerMethod("getFileSize",      make_method(this, &NPAPIFileIOforChromeAPI::getFileSize));
+        registerMethod("isDirectory",      make_method(this, &NPAPIFileIOforChromeAPI::isDirectory));
+        registerMethod("fileExists",      make_method(this, &NPAPIFileIOforChromeAPI::fileExists));
+        registerMethod("removeRecursively",      make_method(this, &NPAPIFileIOforChromeAPI::removeRecursively));
+        registerMethod("getChromeDataDir",      make_method(this, &NPAPIFileIOforChromeAPI::getChromeDataDir));
+        
+        // Read-write property
+        registerProperty("testString",
+                         make_property(this,
+                                       &NPAPIFileIOforChromeAPI::get_testString,
+                                       &NPAPIFileIOforChromeAPI::set_testString));
+        
+        // Read-only property
+        registerProperty("version",
+                         make_property(this,
+                                       &NPAPIFileIOforChromeAPI::get_version));
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////
+    /// @fn NPAPIFileIOforChromeAPI::~NPAPIFileIOforChromeAPI()
+    ///
+    /// @brief  Destructor.  Remember that this object will not be released until
+    ///         the browser is done with it; this will almost definitely be after
+    ///         the plugin is released.
+    ///////////////////////////////////////////////////////////////////////////////
+    virtual ~NPAPIFileIOforChromeAPI() {};
+
+    NPAPIFileIOforChromePtr getPlugin();
+
+    // Read/Write property ${PROPERTY.ident}
+    std::string get_testString();
+    void set_testString(const std::string& val);
+
+    // Read-only property ${PROPERTY.ident}
+    std::string get_version();
+
+    // Method echo
+    FB::variant echo(const FB::variant& msg);
+    
+    // Event helpers
+    FB_JSAPI_EVENT(test, 0, ());
+    FB_JSAPI_EVENT(echo, 2, (const FB::variant&, const int));
+
+    // Method test-event
+    void testEvent();
+    
+    //void saveToFileUrl(std::string url, std::string content);
+    bool createDirectory(std::string path);
+    bool saveBlobToFile(std::string path, FB::JSObjectPtr dataArray);
+    FB::VariantList getDirEntries(std::string path);
+    FB::JSAPIPtr contentsAtPath(std::string path);
+    int getFileSize(std::string path);
+    bool isDirectory(std::string path);
+    bool fileExists(std::string path);
+    bool removeRecursively(std::string path);
+    void launchFileSelect(FB::JSObjectPtr callback); 
+    std::string getChromeDataDir(std::string version);
+
+private:
+    
+    void fileSelectCallback(const std::string &path, FB::JSObjectPtr callback);
+    
+    NPAPIFileIOforChromeWeakPtr m_plugin;
+    FB::BrowserHostPtr m_host;
+
+    std::string m_testString;
+};
+
+#endif // H_NPAPIFileIOforChromeAPI
+

PluginConfig.cmake

+#/**********************************************************\ 
+#
+# Auto-Generated Plugin Configuration file
+# for NPAPI File IO for Chrome
+#
+#\**********************************************************/
+
+set(PLUGIN_NAME "NPAPIFileIOforChrome")
+set(PLUGIN_PREFIX "NFIFC")
+set(COMPANY_NAME "BenryanSoftwareInc")
+
+# ActiveX constants:
+set(FBTYPELIB_NAME NPAPIFileIOforChromeLib)
+set(FBTYPELIB_DESC "NPAPIFileIOforChrome 1.0 Type Library")
+set(IFBControl_DESC "NPAPIFileIOforChrome Control Interface")
+set(FBControl_DESC "NPAPIFileIOforChrome Control Class")
+set(IFBComJavascriptObject_DESC "NPAPIFileIOforChrome IComJavascriptObject Interface")
+set(FBComJavascriptObject_DESC "NPAPIFileIOforChrome ComJavascriptObject Class")
+set(IFBComEventSource_DESC "NPAPIFileIOforChrome IFBComEventSource Interface")
+set(AXVERSION_NUM "1")
+
+# NOTE: THESE GUIDS *MUST* BE UNIQUE TO YOUR PLUGIN/ACTIVEX CONTROL!  YES, ALL OF THEM!
+set(FBTYPELIB_GUID 4e46b83d-4055-5fd3-916c-c0a142b50268)
+set(IFBControl_GUID b46273de-1ce1-57c7-b818-86e524e359af)
+set(FBControl_GUID 2de9b1c0-4533-592c-b41e-cb343a22541b)
+set(IFBComJavascriptObject_GUID cd48eb78-e554-58e9-ac96-b4398ceb2d54)
+set(FBComJavascriptObject_GUID 0ba6037b-28b9-5561-b775-78a7b9a60b16)
+set(IFBComEventSource_GUID 0453fead-e87e-5cc5-828a-0efe94ad7596)
+
+# these are the pieces that are relevant to using it from Javascript
+set(ACTIVEX_PROGID "BenryanSoftwareInc.NPAPIFileIOforChrome")
+set(MOZILLA_PLUGINID "benryan.com/NPAPIFileIOforChrome")
+
+# strings
+set(FBSTRING_CompanyName "Benryan Software Inc.")
+set(FBSTRING_FileDescription "Adds file operations to a javascript api for Chrome")
+set(FBSTRING_PLUGIN_VERSION "1.0.0.0")
+set(FBSTRING_LegalCopyright "Copyright 2012 Benryan Software Inc.")
+set(FBSTRING_PluginFileName "np${PLUGIN_NAME}.dll")
+set(FBSTRING_ProductName "NPAPI File IO for Chrome")
+set(FBSTRING_FileExtents "")
+set(FBSTRING_PluginName "NPAPI File IO for Chrome")
+set(FBSTRING_MIMEType "application/x-npapifileioforchrome")
+
+# Uncomment this next line if you're not planning on your plugin doing
+# any drawing:
+
+set (FB_GUI_DISABLED 1)
+
+# Mac plugin settings. If your plugin does not draw, set these all to 0
+set(FBMAC_USE_QUICKDRAW 0)
+set(FBMAC_USE_CARBON 0)
+set(FBMAC_USE_COCOA 0)
+set(FBMAC_USE_COREGRAPHICS 0)
+set(FBMAC_USE_COREANIMATION 0)
+set(FBMAC_USE_INVALIDATINGCOREANIMATION 0)
+
+# If you want to register per-machine on Windows, uncomment this line
+#set (FB_ATLREG_MACHINEWIDE 1)
+
+option (BOOST_FILESYSTEM_V3 ON)
+add_boost_library(filesystem)

Win/WiX/NPAPIFileIOforChromeInstaller.wxs

+<?xml version="1.0" encoding="UTF-8"?>
+<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
+    <Product Id="*" Name="${FBSTRING_PluginName}" Language="1033" Version="${FBSTRING_PLUGIN_VERSION}" Manufacturer="${FBSTRING_CompanyName}" UpgradeCode="{7444a71d-e342-5c63-8950-ee6e52f008b9}">
+        <Package InstallerVersion="200" Compressed="yes" Description="Installer for the ${PLUGIN_NAME} plugin" InstallScope="perUser" />
+        <Upgrade Id="{7444a71d-e342-5c63-8950-ee6e52f008b9}">
+            <UpgradeVersion
+                Property="OLD_VERSION_FOUND"
+                Minimum="0.0.1" IncludeMinimum="yes"
+                Maximum="${FBSTRING_PLUGIN_VERSION}" IncludeMaximum="yes"
+                OnlyDetect="no" IgnoreRemoveFailure="yes"
+                MigrateFeatures="yes" />
+        </Upgrade>
+		<Property Id="MSIRESTARTMANAGERCONTROL" Value="Disable" />
+        <InstallExecuteSequence>
+            <RemoveExistingProducts After="InstallInitialize" />
+            <InstallExecute After="RemoveExistingProducts" />
+        </InstallExecuteSequence>
+        <Media Id="1" Cabinet="${PLUGIN_NAME}.cab" EmbedCab="yes" />
+
+        <Directory Id="TARGETDIR" Name="SourceDir">
+            <Directory Id="${FB_WIX_INSTALL_LOCATION}">
+                <Directory Id="CompanyDir" Name="${COMPANY_NAME}">
+                    <Component Id="CompanyDirComp" Guid="*">
+                        <RemoveFolder Id="RemoveCompanyDir" On="uninstall" />
+                        <RegistryValue
+                            Root="HKCU"
+                            Key="SOFTWARE\${COMPANY_NAME}"
+                            Name="Uninstall"
+                            Type="string"
+                            Value="${FBSTRING_PLUGIN_VERSION}"
+                            KeyPath="yes" />
+                    </Component>
+                    <Directory Id="PluginNameDir" Name="${PLUGIN_NAME}">
+                        <Component Id="PluginNameDirComp" Guid="*">
+                            <RemoveFolder Id="RemovePluginNameDir" On="uninstall" />
+                            <RegistryValue
+                                Root="HKCU"
+                                Key="SOFTWARE\${COMPANY_NAME}\${PLUGIN_NAME}"
+                                Name="Uninstall"
+                                Type="string"
+                                Value="${FBSTRING_PLUGIN_VERSION}"
+                                KeyPath="yes" />
+                        </Component>
+                        <Directory Id="INSTALLDIR" Name="${FBSTRING_PLUGIN_VERSION}">
+                            <Component Id="InstallDirComp" Guid="*">
+                                <RemoveFolder Id="RemoveInstallDir" On="uninstall" />
+                                <RegistryValue
+                                    Root="HKCU"
+                                    Key="SOFTWARE\${COMPANY_NAME}\${PLUGIN_NAME}\${FBSTRING_PLUGIN_VERSION}"
+                                    Name="Uninstall"
+                                    Type="string"
+                                    Value="${FBSTRING_PLUGIN_VERSION}"
+                                    KeyPath="yes" />
+                            </Component>
+
+                            <!-- Put Additional files here: -->
+                            <!-- example:
+                            <Component Id="UniqueComponentId" Guid="*">
+                                <File Id="uniqueFileId" KeyPath="yes" Source="SourceDir\filename.ext" />
+                            </Component>
+                            /example -->
+                            <!--  -->
+                        </Directory>
+                    </Directory>
+                </Directory>
+            </Directory>
+        </Directory>
+
+        <Feature Id="MainPluginFeature" Title="${FBSTRING_ProductName}" Level="1">
+            <ComponentRef Id="InstallDirComp"/>
+            <ComponentRef Id="PluginNameDirComp"/>
+            <ComponentRef Id="CompanyDirComp"/>
+            <ComponentGroupRef Id="PluginDLLGroup"/>
+        </Feature>
+    </Product>
+</Wix>

Win/projectDef.cmake

+#/**********************************************************\ 
+# Auto-generated Windows project definition file for the
+# NPAPI File IO for Chrome project
+#\**********************************************************/
+
+# Windows template platform definition CMake file
+# Included from ../CMakeLists.txt
+
+# remember that the current source dir is the project root; this file is in Win/
+file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+    Win/[^.]*.cpp
+    Win/[^.]*.h
+    Win/[^.]*.cmake
+    )
+
+# use this to add preprocessor definitions
+add_definitions(
+    /D "_ATL_STATIC_REGISTRY"
+)
+
+SOURCE_GROUP(Win FILES ${PLATFORM})
+
+set (SOURCES
+    ${SOURCES}
+    ${PLATFORM}
+    )
+
+add_windows_plugin(${PROJECT_NAME} SOURCES)
+
+# This is an example of how to add a build step to sign the plugin DLL before
+# the WiX installer builds.  The first filename (certificate.pfx) should be
+# the path to your pfx file.  If it requires a passphrase, the passphrase
+# should be located inside the second file. If you don't need a passphrase
+# then set the second filename to "".  If you don't want signtool to timestamp
+# your DLL then make the last parameter "".
+#
+# Note that this will not attempt to sign if the certificate isn't there --
+# that's so that you can have development machines without the cert and it'll
+# still work. Your cert should only be on the build machine and shouldn't be in
+# source control!
+# -- uncomment lines below this to enable signing --
+#firebreath_sign_plugin(${PROJECT_NAME}
+#    "${CMAKE_CURRENT_SOURCE_DIR}/sign/certificate.pfx"
+#    "${CMAKE_CURRENT_SOURCE_DIR}/sign/passphrase.txt"
+#    "http://timestamp.verisign.com/scripts/timestamp.dll")
+
+# add library dependencies here; leave ${PLUGIN_INTERNAL_DEPS} there unless you know what you're doing!
+target_link_libraries(${PROJECT_NAME}
+    ${PLUGIN_INTERNAL_DEPS}
+    )
+
+set(WIX_HEAT_FLAGS
+    -gg                 # Generate GUIDs
+    -srd                # Suppress Root Dir
+    -cg PluginDLLGroup  # Set the Component group name
+    -dr INSTALLDIR      # Set the directory ID to put the files in
+    )
+
+add_wix_installer( ${PLUGIN_NAME}
+    ${CMAKE_CURRENT_SOURCE_DIR}/Win/WiX/NPAPIFileIOforChromeInstaller.wxs
+    PluginDLLGroup
+    ${FB_BIN_DIR}/${PLUGIN_NAME}/${CMAKE_CFG_INTDIR}/
+    ${FB_BIN_DIR}/${PLUGIN_NAME}/${CMAKE_CFG_INTDIR}/${FBSTRING_PluginFileName}.dll
+    ${PROJECT_NAME}
+    )
+
+# This is an example of how to add a build step to sign the WiX installer
+# -- uncomment lines below this to enable signing --
+#firebreath_sign_file("${PLUGIN_NAME}_WiXInstall"
+#    "${FB_BIN_DIR}/${PLUGIN_NAME}/${CMAKE_CFG_INTDIR}/${PLUGIN_NAME}.msi"
+#    "${CMAKE_CURRENT_SOURCE_DIR}/sign/certificate.pfx"
+#    "${CMAKE_CURRENT_SOURCE_DIR}/sign/passphrase.txt"
+#    "http://timestamp.verisign.com/scripts/timestamp.dll")

X11/projectDef.cmake

+#/**********************************************************\ 
+# Auto-generated X11 project definition file for the
+# NPAPI File IO for Chrome project
+#\**********************************************************/
+
+# X11 template platform definition CMake file
+# Included from ../CMakeLists.txt
+
+# remember that the current source dir is the project root; this file is in X11/
+file (GLOB PLATFORM RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
+    X11/[^.]*.cpp
+    X11/[^.]*.h
+    X11/[^.]*.cmake
+    )
+
+SOURCE_GROUP(X11 FILES ${PLATFORM})
+
+# use this to add preprocessor definitions
+add_definitions(
+)
+
+set (SOURCES
+    ${SOURCES}
+    ${PLATFORM}
+    )
+
+add_x11_plugin(${PROJECT_NAME} SOURCES)
+
+# add library dependencies here; leave ${PLUGIN_INTERNAL_DEPS} there unless you know what you're doing!
+target_link_libraries(${PROJECT_NAME}
+    ${PLUGIN_INTERNAL_DEPS}
+    )