Best Python code snippet using tempest_python
statusmanager.js
Source:statusmanager.js
1/**2 * ownCloud3 *4 * @author Juan Pablo Villafañez Ramos <jvillafanez@owncloud.com>5 * @author Jesus Macias Portela <jesus@owncloud.com>6 * @copyright Copyright (c) 2018, ownCloud GmbH7 *8 * This file is licensed under the Affero General Public License version 39 * or later.10 *11 * See the COPYING-README file.12 *13 */14if (!OCA.External) {15 OCA.External = {};16}17if (!OCA.External.StatusManager) {18 OCA.External.StatusManager = {};19}20OCA.External.StatusManager = {21 mountStatus: null,22 mountPointList: null,23 /**24 * Function25 * @param {callback} afterCallback26 */27 getMountStatus: function (afterCallback) {28 var self = this;29 if (typeof afterCallback !== 'function' || self.isGetMountStatusRunning) {30 return;31 }32 if (self.mountStatus) {33 afterCallback(self.mountStatus);34 }35 },36 /**37 * Function Check mount point status from cache38 * @param {string} mount_point39 */40 getMountPointListElement: function (mount_point) {41 var element;42 $.each(this.mountPointList, function (key, value) {43 if (value.mount_point === mount_point) {44 element = value;45 return false;46 }47 });48 return element;49 },50 /**51 * Function Check mount point status from cache52 * @param {string} mount_point53 * @param {string} mount_point54 */55 getMountStatusForMount: function (mountData, afterCallback) {56 var self = this;57 if (typeof afterCallback !== 'function' || self.isGetMountStatusRunning) {58 return $.Deferred().resolve();59 }60 var defObj;61 if (self.mountStatus[mountData.mount_point]) {62 defObj = $.Deferred();63 afterCallback(mountData, self.mountStatus[mountData.mount_point]);64 defObj.resolve(); // not really useful, but it'll keep the same behaviour65 } else {66 defObj = $.ajax({67 type: 'GET',68 url: OC.webroot + '/index.php/apps/files_external/' + ((mountData.type === 'personal') ? 'userstorages' : 'userglobalstorages') + '/' + mountData.id,69 data: {'testOnly' : false},70 success: function (response) {71 if (response && response.status === 0) {72 self.mountStatus[mountData.mount_point] = response;73 } else {74 var statusCode = response.status ? response.status : 1;75 var statusMessage = response.statusMessage ? response.statusMessage : t('files_external', 'Empty response from the server')76 // failure response with error message77 self.mountStatus[mountData.mount_point] = {78 type: mountData.type,79 status: statusCode,80 id: mountData.id,81 error: statusMessage,82 userProvided: response.userProvided83 };84 }85 afterCallback(mountData, self.mountStatus[mountData.mount_point]);86 },87 error: function (jqxhr, state, error) {88 var message;89 if (mountData.location === 3) {90 // In this case the error is because mount point use Login credentials and don't exist in the session91 message = t('files_external', 'Couldn\'t access. Please logout and login to activate this mount point');92 } else {93 message = t('files_external', 'Couldn\'t get the information from the ownCloud server: {code} {type}', {94 code: jqxhr.status,95 type: error96 });97 }98 self.mountStatus[mountData.mount_point] = {99 type: mountData.type,100 status: 1,101 location: mountData.location,102 error: message103 };104 afterCallback(mountData, self.mountStatus[mountData.mount_point]);105 }106 });107 }108 return defObj;109 },110 /**111 * Function to get external mount point list from the files_external API112 * @param {function} afterCallback function to be executed113 */114 getMountPointList: function (afterCallback) {115 var self = this;116 if (typeof afterCallback !== 'function' || self.isGetMountPointListRunning) {117 return;118 }119 if (self.mountPointList) {120 afterCallback(self.mountPointList);121 } else {122 self.isGetMountPointListRunning = true;123 $.ajax({124 type: 'GET',125 url: OC.linkToOCS('apps/files_external/api/v1') + 'mounts?format=json',126 success: function (response) {127 self.mountPointList = [];128 _.each(response.ocs.data, function (mount) {129 var element = {};130 element.mount_point = mount.name;131 element.type = mount.scope;132 element.location = "";133 element.id = mount.id;134 element.backendText = mount.backend;135 element.backend = mount.class;136 self.mountPointList.push(element);137 });138 afterCallback(self.mountPointList);139 },140 error: function (jqxhr, state, error) {141 self.mountPointList = [];142 OC.Notification.show(t('files_external', 'Couldn\'t get the list of external mount points: {type}', 143 {type: error}), {type: 'error'}144 );145 },146 complete: function () {147 self.isGetMountPointListRunning = false;148 }149 });150 }151 },152 /**153 * Function to manage action when a mountpoint status = 1 (Errored). Show a dialog to be redirected to settings page.154 * @param {string} name MountPoint Name155 */156 manageMountPointError: function (name) {157 this.getMountStatus($.proxy(function (allMountStatus) {158 if (allMountStatus.hasOwnProperty(name) && allMountStatus[name].status > 0 && allMountStatus[name].status < 7) {159 var mountData = allMountStatus[name];160 if (mountData.type === "system") {161 if (mountData.userProvided) {162 // personal mount whit credentials problems163 this.showCredentialsDialog(name, mountData);164 } else {165 OC.dialogs.confirm(t('files_external', 'There was an error with message: ') + mountData.error + '. Do you want to review mount point config in admin settings page?', t('files_external', 'External mount error'), function (e) {166 if (e === true) {167 if (OC.isUserAdmin()) {168 OC.redirect(OC.generateUrl('/settings/admin?sectionid=storage'));169 }170 else {171 OC.redirect(OC.generateUrl('/settings/personal?sectionid=storage'));172 }173 }174 }, true);175 }176 } else {177 OC.dialogs.confirm(t('files_external', 'There was an error with message: ') + mountData.error + '. Do you want to review mount point config in personal settings page?', t('files_external', 'External mount error'), function (e) {178 if (e === true) {179 OC.redirect(OC.generateUrl('/settings/personal?sectionid=storage'));180 }181 }, true);182 }183 }184 }, this));185 },186 /**187 * Function to process a mount point in relation with their status, Called from Async Queue.188 * @param {object} mountData189 * @param {object} mountStatus190 */191 processMountStatusIndividual: function (mountData, mountStatus) {192 var mountPoint = mountData.mount_point;193 if (mountStatus.status > 0) {194 var trElement = FileList.findFileEl(OCA.External.StatusManager.Utils.jqSelEscape(mountPoint));195 var route = OCA.External.StatusManager.Utils.getIconRoute(trElement) + '-error';196 if (OCA.External.StatusManager.Utils.isCorrectViewAndRootFolder()) {197 OCA.External.StatusManager.Utils.showIconError(mountPoint, $.proxy(OCA.External.StatusManager.manageMountPointError, OCA.External.StatusManager), route);198 }199 return false;200 } else {201 if (OCA.External.StatusManager.Utils.isCorrectViewAndRootFolder()) {202 OCA.External.StatusManager.Utils.restoreFolder(mountPoint);203 OCA.External.StatusManager.Utils.toggleLink(mountPoint, true, true);204 }205 return true;206 }207 },208 /**209 * Function to process a mount point in relation with their status210 * @param {object} mountData211 * @param {object} mountStatus212 */213 processMountList: function (mountList) {214 var elementList = null;215 $.each(mountList, function (name, value) {216 var trElement = $('#fileList tr[data-file=\"' + OCA.External.StatusManager.Utils.jqSelEscape(value.mount_point) + '\"]'); //FileList.findFileEl(OCA.External.StatusManager.Utils.jqSelEscape(value.mount_point));217 trElement.attr('data-external-backend', value.backend);218 if (elementList) {219 elementList = elementList.add(trElement);220 } else {221 elementList = trElement;222 }223 });224 if (elementList instanceof $) {225 if (OCA.External.StatusManager.Utils.isCorrectViewAndRootFolder()) {226 // Put their custom icon227 OCA.External.StatusManager.Utils.changeFolderIcon(elementList);228 // Save default view229 OCA.External.StatusManager.Utils.storeDefaultFolderIconAndBgcolor(elementList);230 // Disable row until check status231 elementList.addClass('externalDisabledRow');232 OCA.External.StatusManager.Utils.toggleLink(elementList.find('a.name'), false, false);233 }234 }235 },236 /**237 * Function to process the whole mount point list in relation with their status (Async queue)238 */239 launchFullConnectivityCheckOneByOne: function () {240 var self = this;241 this.getMountPointList(function (list) {242 // check if we have a list first243 if (list === undefined && !self.emptyWarningShown) {244 self.emptyWarningShown = true;245 OC.Notification.show(t('files_external', 'Couldn\'t get the list of Windows network drive mount points: empty response from the server'), 246 {type: 'error'}247 );248 return;249 }250 if (list && list.length > 0) {251 self.processMountList(list);252 if (!self.mountStatus) {253 self.mountStatus = {};254 }255 var ajaxQueue = [];256 $.each(list, function (key, value) {257 var queueElement = {258 funcName: $.proxy(self.getMountStatusForMount, self),259 funcArgs: [value,260 $.proxy(self.processMountStatusIndividual, self)]261 };262 ajaxQueue.push(queueElement);263 });264 var rolQueue = new OCA.External.StatusManager.RollingQueue(ajaxQueue, 4, function () {265 if (!self.notificationHasShown) {266 var showNotification = false;267 $.each(self.mountStatus, function (key, value) {268 if (value.status === 1) {269 self.notificationHasShown = true;270 showNotification = true;271 }272 });273 if (showNotification) {274 OC.Notification.show(t('files_external', 'Some of the configured external mount points are not connected. Please click on the red row(s) for more information'), 275 {type: 'error'}276 );277 }278 }279 });280 rolQueue.runQueue();281 }282 });283 },284 /**285 * Function to process a mount point list in relation with their status (Async queue)286 * @param {object} mountListData287 * @param {boolean} recheck delete cached info and force api call to check mount point status288 */289 launchPartialConnectivityCheck: function (mountListData, recheck) {290 if (mountListData.length === 0) {291 return;292 }293 var self = this;294 var ajaxQueue = [];295 $.each(mountListData, function (key, value) {296 if (recheck && value.mount_point in self.mountStatus) {297 delete self.mountStatus[value.mount_point];298 }299 var queueElement = {300 funcName: $.proxy(self.getMountStatusForMount, self),301 funcArgs: [value,302 $.proxy(self.processMountStatusIndividual, self)]303 };304 ajaxQueue.push(queueElement);305 });306 new OCA.External.StatusManager.RollingQueue(ajaxQueue, 4).runQueue();307 },308 /**309 * Function to relaunch some mount point status check310 * @param {string} mountListNames311 * @param {boolean} recheck delete cached info and force api call to check mount point status312 */313 recheckConnectivityForMount: function (mountListNames, recheck) {314 if (mountListNames.length === 0) {315 return;316 }317 var self = this;318 var mountListData = [];319 if (!self.mountStatus) {320 self.mountStatus = {};321 }322 $.each(mountListNames, function (key, value) {323 var mountData = self.getMountPointListElement(value);324 if (mountData) {325 mountListData.push(mountData);326 }327 });328 // for all mounts in the list, delete the cached status values329 if (recheck) {330 $.each(mountListData, function (key, value) {331 if (value.mount_point in self.mountStatus) {332 delete self.mountStatus[value.mount_point];333 }334 });335 }336 self.processMountList(mountListData);337 self.launchPartialConnectivityCheck(mountListData, recheck);338 },339 credentialsDialogTemplate:340 '<div id="files_external_div_form"><div>' +341 '<div>{{credentials_text}}</div>' +342 '<form>' +343 '<input type="text" name="username" placeholder="{{placeholder_username}}"/>' +344 '<input type="password" name="password" placeholder="{{placeholder_password}}" autocomplete="off"/>' +345 '</form>' +346 '</div></div>',347 /**348 * Function to display custom dialog to enter credentials349 * @param mountPoint350 * @param mountData351 */352 showCredentialsDialog: function (mountPoint, mountData) {353 var template = Handlebars.compile(OCA.External.StatusManager.credentialsDialogTemplate);354 var dialog = $(template({355 credentials_text: t('files_external', 'Please enter the credentials for the {mount} mount', {356 'mount': mountPoint357 }),358 placeholder_username: t('files_external', 'Username'),359 placeholder_password: t('files_external', 'Password')360 }));361 $('body').append(dialog);362 var apply = function () {363 var username = dialog.find('[name=username]').val();364 var password = dialog.find('[name=password]').val();365 var endpoint = OC.generateUrl('apps/files_external/userglobalstorages/{id}', {366 id: mountData.id367 });368 $('.oc-dialog-close').hide();369 $.ajax({370 type: 'PUT',371 url: endpoint,372 data: {373 backendOptions: {374 user: username,375 password: password376 }377 },378 success: function (data) {379 OC.Notification.show(t('files_external', 'Credentials saved'), {type: 'error'});380 dialog.ocdialog('close');381 /* Trigger status check again */382 OCA.External.StatusManager.recheckConnectivityForMount([OC.basename(data.mountPoint)], true);383 },384 error: function () {385 $('.oc-dialog-close').show();386 OC.Notification.show(t('files_external', 'Credentials saving failed'), {type: 'error'});387 }388 });389 return false;390 };391 var ocdialogParams = {392 modal: true,393 title: t('files_external', 'Credentials required'),394 buttons: [{395 text: t('files_external', 'Save'),396 click: apply,397 closeOnEscape: true398 }],399 closeOnExcape: true400 };401 dialog.ocdialog(ocdialogParams)402 .bind('ocdialogclose', function () {403 dialog.ocdialog('destroy').remove();404 });405 dialog.find('form').on('submit', apply);406 dialog.find('form input:first').focus();407 dialog.find('form input').keyup(function (e) {408 if ((e.which && e.which === 13) || (e.keyCode && e.keyCode === 13)) {409 $(e.target).closest('form').submit();410 return false;411 } else {412 return true;413 }414 });415 }416};417OCA.External.StatusManager.Utils = {418 showIconError: function (folder, clickAction, errorImageUrl) {419 var imageUrl = "url(" + errorImageUrl + ")";420 var trFolder = $('#fileList tr[data-file=\"' + OCA.External.StatusManager.Utils.jqSelEscape(folder) + '\"]'); //FileList.findFileEl(OCA.External.StatusManager.Utils.jqSelEscape(folder));421 this.changeFolderIcon(folder, imageUrl);422 this.toggleLink(folder, false, clickAction);423 trFolder.addClass('externalErroredRow');424 },425 /**426 * @param folder string with the folder or jQuery element pointing to the tr element427 */428 storeDefaultFolderIconAndBgcolor: function (folder) {429 var trFolder;430 if (folder instanceof $) {431 trFolder = folder;432 } else {433 trFolder = $('#fileList tr[data-file=\"' + OCA.External.StatusManager.Utils.jqSelEscape(folder) + '\"]'); //FileList.findFileEl(OCA.External.StatusManager.Utils.jqSelEscape(folder)); //$('#fileList tr[data-file=\"' + OCA.External.StatusManager.Utils.jqSelEscape(folder) + '\"]');434 }435 trFolder.each(function () {436 var thisElement = $(this);437 if (thisElement.data('oldbgcolor') === undefined) {438 thisElement.data('oldbgcolor', thisElement.css('background-color'));439 }440 });441 var icon = trFolder.find('td:first-child div.thumbnail');442 icon.each(function () {443 var thisElement = $(this);444 if (thisElement.data('oldImage') === undefined) {445 thisElement.data('oldImage', thisElement.css('background-image'));446 }447 });448 },449 /**450 * @param folder string with the folder or jQuery element pointing to the tr element451 */452 restoreFolder: function (folder) {453 var trFolder;454 if (folder instanceof $) {455 trFolder = folder;456 } else {457 // can't use here FileList.findFileEl(OCA.External.StatusManager.Utils.jqSelEscape(folder)); return incorrect instance of filelist458 trFolder = $('#fileList tr[data-file=\"' + OCA.External.StatusManager.Utils.jqSelEscape(folder) + '\"]');459 }460 trFolder.removeClass('externalErroredRow').removeClass('externalDisabledRow');461 tdChilds = trFolder.find("td:first-child div.thumbnail");462 tdChilds.each(function () {463 var thisElement = $(this);464 thisElement.css('background-image', thisElement.data('oldImage'));465 });466 },467 /**468 * @param folder string with the folder or jQuery element pointing to the first td element469 * of the tr matching the folder name470 */471 changeFolderIcon: function (filename) {472 var file;473 var route;474 if (filename instanceof $) {475 //trElementList476 $.each(filename, function (index) {477 route = OCA.External.StatusManager.Utils.getIconRoute($(this));478 $(this).attr("data-icon", route);479 $(this).find('td:first-child div.thumbnail').css('background-image', "url(" + route + ")").css('display', 'none').css('display', 'inline');480 });481 } else {482 file = $("#fileList tr[data-file=\"" + this.jqSelEscape(filename) + "\"] > td:first-child div.thumbnail");483 parentTr = file.parents('tr:first');484 route = OCA.External.StatusManager.Utils.getIconRoute(parentTr);485 parentTr.attr("data-icon", route);486 file.css('background-image', "url(" + route + ")").css('display', 'none').css('display', 'inline');487 }488 },489 /**490 * @param backend string with the name of the external storage backend491 * of the tr matching the folder name492 */493 getIconRoute: function (tr) {494 var icon = OC.MimeType.getIconUrl('dir-external');495 var backend = null;496 if (tr instanceof $) {497 backend = tr.attr('data-external-backend');498 }499 switch (backend) {500 case 'windows_network_drive':501 icon = OC.imagePath('windows_network_drive', 'folder-windows');502 break;503 case 'sharepoint':504 icon = OC.imagePath('sharepoint', 'folder-sharepoint');505 break;506 }507 return icon;508 },509 toggleLink: function (filename, active, action) {510 var link;511 if (filename instanceof $) {512 link = filename;513 } else {514 link = $("#fileList tr[data-file=\"" + this.jqSelEscape(filename) + "\"] > td:first-child a.name");515 }516 if (active) {517 link.off('click.connectivity');518 OCA.Files.App.fileList.fileActions.display(link.parent(), true, OCA.Files.App.fileList);519 } else {520 link.find('.fileactions, .nametext .action').remove(); // from files/js/fileactions (display)521 link.off('click.connectivity');522 link.on('click.connectivity', function (e) {523 if (action && $.isFunction(action)) {524 action(filename);525 }526 e.preventDefault();527 return false;528 });529 }530 },531 isCorrectViewAndRootFolder: function () {532 // correct views = files & extstoragemounts533 if (OCA.Files.App.getActiveView() === 'files' || OCA.Files.App.getActiveView() === 'extstoragemounts') {534 return OCA.Files.App.getCurrentAppContainer().find('#dir').val() === '/';535 }536 return false;537 },538 /* escape a selector expression for jQuery */539 jqSelEscape: function (expression) {540 if (expression) {541 return expression.replace(/[!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~]/g, '\\$&');542 }543 return null;544 },545 /* Copied from http://stackoverflow.com/questions/2631001/javascript-test-for-existence-of-nested-object-key */546 checkNested: function (cobj /*, level1, level2, ... levelN*/) {547 var args = Array.prototype.slice.call(arguments),548 obj = args.shift();549 for (var i = 0; i < args.length; i++) {550 if (!obj || !obj.hasOwnProperty(args[i])) {551 return false;552 }553 obj = obj[args[i]];554 }555 return true;556 }...
volume_manager.js
Source:volume_manager.js
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4/**5 * VolumeManager is responsible for tracking list of mounted volumes.6 *7 * @constructor8 * @extends {cr.EventTarget}9 */10function VolumeManager() {11 /**12 * The list of archives requested to mount. We will show contents once13 * archive is mounted, but only for mounts from within this filebrowser tab.14 * @type {Object.<string, Object>}15 * @private16 */17 this.requests_ = {};18 /**19 * @type {Object.<string, Object>}20 * @private21 */22 this.mountedVolumes_ = {};23 this.initMountPoints_();24 this.driveStatus_ = VolumeManager.DriveStatus.UNMOUNTED;25}26/**27 * VolumeManager extends cr.EventTarget.28 */29VolumeManager.prototype.__proto__ = cr.EventTarget.prototype;30/**31 * @enum32 */33VolumeManager.Error = {34 /* Internal errors */35 NOT_MOUNTED: 'not_mounted',36 TIMEOUT: 'timeout',37 /* System events */38 UNKNOWN: 'error_unknown',39 INTERNAL: 'error_internal',40 UNKNOWN_FILESYSTEM: 'error_unknown_filesystem',41 UNSUPPORTED_FILESYSTEM: 'error_unsupported_filesystem',42 INVALID_ARCHIVE: 'error_invalid_archive',43 AUTHENTICATION: 'error_authentication',44 PATH_UNMOUNTED: 'error_path_unmounted'45};46/**47 * @enum48 */49VolumeManager.DriveStatus = {50 UNMOUNTED: 'unmounted',51 MOUNTING: 'mounting',52 ERROR: 'error',53 MOUNTED: 'mounted'54};55/**56 * Time in milliseconds that we wait a respone for. If no response on57 * mount/unmount received the request supposed failed.58 */59VolumeManager.TIMEOUT = 15 * 60 * 1000;60/**61 * Delay in milliseconds DRIVE changes its state from |UNMOUNTED| to62 * |MOUNTING|. Used to display progress in the UI.63 */64VolumeManager.MOUNTING_DELAY = 500;65/**66 * @return {VolumeManager} Singleton instance.67 */68VolumeManager.getInstance = function() {69 return VolumeManager.instance_ = VolumeManager.instance_ ||70 new VolumeManager();71};72/**73 * @param {VolumeManager.DriveStatus} newStatus New DRIVE status.74 * @private75 */76VolumeManager.prototype.setDriveStatus_ = function(newStatus) {77 if (this.driveStatus_ != newStatus) {78 this.driveStatus_ = newStatus;79 cr.dispatchSimpleEvent(this, 'drive-status-changed');80 }81};82/**83 * @return {VolumeManager.DriveStatus} Current DRIVE status.84 */85VolumeManager.prototype.getDriveStatus = function() {86 return this.driveStatus_;87};88/**89 * @param {string} mountPath Volume root path.90 * @return {boolean} True if mounted.91 */92VolumeManager.prototype.isMounted = function(mountPath) {93 this.validateMountPath_(mountPath);94 return mountPath in this.mountedVolumes_;95};96/**97 * Initialized mount points.98 * @private99 */100VolumeManager.prototype.initMountPoints_ = function() {101 var mountedVolumes = [];102 var self = this;103 var index = 0;104 this.deferredQueue_ = [];105 function step(mountPoints) {106 if (index < mountPoints.length) {107 var info = mountPoints[index];108 if (info.mountType == 'drive')109 console.error('Drive is not expected initially mounted');110 var error = info.mountCondition ? 'error_' + info.mountCondition : '';111 function onVolumeInfo(volume) {112 mountedVolumes.push(volume);113 index++;114 step(mountPoints);115 }116 self.makeVolumeInfo_('/' + info.mountPath, error, onVolumeInfo);117 } else {118 for (var i = 0; i < mountedVolumes.length; i++) {119 var volume = mountedVolumes[i];120 self.mountedVolumes_[volume.mountPath] = volume;121 }122 // Subscribe to the mount completed event when mount points initialized.123 chrome.fileBrowserPrivate.onMountCompleted.addListener(124 self.onMountCompleted_.bind(self));125 var deferredQueue = self.deferredQueue_;126 self.deferredQueue_ = null;127 for (var i = 0; i < deferredQueue.length; i++) {128 deferredQueue[i]();129 }130 if (mountedVolumes.length > 0)131 cr.dispatchSimpleEvent(self, 'change');132 }133 }134 chrome.fileBrowserPrivate.getMountPoints(step);135};136/**137 * Event handler called when some volume was mounted or unmouted.138 * @param {MountCompletedEvent} event Received event.139 * @private140 */141VolumeManager.prototype.onMountCompleted_ = function(event) {142 if (event.eventType == 'mount') {143 if (event.mountPath) {144 var requestKey = this.makeRequestKey_(145 'mount', event.mountType, event.sourcePath);146 var error = event.status == 'success' ? '' : event.status;147 this.makeVolumeInfo_(event.mountPath, error, function(volume) {148 this.mountedVolumes_[volume.mountPath] = volume;149 this.finishRequest_(requestKey, event.status, event.mountPath);150 cr.dispatchSimpleEvent(this, 'change');151 }.bind(this));152 } else {153 console.log('No mount path');154 this.finishRequest_(requestKey, event.status);155 }156 } else if (event.eventType == 'unmount') {157 var mountPath = event.mountPath;158 this.validateMountPath_(mountPath);159 var status = event.status;160 if (status == VolumeManager.Error.PATH_UNMOUNTED) {161 console.log('Volume already unmounted: ', mountPath);162 status = 'success';163 }164 var requestKey = this.makeRequestKey_('unmount', '', event.mountPath);165 var requested = requestKey in this.requests_;166 if (event.status == 'success' && !requested &&167 mountPath in this.mountedVolumes_) {168 console.log('Mounted volume without a request: ', mountPath);169 var e = new cr.Event('externally-unmounted');170 e.mountPath = mountPath;171 this.dispatchEvent(e);172 }173 this.finishRequest_(requestKey, status);174 if (event.status == 'success') {175 delete this.mountedVolumes_[mountPath];176 cr.dispatchSimpleEvent(this, 'change');177 }178 }179 if (event.mountType == 'drive') {180 if (event.status == 'success') {181 if (event.eventType == 'mount') {182 // If the mount is not requested, the mount status will not be changed183 // at mountDrive(). Sets it here in such a case.184 var self = this;185 var timeout = setTimeout(function() {186 if (self.getDriveStatus() == VolumeManager.DriveStatus.UNMOUNTED)187 self.setDriveStatus_(VolumeManager.DriveStatus.MOUNTING);188 timeout = null;189 }, VolumeManager.MOUNTING_DELAY);190 this.waitDriveLoaded_(event.mountPath, function(success) {191 if (timeout != null)192 clearTimeout(timeout);193 this.setDriveStatus_(success ? VolumeManager.DriveStatus.MOUNTED :194 VolumeManager.DriveStatus.ERROR);195 }.bind(this));196 } else if (event.eventType == 'unmount') {197 this.setDriveStatus_(VolumeManager.DriveStatus.UNMOUNTED);198 }199 } else {200 this.setDriveStatus_(VolumeManager.DriveStatus.ERROR);201 }202 }203};204/**205 * First access to GDrive takes time (to fetch data from the cloud).206 * We want to change state to MOUNTED (likely from MOUNTING) when the207 * drive ready to operate.208 *209 * @param {string} mountPath Drive mount path.210 * @param {function(boolean, FileError=)} callback To be called when waiting211 * finishes. If the case of error, there may be a FileError parameter.212 * @private213 */214VolumeManager.prototype.waitDriveLoaded_ = function(mountPath, callback) {215 chrome.fileBrowserPrivate.requestLocalFileSystem(function(filesystem) {216 filesystem.root.getDirectory(mountPath, {},217 callback.bind(null, true),218 callback.bind(null, false));219 });220};221/**222 * @param {string} mountPath Path to the volume.223 * @param {VolumeManager?} error Mounting error if any.224 * @param {function(Object)} callback Result acceptor.225 * @private226 */227VolumeManager.prototype.makeVolumeInfo_ = function(228 mountPath, error, callback) {229 if (error)230 this.validateError_(error);231 this.validateMountPath_(mountPath);232 function onVolumeMetadata(metadata) {233 callback({234 mountPath: mountPath,235 error: error,236 deviceType: metadata && metadata.deviceType,237 readonly: !!metadata && metadata.isReadOnly238 });239 }240 chrome.fileBrowserPrivate.getVolumeMetadata(241 util.makeFilesystemUrl(mountPath), onVolumeMetadata);242};243/**244 * Creates string to match mount events with requests.245 * @param {string} requestType 'mount' | 'unmount'.246 * @param {string} mountType 'device' | 'file' | 'network' | 'drive'.247 * @param {string} mountOrSourcePath Source path provided by API after248 * resolving mount request or mountPath for unmount request.249 * @return {string} Key for |this.requests_|.250 * @private251 */252VolumeManager.prototype.makeRequestKey_ = function(requestType,253 mountType,254 mountOrSourcePath) {255 return requestType + ':' + mountType + ':' + mountOrSourcePath;256};257/**258 * @param {Function} successCallback Success callback.259 * @param {Function} errorCallback Error callback.260 */261VolumeManager.prototype.mountDrive = function(successCallback, errorCallback) {262 if (this.getDriveStatus() == VolumeManager.DriveStatus.ERROR) {263 this.setDriveStatus_(VolumeManager.DriveStatus.UNMOUNTED);264 }265 var self = this;266 this.mount_('', 'drive', function(mountPath) {267 this.waitDriveLoaded_(mountPath, function(success, error) {268 if (success) {269 successCallback(mountPath);270 } else {271 errorCallback(error);272 }273 });274 }, function(error) {275 if (self.getDriveStatus() != VolumeManager.DriveStatus.MOUNTED)276 self.setDriveStatus_(VolumeManager.DriveStatus.ERROR);277 errorCallback(error);278 });279};280/**281 * @param {string} fileUrl File url to the archive file.282 * @param {Function} successCallback Success callback.283 * @param {Function} errorCallback Error callback.284 */285VolumeManager.prototype.mountArchive = function(fileUrl, successCallback,286 errorCallback) {287 this.mount_(fileUrl, 'file', successCallback, errorCallback);288};289/**290 * Unmounts volume.291 * @param {string} mountPath Volume mounted path.292 * @param {Function} successCallback Success callback.293 * @param {Function} errorCallback Error callback.294 */295VolumeManager.prototype.unmount = function(mountPath,296 successCallback,297 errorCallback) {298 this.validateMountPath_(mountPath);299 if (this.deferredQueue_) {300 this.deferredQueue_.push(this.unmount.bind(this,301 mountPath, successCallback, errorCallback));302 return;303 }304 var volumeInfo = this.mountedVolumes_[mountPath];305 if (!volumeInfo) {306 errorCallback(VolumeManager.Error.NOT_MOUNTED);307 return;308 }309 chrome.fileBrowserPrivate.removeMount(util.makeFilesystemUrl(mountPath));310 var requestKey = this.makeRequestKey_('unmount', '', volumeInfo.mountPath);311 this.startRequest_(requestKey, successCallback, errorCallback);312};313/**314 * @param {string} mountPath Volume mounted path.315 * @return {VolumeManager.Error?} Returns mount error code316 * or undefined if no error.317 */318VolumeManager.prototype.getMountError = function(mountPath) {319 return this.getVolumeInfo_(mountPath).error;320};321/**322 * @param {string} mountPath Volume mounted path.323 * @return {boolean} True if volume at |mountedPath| is mounted but not usable.324 */325VolumeManager.prototype.isUnreadable = function(mountPath) {326 var error = this.getMountError(mountPath);327 return error == VolumeManager.Error.UNKNOWN_FILESYSTEM ||328 error == VolumeManager.Error.UNSUPPORTED_FILESYSTEM;329};330/**331 * @param {string} mountPath Volume mounted path.332 * @return {string} Device type ('usb'|'sd'|'optical'|'mobile'|'unknown')333 * (as defined in chromeos/disks/disk_mount_manager.cc).334 */335VolumeManager.prototype.getDeviceType = function(mountPath) {336 return this.getVolumeInfo_(mountPath).deviceType;337};338/**339 * @param {string} mountPath Volume mounted path.340 * @return {boolean} True if volume at |mountedPath| is read only.341 */342VolumeManager.prototype.isReadOnly = function(mountPath) {343 return !!this.getVolumeInfo_(mountPath).readonly;344};345/**346 * Helper method.347 * @param {string} mountPath Volume mounted path.348 * @return {Object} Structure created in |startRequest_|.349 * @private350 */351VolumeManager.prototype.getVolumeInfo_ = function(mountPath) {352 this.validateMountPath_(mountPath);353 return this.mountedVolumes_[mountPath] || {};354};355/**356 * @param {string} url URL for for |fileBrowserPrivate.addMount|.357 * @param {'drive'|'file'} mountType Mount type for358 * |fileBrowserPrivate.addMount|.359 * @param {Function} successCallback Success callback.360 * @param {Function} errorCallback Error callback.361 * @private362 */363VolumeManager.prototype.mount_ = function(url, mountType,364 successCallback, errorCallback) {365 if (this.deferredQueue_) {366 this.deferredQueue_.push(this.mount_.bind(this,367 url, mountType, successCallback, errorCallback));368 return;369 }370 chrome.fileBrowserPrivate.addMount(url, mountType, {},371 function(sourcePath) {372 console.log('Mount request: url=' + url + '; mountType=' + mountType +373 '; sourceUrl=' + sourcePath);374 var requestKey = this.makeRequestKey_('mount', mountType, sourcePath);375 this.startRequest_(requestKey, successCallback, errorCallback);376 }.bind(this));377};378/**379 * @param {sting} key Key produced by |makeRequestKey_|.380 * @param {Function} successCallback To be called when request finishes381 * successfully.382 * @param {Function} errorCallback To be called when request fails.383 * @private384 */385VolumeManager.prototype.startRequest_ = function(key,386 successCallback, errorCallback) {387 if (key in this.requests_) {388 var request = this.requests_[key];389 request.successCallbacks.push(successCallback);390 request.errorCallbacks.push(errorCallback);391 } else {392 this.requests_[key] = {393 successCallbacks: [successCallback],394 errorCallbacks: [errorCallback],395 timeout: setTimeout(this.onTimeout_.bind(this, key),396 VolumeManager.TIMEOUT)397 };398 }399};400/**401 * Called if no response received in |TIMEOUT|.402 * @param {sting} key Key produced by |makeRequestKey_|.403 * @private404 */405VolumeManager.prototype.onTimeout_ = function(key) {406 this.invokeRequestCallbacks_(this.requests_[key],407 VolumeManager.Error.TIMEOUT);408 delete this.requests_[key];409};410/**411 * @param {sting} key Key produced by |makeRequestKey_|.412 * @param {VolumeManager.Error|'success'} status Status received from the API.413 * @param {string} opt_mountPath Mount path.414 * @private415 */416VolumeManager.prototype.finishRequest_ = function(key, status, opt_mountPath) {417 var request = this.requests_[key];418 if (!request)419 return;420 clearTimeout(request.timeout);421 this.invokeRequestCallbacks_(request, status, opt_mountPath);422 delete this.requests_[key];423};424/**425 * @param {object} request Structure created in |startRequest_|.426 * @param {VolumeManager.Error|string} status If status == 'success'427 * success callbacks are called.428 * @param {string} opt_mountPath Mount path. Required if success.429 * @private430 */431VolumeManager.prototype.invokeRequestCallbacks_ = function(request, status,432 opt_mountPath) {433 function callEach(callbacks, self, args) {434 for (var i = 0; i < callbacks.length; i++) {435 callbacks[i].apply(self, args);436 }437 }438 if (status == 'success') {439 callEach(request.successCallbacks, this, [opt_mountPath]);440 } else {441 this.validateError_(status);442 callEach(request.errorCallbacks, this, [status]);443 }444};445/**446 * @param {VolumeManager.Error} error Status string iusually received from API.447 * @private448 */449VolumeManager.prototype.validateError_ = function(error) {450 for (var i in VolumeManager.Error) {451 if (error == VolumeManager.Error[i])452 return;453 }454 throw new Error('Invalid mount error: ', error);455};456/**457 * @param {string} mountPath Mount path.458 * @private459 */460VolumeManager.prototype.validateMountPath_ = function(mountPath) {461 if (!/^\/(((archive|removable)\/[^\/]+)|drive|Downloads)$/.test(mountPath))462 throw new Error('Invalid mount path: ', mountPath);...
settings.js
Source:settings.js
1(function(){2function updateStatus(statusEl, result){3 statusEl.removeClass('success error loading-small');4 if (result && result.status == 'success' && result.data.message) {5 statusEl.addClass('success');6 return true;7 } else {8 statusEl.addClass('error');9 return false;10 }11}12function getSelection($row) {13 var values = $row.find('.applicableUsers').select2('val');14 if (!values || values.length === 0) {15 values = ['all'];16 }17 return values;18}19OC.MountConfig={20 saveStorage:function(tr, callback) {21 var mountPoint = $(tr).find('.mountPoint input').val();22 var oldMountPoint = $(tr).find('.mountPoint input').data('mountpoint');23 if (mountPoint == '') {24 return false;25 }26 var statusSpan = $(tr).closest('tr').find('.status span');27 var backendClass = $(tr).find('.backend').data('class');28 var configuration = $(tr).find('.configuration input');29 var addMountPoint = true;30 if (configuration.length < 1) {31 return false;32 }33 var classOptions = {};34 $.each(configuration, function(index, input) {35 if ($(input).val() == '' && !$(input).hasClass('optional')) {36 addMountPoint = false;37 return false;38 }39 if ($(input).is(':checkbox')) {40 if ($(input).is(':checked')) {41 classOptions[$(input).data('parameter')] = true;42 } else {43 classOptions[$(input).data('parameter')] = false;44 }45 } else {46 classOptions[$(input).data('parameter')] = $(input).val();47 }48 });49 if ($('#externalStorage').data('admin') === true) {50 var multiselect = getSelection($(tr));51 }52 if (addMountPoint) {53 var status = false;54 if ($('#externalStorage').data('admin') === true) {55 var isPersonal = false;56 var oldGroups = $(tr).find('.applicable').data('applicable-groups');57 var oldUsers = $(tr).find('.applicable').data('applicable-users');58 var groups = [];59 var users = [];60 $.each(multiselect, function(index, value) {61 var pos = value.indexOf('(group)');62 if (pos != -1) {63 var mountType = 'group';64 var applicable = value.substr(0, pos);65 if ($.inArray(applicable, oldGroups) != -1) {66 oldGroups.splice($.inArray(applicable, oldGroups), 1);67 }68 groups.push(applicable);69 } else {70 var mountType = 'user';71 var applicable = value;72 if ($.inArray(applicable, oldUsers) != -1) {73 oldUsers.splice($.inArray(applicable, oldUsers), 1);74 }75 users.push(applicable);76 }77 statusSpan.addClass('loading-small').removeClass('error success');78 $.ajax({type: 'POST',79 url: OC.filePath('files_external', 'ajax', 'addMountPoint.php'),80 data: {81 mountPoint: mountPoint,82 'class': backendClass,83 classOptions: classOptions,84 mountType: mountType,85 applicable: applicable,86 isPersonal: isPersonal,87 oldMountPoint: oldMountPoint88 },89 success: function(result) {90 $(tr).find('.mountPoint input').data('mountpoint', mountPoint);91 status = updateStatus(statusSpan, result);92 if (callback) {93 callback(status);94 }95 },96 error: function(result){97 status = updateStatus(statusSpan, result);98 if (callback) {99 callback(status);100 }101 }102 });103 });104 $(tr).find('.applicable').data('applicable-groups', groups);105 $(tr).find('.applicable').data('applicable-users', users);106 var mountType = 'group';107 $.each(oldGroups, function(index, applicable) {108 $.ajax({type: 'POST',109 url: OC.filePath('files_external', 'ajax', 'removeMountPoint.php'),110 data: {111 mountPoint: mountPoint,112 'class': backendClass,113 classOptions: classOptions,114 mountType: mountType,115 applicable: applicable,116 isPersonal: isPersonal117 }118 });119 });120 var mountType = 'user';121 $.each(oldUsers, function(index, applicable) {122 $.ajax({type: 'POST',123 url: OC.filePath('files_external', 'ajax', 'removeMountPoint.php'),124 data: {125 mountPoint: mountPoint,126 'class': backendClass,127 classOptions: classOptions,128 mountType: mountType,129 applicable: applicable,130 isPersonal: isPersonal131 }132 });133 });134 } else {135 var isPersonal = true;136 var mountType = 'user';137 var applicable = OC.currentUser;138 statusSpan.addClass('loading-small').removeClass('error success');139 $.ajax({type: 'POST',140 url: OC.filePath('files_external', 'ajax', 'addMountPoint.php'),141 data: {142 mountPoint: mountPoint,143 'class': backendClass,144 classOptions: classOptions,145 mountType: mountType,146 applicable: applicable,147 isPersonal: isPersonal,148 oldMountPoint: oldMountPoint149 },150 success: function(result) {151 $(tr).find('.mountPoint input').data('mountpoint', mountPoint);152 status = updateStatus(statusSpan, result);153 if (callback) {154 callback(status);155 }156 },157 error: function(result){158 status = updateStatus(statusSpan, result);159 if (callback) {160 callback(status);161 }162 }163 });164 }165 return status;166 }167 }168};169$(document).ready(function() {170 //initialize hidden input field with list of users and groups171 $('#externalStorage').find('tr:not(#addMountPoint)').each(function(i,tr) {172 var applicable = $(tr).find('.applicable');173 if (applicable.length > 0) {174 var groups = applicable.data('applicable-groups');175 var groupsId = [];176 $.each(groups, function () {177 groupsId.push(this+"(group)");178 });179 var users = applicable.data('applicable-users');180 if (users.indexOf('all') > -1) {181 $(tr).find('.applicableUsers').val('');182 } else {183 $(tr).find('.applicableUsers').val(groupsId.concat(users).join(','));184 }185 }186 });187 var userListLimit = 30;188 function addSelect2 ($elements) {189 if ($elements.length > 0) {190 $elements.select2({191 placeholder: t('files_external', 'All users. Type to select user or group.'),192 allowClear: true,193 multiple: true,194 //minimumInputLength: 1,195 ajax: {196 url: OC.generateUrl('apps/files_external/applicable'),197 dataType: 'json',198 quietMillis: 100,199 data: function (term, page) { // page is the one-based page number tracked by Select2200 return {201 pattern: term, //search term202 limit: userListLimit, // page size203 offset: userListLimit*(page-1) // page number starts with 0204 };205 },206 results: function (data, page) {207 if (data.status === "success") {208 var results = [];209 var userCount = 0; // users is an object210 // add groups211 $.each(data.groups, function(i, group) {212 results.push({name:group+'(group)', displayname:group, type:'group' });213 });214 // add users215 $.each(data.users, function(id, user) {216 userCount++;217 results.push({name:id, displayname:user, type:'user' });218 });219 var more = (userCount >= userListLimit) || (data.groups.length >= userListLimit);220 return {results: results, more: more};221 } else {222 //FIXME add error handling223 }224 }225 },226 initSelection: function(element, callback) {227 var promises = [];228 var results = [];229 $(element.val().split(",")).each(function (i,userId) {230 var def = new $.Deferred();231 promises.push(def.promise());232 var pos = userId.indexOf('(group)');233 if (pos !== -1) {234 //add as group235 results.push({name:userId, displayname:userId.substr(0, pos), type:'group'});236 def.resolve();237 } else {238 $.ajax(OC.generateUrl('apps/files_external/applicable'), {239 data: {240 pattern: userId241 },242 dataType: "json"243 }).done(function(data) {244 if (data.status === "success") {245 if (data.users[userId]) {246 results.push({name:userId, displayname:data.users[userId], type:'user'});247 }248 def.resolve();249 } else {250 //FIXME add error handling251 }252 });253 }254 });255 $.when.apply(undefined, promises).then(function(){256 callback(results);257 });258 },259 id: function(element) {260 return element.name;261 },262 formatResult: function (element) {263 var $result = $('<span><div class="avatardiv"/><span>'+escapeHTML(element.displayname)+'</span></span>');264 var $div = $result.find('.avatardiv')265 .attr('data-type', element.type)266 .attr('data-name', element.name)267 .attr('data-displayname', element.displayname);268 if (element.type === 'group') {269 var url = OC.imagePath('core','places/contacts-dark'); // TODO better group icon270 $div.html('<img width="32" height="32" src="'+url+'">');271 }272 return $result.get(0).outerHTML;273 },274 formatSelection: function (element) {275 if (element.type === 'group') {276 return '<span title="'+escapeHTML(element.name)+'" class="group">'+escapeHTML(element.displayname+' '+t('files_external', '(group)'))+'</span>';277 } else {278 return '<span title="'+escapeHTML(element.name)+'" class="user">'+escapeHTML(element.displayname)+'</span>';279 }280 },281 escapeMarkup: function (m) { return m; } // we escape the markup in formatResult and formatSelection282 }).on("select2-loaded", function() {283 $.each($(".avatardiv"), function(i, div) {284 $div = $(div);285 if ($div.data('type') === 'user') {286 $div.avatar($div.data('name'),32);287 }288 })289 });290 }291 }292 addSelect2($('tr:not(#addMountPoint) .applicableUsers'));293 294 $('#externalStorage').on('change', '#selectBackend', function() {295 var tr = $(this).parent().parent();296 $('#externalStorage tbody').append($(tr).clone());297 $('#externalStorage tbody tr').last().find('.mountPoint input').val('');298 var selected = $(this).find('option:selected').text();299 var backendClass = $(this).val();300 $(this).parent().text(selected);301 if ($(tr).find('.mountPoint input').val() == '') {302 $(tr).find('.mountPoint input').val(suggestMountPoint(selected));303 }304 $(tr).addClass(backendClass);305 $(tr).find('.status').append('<span></span>');306 $(tr).find('.backend').data('class', backendClass);307 var configurations = $(this).data('configurations');308 var td = $(tr).find('td.configuration');309 $.each(configurations, function(backend, parameters) {310 if (backend == backendClass) {311 $.each(parameters['configuration'], function(parameter, placeholder) {312 var is_optional = false;313 if (placeholder.indexOf('&') === 0) {314 is_optional = true;315 placeholder = placeholder.substring(1);316 }317 if (placeholder.indexOf('*') === 0) {318 var class_string = is_optional ? ' optional' : '';319 td.append('<input type="password" class="added' + class_string + '" data-parameter="'+parameter+'" placeholder="'+placeholder.substring(1)+'" />');320 } else if (placeholder.indexOf('!') === 0) {321 td.append('<label><input type="checkbox" class="added" data-parameter="'+parameter+'" />'+placeholder.substring(1)+'</label>');322 } else if (placeholder.indexOf('#') === 0) {323 td.append('<input type="hidden" class="added" data-parameter="'+parameter+'" />');324 } else {325 var class_string = is_optional ? ' optional' : '';326 td.append('<input type="text" class="added' + class_string + '" data-parameter="'+parameter+'" placeholder="'+placeholder+'" />');327 }328 });329 if (parameters['custom'] && $('#externalStorage tbody tr.'+backendClass.replace(/\\/g, '\\\\')).length == 1) {330 OC.addScript('files_external', parameters['custom']);331 }332 return false;333 }334 });335 $(tr).find('td').last().attr('class', 'remove');336 $(tr).find('td').last().removeAttr('style');337 $(tr).removeAttr('id');338 $(this).remove();339 addSelect2(tr.find('.applicableUsers'));340 });341 function suggestMountPoint(defaultMountPoint) {342 var pos = defaultMountPoint.indexOf('/');343 if (pos !== -1) {344 defaultMountPoint = defaultMountPoint.substring(0, pos);345 }346 defaultMountPoint = defaultMountPoint.replace(/\s+/g, '');347 var i = 1;348 var append = '';349 var match = true;350 while (match && i < 20) {351 match = false;352 $('#externalStorage tbody td.mountPoint input').each(function(index, mountPoint) {353 if ($(mountPoint).val() == defaultMountPoint+append) {354 match = true;355 return false;356 }357 });358 if (match) {359 append = i;360 i++;361 } else {362 break;363 }364 }365 return defaultMountPoint+append;366 }367 $('#externalStorage').on('paste', 'td', function() {368 var tr = $(this).parent();369 setTimeout(function() {370 OC.MountConfig.saveStorage(tr);371 }, 20);372 });373 var timer;374 $('#externalStorage').on('keyup', 'td input', function() {375 clearTimeout(timer);376 var tr = $(this).parent().parent();377 if ($(this).val) {378 timer = setTimeout(function() {379 OC.MountConfig.saveStorage(tr);380 }, 2000);381 }382 });383 $('#externalStorage').on('change', 'td input:checkbox', function() {384 OC.MountConfig.saveStorage($(this).parent().parent().parent());385 });386 $('#externalStorage').on('change', '.applicable', function() {387 OC.MountConfig.saveStorage($(this).parent());388 });389 $('#sslCertificate').on('click', 'td.remove>img', function() {390 var $tr = $(this).parent().parent();391 var row = this.parentNode.parentNode;392 $.post(OC.filePath('files_external', 'ajax', 'removeRootCertificate.php'), {cert: row.id});393 $tr.remove();394 return true;395 });396 $('#externalStorage').on('click', 'td.remove>img', function() {397 var tr = $(this).parent().parent();398 var mountPoint = $(tr).find('.mountPoint input').val();399 if ($('#externalStorage').data('admin') === true) {400 var isPersonal = false;401 var multiselect = getSelection($(tr));402 $.each(multiselect, function(index, value) {403 var pos = value.indexOf('(group)');404 if (pos != -1) {405 var mountType = 'group';406 var applicable = value.substr(0, pos);407 } else {408 var mountType = 'user';409 var applicable = value;410 }411 $.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal });412 });413 } else {414 var mountType = 'user';415 var applicable = OC.currentUser;416 var isPersonal = true;417 $.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal });418 }419 $(tr).remove();420 });421 $('#allowUserMounting').bind('change', function() {422 OC.msg.startSaving('#userMountingMsg');423 if (this.checked) {424 OC.AppConfig.setValue('files_external', 'allow_user_mounting', 'yes');425 $('input[name="allowUserMountingBackends\\[\\]"]').prop('checked', true);426 $('#userMountingBackends').removeClass('hidden');427 $('input[name="allowUserMountingBackends\\[\\]"]').eq(0).trigger('change');428 } else {429 OC.AppConfig.setValue('files_external', 'allow_user_mounting', 'no');430 $('#userMountingBackends').addClass('hidden');431 }432 OC.msg.finishedSaving('#userMountingMsg', {status: 'success', data: {message: t('settings', 'Saved')}});433 });434 $('input[name="allowUserMountingBackends\\[\\]"]').bind('change', function() {435 OC.msg.startSaving('#userMountingMsg');436 var userMountingBackends = $('input[name="allowUserMountingBackends\\[\\]"]:checked').map(function(){return $(this).val();}).get();437 OC.AppConfig.setValue('files_external', 'user_mounting_backends', userMountingBackends.join());438 OC.msg.finishedSaving('#userMountingMsg', {status: 'success', data: {message: t('settings', 'Saved')}});439 // disable allowUserMounting440 if(userMountingBackends.length === 0) {441 $('#allowUserMounting').prop('checked', false);442 $('#allowUserMounting').trigger('change');443 }444 });445});...
ReactDoubleInvokeEvents-test.internal.js
Source:ReactDoubleInvokeEvents-test.internal.js
...211 componentDidUpdate() {212 this.test();213 Scheduler.unstable_yieldValue('componentDidUpdate');214 }215 componentWillUnmount() {216 this.test();217 Scheduler.unstable_yieldValue('componentWillUnmount');218 }219 render() {220 return null;221 }222 }223 ReactNoop.act(() => {224 ReactNoop.render(<App />);225 });226 if (__DEV__ && __VARIANT__) {227 expect(Scheduler).toHaveYielded([228 'componentDidMount',229 'componentWillUnmount',230 'componentDidMount',231 ]);232 } else {233 expect(Scheduler).toHaveYielded(['componentDidMount']);234 }235 });236 it('double invoking works for class components', () => {237 class App extends React.PureComponent {238 componentDidMount() {239 Scheduler.unstable_yieldValue('componentDidMount');240 }241 componentDidUpdate() {242 Scheduler.unstable_yieldValue('componentDidUpdate');243 }244 componentWillUnmount() {245 Scheduler.unstable_yieldValue('componentWillUnmount');246 }247 render() {248 return this.props.text;249 }250 }251 ReactNoop.act(() => {252 ReactNoop.render(<App text={'mount'} />);253 });254 if (__DEV__ && __VARIANT__) {255 expect(Scheduler).toHaveYielded([256 'componentDidMount',257 'componentWillUnmount',258 'componentDidMount',259 ]);260 } else {261 expect(Scheduler).toHaveYielded(['componentDidMount']);262 }263 ReactNoop.act(() => {264 ReactNoop.render(<App text={'update'} />);265 });266 expect(Scheduler).toHaveYielded(['componentDidUpdate']);267 ReactNoop.act(() => {268 ReactNoop.render(null);269 });270 expect(Scheduler).toHaveYielded(['componentWillUnmount']);271 });272 it('double flushing passive effects only results in one double invoke', () => {273 function App({text}) {274 const [state, setState] = React.useState(0);275 React.useEffect(() => {276 if (state !== 1) {277 setState(1);278 }279 Scheduler.unstable_yieldValue('useEffect mount');280 return () => Scheduler.unstable_yieldValue('useEffect unmount');281 });282 React.useLayoutEffect(() => {283 Scheduler.unstable_yieldValue('useLayoutEffect mount');284 return () => Scheduler.unstable_yieldValue('useLayoutEffect unmount');285 });286 Scheduler.unstable_yieldValue(text);287 return text;288 }289 ReactNoop.act(() => {290 ReactNoop.render(<App text={'mount'} />);291 });292 if (__DEV__ && __VARIANT__) {293 expect(Scheduler).toHaveYielded([294 'mount',295 'useLayoutEffect mount',296 'useEffect mount',297 'useLayoutEffect unmount',298 'useEffect unmount',299 'useLayoutEffect mount',300 'useEffect mount',301 'mount',302 'useLayoutEffect unmount',303 'useLayoutEffect mount',304 'useEffect unmount',305 'useEffect mount',306 ]);307 } else {308 expect(Scheduler).toHaveYielded([309 'mount',310 'useLayoutEffect mount',311 'useEffect mount',312 'mount',313 'useLayoutEffect unmount',314 'useLayoutEffect mount',315 'useEffect unmount',316 'useEffect mount',317 ]);318 }319 });320 it('newly mounted components after initial mount get double invoked', () => {321 let _setShowChild;322 function Child() {323 React.useEffect(() => {324 Scheduler.unstable_yieldValue('Child useEffect mount');325 return () => Scheduler.unstable_yieldValue('Child useEffect unmount');326 });327 React.useLayoutEffect(() => {328 Scheduler.unstable_yieldValue('Child useLayoutEffect mount');329 return () =>330 Scheduler.unstable_yieldValue('Child useLayoutEffect unmount');331 });332 return null;333 }334 function App() {335 const [showChild, setShowChild] = React.useState(false);336 _setShowChild = setShowChild;337 React.useEffect(() => {338 Scheduler.unstable_yieldValue('App useEffect mount');339 return () => Scheduler.unstable_yieldValue('App useEffect unmount');340 });341 React.useLayoutEffect(() => {342 Scheduler.unstable_yieldValue('App useLayoutEffect mount');343 return () =>344 Scheduler.unstable_yieldValue('App useLayoutEffect unmount');345 });346 return showChild && <Child />;347 }348 ReactNoop.act(() => {349 ReactNoop.render(<App />);350 });351 if (__DEV__ && __VARIANT__) {352 expect(Scheduler).toHaveYielded([353 'App useLayoutEffect mount',354 'App useEffect mount',355 'App useLayoutEffect unmount',356 'App useEffect unmount',357 'App useLayoutEffect mount',358 'App useEffect mount',359 ]);360 } else {361 expect(Scheduler).toHaveYielded([362 'App useLayoutEffect mount',363 'App useEffect mount',364 ]);365 }366 ReactNoop.act(() => {367 _setShowChild(true);368 });369 if (__DEV__ && __VARIANT__) {370 expect(Scheduler).toHaveYielded([371 'App useLayoutEffect unmount',372 'Child useLayoutEffect mount',373 'App useLayoutEffect mount',374 'App useEffect unmount',375 'Child useEffect mount',376 'App useEffect mount',377 'Child useLayoutEffect unmount',378 'Child useEffect unmount',379 'Child useLayoutEffect mount',380 'Child useEffect mount',381 ]);382 } else {383 expect(Scheduler).toHaveYielded([384 'App useLayoutEffect unmount',385 'Child useLayoutEffect mount',386 'App useLayoutEffect mount',387 'App useEffect unmount',388 'Child useEffect mount',389 'App useEffect mount',390 ]);391 }392 });393 it('classes and functions are double invoked together correctly', () => {394 class ClassChild extends React.PureComponent {395 componentDidMount() {396 Scheduler.unstable_yieldValue('componentDidMount');397 }398 componentWillUnmount() {399 Scheduler.unstable_yieldValue('componentWillUnmount');400 }401 render() {402 return this.props.text;403 }404 }405 function FunctionChild({text}) {406 React.useEffect(() => {407 Scheduler.unstable_yieldValue('useEffect mount');408 return () => Scheduler.unstable_yieldValue('useEffect unmount');409 });410 React.useLayoutEffect(() => {411 Scheduler.unstable_yieldValue('useLayoutEffect mount');412 return () => Scheduler.unstable_yieldValue('useLayoutEffect unmount');...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!