Thu, 15 Jan 2015 21:03:48 +0100
Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)
michael@0 | 1 | /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | // Standard values to use for <img>/<embed> height & width, if requested. |
michael@0 | 7 | var HOST_NODE_HEIGHT = "20"; |
michael@0 | 8 | var HOST_NODE_WIDTH = "30"; |
michael@0 | 9 | |
michael@0 | 10 | // All the possible values of "align" |
michael@0 | 11 | const ALIGN_VALS = ["none", |
michael@0 | 12 | "xMinYMin", "xMinYMid", "xMinYMax", |
michael@0 | 13 | "xMidYMin", "xMidYMid", "xMidYMax", |
michael@0 | 14 | "xMaxYMin", "xMaxYMid", "xMaxYMax"]; |
michael@0 | 15 | |
michael@0 | 16 | // All the possible values of "meetOrSlice" |
michael@0 | 17 | const MEETORSLICE_VALS = [ "meet", "slice" ]; |
michael@0 | 18 | |
michael@0 | 19 | /** |
michael@0 | 20 | * Generates full data URI for an SVG document, with the given parameters |
michael@0 | 21 | * on the SVG element. |
michael@0 | 22 | * |
michael@0 | 23 | * @param aViewboxArr An array of four numbers, representing the |
michael@0 | 24 | * viewBox attribute, or null for no viewBox. |
michael@0 | 25 | * @param aWidth The width attribute, or null for no width. |
michael@0 | 26 | * @param aHeight The height attribute, or null for no height. |
michael@0 | 27 | * @param aAlign The 'align' component of the |
michael@0 | 28 | * preserveAspectRatio attribute, or null for none. |
michael@0 | 29 | * @param aMeetOrSlice The 'meetOrSlice' component of the |
michael@0 | 30 | * preserveAspectRatio attribute, or null for |
michael@0 | 31 | * none. (If non-null, implies non-null value for |
michael@0 | 32 | * aAlign.) |
michael@0 | 33 | * @param aViewParams Parameters to use for the view element. |
michael@0 | 34 | * @param aFragmentIdentifier The SVG fragment identifier. |
michael@0 | 35 | */ |
michael@0 | 36 | function generateSVGDataURI(aViewboxArr, aWidth, aHeight, |
michael@0 | 37 | aAlign, aMeetOrSlice, |
michael@0 | 38 | aViewParams, aFragmentIdentifier) { |
michael@0 | 39 | // prefix |
michael@0 | 40 | var datauri = "data:image/svg+xml," |
michael@0 | 41 | // Begin the SVG tag |
michael@0 | 42 | datauri += "%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20shape-rendering%3D%22crispEdges%22"; |
michael@0 | 43 | |
michael@0 | 44 | // Append the custom chunk from our params |
michael@0 | 45 | // If we're working with views, the align customisation is applied there instead |
michael@0 | 46 | datauri += generateSVGAttrsForParams(aViewboxArr, aWidth, aHeight, |
michael@0 | 47 | aViewParams ? null : aAlign, |
michael@0 | 48 | aMeetOrSlice); |
michael@0 | 49 | |
michael@0 | 50 | // Add 'font-size' just in case the client wants to use ems |
michael@0 | 51 | datauri += "%20font-size%3D%22" + "10px" + "%22"; |
michael@0 | 52 | |
michael@0 | 53 | // Put closing right bracket on SVG tag |
michael@0 | 54 | datauri += "%3E"; |
michael@0 | 55 | |
michael@0 | 56 | if (aViewParams) { |
michael@0 | 57 | // Give the view the id of the fragment identifier |
michael@0 | 58 | datauri += "%3Cview%20id%3D%22" + aFragmentIdentifier + "%22"; |
michael@0 | 59 | |
michael@0 | 60 | // Append the custom chunk from our view params |
michael@0 | 61 | datauri += generateSVGAttrsForParams(aViewParams.viewBox, null, null, |
michael@0 | 62 | aAlign, aViewParams.meetOrSlice); |
michael@0 | 63 | |
michael@0 | 64 | datauri += "%2F%3E"; |
michael@0 | 65 | } |
michael@0 | 66 | |
michael@0 | 67 | // Add the rest of the SVG document |
michael@0 | 68 | datauri += "%3Crect%20x%3D%221%22%20y%3D%221%22%20height%3D%2218%22%20width%3D%2218%22%20stroke-width%3D%222%22%20stroke%3D%22black%22%20fill%3D%22yellow%22%2F%3E%3Ccircle%20cx%3D%2210%22%20cy%3D%2210%22%20r%3D%228%22%20style%3D%22fill%3A%20blue%22%2F%3E%3C%2Fsvg%3E"; |
michael@0 | 69 | |
michael@0 | 70 | return datauri; |
michael@0 | 71 | } |
michael@0 | 72 | |
michael@0 | 73 | // Generates just the chunk of a data URI that's relevant to |
michael@0 | 74 | // the given params. |
michael@0 | 75 | function generateSVGAttrsForParams(aViewboxArr, aWidth, aHeight, |
michael@0 | 76 | aAlign, aMeetOrSlice) { |
michael@0 | 77 | var str = ""; |
michael@0 | 78 | if (aViewboxArr) { |
michael@0 | 79 | str += "%20viewBox%3D%22"; |
michael@0 | 80 | for (var i in aViewboxArr) { |
michael@0 | 81 | str += aViewboxArr[i]; |
michael@0 | 82 | if (i != aViewboxArr.length - 1) { |
michael@0 | 83 | str += "%20"; |
michael@0 | 84 | } |
michael@0 | 85 | } |
michael@0 | 86 | str += "%22"; |
michael@0 | 87 | } |
michael@0 | 88 | if (aWidth) { |
michael@0 | 89 | str += "%20width%3D%22" + aWidth + "%22"; |
michael@0 | 90 | } |
michael@0 | 91 | if (aHeight) { |
michael@0 | 92 | str += "%20height%3D%22" + aHeight + "%22"; |
michael@0 | 93 | } |
michael@0 | 94 | if (aAlign) { |
michael@0 | 95 | str += "%20preserveAspectRatio%3D%22" + aAlign; |
michael@0 | 96 | if (aMeetOrSlice) { |
michael@0 | 97 | str += "%20" + aMeetOrSlice; |
michael@0 | 98 | } |
michael@0 | 99 | str += "%22"; |
michael@0 | 100 | } |
michael@0 | 101 | |
michael@0 | 102 | return str; |
michael@0 | 103 | } |
michael@0 | 104 | |
michael@0 | 105 | // Returns a newly-generated element with the given tagname, the given URI |
michael@0 | 106 | // for its |src| attribute, and the given width & height values. |
michael@0 | 107 | function generateHostNode(aHostNodeTagName, aUri, |
michael@0 | 108 | aHostNodeWidth, aHostNodeHeight) { |
michael@0 | 109 | var elem = document.createElement(aHostNodeTagName); |
michael@0 | 110 | elem.setAttribute("src", aUri); |
michael@0 | 111 | |
michael@0 | 112 | if (aHostNodeWidth) { |
michael@0 | 113 | elem.setAttribute("width", aHostNodeWidth); |
michael@0 | 114 | } |
michael@0 | 115 | if (aHostNodeHeight) { |
michael@0 | 116 | elem.setAttribute("height", aHostNodeHeight); |
michael@0 | 117 | } |
michael@0 | 118 | |
michael@0 | 119 | return elem; |
michael@0 | 120 | } |
michael@0 | 121 | |
michael@0 | 122 | // THIS IS THE CHIEF HELPER FUNCTION TO BE CALLED BY CLIENTS |
michael@0 | 123 | function appendSVGArrayWithParams(aSVGParams, aHostNodeTagName) { |
michael@0 | 124 | // These are width & height vals that will be used for the *host node*. |
michael@0 | 125 | // (i.e. the <img> or <embed> node -- not the <svg> node) |
michael@0 | 126 | var hostNodeWidthVals = [ null, HOST_NODE_WIDTH ]; |
michael@0 | 127 | var hostNodeHeightVals = [ null, HOST_NODE_HEIGHT ]; |
michael@0 | 128 | |
michael@0 | 129 | for (var i = 0; i < hostNodeWidthVals.length; i++) { |
michael@0 | 130 | var hostNodeWidth = hostNodeWidthVals[i]; |
michael@0 | 131 | for (var j = 0; j < hostNodeHeightVals.length; j++) { |
michael@0 | 132 | var hostNodeHeight = hostNodeHeightVals[j]; |
michael@0 | 133 | appendSVGSubArrayWithParams(aSVGParams, aHostNodeTagName, |
michael@0 | 134 | hostNodeWidth, hostNodeHeight); |
michael@0 | 135 | } |
michael@0 | 136 | } |
michael@0 | 137 | } |
michael@0 | 138 | |
michael@0 | 139 | // Helper function for above, for a fixed [host-node-width][host-node-height] |
michael@0 | 140 | function appendSVGSubArrayWithParams(aSVGParams, aHostNodeTagName, |
michael@0 | 141 | aHostNodeWidth, aHostNodeHeight) { |
michael@0 | 142 | var rootNode = document.getElementsByTagName("body")[0]; |
michael@0 | 143 | for (var k = 0; k < ALIGN_VALS.length; k++) { |
michael@0 | 144 | var alignVal = ALIGN_VALS[k]; |
michael@0 | 145 | if (!aSVGParams.meetOrSlice) { |
michael@0 | 146 | alignVal = "none"; |
michael@0 | 147 | } |
michael@0 | 148 | |
michael@0 | 149 | // Generate the Data URI |
michael@0 | 150 | var uri = generateSVGDataURI(aSVGParams.viewBox, |
michael@0 | 151 | aSVGParams.width, aSVGParams.height, |
michael@0 | 152 | alignVal, |
michael@0 | 153 | aSVGParams.meetOrSlice, |
michael@0 | 154 | aSVGParams.view, |
michael@0 | 155 | aSVGParams.fragmentIdentifier); |
michael@0 | 156 | |
michael@0 | 157 | if (aSVGParams.fragmentIdentifier) { |
michael@0 | 158 | uri += "#" + aSVGParams.fragmentIdentifier; |
michael@0 | 159 | } |
michael@0 | 160 | |
michael@0 | 161 | // Generate & append the host node element |
michael@0 | 162 | var hostNode = generateHostNode(aHostNodeTagName, uri, |
michael@0 | 163 | aHostNodeWidth, aHostNodeHeight); |
michael@0 | 164 | rootNode.appendChild(hostNode); |
michael@0 | 165 | |
michael@0 | 166 | // Cosmetic: Add a newline when we get halfway through the ALIGN_VALS |
michael@0 | 167 | // and then again when we reach the end |
michael@0 | 168 | if (k + 1 == ALIGN_VALS.length / 2 || |
michael@0 | 169 | k + 1 == ALIGN_VALS.length) { |
michael@0 | 170 | rootNode.appendChild(document.createElement("br")); |
michael@0 | 171 | } |
michael@0 | 172 | } |
michael@0 | 173 | } |