manifest-state.js (4130B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 const { 8 MANIFEST_CATEGORIES, 9 MANIFEST_ISSUE_LEVELS, 10 MANIFEST_MEMBER_VALUE_TYPES, 11 FETCH_MANIFEST_FAILURE, 12 FETCH_MANIFEST_START, 13 FETCH_MANIFEST_SUCCESS, 14 RESET_MANIFEST, 15 } = require("resource://devtools/client/application/src/constants.js"); 16 17 function _processRawManifestIcons(rawIcons) { 18 // NOTE: about `rawIcons` array we are getting from platform: 19 // - Icons that do not comform to the spec are filtered out 20 // - We will always get a `src` 21 // - We will always get `purpose` with a value (default is `["any"]`) 22 // - `sizes` may be undefined 23 // - `type` may be undefined 24 return rawIcons.map(icon => { 25 return { 26 key: { 27 sizes: Array.isArray(icon.sizes) ? icon.sizes.join(" ") : icon.sizes, 28 contentType: icon.type, 29 }, 30 value: { 31 src: icon.src, 32 purpose: icon.purpose.join(" "), 33 }, 34 type: MANIFEST_MEMBER_VALUE_TYPES.ICON, 35 }; 36 }); 37 } 38 39 function _processRawManifestMembers(rawManifest) { 40 function getCategoryForMember(key) { 41 switch (key) { 42 case "name": 43 case "short_name": 44 return MANIFEST_CATEGORIES.IDENTITY; 45 default: 46 return MANIFEST_CATEGORIES.PRESENTATION; 47 } 48 } 49 50 function getValueTypeForMember(key) { 51 switch (key) { 52 case "start_url": 53 case "scope": 54 return MANIFEST_MEMBER_VALUE_TYPES.URL; 55 case "theme_color": 56 case "background_color": 57 return MANIFEST_MEMBER_VALUE_TYPES.COLOR; 58 default: 59 return MANIFEST_MEMBER_VALUE_TYPES.STRING; 60 } 61 } 62 63 const res = { 64 [MANIFEST_CATEGORIES.IDENTITY]: [], 65 [MANIFEST_CATEGORIES.PRESENTATION]: [], 66 }; 67 68 // filter out extra metadata members (those with moz_ prefix) and icons 69 const rawMembers = Object.entries(rawManifest).filter( 70 ([key]) => !key.startsWith("moz_") && !(key === "icons") 71 ); 72 73 for (const [key, value] of rawMembers) { 74 const category = getCategoryForMember(key); 75 const type = getValueTypeForMember(key); 76 res[category].push({ key, value, type }); 77 } 78 79 return res; 80 } 81 82 function _processRawManifestIssues(issues) { 83 return issues.map(x => { 84 return { 85 level: x.warn 86 ? MANIFEST_ISSUE_LEVELS.WARNING 87 : MANIFEST_ISSUE_LEVELS.ERROR, 88 message: x.warn || x.error, 89 type: x.type || null, 90 }; 91 }); 92 } 93 94 function _processRawManifest(rawManifest) { 95 const res = { 96 url: rawManifest.moz_manifest_url, 97 }; 98 99 // group manifest members by category 100 Object.assign(res, _processRawManifestMembers(rawManifest)); 101 // process icons 102 res.icons = _processRawManifestIcons(rawManifest.icons || []); 103 // process error messages 104 res.validation = _processRawManifestIssues(rawManifest.moz_validation || []); 105 106 return res; 107 } 108 109 function ManifestState() { 110 return { 111 errorMessage: "", 112 isLoading: false, 113 manifest: undefined, 114 }; 115 } 116 117 function manifestReducer(state = ManifestState(), action) { 118 switch (action.type) { 119 case FETCH_MANIFEST_START: 120 return Object.assign({}, state, { 121 isLoading: true, 122 mustLoadManifest: false, 123 }); 124 125 case FETCH_MANIFEST_FAILURE: { 126 const { error } = action; 127 // If we add a redux middleware to log errors, we should move the 128 // console.error below there. 129 console.error(error); 130 return Object.assign({}, state, { 131 errorMessage: error, 132 isLoading: false, 133 manifest: null, 134 }); 135 } 136 137 case FETCH_MANIFEST_SUCCESS: { 138 // NOTE: we don't get an error when the page does not have a manifest, 139 // but a `null` value there. 140 const { manifest } = action; 141 return Object.assign({}, state, { 142 errorMessage: "", 143 isLoading: false, 144 manifest: manifest ? _processRawManifest(manifest) : null, 145 }); 146 } 147 148 case RESET_MANIFEST: 149 return ManifestState(); 150 151 default: 152 return state; 153 } 154 } 155 156 module.exports = { 157 ManifestState, 158 manifestReducer, 159 };