1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5// Custom binding for the fileSystemProvider API. 6 7var binding = require('binding').Binding.create('fileSystemProvider'); 8var fileSystemProviderInternal = 9 require('binding').Binding.create('fileSystemProviderInternal').generate(); 10var eventBindings = require('event_bindings'); 11var fileSystemNatives = requireNative('file_system_natives'); 12var GetDOMError = fileSystemNatives.GetDOMError; 13 14/** 15 * Annotates a date with its serialized value. 16 * @param {Date} date Input date. 17 * @return {Date} Date with an extra <code>value</code> attribute. 18 */ 19function annotateDate(date) { 20 // Copy in case the input date is frozen. 21 var result = new Date(date.getTime()); 22 result.value = result.toString(); 23 return result; 24} 25 26/** 27 * Annotates an entry metadata by serializing its modifiedTime value. 28 * @param {EntryMetadata} metadata Input metadata. 29 * @return {EntryMetadata} metadata Annotated metadata, which can be passed 30 * back to the C++ layer. 31 */ 32function annotateMetadata(metadata) { 33 var result = { 34 isDirectory: metadata.isDirectory, 35 name: metadata.name, 36 size: metadata.size, 37 modificationTime: annotateDate(metadata.modificationTime) 38 }; 39 return result; 40} 41 42binding.registerCustomHook(function(bindingsAPI) { 43 var apiFunctions = bindingsAPI.apiFunctions; 44 45 apiFunctions.setUpdateArgumentsPostValidate( 46 'mount', 47 function(options, successCallback, errorCallback) { 48 // Piggyback the error callback onto the success callback, 49 // so we can use the error callback later. 50 successCallback.errorCallback_ = errorCallback; 51 return [options, successCallback]; 52 }); 53 54 apiFunctions.setCustomCallback( 55 'mount', 56 function(name, request, response) { 57 var domError = null; 58 if (request.callback && response) { 59 // DOMError is present only if mount() failed. 60 if (response[0]) { 61 // Convert a Dictionary to a DOMError. 62 domError = GetDOMError(response[0].name, response[0].message); 63 response.length = 1; 64 } 65 66 var successCallback = request.callback; 67 var errorCallback = request.callback.errorCallback_; 68 delete request.callback; 69 70 if (domError) 71 errorCallback(domError); 72 else 73 successCallback(); 74 } 75 }); 76 77 apiFunctions.setUpdateArgumentsPostValidate( 78 'unmount', 79 function(options, successCallback, errorCallback) { 80 // Piggyback the error callback onto the success callback, 81 // so we can use the error callback later. 82 successCallback.errorCallback_ = errorCallback; 83 return [options, successCallback]; 84 }); 85 86 apiFunctions.setCustomCallback( 87 'unmount', 88 function(name, request, response) { 89 var domError = null; 90 if (request.callback) { 91 // DOMError is present only if mount() failed. 92 if (response && response[0]) { 93 // Convert a Dictionary to a DOMError. 94 domError = GetDOMError(response[0].name, response[0].message); 95 response.length = 1; 96 } 97 98 var successCallback = request.callback; 99 var errorCallback = request.callback.errorCallback_; 100 delete request.callback; 101 102 if (domError) 103 errorCallback(domError); 104 else 105 successCallback(); 106 } 107 }); 108}); 109 110eventBindings.registerArgumentMassager( 111 'fileSystemProvider.onUnmountRequested', 112 function(args, dispatch) { 113 var options = args[0]; 114 var onSuccessCallback = function() { 115 fileSystemProviderInternal.unmountRequestedSuccess( 116 options.fileSystemId, options.requestId); 117 }; 118 var onErrorCallback = function(error) { 119 fileSystemProviderInternal.unmountRequestedError( 120 options.fileSystemId, options.requestId, error); 121 } 122 dispatch([options, onSuccessCallback, onErrorCallback]); 123 }); 124 125eventBindings.registerArgumentMassager( 126 'fileSystemProvider.onGetMetadataRequested', 127 function(args, dispatch) { 128 var options = args[0]; 129 var onSuccessCallback = function(metadata) { 130 fileSystemProviderInternal.getMetadataRequestedSuccess( 131 options.fileSystemId, 132 options.requestId, 133 annotateMetadata(metadata)); 134 }; 135 var onErrorCallback = function(error) { 136 fileSystemProviderInternal.getMetadataRequestedError( 137 options.fileSystemId, options.requestId, error); 138 } 139 dispatch([options, onSuccessCallback, onErrorCallback]); 140 }); 141 142eventBindings.registerArgumentMassager( 143 'fileSystemProvider.onReadDirectoryRequested', 144 function(args, dispatch) { 145 var options = args[0]; 146 var onSuccessCallback = function(entries, hasNext) { 147 var annotatedEntries = entries.map(annotateMetadata); 148 fileSystemProviderInternal.readDirectoryRequestedSuccess( 149 options.fileSystemId, options.requestId, annotatedEntries, hasNext); 150 }; 151 var onErrorCallback = function(error) { 152 fileSystemProviderInternal.readDirectoryRequestedError( 153 options.fileSystemId, options.requestId, error); 154 } 155 dispatch([options, onSuccessCallback, onErrorCallback]); 156 }); 157 158eventBindings.registerArgumentMassager( 159 'fileSystemProvider.onOpenFileRequested', 160 function(args, dispatch) { 161 var options = args[0]; 162 var onSuccessCallback = function() { 163 fileSystemProviderInternal.openFileRequestedSuccess( 164 options.fileSystemId, options.requestId); 165 }; 166 var onErrorCallback = function(error) { 167 fileSystemProviderInternal.openFileRequestedError( 168 options.fileSystemId, options.requestId, error); 169 } 170 dispatch([options, onSuccessCallback, onErrorCallback]); 171 }); 172 173eventBindings.registerArgumentMassager( 174 'fileSystemProvider.onCloseFileRequested', 175 function(args, dispatch) { 176 var options = args[0]; 177 var onSuccessCallback = function() { 178 fileSystemProviderInternal.closeFileRequestedSuccess( 179 options.fileSystemId, options.requestId); 180 }; 181 var onErrorCallback = function(error) { 182 fileSystemProviderInternal.closeFileRequestedError( 183 options.fileSystemId, options.requestId, error); 184 } 185 dispatch([options, onSuccessCallback, onErrorCallback]); 186 }); 187 188eventBindings.registerArgumentMassager( 189 'fileSystemProvider.onReadFileRequested', 190 function(args, dispatch) { 191 var options = args[0]; 192 var onSuccessCallback = function(data, hasNext) { 193 fileSystemProviderInternal.readFileRequestedSuccess( 194 options.fileSystemId, options.requestId, data, hasNext); 195 }; 196 var onErrorCallback = function(error) { 197 fileSystemProviderInternal.readFileRequestedError( 198 options.fileSystemId, options.requestId, error); 199 } 200 dispatch([options, onSuccessCallback, onErrorCallback]); 201 }); 202 203exports.binding = binding.generate(); 204