الخطوة 6: تصدير المهام إلى نظام الملفات

في هذه الخطوة، ستتعلم ما يلي:

  • كيف يمكن الحصول على مرجع إلى ملف في نظام الملفات الخارجي.
  • كيفية الكتابة إلى نظام الملفات.

الوقت المقدَّر لإكمال هذه الخطوة: 20 دقيقة.
لمعاينة ما ستكمله في هذه الخطوة، انتقِل إلى أسفل هذه الصفحة ↓.

تصدير المهام

تؤدي هذه الخطوة إلى إضافة زر تصدير إلى التطبيق. عند النقر عليها، يتم حفظ عناصر المهام الحالية في ملف نصي يختاره المستخدم. إذا كان الملف موجودًا، يتم استبداله. وإلا، يتم إنشاء ملف جديد.

تحديث الأذونات

يمكن طلب أذونات نظام الملفات كسلسلة للوصول للقراءة فقط أو ككائن ذي خصائص إضافية. مثال:

// Read only
"permissions": ["fileSystem"]

// Read and write
"permissions": [{"fileSystem": ["write"]}]

// Read, write, autocomplate previous input, and select folder directories instead of files
"permissions": [{"fileSystem": ["write", "retainEntries", "directory"]}]

يجب أن يكون لديك إذن بالقراءة والكتابة. في manifest.json، يمكنك طلب إذن {fileSystem: [ "write" ] }:

"permissions": [
  "storage", 
  "alarms", 
  "notifications", 
  "webview",
  "<all_urls>", 
  { "fileSystem": ["write"] } 
],

تعديل عرض HTML

في index.html، أضِف الزر تصدير إلى القرص والزر div حيث يعرض التطبيق رسالة حالة:

<footer id="info">
  <button id="toggleAlarm">Activate alarm</button>
  <button id="exportToDisk">Export to disk</button>
  <div id="status"></div>
  ...
</footer>

في index.html أيضًا، حمِّل النص البرمجي export.js:

...
<script src="js/alarms.js"></script>
<script src="js/export.js"></script>

إنشاء نص برمجي للتصدير

أنشئ ملف JavaScript جديدًا باسم export.js باستخدام الرمز أدناه. احفظه في مجلد js.

(function() {

  var dbName = 'todos-vanillajs';

  var savedFileEntry, fileDisplayPath;

  function getTodosAsText(callback) {
  }

  function exportToFileEntry(fileEntry) {
  }

  function doExportToDisk() {
  }

  document.getElementById('exportToDisk').addEventListener('click', doExportToDisk);

})();

في الوقت الحالي، يحتوي الملف export.js على أداة معالجة النقرات فقط على الزر تصدير إلى القرص وكبائن دعم getTodosAsText() وexportToFileEntry وdoExportToDisk().

الحصول على عناصر المهام كنص

عدِّل getTodosAsText() بحيث تتم قراءة المهام من chrome.storage.local وإنشاء تمثيل نصي لها:

function getTodosAsText(callback) {
  chrome.storage.local.get(dbName, function(storedData) {
    var text = '';

    if ( storedData[dbName].todos ) {
      storedData[dbName].todos.forEach(function(todo) {
          text += '- ';
          if ( todo.completed ) {
            text += '[DONE] ';
          }
          text += todo.title;
          text += '\n';
        }, '');
    }

    callback(text);

  }.bind(this));
}

اختيار ملف

يمكنك تحديث doExportToDisk() باستخدام chrome.fileSystem.chooseEntry() للسماح للمستخدم باختيار ملف:

function doExportToDisk() {

  if (savedFileEntry) {

    exportToFileEntry(savedFileEntry);

  } else {

    chrome.fileSystem.chooseEntry( {
      type: 'saveFile',
      suggestedName: 'todos.txt',
      accepts: [ { description: 'Text files (*.txt)',
                   extensions: ['txt']} ],
      acceptsAllTypes: true
    }, exportToFileEntry);

  }
}

المعلمة الأولى لـ chrome.fileSystem.chooseEntry() هي كائن من الخيارات. المعلمة الثانية هي طريقة رد اتصال.

إذا سبق أن حفظت FileEntry، يمكنك استخدامها بدلاً من ذلك عند الاتصال بـ exportToFileEntry(). تتوفّر مراجع الملفات عمر الكائن الذي يمثّل FileEntry. يربط هذا المثال FileEntry بنافذة التطبيق لكي يتمكن رمز JavaScript من الكتابة إلى الملف المحدّد بدون أي تفاعل من جانب المستخدم طالما ظلت نافذة التطبيق مفتوحة.

استخدام FileEntry (إدخال الملفات) لكتابة عناصر المهام على القرص

يمكنك تحديث exportToFileEntry() لحفظ المهام كنص عبر FileEntry Web API:

function exportToFileEntry(fileEntry) {
  savedFileEntry = fileEntry;

  var status = document.getElementById('status');

  // Use this to get a file path appropriate for displaying
  chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
    fileDisplayPath = path;
    status.innerText = 'Exporting to '+path;
  });

  getTodosAsText( function(contents) {

    fileEntry.createWriter(function(fileWriter) {

      var truncated = false;
      var blob = new Blob([contents]);

      fileWriter.onwriteend = function(e) {
        if (!truncated) {
          truncated = true;
          // You need to explicitly set the file size to truncate
          // any content that might have been there before
          this.truncate(blob.size);
          return;
        }
        status.innerText = 'Export to '+fileDisplayPath+' completed';
      };

      fileWriter.onerror = function(e) {
        status.innerText = 'Export failed: '+e.toString();
      };

      fileWriter.write(blob);

    });
  });
}

تحصل chrome.fileSystem.getDisplayPath() على مسار ملف قابل للعرض ويؤدّي إلى الحالة div.

استخدِم fileEntry.createWriter() لإنشاء عنصر FileWriter. يمكن لـ fileWriter.write() بعد ذلك كتابة Blob لنظام الملفات. يمكنك استخدام fileWriter.onwriteend() وfileWriter.onerror() لتعديل الحالة div.

لمزيد من المعلومات حول FileEntry، يُرجى قراءة استكشاف واجهات برمجة التطبيقات FileSystem على HTML5Rocks، أو الرجوع إلى FileEntry docs على MDN.

الاحتفاظ بكائنات إدخال الملفات

متقدّم: لا يمكن الاحتفاظ بكائنات FileEntry إلى أجل غير مسمى. يحتاج تطبيقك إلى مطالبة المستخدم باختيار ملف في كل مرة يتم فيها تشغيل التطبيق. إذا تم فرض إعادة تشغيل تطبيقك بسبب تعطُّله أو تحديثه في وقت التشغيل، يكون restoreEntry() خيارًا لاستعادة FileEntry.

يمكنك تجربة حفظ رقم التعريف الذي يعرضه retainEntry() واستعادته عند إعادة تشغيل التطبيق إذا أردت ذلك. (تلميح: أضِف أداة معالجة إلى حدث onRestarted في صفحة الخلفية).

تشغيل تطبيق Todo المكتمل

لقد انتهيت من الخطوة 6! أعِد تحميل تطبيقك وأضِف بعض المهام. انقر على تصدير إلى القرص لتصدير المهام إلى ملف .txt.

تطبيق Todo الذي يتضمّن المهام التي تم تصديرها

لمزيد من المعلومات

للحصول على معلومات أكثر تفصيلاً حول بعض واجهات برمجة التطبيقات التي تم تقديمها في هذه الخطوة، يُرجى الرجوع إلى:

هل أنت جاهز للمتابعة إلى الخطوة التالية؟ الانتقال إلى الخطوة 7: نشر التطبيق »