Xpoint
   [напомнить пароль]

Drag&Drop на рабочий стол Mac,FF3.6 flavour "application/x-moz-file-promise" проблема

Метки: [без меток]
2010-07-20 17:44:23 [обр] Slash77[досье]

Перевожу приложение с FF 3.0 на FF 3.6 версию.
Данный код отвечал за то, что на рабочий стол копировался файл с веб сервера.
Было:

var observer = {
    onDragStart: function (evt , transferData, action) {
        transferData.data = new TransferData();
        transferData.data.addDataForFlavour("text/x-moz-url", proxyUrl);
        transferData.data.addDataForFlavour('application/x-moz-file-promise-url', proxyUrl);// + '\n' + name);
        transferData.data.addDataForFlavour('application/x-moz-file-promise', new dataProvider(), 0, nsCI.nsISupports);
    }
}

function dataProvider(){}

dataProvider.prototype = {
    QueryInterface : function(iid) {
        if (iid.equals(nsCI.nsIFlavorDataProvider) || iid.equals(nsCI.nsISupports))
            return this;
        throw Components.results.NS_NOINTERFACE;
    },
    getFlavorData : function(aTransferable, aFlavor, aData, aDataLen) {
        if (aFlavor == 'application/x-moz-file-promise') {
            // code
        }
    }
}

Он работал в FF 3.0 и на Маке и на Винде.

Теперь код такой (читай комментарии):

dragStart: function (evt) {
    evt.dataTransfer.setData("text/x-moz-url", proxyUrl);
    evt.dataTransfer.setData('application/x-moz-file-promise-url', proxyUrl);
    evt.dataTransfer.setData('application/x-moz-file-promise', new adfolderFDP(), 0, nsCI.nsISupports);
    evt.dataTransfer.mozSetDataAt("application/x-moz-file-promise", null, 0); // такое работает в Windows, но не на Mac 
    //evt.dataTransfer.mozSetDataAt("application/x-moz-file-promise", new dataProvider(), 0); // этот код не работает на Мас
}

В случае evt.dataTransfer.mozSetDataAt("application/x-moz-file-promise", new dataProvider(), 0) - проверял на другой панели FF можно получить этот объект через mozGetDataAt. Но Мас не хочет обрабатывать эту ситуацию. Mac OS X ver. 10.5.6

спустя 9 минут [обр] Алексей Севрюков(2/1280)[досье]
Mac OS 10.5.6 старовата, может в этом дело?
спустя 22 минуты [обр] Slash77[досье]
Обновлюсь, попробую.
спустя 16 часов [обр] Slash77[досье]
Обновился до 10.5.8. Не помогло.
спустя 4 часа 12 минут [обр] Алексей Севрюков(2/1280)[досье]
10.5.8 тоже устаревшая. А можете хотя бы пример дать полностью рабочий с инструкцией как проверять? Я бы на 10.6.4 проверил.
спустя 1 день 19 часов [обр] Slash77[досье]
обновлюсь до 10.6.4 и расскажу что вышло...
спустя 1 час 49 минут [обр] Slash77[досье]

обновился. но ничего не вышло.
Код ниже, но по-моему ни QueryInterface не вызывается, ни getFlavouData (так что его содержимое вряд ли важно)

<hbox ondragstart="dragStart(event);" />

function dragStart(evt) {
    netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
    var proxyUrl; // какой нить урл файла
    evt.dataTransfer.setData("text/x-moz-url", proxyUrl);
    evt.dataTransfer.setData('application/x-moz-file-promise-url', proxyUrl);
    evt.dataTransfer.setData('application/x-moz-file-promise', new adfolderFDP(), 0, nsCI.nsISupports);
    evt.dataTransfer.mozSetDataAt("application/x-moz-file-promise", null, 0); // такое работает в Windows, но не на Mac 
    //evt.dataTransfer.mozSetDataAt("application/x-moz-file-promise", new dataProvider(), 0); // этот код не работает на Мас
}

function dataProvider(){}

dataProvider.prototype = {
    QueryInterface : function(iid) {
        if (iid.equals(nsCI.nsIFlavorDataProvider) || iid.equals(nsCI.nsISupports))
            return this;
        throw Components.results.NS_NOINTERFACE;
    },
    getFlavorData : function(aTransferable, aFlavor, aData, aDataLen) {
        netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
        if (aFlavor == 'application/x-moz-file-promise') {
            var urlPrimitive = {};
            var dataSize = {};
            try {
                aTransferable.getTransferData('application/x-moz-file-promise-url', urlPrimitive, dataSize);
                var url = new String(urlPrimitive.value.QueryInterface(nsCI.nsISupportsString));
                var namePrimitive = {};
                aTransferable.getTransferData('application/x-moz-file-promise-filename', namePrimitive, dataSize);
                var name = new String(namePrimitive.value.QueryInterface(nsCI.nsISupportsString));
                var dirPrimitive = {};
                aTransferable.getTransferData('application/x-moz-file-promise-dir', dirPrimitive, dataSize);
                var dir = dirPrimitive.value.QueryInterface(nsCI.nsILocalFile);
                var fpath = dir.path+DIR_SEP+name;
                var file = nsCC['@mozilla.org/file/local;1'].createInstance(nsCI.nsILocalFile);
                file.initWithPath(fpath);
                var ioService = nsCC['@mozilla.org/network/io-service;1'].getService(nsCI.nsIIOService);
                var urlURI = ioService.newURI(url, null, null);
                var fileURI = ioService.newFileURI(file);
                var persist = nsCC['@mozilla.org/embedding/browser/nsWebBrowserPersist;1'].createInstance(nsCI.nsIWebBrowserPersist);
                var dl = nsCC["@mozilla.org/transfer;1"].createInstance(nsCI.nsITransfer);
                dl.init(urlURI, fileURI, "", null, null, null, persist);
                persist.progressListener = dl;
                persist.saveURI(urlURI, null, null, null, null, fileURI);
                logToJSConsole("adfolderFDP end");
            } catch (e) {
                logToJSConsole(e);
            }
        }
    }
}

спустя 24 дня [обр] VaDima(0/1)[досье]

Решаю ту же задачу (drag-and-drop ссылок на файл на десктоп).
Скажите, Вам удалось побороть?

Вот как я делал, пока не упёрся.

  1. Используя метод JQuery bind(), подвязываюсь на нужные ссылки так:
links.bind("dragstart", function(evt) {
   var link = $(this),
      href = link.attr("href"),
      name = link.text() + " (" + link.attr("version") + ")." + link.attr("ext");

   log("Start: " + name + " (" + href + ")");

   var domE = evt.originalEvent,
      trans = domE.dataTransfer;

   trans.mozSetDataAt("application/x-moz-file-promise-url", href, 0);
   trans.mozSetDataAt("application/x-moz-file-promise", new dragFileProvider(), 0, _CI.nsISupports);
   trans.mozSetDataAt("text/x-moz-url", href + "\n" + name, 0);
   trans.mozSetDataAt("text/x-moz-url-data", href, 0);
   trans.mozSetDataAt("text/x-moz-url-desc", name, 0);
   trans.setData('text/plain', name + "(" + href + ")");
});
  1. ФлейворПровайдер определен почти так же:
var dragFileProvider = function() {
   this.QueryInterface = function(iid) {
      log("dpQI: " + iid);
      if (iid.equals(_CI.nsIFlavorDataProvider) || iid.equals(_CI.nsIFormatConverter)
         || iid.equals(_CI.nsISupports)) {
         return this;
      }
      throw _CR.NS_NOINTERFACE;
   };

   /**
    * nsIFlavorDataProvider
    */
   this.getFlavorData = function(aTransferable, aFlavor, aData, aDataLen) {
      log("dp.getFlavorData: " + aFlavor);
      // сюда не попадаем!
   };
   
   /**
    * nsIFormatConverter
    */
   this.canConvert = function(aFromDataFlavor, aToDataFlavor) {
      log("dpQI.canConvert: " + aFromDataFlavor + " -> " + aToDataFlavor);
      return true;
   };
   this.convert = function(aFromDataFlavor, aFromData, aDataLen, aToDataFlavor, aToData, aDataToLen) {
      log("dpQI.convert: " + aFromDataFlavor + " -> " + aToDataFlavor);
   };
   this.getInputDataFlavors = function() {
      log("dpQI.getInputDataFlavors");
      return _CC["@mozilla.org/array;1"].createInstance(_CI.nsIMutableArray);

   };
   this.getOutputDataFlavors = function() {
      log("dpQI.getOutputDataFlavors");
      return _CC["@mozilla.org/array;1"].createInstance(_CI.nsIMutableArray);
   };
};

Метод getFlavorData провайдера ни разу не дергается.
У самого провайдера спрашивается интерфейс nsIFormatConverter (948a0023-e3a7-11d2-96cf-0060b0fb9956), потом getOutputDataFlavors (я не знаю, что из чего надо ковнвертировать), после чего, похоже, всё падает, и в проводнике, где брошена ссылка, ничего не появляется.

Расскажите, пожалуйста, в чем проблема?

спустя 23 дня [обр] Slash77[досье]
Проблему пока не решил.
а про использование nsIFormatConverter для этих целей нигде до этого не слышал. Откуда этот подход? ссылочку?
спустя 5 месяцев [обр] Slash77[досье]
Проблему решил.
перевел код dataProvider из подписанного кода в экстеншион, который ставится локально на мак.
Код похожий на мой можно найти на сайте мозиллы. Догадки оказались правильны - но надо было перенести код в нужное место.
спустя 21 день [обр] Dukedoc[досье]

В продолжение:
Похожая проблема. Но: копируется на десктоп драг-дропом не файл, а фолдер (элемент дерева, содержащий дочерние узлы - файлы).

function dragStart(evt) {
    if (treerow.getAttribute('type') == 'dir' || treeSelection.count > 1) {
        var adfolder = main.adfolderFDPfileObj;
        adfolder.win = win;
        adfolder.items = win.getSelectionItems();
        evt.dataTransfer.mozSetDataAt('application/x-moz-file-promise', adfolder, 0);
    }
}

Флэйвор провайдер определён вот так:

function adfolderFDPfile(win){
    this._window = win; // main window
    this.win = null; // adfolder frame
    this.items = null;
}

adfolderFDPfile.prototype = {
    QueryInterface : function(iid) {
        if (iid.equals(Components.interfaces.nsIFlavorDataProvider) || iid.equals(Components.interfaces.nsISupports))
            return this;
        throw Components.results.NS_NOINTERFACE;
    },
    getFlavorData : function(aTransferable, aFlavor, aData, aDataLen) {
      netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
      netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserWrite");
        if (aFlavor == 'application/x-moz-file-promise') {
            var namePrimitive = {};
            var dataSize = {};
            aTransferable.getTransferData('application/x-moz-file-promise-filename', namePrimitive, dataSize);
            var dirPrimitive = {};
            aTransferable.getTransferData('application/x-moz-file-promise-dir', dirPrimitive, dataSize);
            var dir = dirPrimitive.value.QueryInterface(Components.interfaces.nsILocalFile);
            var structure = this.win.makeStructure(null, this.items);
            this._window.saveDir(structure, dir.path);
        }
    }
}

При dragStart вызывается метод QueryInterface провайдера, но при дропе метод getFlavorData не вызывается.
На MAC OS всё работает отлично, но отказывается работать на виндах. Может кто-нибудь подсказать в чём особенность?

Powered by POEM™ Engine Copyright © 2002-2005