בשלב הזה תלמדו:
- איך מקבלים הפניה לקובץ במערכת הקבצים החיצונית.
- איך לכתוב במערכת הקבצים.
הזמן המשוער לביצוע השלב הזה: 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 מכיל רק מאזין לקליק על הלחצן ייצוא לדיסק וקטעי קוד חלולים (stubs) עבור 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()
כדי לשמור את המשימות כטקסט באמצעות Web API של FileEntry
:
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
, אפשר לקרוא את המאמר Exploring the FileSystem APIs ב-HTML5Rocks, או לעיין במאמר FileEntry docs
ב-MDN.
שמירת אובייקטים מסוג FileEntry
מתקדם: אי אפשר לשמור אובייקטים מסוג FileEntry
ללא הגבלת זמן. האפליקציה צריכה לבקש מהמשתמש לבחור קובץ בכל פעם שהיא מופעלת. אם האפליקציה אולצה להתחיל מחדש בגלל קריסת זמן ריצה או עדכון, אפשר להשתמש ב-restoreEntry() כדי לשחזר FileEntry
.
אם רוצים, אפשר לנסות לשמור את המזהה שמוחזר על ידי retainEntry() ולשחזר אותו כשמפעילים מחדש את האפליקציה. (טיפ: מוסיפים listener לאירוע onRestarted
בדף הרקע).
הפעלת אפליקציית Todo שהשלמתם
סיימתם את שלב 6! טענו מחדש את האפליקציה והוסיפו כמה משימות. לוחצים על ייצוא לדיסק כדי לייצא את המשימות לקובץ .txt.
אפשר לקבל מידע נוסף
מידע מפורט יותר על חלק מממשקי ה-API שצוינו בשלב הזה זמין במאמרים הבאים:
- שימוש ב-Chrome Filesystem API ↑
- הצהרת הרשאות ↑
- chrome.storage.local.get() ↑
- chrome.fileSystem.chooseEntry() ↑
- chrome.fileSystem.getDisplayPath() ↑
- chrome.fileSystem.restoreEntry() ↑
- chrome.fileSystem.retainEntry() ↑
רוצה להמשיך לשלב הבא? עוברים אל שלב 7 – פרסום האפליקציה »