Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
Merge pull request #8834 from davidflanagan/bug834773
Browse files Browse the repository at this point in the history
Bug 834773 - Support image/* and type arrays in pick activity r=dkuo
  • Loading branch information
David Flanagan committed Apr 2, 2013
2 parents bdc26bc + 693c233 commit e64428c
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 39 deletions.
6 changes: 4 additions & 2 deletions apps/email/js/compose-cards.js
Expand Up @@ -541,8 +541,10 @@ ComposeCard.prototype = {
var activity = new MozActivity({
name: 'pick',
data: {
type: 'image/jpeg',
isAttachment: true
// image/* allows gallery to return any kind of image
// image/jpeg is here so that the camera app is offered
type: ['image/*', 'image/jpeg'],
nocrop: true
}
});
activity.onsuccess = (function success() {
Expand Down
10 changes: 10 additions & 0 deletions apps/gallery/js/ImageEditor.js
Expand Up @@ -593,6 +593,16 @@ ImageEditor.prototype.isCropOverlayShown = function() {
return this.cropCanvas;
};

// Returns true if the crop region is anything different than the
// entire dest rectangle. If this method returns false, there is no
// need to call getCroppedRegionBlob().
ImageEditor.prototype.hasBeenCropped = function() {
return (this.cropRegion.left !== 0 ||
this.cropRegion.top !== 0 ||
this.cropRegion.right !== this.dest.w ||
this.cropRegion.bottom !== this.dest.h);
};

// Display cropping controls
// XXX: have to handle rotate/resize
ImageEditor.prototype.showCropOverlay = function showCropOverlay(newRegion) {
Expand Down
80 changes: 62 additions & 18 deletions apps/gallery/js/gallery.js
Expand Up @@ -134,7 +134,7 @@ function init() {
};

// In crop view, the done button finishes the pick
$('crop-done-button').onclick = finishPick;
$('crop-done-button').onclick = cropAndEndPick;

// The camera buttons should both launch the camera app
$('fullscreen-camera-button').onclick = launchCameraApp;
Expand Down Expand Up @@ -672,14 +672,14 @@ function thumbnailOffscreen(thumbnail) {
var pendingPick;
var pickType;
var pickWidth, pickHeight;
var pickedFile;
var cropURL;
var cropEditor;
var isAttachment;

function startPick(activityRequest) {
pendingPick = activityRequest;
pickType = activityRequest.source.data.type;
isAttachment = activityRequest.source.data.isAttachment;

if (pendingPick.source.data.width && pendingPick.source.data.height) {
pickWidth = pendingPick.source.data.width;
pickHeight = pendingPick.source.data.height;
Expand All @@ -693,12 +693,36 @@ function startPick(activityRequest) {
});
}

// Called when the user clicks on a thumbnail in pick mode
function cropPickedImage(fileinfo) {
pickedFile = fileinfo;

// Do we actually want to allow the user to crop the image?
var nocrop = pendingPick.source.data.nocrop;

if (nocrop) {
// If we're not cropping we don't want the word "Crop" in the title bar
// XXX: UX will probably get rid of this title bar soon, anyway.
$('crop-header').textContent = '';
}

setView(cropView);

photodb.getFile(fileinfo.name, function(file) {
photodb.getFile(pickedFile.name, function(file) {
cropURL = URL.createObjectURL(file);
cropEditor = new ImageEditor(cropURL, $('crop-frame'), {}, function() {
// If the initiating app doesn't want to allow the user to crop
// the image, we don't display the crop overlay. But we still use
// this image editor to preview the image.
if (nocrop) {
// Set a fake crop region even though we won't display it
// so that getCroppedRegionBlob() works.
cropEditor.cropRegion.left = cropEditor.cropRegion.top = 0;
cropEditor.cropRegion.right = cropEditor.dest.w;
cropEditor.cropRegion.bottom = cropEditor.dest.h;
return;
}

cropEditor.showCropOverlay();
if (pickWidth)
cropEditor.setCropAspectRatio(pickWidth, pickHeight);
Expand All @@ -708,21 +732,43 @@ function cropPickedImage(fileinfo) {
});
}

function finishPick(fileinfo) {
if (fileinfo.name) {
photodb.getFile(fileinfo.name, endPick);
function cropAndEndPick() {
if (Array.isArray(pickType)) {
if (pickType.length === 0 ||
pickType.indexOf(pickedFile.type) !== -1 ||
pickType.indexOf('image/*') !== -1) {
pickType = pickedFile.type;
}
else if (pickType.indexOf('image/png') !== -1) {
pickType = 'image/png';
}
else {
pickType = 'image/jpeg';
}
}
else if (pickType === 'image/*') {
pickType = pickedFile.type;
}

// If we're not changing the file type or resizing the image and if
// we're not cropping, or if the user did not crop, then we can just
// use the file as it is.
if (pickType === pickedFile.type &&
!pickWidth && !pickHeight &&
(pendingPick.source.data.nocrop || !cropEditor.hasBeenCropped())) {
photodb.getFile(pickedFile.name, endPick);
}
else {
cropEditor.getCroppedRegionBlob(pickType, pickWidth, pickHeight, endPick);
}
}

function endPick(blob) {
pendingPick.postResult({
type: pickType,
blob: blob
});
cleanupPick();
}
function endPick(blob) {
pendingPick.postResult({
type: pickType,
blob: blob
});
cleanupPick();
}

function cancelPick() {
Expand All @@ -744,6 +790,7 @@ function cleanupCrop() {
function cleanupPick() {
cleanupCrop();
pendingPick = null;
pickedFile = null;
setView(thumbnailListView);
}

Expand Down Expand Up @@ -780,12 +827,9 @@ function thumbnailClickHandler(evt) {
else if (currentView === thumbnailSelectView) {
updateSelection(target);
}
else if (currentView === pickView && !isAttachment) {
else if (currentView === pickView) {
cropPickedImage(files[parseInt(target.dataset.index)]);
}
else if (currentView === pickView && isAttachment) {
finishPick(files[parseInt(target.dataset.index)]);
}
}

function clearSelection() {
Expand Down
2 changes: 1 addition & 1 deletion apps/gallery/manifest.webapp
Expand Up @@ -25,7 +25,7 @@
},
"pick": {
"filters": {
"type": ["image/jpeg", "image/png"]
"type": ["image/*", "image/jpeg", "image/png"]
},
"disposition": "inline",
"returnValue": true,
Expand Down
4 changes: 2 additions & 2 deletions shared/js/media/media_frame.js
Expand Up @@ -75,7 +75,7 @@ MediaFrame.prototype.displayImage = function displayImage(blob, width, height,
if (preview && (preview.start || preview.filename)) {
this.displayingPreview = true;
if (preview.start) {
this.previewblob = blob.slice(preview.start, preview.end, 'image/jpeg')
this.previewblob = blob.slice(preview.start, preview.end, 'image/jpeg');
this._displayImage(this.previewblob, preview.width, preview.height);
}
else {
Expand All @@ -90,7 +90,7 @@ MediaFrame.prototype.displayImage = function displayImage(blob, width, height,
self.displayingPreview = false;
self.preview = null;
self._displayImage(blob, width, height);
}
};
}
}
else {
Expand Down
25 changes: 25 additions & 0 deletions test_apps/uitest/js/pickphoto.js
@@ -0,0 +1,25 @@
function pick(type, nocrop, width, height) {
var data = {type: type};
if (nocrop) data.nocrop = true;
if (width) data.width = width;
if (height) data.height = height;
var a = new MozActivity({ name: 'pick', data: data});
a.onsuccess = function(e) {
console.log('got blob of type', a.result.blob.type);
var url = URL.createObjectURL(a.result.blob);
var img = document.getElementById('result');
img.src = url;
img.onload = function() { URL.revokeObjectURL(url); };
};
a.onerror = function() { alert('Failure picking photo'); };
}

document.getElementById('b1').onclick = function() { pick('image/jpeg'); };
document.getElementById('b2').onclick = function() { pick('image/png'); };
document.getElementById('b3').onclick = function() {
pick(['image/jpeg', 'image/png']);
};
document.getElementById('b4').onclick = function() { pick('image/*'); };
document.getElementById('b5').onclick = function() { pick('image/*', true); };
document.getElementById('b6').onclick = function() { pick('image/*', false,
100, 100); };
25 changes: 9 additions & 16 deletions test_apps/uitest/tests/pickphoto.html
Expand Up @@ -5,26 +5,19 @@
<title>Pick Photo test</title>
<style>
button {
font-size: 40px;
font-size: 24px;
}
</style>
<script>
var go = function _go() {
var a = new MozActivity({ name: 'pick', data: {type: 'image/jpeg'}});
a.onsuccess = function(e) {
var url = URL.createObjectURL(a.result.blob);
var img = document.getElementById('result');
img.src = url;
img.onload = function() { URL.revokeObjectURL(url); };
};
a.onerror = function() { alert('Failure picking photo'); };
};
</script>
<script defer src="../js/pickphoto.js"></script>
</head>
<body>
<h1>Pick Photo Test</h1>
<h2>Go to:</h2>
<button onclick="go()">Go</button></p>
Result is: <img id="result"></img>
<button id="b1">Pick image/jpeg</button></p>
<button id="b2">Pick image/png</button></p>
<button id="b3">Pick either</button></p>
<button id="b4">Pick any</button></p>
<button id="b5">Pick without crop</button></p>
<button id="b6">Pick small</button></p>
Result: <img id="result"></img>
</body>
</html>

0 comments on commit e64428c

Please sign in to comment.