1 module uim.html.apps.manifest; 2 3 import uim.html; 4 5 class DH5AppManifest : DH5AppObj { 6 this() { super(); } 7 this(DH5App anApp) { this().app(anApp); } 8 this(string aName) { this().name(aName); } 9 this(DH5App anApp, string aName) { this().app(anApp).name(aName); } 10 11 /** 12 * backgroundColor 13 * Type: string 14 * Description: A placeholder background color for the application page to display before its stylesheet is loaded. 15 * This value is used by the user agent to draw the background color of a shortcut when the manifest is available before the stylesheet has loaded. 16 */ 17 mixin(OProperty!("string", "backgroundColor")); 18 unittest { 19 assert(H5AppManifest.backgroundColor("blue").backgroundColor == "blue"); 20 assert(H5AppManifest.backgroundColor("blue").backgroundColor("red").backgroundColor == "red"); 21 } 22 23 /** 24 * categories - defining the names of categories that the application supposedly belongs to. 25 * Examples for categories (W3C) are "books", "business", "education", "entertainment", "finance", "fitness", 26 * "food", "games", "government", "health", "kids", "lifestyle", "magazines", "medical", "music", "navigation", 27 * "news", "personalization", "photo", "politics", "productivity", "security", "shopping", "social", "sports", 28 * "travel", "utilities", "weather" and vendor-specific values. 29 */ 30 protected string[] _categories; 31 /* protected O category(this O)(string addCategory) { if (!_categories.has(addCategory)) _categories ~= addCategory; return cast(O)this; } 32 /// Work with categories 33 auto categories() { return _categories; } 34 O categories(this O)(string[] addCategories...) { foreach(cat; addCategories) this.category(cat); return cast(O)this; } 35 O categories(this O)(string[] addCategories) { foreach(cat; addCategories) this.category(cat); return cast(O)this; } 36 O clearCategories(this O)() { _categories = null; return cast(O)this; } 37 unittest { 38 assert(H5AppManifest.categories(["tool", "www"]).categories == ["tool", "www"]); 39 assert(H5AppManifest.categories(["tool", "www"]).categories("map").categories == ["tool", "www", "map"]); 40 } 41 */ 42 /** 43 * description - string in which developers can explain what the application does. 44 * description is directionality-capable 45 */ 46 mixin(OProperty!("string", "description")); 47 unittest { 48 assert(H5AppManifest.description("This is an app").description == "This is an app"); 49 assert(H5AppManifest.description("This is an app").description("This is a second app").description == "This is a second app"); 50 } 51 52 /** 53 * dir - base direction in which to display direction-capable members of the manifest. 54 * Direction-capable members are name, short_name and _description 55 * Valid values are "auto", "ltr" and "rtl" 56 */ 57 mixin(OProperty!("string", "dir")); 58 unittest { 59 assert(H5AppManifest.dir("auto").dir == "auto"); 60 } 61 62 /** 63 * display - determines the developers’ preferred display mode for the website. 64 * Valid values are 65 * "fullscreen" - All of the available display area is used and no user agent chrome is shown. 66 * "standalone" - Application will look and feel like a standalone application. This can include the application having a different window, its own icon in the application launcher, etc. 67 * In this mode, the user agent will exclude UI elements for controlling navigation, but can include other UI elements such as a status bar. 68 * "minimal-ui" - Application will look and feel like a standalone application, but will have a minimal set of UI elements for controlling navigation. The elements will vary by browser. 69 * "browser" - (Default) Application opens in a conventional browser tab or new window, depending on the browser and platform. 70 */ 71 mixin(OProperty!("string", "display")); 72 unittest { 73 assert(H5AppManifest.display("fullscreen").display == "fullscreen"); 74 } 75 76 /** 77 * iarcRatingId - string that represents the International Age Rating Coalition (IARC) certification code of the web application. 78 * It is intended to be used to determine which ages the web application is appropriate for. 79 */ 80 protected string _iarcRatingId; 81 auto iarcRatingId() { return _iarcRatingId; } 82 O iarcRatingId(this O)(UUID newIarcRatingId) { iarcRatingId(newIarcRatingId.toString); return cast(O)this; } 83 O iarcRatingId(this O)(string newIarcRatingId) { _iarcRatingId = newIarcRatingId; return cast(O)this; } 84 unittest { 85 assert(H5AppManifest.iarcRatingId("1768d43e-73a7-41c7-90fe-fe2e5ea3b7a2").iarcRatingId == "1768d43e-73a7-41c7-90fe-fe2e5ea3b7a2"); 86 } 87 88 /** 89 * icons - specifies an array of objects representing image files that can serve as application icons for different contexts. 90 * Object members are 91 * # sizes - A string containing space-separated image dimensions. 92 * # src - The path to the image file. If src is a relative URL, the base URL will be the URL of the manifest. 93 * # type - A hint as to the media type of the image. The purpose of this member is to allow a user agent to quickly ignore images with media types it does not support. 94 * # purpose - Defines the purpose of the image, for example if the image is intended to serve some special purpose in the context of the host OS (i.e., for better integration). 95 * Valid values are 96 * "badge": A user agent can present this icon where space constraints and/or color requirements differ from those of the application icon. 97 * "maskable": The image is designed with icon masks and safe zone in mind, such that any part of the image outside the safe zone can safely be ignored and masked away by the user agent. 98 * "any": (Default) The user agent is free to display the icon in any context. 99 */ 100 protected string[string][] _icons; 101 auto icons() { return _icons; } 102 O icons(this O)(string[string][] addIcons...) { _icons ~= addIcons; return cast(O)this; } 103 O icons(this O)(string[string][] addIcons) { _icons ~= addIcons; return cast(O)this; } 104 O clearIcons(this O)() { _icons = null; return cast(O)this; } 105 unittest { 106 assert(H5AppManifest.icons(["sizes":"1280x794"]).icons == [["sizes":"1280x794"]]); 107 } 108 109 /** 110 * lang - string containing a single language tag. 111 * It specifies the primary language for the values of the manifest's directionality-capable members, 112 * and together with dir determines their directionality. 113 */ 114 protected string _lang; 115 auto lang() { return _lang; } 116 O lang(this O)(string newLang) { _lang = newLang; return cast(O)this; } 117 unittest { 118 assert(H5AppManifest.lang("DE-de").lang == "DE-de"); 119 } 120 121 122 /** 123 * orientation - defines the default orientation for all the website's top-level browsing contexts. 124 * Valid values are "any", "natural", "landscape", "landscape-primary", "landscape-secondary", "portrait", "portrait-primary", "portrait-secondary" 125 */ 126 protected string _orientation; 127 auto orientation() { return _orientation; } 128 O orientation(this O)(string newOrientation) { _orientation = newOrientation; return cast(O)this; } 129 unittest { 130 assert(H5AppManifest.orientation("any").orientation == "any"); 131 } 132 133 /** 134 * preferRelatedApplications - specifies that applications listed in related_applications should be preferred over the web application. 135 * If the prefer_related_applications member is set to true, the user agent might 136 * suggest installing one of the related applications instead of this web app. 137 */ 138 protected bool _preferRelatedApplications; 139 auto preferRelatedApplications() { return _preferRelatedApplications; } 140 O preferRelatedApplications(this O)(bool newPreferRelatedApplications) { _preferRelatedApplications = newPreferRelatedApplications; return cast(O)this; } 141 unittest { 142 assert(H5AppManifest.preferRelatedApplications(true).preferRelatedApplications); 143 } 144 145 /** 146 * relatedApplications - array of objects specifying native applications that are installable by, or accessible to, the underlying platform 147 * Object members are 148 * "platform" - The platform on which the application can be found. 149 * "url" - The URL at which the application can be found. 150 * "id" -The ID used to represent the application on the specified platform. 151 */ 152 protected string[string][] _relatedApplications; 153 auto relatedApplications() { return _relatedApplications; } 154 O relatedApplications(this O)(string[string] addRelatedApplication) { _relatedApplications ~= addRelatedApplication; return cast(O)this; } 155 O clearRelatedApplications(this O)() { _relatedApplications = null; return cast(O)this; } 156 unittest { 157 assert(H5AppManifest.relatedApplications(["id":"1768d43e-73a7-41c7-90fe-fe2e5ea3b7a2"]).relatedApplications == [["id":"1768d43e-73a7-41c7-90fe-fe2e5ea3b7a2"]]); 158 } 159 160 /** 161 * scope - defines the navigation scope of this web application's application context. 162 * It restricts what web pages can be viewed while the manifest is applied. 163 * If the user navigates outside the scope, it reverts to a normal web page inside a browser tab or window. 164 */ 165 protected string _scope; 166 auto navScope() { return _scope; } 167 O navScope(this O)(string newScope) { _scope = newScope; return cast(O)this; } 168 unittest { 169 assert(H5AppManifest.navScope("/app").navScope == "/app"); 170 } 171 172 /** 173 * screenshots - array of screenshots intended to showcase the application. 174 "src": "screenshot.webp", 175 "sizes": "1280x720", 176 "type": "image/webp" 177 */ 178 protected string[string][] _screenshots; 179 auto screenshots() { return _screenshots; } 180 O screenshots(this O)(string[string][] addScreenshots...) { _screenshots ~= addScreenshots; return cast(O)this; } 181 O screenshots(this O)(string[string][] addScreenshots) { _screenshots ~= addScreenshots; return cast(O)this; } 182 O clearScreenshots(this O)() { _screenshots = null; return cast(O)this; } 183 unittest { 184 assert(H5AppManifest.screenshots(["sizes":"1280x720"]).screenshots == [["sizes":"1280x720"]]); 185 assert(H5AppManifest.screenshots([["sizes":"1280x720"]]).screenshots == [["sizes":"1280x720"]]); 186 } 187 188 /** 189 * serviceworker - describes a service worker that the developer intends to install to control the PWA. 190 src The URL to download the service worker script from. This is the only required member of the serviceworker member. 191 scope A string representing a URL that defines a service worker's registration scope; that is, what range of URLs a service worker can control. This is usually a relative URL, relative to the base URL of the application. By default, the scope value for a service worker registration is set to the directory where the service worker script is located. 192 type ? 193 update_via_cache 194 Whether the user agent cache should be bypassed when fetching the service worker. 195 */ 196 protected string[string] _serviceworker; 197 auto serviceworker() { return _serviceworker; } 198 O serviceworker(this O)(string[string] newServiceworker) { _serviceworker = newServiceworker; return cast(O)this; } 199 unittest { 200 assert(H5AppManifest.serviceworker(["src":"/app/sw.js"]).serviceworker == ["src":"/app/sw.js"]); 201 } 202 203 /** 204 * shortName - represents the name of the web application displayed to the user if there is not enough space to display name 205 * shortName is directionality-capable 206 */ 207 protected string _shortName; 208 auto shortName() { return _shortName; } 209 O shortName(this O)(string newShortName) { _shortName = newShortName; return cast(O)this; } 210 unittest { 211 assert(H5AppManifest.shortName("test").shortName == "test"); 212 } 213 214 /** 215 * startUrl - represents the start URL of the web application — the prefered URL that should be loaded when the user launches the web application 216 */ 217 protected string _startUrl; 218 auto startUrl() { return _startUrl; } 219 O startUrl(this O)(string newStartUrl) { _startUrl = newStartUrl; return cast(O)this; } 220 unittest { 221 assert(H5AppManifest.startUrl("/app").startUrl == "/app"); 222 } 223 224 /** 225 * themeColor - defines the default theme color for the application 226 */ 227 protected string _themeColor; 228 auto themeColor() { return _themeColor; } 229 O themeColor(this O)(string newThemeColor) { _themeColor = newThemeColor; return cast(O)this; } 230 unittest { 231 assert(H5AppManifest.themeColor("red").themeColor == "red"); 232 } 233 234 override string toString() { 235 Json values; 236 if (_backgroundColor) values["background-color"] = _backgroundColor; 237 if (_categories) values["categories"] = _categories.toJson; 238 if (_description) values["description"] = _description; 239 if (_dir) values["dir"] = _dir; 240 if (_display) values["display"] = _display; 241 if (_iarcRatingId) values["iarc_rating_id"] = _iarcRatingId; 242 if (_icons) values["icons"] = _icons.toJson; 243 if (_lang) values["lang"] = _lang; 244 if (_name) values["name"] = _name; 245 if (_orientation) values["orientation"] = _orientation; 246 if (_preferRelatedApplications) values["prefer_related_applications"] = _preferRelatedApplications; 247 if (_relatedApplications) values["related_applications"] = _relatedApplications.toJson; 248 if (_scope) values["scope"] = _scope; 249 if (_screenshots) values["screenshots"] = _screenshots.toJson; 250 if (_serviceworker) values["serviceworker"] = _serviceworker.toJson; 251 if (_shortName) values["short_name"] = _shortName; 252 if (_startUrl) values["start_url"] = _startUrl; 253 if (_themeColor) values["theme_color"] = _themeColor; 254 255 return values.toString; 256 } 257 } 258 auto H5AppManifest() { return new DH5AppManifest(); } 259 auto H5AppManifest(DH5App anApp) { return new DH5AppManifest(anApp); } 260 auto H5AppManifest(string aName) { return new DH5AppManifest(aName); } 261 auto H5AppManifest(DH5App anApp, string aName) { return new DH5AppManifest(anApp, aName); } 262 263 unittest { 264 assert(H5AppManifest); 265 }