סקירה כללית של הארכיטקטורה

תוספים הם חבילות דחוסות של קובצי HTML,‏ CSS,‏ JavaScript, תמונות וקבצים אחרים שמשמשים בפלטפורמת האינטרנט, ומאפשרים להתאים אישית את חוויית הגלישה ב-Google Chrome. תוספים מבוססים על טכנולוגיות אינטרנט ויכולים להשתמש באותם ממשקי API שהדפדפן מספק לאינטרנט הפתוח.

התוספים מציעים מגוון רחב של אפשרויות פונקציונליות. הם יכולים לשנות את תוכן האינטרנט שהמשתמשים רואים ויוצרים איתו אינטראקציה, או להרחיב ולשנות את ההתנהגות של הדפדפן עצמו.

אפשר לחשוב על תוספים כעל שער שמאפשר להתאים אישית את דפדפן Chrome.

קבצים של הרחבות

התוספים שונים בסוגי הקבצים ובמספר הספריות, אבל כולם צריכים לכלול [מניפסט][docs-manifest]. תוספים בסיסיים, אבל שימושיים, יכולים לכלול רק את קובץ המניפסט ואת הסמל שלהם בסרגל הכלים.

קובץ המניפסט, שנקרא manifest.json, מספק לדפדפן מידע על התוסף, כמו הקבצים הכי חשובים והיכולות שהתוסף עשוי להשתמש בהן.

{
  "name": "My Extension",
  "version": "2.1",
  "description": "Gets information from Google.",
  "icons": {
    "128": "icon_16.png",
    "128": "icon_32.png",
    "128": "icon_48.png",
    "128": "icon_128.png"
  },
  "background": {
    "persistent": false,
    "scripts": ["background_script.js"]
  },
  "permissions": ["https://*.google.com/", "activeTab"],
  "browser_action": {
    "default_icon": "icon_16.png",
    "default_popup": "popup.html"
  }
}

לתוספים צריך להיות סמל שמופיע בסרגל הכלים של הדפדפן. הסמלים בסרגל הכלים מאפשרים גישה קלה ומעדכנים את המשתמשים לגבי התוספים המותקנים. רוב המשתמשים יקיימו אינטראקציה עם תוסף שמשתמש בחלון קופץ על ידי לחיצה על הסמל.

התוסף הזה של Google Mail Checker משתמש בפעולה בדפדפן:

צילום מסך של התוסף Google Mail Checker

התוסף Mappy הזה משתמש בפעולת דף ובסקריפט תוכן:

צילום מסך של התוסף Mappy

הפניה לקבצים

אפשר להפנות לקבצים של תוסף באמצעות כתובת URL יחסית, בדיוק כמו לקבצים בדף HTML רגיל.

<img src="images/my_image.png">

בנוסף, אפשר לגשת לכל קובץ גם באמצעות כתובת URL אבסולוטית.

chrome-extension://EXTENSION_ID/PATH_TO_FILE

בכתובת URL אבסולוטית, EXTENSION_ID הוא מזהה ייחודי שמערכת התוספים יוצרת לכל תוסף. כדי לראות את המזהים של כל התוספים שנטענו, עוברים לכתובת ה-URL chrome://extensions. ‫PATH_TO_FILE הוא המיקום של הקובץ בתיקייה העליונה של התוסף, והוא זהה לכתובת ה-URL היחסית.

בזמן עבודה על תוסף לא ארוז, מזהה התוסף יכול להשתנות. באופן ספציפי, המזהה של תוסף לא ארוז ישתנה אם התוסף ייטען מספרייה אחרת. המזהה ישתנה שוב כשהתוסף ייארז. אם הקוד של תוסף מסתמך על כתובת URL אבסולוטית, אפשר להשתמש בשיטה chrome.runtime.getURL() כדי להימנע מכתיבה בתוך הקוד של המזהה במהלך הפיתוח.

ארכיטקטורה

הארכיטקטורה של תוסף תלויה בפונקציונליות שלו, אבל הרבה תוספים חזקים יכללו כמה רכיבים:

סקריפט ברקע

סקריפט הרקע הוא גורם מטפל באירועים בתוסף. הוא מכיל listeners לאירועים בדפדפן שחשובים לתוסף. הוא נשאר במצב לא פעיל עד שמופעל אירוע, ואז הוא מבצע את הלוגיקה שהוגדרה לו. סקריפט רקע יעיל נטען רק כשצריך אותו, ומוסר מהזיכרון כשהוא לא פעיל.

רכיבים בממשק המשתמש

ממשק המשתמש של התוסף צריך להיות ממוקד ומינימלי. ממשק המשתמש צריך להתאים אישית את חוויית הגלישה או לשפר אותה, בלי להסיח את הדעת ממנה. לרוב התוספים יש פעולה בדפדפן או פעולה בדף, אבל הם יכולים להכיל צורות אחרות של ממשק משתמש, כמו תפריטי הקשר, שימוש בסרגל הכתובות או יצירה של מקשי קיצור.

דפים בממשק המשתמש של התוסף, כמו חלון קופץ, יכולים להכיל דפי HTML רגילים עם לוגיקה של JavaScript. תוספים יכולים גם להפעיל את tabs.create או window.open() כדי להציג קובצי HTML נוספים שקיימים בתוסף.

תוסף שמשתמש בפעולת דף ובפריט קופץ יכול להשתמש ב-API של הצהרת תוכן כדי להגדיר כללים בסקריפט הרקע לגבי המקרים שבהם הפריט הקופץ זמין למשתמשים. כשהתנאים מתקיימים, סקריפט הרקע מתקשר עם החלון הקופץ כדי שהמשתמשים יוכלו ללחוץ על הסמל שלו.

חלון דפדפן שמכיל פעולת דף שמוצג בה חלון קופץ

סקריפטים של תוכן

תוספים שקוראים דפי אינטרנט או כותבים בהם משתמשים בסקריפט תוכן. סקריפט התוכן מכיל JavaScript שמופעל בהקשרים של דף שנטען בדפדפן. סקריפטים של תוכן קוראים את ה-DOM של דפי אינטרנט שהדפדפן מבקר בהם ומשנים אותו.

חלון דפדפן עם פעולת דף וסקריפט תוכן

סקריפטים של תוכן יכולים לתקשר עם תוסף האב שלהם באמצעות החלפת הודעות ואחסון ערכים באמצעות storage API.

הצגת נתיב תקשורת בין סקריפט התוכן לבין תוסף האב

דף האפשרויות

כמו שתוספים מאפשרים למשתמשים להתאים אישית את דפדפן Chrome, דף האפשרויות מאפשר התאמה אישית של התוסף. אפשר להשתמש באפשרויות כדי להפעיל תכונות ולאפשר למשתמשים לבחור את הפונקציונליות שרלוונטית לצרכים שלהם.

שימוש בממשקי Chrome API

בנוסף לגישה לאותם ממשקי API כמו דפי אינטרנט, תוספים יכולים גם להשתמש בממשקי API ספציפיים לתוספים שיוצרים שילוב הדוק עם הדפדפן. גם תוספים וגם דפי אינטרנט יכולים לגשת לשיטה הרגילה window.open() כדי לפתוח כתובת URL, אבל תוספים יכולים לציין באיזה חלון כתובת ה-URL תוצג באמצעות השיטה tabs.create של Chrome API.

שיטות אסינכרוניות לעומת שיטות סינכרוניות

רוב ה-methods ב-Chrome API הם אסינכרוניים: הם מחזירים ערך באופן מיידי בלי לחכות שהפעולה תסתיים. אם תוסף צריך לדעת את התוצאה של פעולה אסינכרונית, הוא יכול להעביר פונקציית קריאה חוזרת לשיטה. הקריאה החוזרת מבוצעת מאוחר יותר, יכול להיות הרבה יותר מאוחר, אחרי שהשיטה מחזירה ערך.

אם התוסף צריך להפנות את הכרטיסייה הנוכחית שהמשתמש בחר לכתובת URL חדשה, הוא צריך לקבל את המזהה של הכרטיסייה הנוכחית ואז לעדכן את הכתובת של הכרטיסייה לכתובת ה-URL החדשה.

אם השיטה tabs.query הייתה סינכרונית, היא הייתה נראית בערך כמו הקוד שבהמשך.

//THIS CODE DOESN'T WORK
var tab = chrome.tabs.query({'active': true}); //WRONG!!!
chrome.tabs.update(tab.id, {url:newUrl});
someOtherFunction();

הגישה הזו תיכשל כי query() היא אסינכרונית. היא מחזירה ערך בלי לחכות לסיום העבודה, ולא מחזירה ערך. שיטה היא אסינכרונית אם פרמטר הקריאה החוזרת זמין בחתימה שלה.

// Signature for an asynchronous method
chrome.tabs.query(object queryInfo, function callback)

כדי לשלוח שאילתה לכרטיסייה ולעדכן את כתובת ה-URL שלה בצורה נכונה, התוסף צריך להשתמש בפרמטר הקריאה החוזרת (callback).

//THIS CODE WORKS
chrome.tabs.query({'active': true}, function(tabs) {
  chrome.tabs.update(tabs[0].id, {url: newUrl});
});
someOtherFunction();

בקוד שלמעלה, השורות מופעלות בסדר הבא: 1, 4, 2. פונקציית הקריאה החוזרת שצוינה ב-query() נקראת ואז שורה 2 מופעלת, אבל רק אחרי שמידע על הכרטיסייה שנבחרה כרגע זמין. הפעולה הזו מתרחשת זמן מה אחרי שהפונקציה query() מחזירה ערך. למרות ש-update() הוא אסינכרוני, הקוד לא משתמש בפרמטר של קריאה חוזרת, כי התוסף לא עושה שום דבר עם תוצאות העדכון.

// Synchronous methods have no callback option and returns a type of string
string chrome.runtime.getURL()

השיטה הזו מחזירה באופן סינכרוני את כתובת ה-URL כ-string ולא מבצעת עבודה אסינכרונית אחרת.

פרטים נוספים

מידע נוסף מופיע במסמכי הפניית API של Chrome ובסרטון הבא.

תקשורת בין דפים

לרוב, רכיבים שונים בתוסף צריכים לתקשר ביניהם. דפי HTML שונים יכולים למצוא אחד את השני באמצעות השיטות chrome.extension, כמו getViews() ו-getBackgroundPage(). אחרי שדף מסוים מפנה לדפים אחרים של התוסף, הדף הראשון יכול להפעיל פונקציות בדפים האחרים ולשנות את ה-DOM שלהם. בנוסף, כל הרכיבים של התוסף יכולים לגשת לערכים שמאוחסנים באמצעות storage API ולתקשר באמצעות message passing.

שמירת נתונים ומצב פרטי

תוספים יכולים לשמור נתונים באמצעות storage API,‏ web storage API של HTML5 או על ידי שליחת בקשות לשרת שגורמות לשמירת נתונים. כשהתוסף צריך לשמור משהו, קודם צריך לבדוק אם הוא מחלון פרטי. כברירת מחדל, תוספים לא פועלים בחלונות פרטיים.

מצב פרטי מבטיח שלא יישארו עקבות של הפעילות בחלון. כשמטפלים בנתונים מחלונות פרטיים, התוספים צריכים לכבד את ההבטחה הזו. אם תוסף בדרך כלל שומר את היסטוריית הגלישה, הוא לא ישמור את ההיסטוריה מחלונות פרטיים. עם זאת, תוספים יכולים לאחסן העדפות הגדרה מכל חלון, פרטי או לא.

כדי לזהות אם חלון נמצא במצב פרטי, בודקים את המאפיין incognito של האובייקט הרלוונטי tabs.Tab או windows.Window.

function saveTabData(tab) {
  if (tab.incognito) {
    return;
  } else {
    chrome.storage.local.set({data: tab.url});
  }
}

עבור לשלב הבא

אחרי שתקראו את הסקירה הכללית ותשלימו את המדריך תחילת העבודה, המפתחים יהיו מוכנים להתחיל לכתוב תוספים משלהם. כדי להעמיק את הידע על התאמה אישית של Chrome, אפשר לעיין במקורות המידע הבאים.