Improved lesion removing / renumbering after removal
This commit is contained in:
parent
44491c639d
commit
96ddd36151
@ -158,9 +158,7 @@ Template.viewer.onCreated(function() {
|
||||
}
|
||||
|
||||
log.info('Measurement added');
|
||||
|
||||
addMeasurementAsToolData(data);
|
||||
|
||||
syncMeasurementAndToolData(data);
|
||||
updateRelatedElements(data.imageId);
|
||||
},
|
||||
removed: function(data) {
|
||||
@ -174,34 +172,43 @@ Template.viewer.onCreated(function() {
|
||||
var measurementId = data._id;
|
||||
var toolType = data.isTarget ? 'lesion' : 'nonTarget';
|
||||
|
||||
// Find the list of imageIds that needs to be updated
|
||||
var imageIds = [];
|
||||
// Remove the measurement from all the imageIds on which it exists
|
||||
// as toolData
|
||||
Object.keys(data.timepoints).forEach(function(timepointID) {
|
||||
// Clear the toolData for this timepoint
|
||||
var imageId = data.timepoints[timepointID].imageId;
|
||||
removeToolDataWithMeasurementId(imageId, toolType, measurementId);
|
||||
|
||||
// Add this imageId to the list to be updated
|
||||
// (if they are currently displayed)
|
||||
imageIds.push(imageId);
|
||||
});
|
||||
|
||||
// Find the enabled Cornerstone elements currently displaying these image IDs
|
||||
var enabledElements = [];
|
||||
imageIds.forEach(function(imageId) {
|
||||
var elems = cornerstone.getEnabledElementsByImageId(imageId);
|
||||
enabledElements = enabledElements.concat(elems);
|
||||
});
|
||||
|
||||
// Update each related viewport
|
||||
enabledElements.forEach(function(enabledElement) {
|
||||
// Skip thumbnails or other elements that are not primary viewports
|
||||
var element = enabledElement.element;
|
||||
if (!element.classList.contains('imageViewerViewport')) {
|
||||
return;
|
||||
// Update all Measurements to decrement the lesion numbers for those
|
||||
// that were created after the current lesion by 1
|
||||
Meteor.call('decrementLesionNumbers', data, function(error, response) {
|
||||
if (error) {
|
||||
log.warn(error)
|
||||
}
|
||||
|
||||
// Sync database data with toolData for all the measurements
|
||||
// that have just been updated
|
||||
|
||||
// Note that here we need to use greater than and equals to
|
||||
// find the Measurements, whereas on the server it's
|
||||
// only "greater than", since inside this callback the
|
||||
// Measurements have already been decremented.
|
||||
Measurements.find({
|
||||
patientId: data.patientId,
|
||||
lesionNumberAbsolute: {
|
||||
$gte: data.lesionNumberAbsolute
|
||||
}
|
||||
}).forEach(function(measurementData) {
|
||||
syncMeasurementAndToolData(measurementData);
|
||||
});
|
||||
|
||||
// Update each displayed viewport
|
||||
var viewports = $('.imageViewerViewport').not('.empty');
|
||||
viewports.each(function(index, element) {
|
||||
cornerstone.updateImage(element);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -224,7 +231,7 @@ function updateRelatedElements(imageId) {
|
||||
});
|
||||
}
|
||||
|
||||
function addMeasurementAsToolData(data) {
|
||||
function syncMeasurementAndToolData(data) {
|
||||
// Check what toolType we should be adding this to, based on the isTarget value
|
||||
// of the stored Measurement
|
||||
var toolType = data.isTarget ? 'lesion' : 'nonTarget';
|
||||
@ -266,6 +273,9 @@ function addMeasurementAsToolData(data) {
|
||||
toolState[imageId][toolType].data.forEach(function(measurement) {
|
||||
if (measurement.id === data._id) {
|
||||
alreadyExists = true;
|
||||
|
||||
// Update the toolData lesionNumber from the Measurement
|
||||
measurement.lesionNumber = data.lesionNumber;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
@ -282,7 +292,6 @@ function addMeasurementAsToolData(data) {
|
||||
measurementData.isTarget = data.isTarget;
|
||||
measurementData.lesionNumber = data.lesionNumber;
|
||||
measurementData.measurementText = data.measurementText;
|
||||
measurementData.lesionName = data.lesionName;
|
||||
measurementData.isDeleted = data.isDeleted;
|
||||
measurementData.location = data.location;
|
||||
measurementData.locationUID = data.locationUID;
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneTools) {
|
||||
(function($, cornerstone, cornerstoneMath, cornerstoneTools) {
|
||||
|
||||
"use strict";
|
||||
|
||||
if (cornerstoneTools === undefined) {
|
||||
cornerstoneTools = {};
|
||||
}
|
||||
var toolType = "lesion";
|
||||
|
||||
var configuration = {
|
||||
setLesionNumberCallback: setLesionNumberCallback,
|
||||
@ -29,15 +27,12 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
||||
//doneCallback(prompt('Change your lesion location:'));
|
||||
}
|
||||
|
||||
var toolType = "lesion";
|
||||
|
||||
///////// BEGIN ACTIVE TOOL ///////
|
||||
|
||||
function addNewMeasurement(mouseEventData) {
|
||||
var element = mouseEventData.element;
|
||||
|
||||
function doneCallback(lesionNumber) {
|
||||
measurementData.lesionName = "Target " + lesionNumber;
|
||||
measurementData.lesionNumber = lesionNumber;
|
||||
measurementData.active = false;
|
||||
cornerstone.updateImage(element);
|
||||
@ -82,8 +77,6 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
||||
$(element).on('CornerstoneToolsMouseDown', eventData, mouseDownCallback);
|
||||
$(element).on('CornerstoneToolsMouseDownActivate', eventData, cornerstoneTools.lesion.mouseDownActivateCallback);
|
||||
cornerstone.updateImage(element);
|
||||
|
||||
//updateLesionCollection(measurementData);
|
||||
});
|
||||
}
|
||||
|
||||
@ -91,7 +84,6 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
||||
var element = touchEventData.element;
|
||||
|
||||
function doneCallback(lesionNumber) {
|
||||
measurementData.lesionName = "Bi-Directional " + lesionNumber;
|
||||
measurementData.lesionNumber = lesionNumber;
|
||||
measurementData.active = false;
|
||||
cornerstone.updateImage(element);
|
||||
@ -199,7 +191,6 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
||||
measurementText: 0,
|
||||
widthMeasurement: 0,
|
||||
perpendicularMeasurement: 0,
|
||||
lesionName: 'Target',
|
||||
isDeleted: false,
|
||||
isTarget: true,
|
||||
uid: uuid.v4()
|
||||
@ -262,7 +253,10 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
||||
|
||||
var k = distanceToLineP2 / newLineLength;
|
||||
|
||||
var newIntersection = { x: data.handles.end.x + ((eventData.currentPoints.image.x - data.handles.end.x) * k), y: data.handles.end.y + ((eventData.currentPoints.image.y - data.handles.end.y) * k)};
|
||||
var newIntersection = {
|
||||
x: data.handles.end.x + ((eventData.currentPoints.image.x - data.handles.end.x) * k),
|
||||
y: data.handles.end.y + ((eventData.currentPoints.image.y - data.handles.end.y) * k)
|
||||
};
|
||||
|
||||
data.handles.perpendicularStart.x = newIntersection.x - distanceFromPerpendicularP1 * dy;
|
||||
data.handles.perpendicularStart.y = newIntersection.y + distanceFromPerpendicularP1 * dx;
|
||||
@ -294,7 +288,10 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
||||
|
||||
var k = distanceToLineP2 / newLineLength;
|
||||
|
||||
var newIntersection = { x: data.handles.start.x + ((eventData.currentPoints.image.x - data.handles.start.x) * k), y: data.handles.start.y + ((eventData.currentPoints.image.y - data.handles.start.y) * k)};
|
||||
var newIntersection = {
|
||||
x: data.handles.start.x + ((eventData.currentPoints.image.x - data.handles.start.x) * k),
|
||||
y: data.handles.start.y + ((eventData.currentPoints.image.y - data.handles.start.y) * k)
|
||||
};
|
||||
|
||||
data.handles.perpendicularStart.x = newIntersection.x + distanceFromPerpendicularP1 * dy;
|
||||
data.handles.perpendicularStart.y = newIntersection.y - distanceFromPerpendicularP1 * dx;
|
||||
@ -330,8 +327,14 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
||||
var dx = (data.handles.start.x - data.handles.end.x) / length;
|
||||
var dy = (data.handles.start.y - data.handles.end.y) / length;
|
||||
|
||||
var adjustedLineP1 = {x: data.handles.start.x - fudgeFactor * dx, y: data.handles.start.y - fudgeFactor * dy};
|
||||
var adjustedLineP2 = {x: data.handles.end.x + fudgeFactor * dx, y: data.handles.end.y + fudgeFactor * dy};
|
||||
var adjustedLineP1 = {
|
||||
x: data.handles.start.x - fudgeFactor * dx,
|
||||
y: data.handles.start.y - fudgeFactor * dy
|
||||
};
|
||||
var adjustedLineP2 = {
|
||||
x: data.handles.end.x + fudgeFactor * dx,
|
||||
y: data.handles.end.y + fudgeFactor * dy
|
||||
};
|
||||
|
||||
data.handles.perpendicularStart.x = movedPoint.x;
|
||||
data.handles.perpendicularStart.y = movedPoint.y;
|
||||
@ -386,8 +389,14 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
||||
var dx = (data.handles.start.x - data.handles.end.x) / length;
|
||||
var dy = (data.handles.start.y - data.handles.end.y) / length;
|
||||
|
||||
var adjustedLineP1 = {x: data.handles.start.x - fudgeFactor * dx, y: data.handles.start.y - fudgeFactor * dy};
|
||||
var adjustedLineP2 = {x: data.handles.end.x + fudgeFactor * dx, y: data.handles.end.y + fudgeFactor * dy};
|
||||
var adjustedLineP1 = {
|
||||
x: data.handles.start.x - fudgeFactor * dx,
|
||||
y: data.handles.start.y - fudgeFactor * dy
|
||||
};
|
||||
var adjustedLineP2 = {
|
||||
x: data.handles.end.x + fudgeFactor * dx,
|
||||
y: data.handles.end.y + fudgeFactor * dy
|
||||
};
|
||||
|
||||
data.handles.perpendicularStart.x = movedPoint.x + total * dy;
|
||||
data.handles.perpendicularStart.y = movedPoint.y - total * dx;
|
||||
@ -729,18 +738,27 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
||||
|
||||
// Find distances between handles and textBox
|
||||
var distanceToStart = getDistance(data.handles.start, data.handles.textBox);
|
||||
distancesArr.push({distance: distanceToStart, point: data.handles.start});
|
||||
distancesArr.push({
|
||||
distance: distanceToStart,
|
||||
point: data.handles.start
|
||||
});
|
||||
minDistance = distanceToStart;
|
||||
|
||||
var distanceToEnd = getDistance(data.handles.end, data.handles.textBox);
|
||||
distancesArr.push({distance: distanceToEnd, point: data.handles.end});
|
||||
distancesArr.push({
|
||||
distance: distanceToEnd,
|
||||
point: data.handles.end
|
||||
});
|
||||
if (distanceToEnd < minDistance) {
|
||||
minDistance = distanceToEnd;
|
||||
}
|
||||
|
||||
if (data.handles.perpendicularStart.x && data.handles.perpendicularStart.y) {
|
||||
var distanceToPerpendicularStart = getDistance(data.handles.perpendicularStart, data.handles.textBox);
|
||||
distancesArr.push({distance: distanceToPerpendicularStart, point: data.handles.perpendicularStart});
|
||||
distancesArr.push({
|
||||
distance: distanceToPerpendicularStart,
|
||||
point: data.handles.perpendicularStart
|
||||
});
|
||||
if (distanceToPerpendicularStart < minDistance) {
|
||||
minDistance = distanceToPerpendicularStart;
|
||||
}
|
||||
@ -749,7 +767,10 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
||||
|
||||
if (data.handles.perpendicularEnd.x && data.handles.perpendicularEnd.y) {
|
||||
var distanceToPerpendicularEnd = getDistance(data.handles.perpendicularEnd, data.handles.textBox);
|
||||
distancesArr.push({distance: distanceToPerpendicularEnd, point: data.handles.perpendicularEnd});
|
||||
distancesArr.push({
|
||||
distance: distanceToPerpendicularEnd,
|
||||
point: data.handles.perpendicularEnd
|
||||
});
|
||||
if (distanceToPerpendicularEnd < minDistance) {
|
||||
minDistance = distanceToPerpendicularEnd;
|
||||
}
|
||||
@ -845,7 +866,7 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
||||
|
||||
var lengthText = ' L ' + length.toFixed(1) + suffix;
|
||||
var widthText = ' W ' + width.toFixed(1) + suffix;
|
||||
var textLines = [data.lesionName, lengthText, widthText];
|
||||
var textLines = ['Target ' + data.lesionNumber, lengthText, widthText];
|
||||
|
||||
var boundingBox = cornerstoneTools.drawTextBox(context,
|
||||
textLines,
|
||||
@ -861,18 +882,6 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
||||
}
|
||||
}
|
||||
|
||||
function updateLesionCollection(lesionData) {
|
||||
// TODO = Remove this in favour of measurement events
|
||||
if (!lesionData.active) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (lesionData.timepointID && lesionData.timepointID !== "") {
|
||||
// Update Measurements Collection
|
||||
LesionManager.updateLesionData(lesionData);
|
||||
}
|
||||
}
|
||||
|
||||
function doubleClickCallback(e, eventData) {
|
||||
// Prevent other double click handlers from firing after this one
|
||||
//e.stopImmediatePropagation();
|
||||
@ -884,16 +893,7 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
||||
if (deleteTool === true) {
|
||||
cornerstoneTools.removeToolState(element, toolType, data);
|
||||
cornerstone.updateImage(element);
|
||||
//return;
|
||||
}
|
||||
|
||||
/*// TODO= Find a better way to do this! This is very messy
|
||||
config.setLesionNumberCallback(data, eventData, function(lesionNumber) {
|
||||
data.lesionName = "Target " + lesionNumber;
|
||||
data.lesionNumber = lesionNumber;
|
||||
data.active = false;
|
||||
cornerstone.updateImage(element);
|
||||
});*/
|
||||
}
|
||||
|
||||
if (e.data && e.data.mouseButtonMask && !cornerstoneTools.isMouseButtonEnabled(eventData.which, e.data.mouseButtonMask)) {
|
||||
@ -948,6 +948,4 @@ var cornerstoneTools = (function($, cornerstone, cornerstoneMath, cornerstoneToo
|
||||
|
||||
cornerstoneTools.lesion.setConfiguration(configuration);
|
||||
|
||||
return cornerstoneTools;
|
||||
|
||||
}($, cornerstone, cornerstoneMath, cornerstoneTools));
|
||||
})($, cornerstone, cornerstoneMath, cornerstoneTools);
|
||||
@ -35,7 +35,6 @@
|
||||
var element = mouseEventData.element;
|
||||
|
||||
function doneCallback(lesionNumber) {
|
||||
measurementData.lesionName = "Non-Target " + lesionNumber;
|
||||
measurementData.lesionNumber = lesionNumber;
|
||||
measurementData.active = true;
|
||||
cornerstone.updateImage(element);
|
||||
@ -208,7 +207,7 @@
|
||||
}
|
||||
|
||||
// Draw the text
|
||||
if (data.lesionName && data.lesionName !== '') {
|
||||
if (data.lesionNumber) {
|
||||
// Draw linked line as dashed
|
||||
var mid = {
|
||||
x: (handleStartCanvas.x + handleEndCanvas.x) / 2,
|
||||
@ -224,7 +223,7 @@
|
||||
context.lineTo(canvasTextLocation.x + 20, canvasTextLocation.y + 20);
|
||||
context.stroke();
|
||||
|
||||
var boundingBox = cornerstoneTools.drawTextBox(context, data.lesionName, canvasTextLocation.x, canvasTextLocation.y, color);
|
||||
var boundingBox = cornerstoneTools.drawTextBox(context, 'Non-Target ' + data.lesionNumber, canvasTextLocation.x, canvasTextLocation.y, color);
|
||||
data.handles.textBox.boundingBox = boundingBox;
|
||||
}
|
||||
|
||||
@ -239,7 +238,6 @@
|
||||
var element = touchEventData.element;
|
||||
|
||||
function doneCallback(lesionNumber) {
|
||||
measurementData.lesionName = "Non-Target " + lesionNumber;
|
||||
measurementData.lesionNumber = lesionNumber;
|
||||
measurementData.active = true;
|
||||
cornerstone.updateImage(element);
|
||||
|
||||
@ -12,9 +12,9 @@
|
||||
border-radius: 5px
|
||||
padding: 10px 20px 10px 20px
|
||||
background-color: rgba(255,255,255,1)
|
||||
outline: none
|
||||
|
||||
.btn
|
||||
outline: none
|
||||
text-decoration: none
|
||||
|
||||
#cancel
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
border-radius: 5px
|
||||
padding: 10px 20px 10px 20px
|
||||
background-color: rgba(255,255,255,1)
|
||||
outline: none
|
||||
|
||||
#closeLesionPopup
|
||||
outline: none
|
||||
|
||||
@ -10,7 +10,9 @@ function doneCallback(measurementData, deleteTool) {
|
||||
// the specified Timepoint Cell
|
||||
if (deleteTool === true) {
|
||||
Meteor.call("removeMeasurement", measurementData.id, function(error, response) {
|
||||
console.log('Removed!');
|
||||
if (error) {
|
||||
log.warn(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -47,7 +49,6 @@ Template.lesionTableRow.events({
|
||||
if (error) {
|
||||
log.warn(error);
|
||||
}
|
||||
log.info(response);
|
||||
});
|
||||
}, options);
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
border-radius: 5px
|
||||
padding: 10px 20px 10px 20px
|
||||
background-color: rgba(255,255,255,1)
|
||||
outline: none
|
||||
|
||||
#selectNonTargetLesionLocation, #selectNonTargetLesionLocationResponse
|
||||
width: 100%
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
border-radius: 5px
|
||||
padding: 10px 20px 10px 20px
|
||||
background-color: rgba(255,255,255,1)
|
||||
outline: none
|
||||
|
||||
#selectNonTargetLesionLocationResponse
|
||||
width: 100%
|
||||
|
||||
@ -1,14 +1,10 @@
|
||||
Meteor.publish('timepoints', function(patientId) {
|
||||
console.log('Publish timepoints');
|
||||
console.log('patientId ' + patientId);
|
||||
return Timepoints.find({
|
||||
patientId: patientId
|
||||
});
|
||||
});
|
||||
|
||||
Meteor.publish('measurements', function(patientId) {
|
||||
console.log('Publish measurements');
|
||||
console.log('patientId ' + patientId);
|
||||
return Measurements.find({
|
||||
patientId: patientId
|
||||
});
|
||||
|
||||
@ -1,54 +1,44 @@
|
||||
Meteor.methods({
|
||||
"removeMeasurement": function(id) {
|
||||
console.log(Measurements.find().fetch());
|
||||
console.log("Removing: " + id);
|
||||
Measurements.remove(id);
|
||||
console.log(Measurements.find().fetch());
|
||||
},
|
||||
"removeMeasurementsByPatientId": function(patientId) {
|
||||
Measurements.remove({patientId: patientId});
|
||||
},
|
||||
// TODO= Check where this is used? Seems like nowhere..
|
||||
"removePatientMeasurement": function(lesionObject) {
|
||||
// Find patient data
|
||||
var measurementData = Measurements.findOne({
|
||||
patientId: lesionObject.patientId,
|
||||
isTarget: lesionObject.isTarget,
|
||||
lesionNumber: lesionObject.lesionNumber
|
||||
});
|
||||
"decrementLesionNumbers": function(lesionData) {
|
||||
// Update all Measurements to decrement the lesion numbers for those
|
||||
// that were created after the current lesion by 1
|
||||
|
||||
// Get timepoints
|
||||
var timepoints = measurementData.timepoints;
|
||||
|
||||
// Create an array to hold keys of timepoints
|
||||
var timepointsIds = Object.keys(timepoints).slice(0);
|
||||
|
||||
timepointsIds.forEach(function(timepointId) {
|
||||
if (timepointId === lesionObject.timepointId) {
|
||||
delete timepoints[timepointId];
|
||||
}
|
||||
});
|
||||
|
||||
var newTimepointsIds = Object.keys(timepoints);
|
||||
// If there is no timepoints object, remove measurement data
|
||||
if (newTimepointsIds.length) {
|
||||
//Update measurement timepoints
|
||||
// TODO: Update this when we have more criteria than patientId
|
||||
// Decrement the absolute lesion number of all lesions with
|
||||
// absolute lesion numbers greater than the current lesion by 1
|
||||
Measurements.update({
|
||||
patientId: lesionObject.patientId,
|
||||
isTarget: lesionObject.isTarget,
|
||||
lesionNumber: lesionObject.lesionNumber
|
||||
patientId: lesionData.patientId,
|
||||
lesionNumberAbsolute: {
|
||||
$gt: lesionData.lesionNumberAbsolute
|
||||
}
|
||||
}, {
|
||||
$set: {
|
||||
timepoints: timepoints
|
||||
$inc: {
|
||||
lesionNumberAbsolute: -1
|
||||
}
|
||||
}, {
|
||||
multi: true
|
||||
});
|
||||
} else {
|
||||
// Remove all data
|
||||
Measurements.remove({
|
||||
patientId: lesionObject.patientId,
|
||||
isTarget: lesionObject.isTarget,
|
||||
lesionNumber: lesionObject.lesionNumber
|
||||
|
||||
// Decrement the lesion number of all related (i.e. target or non-target)
|
||||
// lesions with lesion numbers greater than the current lesion by 1
|
||||
Measurements.update({
|
||||
patientId: lesionData.patientId,
|
||||
lesionNumber: {
|
||||
$gt: lesionData.lesionNumber
|
||||
},
|
||||
isTarget: lesionData.isTarget
|
||||
}, {
|
||||
$inc: {
|
||||
lesionNumber: -1
|
||||
}
|
||||
}, {
|
||||
multi: true
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
19
Packages/viewerbase/lib/setFocusToActiveViewport.js
Normal file
19
Packages/viewerbase/lib/setFocusToActiveViewport.js
Normal file
@ -0,0 +1,19 @@
|
||||
/**
|
||||
* Restores the browser focus to the currently specified active viewport
|
||||
* as determined from Meteor's Session variable.
|
||||
*
|
||||
* This is allows keydown events to be captured on the focused element
|
||||
*/
|
||||
setFocusToActiveViewport = function() {
|
||||
// Get the list of viewports
|
||||
var viewports = $('.imageViewerViewport');
|
||||
|
||||
// Get the current active viewport index from Session
|
||||
var activeViewportIndex = Session.get('activeViewport');
|
||||
|
||||
// Find the div from the list of viewports
|
||||
var activeViewport = viewports.eq(activeViewportIndex);
|
||||
|
||||
// Set the browser focus to this div
|
||||
activeViewport.focus();
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user