diff options
author | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
---|---|---|
committer | Matt A. Tobin <mattatobin@localhost.localdomain> | 2018-02-02 04:16:08 -0500 |
commit | 5f8de423f190bbb79a62f804151bc24824fa32d8 (patch) | |
tree | 10027f336435511475e392454359edea8e25895d /dom/manifest/ImageObjectProcessor.jsm | |
parent | 49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff) | |
download | UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip |
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/manifest/ImageObjectProcessor.jsm')
-rw-r--r-- | dom/manifest/ImageObjectProcessor.jsm | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/dom/manifest/ImageObjectProcessor.jsm b/dom/manifest/ImageObjectProcessor.jsm new file mode 100644 index 000000000..7ef5fe811 --- /dev/null +++ b/dom/manifest/ImageObjectProcessor.jsm @@ -0,0 +1,153 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +/* + * ImageObjectProcessor + * Implementation of Image Object processing algorithms from: + * http://www.w3.org/TR/appmanifest/#image-object-and-its-members + * + * This is intended to be used in conjunction with ManifestProcessor.jsm + * + * Creates an object to process Image Objects as defined by the + * W3C specification. This is used to process things like the + * icon member and the splash_screen member. + * + * Usage: + * + * .process(aManifest, aBaseURL, aMemberName); + * + */ +/*exported EXPORTED_SYMBOLS*/ +/*globals Components */ +'use strict'; +const { + utils: Cu, + interfaces: Ci, + classes: Cc +} = Components; + +Cu.importGlobalProperties(['URL']); +const netutil = Cc['@mozilla.org/network/util;1'] + .getService(Ci.nsINetUtil); + +function ImageObjectProcessor(aConsole, aExtractor) { + this.console = aConsole; + this.extractor = aExtractor; +} + +// Static getters +Object.defineProperties(ImageObjectProcessor, { + 'decimals': { + get: function() { + return /^\d+$/; + } + }, + 'anyRegEx': { + get: function() { + return new RegExp('any', 'i'); + } + } +}); + +ImageObjectProcessor.prototype.process = function( + aManifest, aBaseURL, aMemberName +) { + const spec = { + objectName: 'manifest', + object: aManifest, + property: aMemberName, + expectedType: 'array', + trim: false + }; + const extractor = this.extractor; + const images = []; + const value = extractor.extractValue(spec); + if (Array.isArray(value)) { + // Filter out images whose "src" is not useful. + value.filter(item => !!processSrcMember(item, aBaseURL)) + .map(toImageObject) + .forEach(image => images.push(image)); + } + return images; + + function toImageObject(aImageSpec) { + return { + 'src': processSrcMember(aImageSpec, aBaseURL), + 'type': processTypeMember(aImageSpec), + 'sizes': processSizesMember(aImageSpec), + }; + } + + function processTypeMember(aImage) { + const charset = {}; + const hadCharset = {}; + const spec = { + objectName: 'image', + object: aImage, + property: 'type', + expectedType: 'string', + trim: true + }; + let value = extractor.extractValue(spec); + if (value) { + value = netutil.parseRequestContentType(value, charset, hadCharset); + } + return value || undefined; + } + + function processSrcMember(aImage, aBaseURL) { + const spec = { + objectName: 'image', + object: aImage, + property: 'src', + expectedType: 'string', + trim: false + }; + const value = extractor.extractValue(spec); + let url; + if (value && value.length) { + try { + url = new URL(value, aBaseURL).href; + } catch (e) {} + } + return url; + } + + function processSizesMember(aImage) { + const sizes = new Set(); + const spec = { + objectName: 'image', + object: aImage, + property: 'sizes', + expectedType: 'string', + trim: true + }; + const value = extractor.extractValue(spec); + if (value) { + // Split on whitespace and filter out invalid values. + value.split(/\s+/) + .filter(isValidSizeValue) + .reduce((collector, size) => collector.add(size), sizes); + } + return (sizes.size) ? Array.from(sizes).join(" ") : undefined; + // Implementation of HTML's link@size attribute checker. + function isValidSizeValue(aSize) { + const size = aSize.toLowerCase(); + if (ImageObjectProcessor.anyRegEx.test(aSize)) { + return true; + } + if (!size.includes('x') || size.indexOf('x') !== size.lastIndexOf('x')) { + return false; + } + // Split left of x for width, after x for height. + const widthAndHeight = size.split('x'); + const w = widthAndHeight.shift(); + const h = widthAndHeight.join('x'); + const validStarts = !w.startsWith('0') && !h.startsWith('0'); + const validDecimals = ImageObjectProcessor.decimals.test(w + h); + return (validStarts && validDecimals); + } + } +}; +this.ImageObjectProcessor = ImageObjectProcessor; // jshint ignore:line +this.EXPORTED_SYMBOLS = ['ImageObjectProcessor']; // jshint ignore:line |