התאמה אישית של שכבת-העל של פקדי החלון בסרגל הכותרת של PWA'

השתמשו באזור של סרגל הכותרת ליד פקדי החלונות כדי שה-PWA תהיה דומה יותר לאפליקציה.

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

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

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

רכיבי שכבת-על של פקדי החלונות

שכבת-העל של פקדי החלונות כוללת ארבע תכונות משנה:

  1. הערך "window-controls-overlay" עבור השדה "display_override" ב- את המניפסט של אפליקציית האינטרנט.
  2. משתני הסביבה של ה-CSS: titlebar-area-x, titlebar-area-y, titlebar-area-width ו- titlebar-area-height
  3. סטנדרטיזציה של נכס ה-CSS שבבעלותו הקודם, -webkit-app-region, בתור מאפיין app-region להגדרת אזורים שניתנים לגרירה בתוכן אינטרנט.
  4. מנגנון לשליחת שאילתות לגבי אזור הבקרה של החלונות ולעקוף אותו באמצעות האופרטור windowControlsOverlay חבר בקבוצה window.navigator.

מהי שכבת-על של פקדי החלונות

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

הסטטוס הנוכחי

שלב סטטוס
1. יצירת הסבר הושלם
2. יצירת טיוטה ראשונית של מפרט הושלם
3. איסוף משוב לבצע איטרציה בעיצוב בתהליך
4. גרסת מקור לניסיון התשובה מלאה
5. הפעלה הושלם (ב-Chromium 104)

איך משתמשים בשכבת-על של פקדי החלונות

מתבצעת הוספה של window-controls-overlay למניפסט של אפליקציית האינטרנט

Progressive Web App יכולה להצטרף לשכבת-העל של פקדי החלונות על ידי הוספה של "window-controls-overlay" כחבר/ה הראשי/ת "display_override" בקובץ המניפסט של אפליקציית האינטרנט:

{
  "display_override": ["window-controls-overlay"]
}

שכבת-העל של פקדי החלונות תהיה גלויה רק אם כל התנאים הבאים יתקיימו:

  1. האפליקציה לא פתוחה בדפדפן, אלא בחלון PWA נפרד.
  2. המניפסט כולל "display_override": ["window-controls-overlay"]. (ערכים אחרים הם מותר לאחר מכן.)
  3. אפליקציית ה-PWA פועלת במערכת הפעלה למחשב.
  4. המקור הנוכחי תואם למקור שעבורו הותקנה ה-PWA.

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

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

העברת תוכן לסרגל הכותרת

עכשיו, שיש מקום בסרגל הכותרת, אפשר להעביר לשם משהו. במאמר הזה, יצר PWA של תוכן מוצג ב-Wikimedia. תכונה שימושית לאפליקציה הזו יכולה להיות חיפוש מילים כותרות המאמרים. ה-HTML של תכונת החיפוש נראה כך:

<div class="search">
  <img src="logo.svg" alt="Wikimedia logo." width="32" height="32" />
  <label>
    <input type="search" />
    Search for words in articles
  </label>
</div>

כדי להעביר את div למעלה לסרגל הכותרת, יש צורך בשירות CSS:

.search {
  /* Make sure the `div` stays there, even when scrolling. */
  position: fixed;
  /**
   * Gradient, because why not. Endless opportunities.
   * The gradient ends in `#36c`, which happens to be the app's
   * `<meta name="theme-color" content="#36c">`.
   */
  background-image: linear-gradient(90deg, #36c, #131313, 33%, #36c);
  /* Use the environment variable for the left anchoring with a fallback. */
  left: env(titlebar-area-x, 0);
  /* Use the environment variable for the top anchoring with a fallback. */
  top: env(titlebar-area-y, 0);
  /* Use the environment variable for setting the width with a fallback. */
  width: env(titlebar-area-width, 100%);
  /* Use the environment variable for setting the height with a fallback. */
  height: env(titlebar-area-height, 33px);
}

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

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

החלטה אילו חלקים של סרגל הכותרת ניתנים לגרירה

בצילום המסך שלמעלה רואים שסיימתם, אבל עדיין לא סיימתם. חלון ה-PWA הוא לא ניתנים עוד לגרירה (חוץ מאזור קטן מאוד), מכיוון שלחצני פקדי החלונות לא גוררים ושאר סרגל הכותרת מורכב מווידג'ט החיפוש. תיקון הבעיה באמצעות מאפיין ה-CSS app-region עם הערך drag. במקרה קונקרטי, זה בסדר ליצור כל מה מלבד הרכיב input שניתן לגרירה.

/* The entire search `div` is draggable… */
.search {
  -webkit-app-region: drag;
  app-region: drag;
}

/* …except for the `input`. */
input {
  -webkit-app-region: no-drag;
  app-region: no-drag;
}

כששירות CSS הזה במקומו, המשתמש יכול לגרור את חלון האפליקציה כרגיל על ידי גרירת div, ה-img, או label. רק הרכיב input הוא אינטראקטיבי, לכן אפשר להזין את שאילתת החיפוש.

זיהוי תכונות

ניתן לזהות תמיכה בשכבת-על של פקדי החלונות על ידי בדיקת קיומו של windowControlsOverlay:

if ('windowControlsOverlay' in navigator) {
  // Window Controls Overlay is supported.
}

שליחת שאילתה לגבי אזור הבקרה של החלון באמצעות windowControlsOverlay

עד כה יש בקוד בעיה אחת: בפלטפורמות מסוימות, פקדי החלונות נמצאים בצד שמאל, במצב מופעל אחרים הם משמאל. כדי להחמיר את העניין, שלוש הנקודות תפריט Chrome ישתנה גם לפי הפלטפורמה. זה אומר שתמונת הרקע ההדרגתית הלינארית צריכה להתאים באופן דינמי להרצה מ-#131313maroon או maroon#131313maroon, כדי משתלב עם צבע הרקע maroon של שורת הכותרת, שנקבע לפי <meta name="theme-color" content="maroon">. כדי לעשות את זה, API של getTitlebarAreaRect() בנכס navigator.windowControlsOverlay.

if ('windowControlsOverlay' in navigator) {
  const { x } = navigator.windowControlsOverlay.getTitlebarAreaRect();
  // Window controls are on the right (like on Windows).
  // Chrome menu is left of the window controls.
  // [ windowControlsOverlay___________________ […] [_] [■] [X] ]
  if (x === 0) {
    div.classList.add('search-controls-right');
  }
  // Window controls are on the left (like on macOS).
  // Chrome menu is right of the window controls overlay.
  // [ [X] [_] [■] ___________________windowControlsOverlay [⋮] ]
  else {
    div.classList.add('search-controls-left');
  }
} else {
  // When running in a non-supporting browser tab.
  div.classList.add('search-controls-right');
}

במקום להוסיף את תמונת הרקע בכללי ה-CSS של הכיתה .search ישירות (כמו קודם), בקוד שהשתנה, נעשה עכשיו שימוש בשני מחלקות שהקוד שלמעלה מגדיר באופן דינמי.

/* For macOS: */
.search-controls-left {
  background-image: linear-gradient(90deg, #36c, 45%, #131313, 90%, #36c);
}

/* For Windows: */
.search-controls-right {
  background-image: linear-gradient(90deg, #36c, #131313, 33%, #36c);
}

איך להחליט אם שכבת-העל של פקדי החלונות גלויה

שכבת-העל של פקדי החלונות לא תהיה גלויה באזור סרגל הכותרת בכל מצב. אומנם בדרך כלל לא יופיעו בדפדפנים שלא תומכים בתכונה 'שכבת-על של פקדי חלונות', לא יהיו גם כשה-PWA הרלוונטית תרוץ בכרטיסייה. כדי לזהות את המצב הזה, אפשר שולחים שאילתה על המאפיין visible של windowControlsOverlay:

if (navigator.windowControlsOverlay.visible) {
  // The window controls overlay is visible in the title bar area.
}

לחלופין, אפשר גם להשתמש בשאילתת המדיה display-mode ב-JavaScript או ב-CSS:

// Create the query list.
const mediaQueryList = window.matchMedia('(display-mode: window-controls-overlay)');

// Define a callback function for the event listener.
function handleDisplayModeChange(mql) {
  // React on display mode changes.
}

// Run the display mode change handler once.
handleDisplayChange(mediaQueryList);

// Add the callback function as a listener to the query list.
mediaQueryList.addEventListener('change', handleDisplayModeChange);
@media (display-mode: window-controls-overlay) { 
  /* React on display mode changes. */ 
}

קבלת התראות על שינויים בגיאומטריה

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

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

אפשר לקבל התראות על שינויים בגיאומטריה באמצעות הרשמה אל navigator.windowControlsOverlay.ongeometrychange או על ידי הגדרה של האזנה לאירועים אירוע geometrychange. האירוע הזה יופעל רק כששכבת-העל של פקדי החלונות גלויה, כאשר navigator.windowControlsOverlay.visible הוא true.

const debounce = (func, wait) => {
  let timeout;
  return function executedFunction(...args) {
    const later = () => {
      clearTimeout(timeout);
      func(...args);
    };
    clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
};

if ('windowControlsOverlay' in navigator) {
  navigator.windowControlsOverlay.ongeometrychange = debounce((e) => {
    span.hidden = e.titlebarAreaRect.width < 800;
  }, 250);
}

במקום להקצות פונקציה ל-ongeometrychange, אפשר גם להוסיף פונקציות event listener windowControlsOverlay כמו שמתואר בהמשך. אפשר לקרוא על ההבדל בין השניים בכתובת MDN

navigator.windowControlsOverlay.addEventListener(
  'geometrychange',
  debounce((e) => {
    span.hidden = e.titlebarAreaRect.width < 800;
  }, 250),
);

תאימות להפעלה בכרטיסייה ובדפדפנים שאינם תומכים

יש שני מקרים אפשריים:

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

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

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

כתזכורת, דפדפנים שאינם תומכים לא יתייחסו נכס "display_override" בקובץ המניפסט של אפליקציית האינטרנט, או שאינו מזהה את הנכס "window-controls-overlay" ולכן משתמשים בערך האפשרי הבא בהתאם לשרשרת החלופית, לדוגמה, "standalone".

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

שיקולים בקשר לממשק המשתמש

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

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

הדגמה (דמו)

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

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

תכונת החיפוש בשכבת-העל של פקדי החלונות פועלת באופן מלא:

אפליקציית ההדגמה של תוכן מוצג ב-Wikimedia עם שכבת-על של פקדי החלונות וחיפוש פעיל אחר המונח &#39;cleopa...&#39; הדגשה של אחד מהמאמרים עם המונח התואם &#39;קליאופטרה&#39;.
תכונת חיפוש באמצעות שכבת-על של פקדי החלונות.

שיקולי אבטחה

צוות Chromium עיצב והטמיע את window Controls Overlay API באמצעות עקרונות הליבה מוגדרת בקטע שליטה בגישה לתכונות מתקדמות של פלטפורמת אינטרנט, כולל משתמשים שליטה, שקיפות וארגונומיה.

זיוף

אם נותנים לאתרים שליטה חלקית בסרגל הכותרת, מפתחים יכולים לזייף תוכן היה בעבר אזור מהימן שנשלט על ידי הדפדפן. נכון לעכשיו, בדפדפני Chromium, מודעות עצמאיות כולל סרגל כותרת שבהפעלה הראשונית מציג את כותרת דף האינטרנט בצד שמאל, מקור הדף בצד ימין (ולאחר מכן הלחצן 'הגדרות ועוד' והחלון ). אחרי כמה שניות, טקסט המקור ייעלם. אם הדפדפן מוגדר מימין לשמאל (RTL), הפריסה הזו הופכת כך שטקסט המקור מופיע בצד ימין. פעולה זו פותחת את שכבת-על של פקדי חלונות כדי לזייף את המקור אם אין מספיק מרווח בין המקור בקצה הימני של שכבת-העל. לדוגמה, המקור 'evil.ltd' ניתן לצרף אל איש קשר מהימן האתר google.com, ולגרום למשתמשים להאמין שהמקור מהימן. התוכנית היא לשמור טקסט המקור, כדי שהמשתמשים יידעו מה מקור האפליקציה ויוכלו להבטיח שהיא תואמת לציפיות שלכם. בדפדפנים שבהם מוגדר RTL, צריך להיות מספיק מרווח פנימי מימין למקור. טקסט כדי למנוע מאתר זדוני לצרף את המקור הלא בטוח עם מקור מהימן.

יצירה של טביעת אצבע דיגיטלית (fingerprinting)

הפעלת שכבת-העל של פקדי החלונות והאזורים שניתנים לגרירה לא יוצרים מצב חשש משמעותי בנוגע לפרטיות, מלבד זיהוי תכונות. עם זאת, עקב גדלים ומיקומים שונים של הלחצנים של פקדי החלונות המערכות שלנו, navigator.windowControlsOverlay.getTitlebarAreaRect() מחזירה DOMRect שהמיקום והמידות שלו חושפים מידע על מערכת ההפעלה שהדפדפן פועל. נכון לעכשיו, מפתחים כבר יכולים לגלות את מערכת ההפעלה מהמחרוזת של סוכן המשתמש, אבל בגלל חששות ליצירה של טביעת אצבע דיגיטלית (fingerprinting), דיון על הקפאת המחרוזת של UA ואיחוד גרסאות מערכת ההפעלה. קיימת במאמץ מתמשך בתוך קהילת הדפדפנים כדי להבין את התדירות שבה גודל שכבת-העל של פקדי החלונות משתנה בין פלטפורמות, כאשר ההנחה היא שהן יציבות למדי בכל הגרסאות של מערכת ההפעלה, ולכן לא שימושי לצפייה בגרסאות מערכת הפעלה משניות. למרות שמדובר בפוטנציאל יצירה של טביעת אצבע דיגיטלית (fingerprinting), היא רלוונטית רק לאפליקציות PWA מותקנות שמשתמשות של סרגל הכותרת והיא לא חלה על שימוש כללי בדפדפן. בנוסף, navigator.windowControlsOverlay API לא יהיה זמין מסגרות iframe שמוטמעות בתוך PWA.

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

סרגל כתובות URL שחור לניווט מחוץ למקור.
סרגל שחור מוצג כשהמשתמש מנווט למקור אחר.

משוב

צוות Chromium רוצה לשמוע על חוויית השימוש שלך ב-Window Controls Overlay API.

מתארים את עיצוב ה-API

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

דיווח על בעיה בהטמעה

מצאת באג בהטמעה של Chromium? או שההטמעה שונה מהמפרט? דווחו על באג בכתובת new.crbug.com. כדאי לכלול כמה שיותר פרטים, לפי ההוראות הפשוטות לשחזור, ומזינים UI>Browser>WebAppInstalls בקטע רכיבים . Glitch היא אפשרות טובה לשיתוף תגובות מהירות וקלות.

הצגת תמיכה ב-API

האם בכוונתך להשתמש ב-Window Controls Overlay API? התמיכה הציבורית שלך עוזרת לצוות Chromium כדי לתת עדיפות לתכונות, ולהראות לספקי דפדפנים אחרים עד כמה זה קריטי לתמוך בהם.

שליחת ציוץ אל @ChromiumDev עם #WindowControlsOverlay hashtag, ומציינים איפה ואיך משתמשים בו.

קישורים שימושיים

אישורים

שכבת-העל של פקדי החלונות יושמה וצוינה על ידי Amanda Baker מצוות Microsoft Edge. המאמר הזה נבדק על ידי ג'ו מדלי קן רודה כריסטיאנסן. תמונה ראשית (Hero) מאת Sigmund ב-Unbounce.