কেস স্টাডি - ক্রোমে ডাউনলোড টেনে আনুন

ভূমিকা

টেনে আনুন এবং ড্রপ (DnD) হল HTML 5 এর অনেকগুলি দুর্দান্ত বৈশিষ্ট্যগুলির মধ্যে একটি, এবং এটি Firefox 3.5, Safari, Chrome এবং IE-তে সমর্থিত। গুগল সম্প্রতি একটি নতুন বৈশিষ্ট্য চালু করেছে যা গুগল ক্রোম ব্যবহারকারীদের ব্রাউজার থেকে ডেস্কটপে ফাইল টেনে আনতে এবং ড্রপ করতে দেয়। এটি একটি অত্যন্ত সুবিধাজনক বৈশিষ্ট্য, তবে রায়ান সেডন এই নতুন বৈশিষ্ট্যটিতে তার বিপরীত প্রকৌশলের আবিষ্কারগুলির উপর একটি নিবন্ধ পোস্ট না করা পর্যন্ত এটি ব্যাপকভাবে পরিচিত ছিল না।

Box.net-এ, এই নতুন ক্ষমতাগুলি কীভাবে আমাদের ক্লাউড বিষয়বস্তু পরিচালনার সমাধান উন্নত করতে এবং সেইসাথে বিকাশকারী সম্প্রদায়কে আরও বেশি অবদান রাখতে সক্ষম করছে তা নিয়ে আমরা খুব উত্তেজিত৷ আমি ঘোষণা করতে পেরে আনন্দিত যে DnD ডাউনলোড আমাদের পণ্যের সাথে একত্রিত হয়েছে। এখন, বক্স ব্যবহারকারীরা ফাইল ডাউনলোড এবং সংরক্ষণ করতে একটি Chrome ব্রাউজার থেকে সরাসরি তাদের ডেস্কটপে ফাইল টেনে আনতে পারেন।

এই নতুন বৈশিষ্ট্যটির বিকাশের সময় আমি কীভাবে বেশ কয়েকটি পুনরাবৃত্তির মধ্য দিয়ে গিয়েছিলাম তা আমি শেয়ার করতে চাই।

ড্র্যাগ এবং ড্রপ API সমর্থনের জন্য চেক করুন

আপনার ব্রাউজারটি সম্পূর্ণরূপে HTML5 ড্র্যাগ এবং ড্রপ সমর্থন করে কিনা তা পরীক্ষা করার জন্য প্রথম জিনিসটি। এটি করার একটি সহজ উপায় হল একটি নির্দিষ্ট বৈশিষ্ট্য পরীক্ষা করতে Modernizr নামক একটি লাইব্রেরি ব্যবহার করুন:

if (Modernizr.draganddrop) {
// Browser supports native HTML5 DnD.
} else {
// Fallback to a library solution.
}

পুনরাবৃত্তি ঘ

আমি প্রথমে জিমেইলে সেডন যে পদ্ধতিটি পেয়েছি তা চেষ্টা করেছি। আমি ফাইলগুলির লিঙ্কগুলিকে অ্যাঙ্কর করতে 'ডেটা-ডাউনলোডর্ল' নামে একটি নতুন বৈশিষ্ট্য যুক্ত করেছি। এই প্রক্রিয়াটি HTML5 এর কাস্টম ডেটা বৈশিষ্ট্য ব্যবহার করে। data-downloadurl-এ, আপনাকে ফাইলের MIME প্রকার, গন্তব্য ফাইলের নাম (ডাউনলোড করা ফাইলের পছন্দসই ফাইলের নাম) এবং ফাইলের ডাউনলোড URL অন্তর্ভুক্ত করতে হবে। এইভাবে, এটি HTML টেমপ্লেটে যোগ করা হয়েছে:

<a href="#" class="dnd"
data-downloadurl="{$item.mime}:{$item.filename}:{$item.url}"></a>

যা নিম্নলিখিত মত একটি আউটপুট তৈরি করবে:

<a href="#" class="dnd" data-downloadurl=
"image/jpeg:Penguins.jpg:https://www.box.net/box_download_file?file_id=f66690"></a>

ভন স্কোর্শ তৈরি করা একটি jQuery প্লাগইনের উপর ভিত্তি করে, যা Seddon এর নিবন্ধের উপর ভিত্তি করে, আমি একটি jQuery প্লাগইন যোগ করেছি যা ব্রাউজার বৈশিষ্ট্য সনাক্তকরণের কিছুটা কাজ করে। আমি ভন স্কোর্শের সংস্করণে যে লাইনগুলি যুক্ত করেছি তা হাইলাইট করা হয়েছে:

(function($) {

$.fn.extend({
dragout: function() {
var files = this;
if (files.length > 0) {
    $(files).each(function() {
    var url = (this.dataset && this.dataset.downloadurl) ||
                this.getAttribute("data-downloadurl");
    if (this.addEventListener) {
        this.addEventListener("dragstart", function(e) {
        if (e.dataTransfer && e.dataTransfer.constructor == Clipboard &&
            e.dataTransfer.setData('DownloadURL', 'http://www.box.net')) {
            e.dataTransfer.setData("DownloadURL", url);
        }
        },false);
    }
    });
}
}
});

})(jQuery);

আমি এটি করার কারণ হল পূর্বে ব্রাউজার সনাক্তকরণ ছাড়াই, IE-তে একটি HTML উপাদানে addEventListener() করলে একটি জাভাস্ক্রিপ্ট ত্রুটি তৈরি হবে কারণ IE তার নিজস্ব attachEvent() পদ্ধতি ব্যবহার করে। e.dataTransfer IE (এখন পর্যন্ত) অনির্ধারিত, e.dataTransfer.constructor Firefox (Mozilla) এ DataTransfer প্রদান করে, যখন Webkit ব্রাউজার (Chrome এবং Safari) ক্লিপবোর্ড কনস্ট্রাক্টরকে প্রয়োগ করে। Safari-এ, e.dataTransfer.setData('DownloadURL','http://www.box.net') মিথ্যা ফেরত দেয় এবং Chrome এই বিবৃতিটির জন্য সত্য ফেরত দেয়। উপরে উল্লিখিত সমস্ত পরীক্ষা করার ফলে বৈশিষ্ট্যটি শুধুমাত্র Chrome-এ উপলব্ধ থাকে। আপনি যুক্তি দিতে পারেন যে আমি কেবল নিম্নলিখিতগুলি করতে পারি:

/chrome/.test( navigator.userAgent.toLowerCase() )

কিন্তু আমি ব্রাউজার সনাক্তকরণের থেকে বৈশিষ্ট্য সনাক্তকরণ পছন্দ করি, যদিও এটি প্রযুক্তিগতভাবে সনাক্ত করে না যে DnD ডাউনলোড কাজ করবে।

পুনরাবৃত্তির সমস্যা 1

1) যেহেতু আমরা বর্তমানে ফোল্ডারগুলির মধ্যে ফাইলগুলি সরানোর/কপি করার জন্য অন-পৃষ্ঠা DnD সক্ষম করেছি, তাই আমাদের DnD ডাউনলোড এবং অন-পৃষ্ঠা DnD আলাদা করার একটি উপায় প্রয়োজন৷ প্রযুক্তিগতভাবে, আমরা এই দুটি ক্রিয়াকে একত্রিত করতে পারি না। আমরা ভবিষ্যদ্বাণী করতে পারি না যে ব্যবহারকারী Box.net অ্যাকাউন্টের মধ্যে একটি ফাইল অন্য ফোল্ডারে সরাতে চান বা এটিকে তাদের ডেস্কটপে টেনে আনতে চান। এই দুটি কর্ম সম্পূর্ণ ভিন্ন। তাছাড়া, কার্সার ব্রাউজার উইন্ডোর বাইরে আছে কিনা তা সনাক্ত করার কোন সহজ উপায় নেই। আপনি নথিতে মাউসআউট ইভেন্ট সংযুক্ত করতে window.onmouseout (IE) এবং document.onmouseout (অন্যান্য ব্রাউজার) ব্যবহার করতে পারেন এবং e.relatedTarget.nodeName == "HTML" (e mouseout ইভেন্ট বা window.event, যেটিই হোক না কেন তা পরীক্ষা করুন) সহজলভ্য). কিন্তু ঘটনা বুদবুদ কারণে এটি বেশ কঠিন. ইভেন্টটি এলোমেলোভাবে ট্রিগার হতে পারে যখন আপনি একটি চিত্র বা স্তরের উপরে থাকেন, বিশেষ করে Box.net এর মতো একটি জটিল ওয়েব অ্যাপে।

2) আমরা ব্যবহারকারীকে স্পষ্টভাবে কিছু করতে চাই যাতে তারা ভুল করে ডেস্কটপে কিছু টেনে আনতে না পারে। সম্ভবত, একটি বক্স ফোল্ডারের একজন সম্পাদক একটি এক্সিকিউটেবল ফাইল আপলোড করতে পারেন যা যে কেউ এটি ডাউনলোড করে তার কম্পিউটারে অবাঞ্ছিত কিছু করে। আমরা ব্যবহারকারীকে জানতে চাই যে কখন একটি ফাইল ডেস্কটপে ডাউনলোড করা হবে।

পুনরাবৃত্তি 2

আমরা নিয়ন্ত্রণ + টেনে নিয়ে পরীক্ষা করার সিদ্ধান্ত নিয়েছি (Windows Ctrl কী চাপলে একটি ফাইল টেনে আনা)। এই ক্রিয়াটি একটি ফাইলের নকল করতে উইন্ডোজ ডেস্কটপে লোকেরা যা করতে পারে তার সাথে সামঞ্জস্যপূর্ণ। ভুলবশত ফাইল ডাউনলোড হওয়া থেকে বিরত রাখতে ব্যবহারকারীর কাছ থেকে অতিরিক্ত কাজ (কিন্তু একটি অতিরিক্ত পদক্ষেপ নয়) প্রয়োজন।

পুনরাবৃত্তি 1-এ jQuery প্লাগইনটি এখন পরিত্যক্ত হয়েছে কারণ আমাদের অন-পৃষ্ঠা DnD-এর সাথে DnD ডাউনলোডকে শক্তভাবে সংহত করতে হবে। যারা আগ্রহী তাদের জন্য, আমরা jQuery UI এর ড্র্যাগেবল প্লাগইনের একটি পরিবর্তিত সংস্করণ ব্যবহার করি। একটি লক্ষ্য উপাদানের মাউসডাউন ইভেন্টের ভিতরে, আমরা নিম্নলিখিত কোড রাখি:

// DnD to desktop when the Ctrl key is pressed while dragging
if (e.ctrlKey) {
var that = $(e.target);
// make sure it is not IE (attachEvent).
if (that[0].addEventListener) {
    that[0].addEventListener("dragstart",function(e) {
        // e.dataTransfer in Firefox uses the DataTransfer constructor
        // instead of Clipboard
        // make sure it's Chrome and not Safari (both webkit-based).
        // setData on DownloadURL returns true on Chrome, and false on Safari
        if (e.dataTransfer && e.dataTransfer.constructor == Clipboard &&
            e.dataTransfer.setData('DownloadURL','http://www.box.net')) {
        var url = (this.dataset && this.dataset.downloadurl) ||
                    this.getAttribute("data-downloadurl");
        e.dataTransfer.setData("DownloadURL", url);
        }
    }, false);
    return;
}
}

Ctrl কী সক্রিয় করার পাশাপাশি, আমরা একটি ছোট টোস্টার টুলটিপও যোগ করেছি, যা ব্যবহারকারী যখন নিয়মিত অন-পেজ টেনে আনে তখন দেখায়। এটি ব্যবহারকারীকে বলে যে ফাইলগুলি ডাউনলোড করা যেতে পারে যদি ফাইল আইকনটি ডেস্কটপে টেনে আনা হয় যখন Ctrl কী রাখা হয়।

পুনরাবৃত্তির সমস্যা 2

নিরাপত্তা সংক্রান্ত উদ্বেগের কারণে, Box.net স্থায়ী ইউআরএল সরাসরি স্ট্যাটিক ফাইল অ্যাক্সেস করার জন্য প্রকাশ করে না। এটি Box.net এর জন্য অনন্য নয়। ফাইলটি সর্বজনীন কিনা এবং উপযুক্ত অনুমতি সহ ব্যবহারকারীর দ্বারা ইচ্ছাকৃত ডাউনলোডের জন্য অনুরোধ করা হয়েছে কিনা তা পরীক্ষা করার জন্য যেকোন অনলাইন স্টোরেজ পরিষেবার নিরাপত্তার একটি অতিরিক্ত স্তর ছাড়া স্থায়ী URL প্রকাশ করা উচিত নয়।

একটি আইটেমের "ডাউনলোড URL" (যেমন https://www.box.net/box_download_file?file_id=f_60466690 ) অনুসরণ করার সময়, এটি একটি "302 পাওয়া" স্ট্যাটাস কোড প্রদান করে এবং একটি এলোমেলো URL এ পুনঃনির্দেশ করে (যেমন https://www.box.net/dl/6045?a=1f1207a084&m=168299,11211&t=2&b=aca15820d924e3b ) এটি ফাইলের অস্থায়ী "প্রকৃত URL"৷ চ্যালেঞ্জ হল যে এটি প্রতি কয়েক মিনিটে মেয়াদ শেষ হয়ে যায়, এবং তাই এটিকে HTML আউটপুটে স্থাপন করা অব্যবহার্য। ব্যবহারকারী যখন কয়েক মিনিট আগে উত্পন্ন HTML আউটপুটে লিঙ্কে ফাইলটি ডাউনলোড করার চেষ্টা করে তখন এটি "404" ফেরত দিতে পারে।

DnD ডাউনলোড শুধুমাত্র প্রকৃত URL-এ কাজ করে যা সরাসরি কোনো সম্পদের দিকে নির্দেশ করে। যদি পুনঃনির্দেশ জড়িত থাকে তবে এটি বর্তমানে চেইন অনুসরণ করার জন্য যথেষ্ট স্মার্ট নয় (এবং নিরাপত্তার কারণে এটি কখনই চেইন অনুসরণ করা উচিত নয়)। অতএব, যদিও উপরের লিঙ্কটি https://www.box.net/box_download_file?file_id=f_60466690 আপনাকে ফাইলটি ডাউনলোড করতে দেয় যখন আপনি এটি ব্রাউজার অবস্থান বারে প্রবেশ করেন, এটি DnD এর সাথে কাজ করবে না।

একটি "প্রকৃত URL" এবং একটি "রিডাইরেক্ট URL" এর মধ্যে পার্থক্যগুলিকে আরও ভালভাবে বোঝাতে, স্ক্রিনশটগুলি দেখুন:

302 রিডাইরেক্ট ইউআরএল
302 রিডাইরেক্ট ইউআরএল
প্রকৃত URL
প্রকৃত URL

পুনরাবৃত্তি 3

এর Ajax চেষ্টা করা যাক.

আমরা পূর্ববর্তী পুনরাবৃত্তিতে কোডটি সামান্য পরিবর্তন করেছি এবং নিম্নলিখিতগুলি নিয়ে এসেছি:

// DnD to desktop when the Ctrl key is pressed while dragging
if (e.ctrlKey) {
var that = $(e.target);
// make sure it is not IE (attachEvent).
if (that[0].addEventListener) {
that[0].addEventListener("dragstart", function(e) {
    // e.dataTransfer in Firefox uses the DataTransfer constructor
    // instead of Clipboard
    // make sure it's Chrome and not Safari (both webkit-based).
    // setData on DownloadURL returns true on Chrome, and false on Safari
    if (e.dataTransfer && e.dataTransfer.constructor == Clipboard &&
        e.dataTransfer.setData('DownloadURL', 'http://www.box.net')) {
    var url = (this.dataset && this.dataset.downloadurl) ||
                this.getAttribute("data-downloadurl");
    $.ajax({
        complete: function(data) {
        e.dataTransfer.setData("DownloadURL", data.responseText);
        },
        type:'GET',
        url: url
    });
    }
}, false);
return;
}
}

এইবার বুঝতে পারছি. ড্র্যাগস্টার্ট করার পরে, এটি অবিলম্বে ফাইলটির সর্বশেষ ডাউনলোড URL পুনরুদ্ধার করতে সার্ভারে একটি Ajax কল করে। যাইহোক, এটা কাজ করে না।

দেখা যাচ্ছে যে এটি একটি সিঙ্ক্রোনাস কল হওয়া দরকার (বা আমি এটিকে কল করতে চাই, Sjax)। ইভেন্ট লিসেনার সংযুক্ত করার সময় সেটডেটা করতে হবে বলে মনে হচ্ছে। jQuery এর API অনুসারে, হাইলাইট করা লাইনগুলি হয়ে যায়:

$.ajax({
async: false,
complete: function(data) {
e.dataTransfer.setData("DownloadURL", data.responseText);
},
type: 'GET',
url: url
});

এবং আমি নেটওয়ার্ক সংযোগ আনপ্লাগ না করা পর্যন্ত এটি ভাল কাজ করে। যেহেতু এটি একটি সিঙ্ক্রোনাস কল করে, কলটি সফল না হওয়া পর্যন্ত ব্রাউজার হিমায়িত হয়। Ajax কল ব্যর্থ হলে (404, অথবা যদি এটি একেবারেই সাড়া না দেয়), ব্রাউজারটি একেবারেই ডিফ্রস্ট হবে না যেন এটি ক্র্যাশ হয়ে গেছে।

নিম্নলিখিত মত কিছু করা অনেক নিরাপদ:

$.ajax({
async: false,
complete: function(data) {
e.dataTransfer.setData("DownloadURL", data.responseText);
},
error: function(xhr) {
if (xhr.status == 404) {
    xhr.abort();
}
},
type: 'GET',
timeout: 3000,
url: url
});

এই বৈশিষ্ট্যের একটি ডেমোর জন্য, একটি Box.net অ্যাকাউন্টে একটি স্ট্যাটিক ফাইল আপলোড করুন। Ctrl কী ধরে রেখে ফাইল আইকনটিকে আপনার ডেস্কটপে টেনে আনুন। আপনার যদি একটি অ্যাকাউন্ট না থাকে, তবে এটি একটি তৈরি করতে আক্ষরিকভাবে 30 সেকেন্ডের কম সময় নেয়।

এই বৈশিষ্ট্যের সাহায্যে, আপনি সৃজনশীল হতে পারেন এবং অনেক কিছু সম্ভব করতে পারেন। একটি উইন্ডোজ প্রিন্টার ডায়ালগে একটি ইমেজ টেনে আনলে ছবি অবিলম্বে মুদ্রিত হবে। আপনি আপনার মোবাইল ফোনের ড্রাইভে বক্স থেকে একটি গান কপি করতে পারেন, আপনার বন্ধুর কাছে সরাসরি স্থানান্তর করার জন্য বক্স থেকে একটি ফাইল আপনার IM ক্লায়েন্টে টেনে আনতে পারেন... এটি আপনার উত্পাদনশীলতা বাড়ানোর জন্য অফুরন্ত সম্ভাবনার খোলে।

প্রিন্টারে একটি ফাইল র‍্যাগিং করা
প্রিন্টারে একটি ফাইল টেনে আনা।
IM ক্লায়েন্টে একটি ফাইল টেনে আনা হচ্ছে
IM ক্লায়েন্টে একটি ফাইল টেনে আনা হচ্ছে।

চিন্তাভাবনা, এবং ভবিষ্যতের উন্নতি

এটি এখনও আদর্শের চেয়ে কম, কারণ একটি সিঙ্ক্রোনাস কল একটি সংক্ষিপ্ত মুহুর্তের জন্য ব্রাউজারটিকে লক আপ করতে পারে৷ HTML 5 ওয়েব ওয়ার্কারও সাহায্য করে না, কারণ একজন ওয়েব ওয়ার্কারকে অ্যাসিঙ্ক্রোনাস হতে হবে। ইভেন্ট শ্রোতা সংযুক্ত করার সময় সেটডেটা করতে হবে বলে মনে হচ্ছে।

বাস্তবে, পারফরম্যান্সটি বেশ গ্রহণযোগ্য। সিঙ্ক্রোনাস Ajax (Sjax) কল শুধুমাত্র একটি URL স্ট্রিং পুনরুদ্ধার করে, যা খুব দ্রুত হওয়া উচিত। এটি HTTP হেডারে বড় ওভারহেড সহ আসে, যা সম্ভবত WebSockets দ্বারা সম্বোধন করা যেতে পারে। যাইহোক, যতক্ষণ না আমরা এই ধরনের প্রযুক্তির আরও ব্যবহার দেখতে পাচ্ছি, ক্লায়েন্টের কাছে প্রতিটি ছোট আপডেট পাঠানোর জন্য WebSockets ব্যবহার করা মূল্যবান নয়।

আমি আরও আশা করি যে মাল্টি-ফাইল ডাউনলোডের ক্ষমতা ভবিষ্যতে API-তে যোগ করা হবে। ব্যবহারকারী ইন্টারফেসে একাধিক ফাইল নির্বাচন করতে কাস্টম চেকবক্সের সাথে মিলিত, এটি অবিশ্বাস্য হবে। উপরন্তু, এটি আরও ভাল হবে যদি ক্লায়েন্ট-জেনারেটেড ফাইল, যেমন জমা দেওয়া ফর্মের ফলাফল থেকে তৈরি করা টেক্সট ফাইলগুলি এইভাবে ডাউনলোড করা যায়।

  • কলাম dnd
  • তালিকা পুনর্বিন্যাস করুন
  • একটি ইমেজ গ্যালারি তৈরি করা হচ্ছে
  • একটি ক্যানভাস ছবি রপ্তানি করা হচ্ছে

তথ্যসূত্র