/* Helper methods */
String.prototype.f = function () {
var s = this,
i = arguments.length;
while (i--) {
s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
}
return s;
};
String.prototype.repeat = function (num) {
return new Array(num + 1).join(this);
};
function pushUnique(array, item) {
if (array.indexOf(item) == -1) {
array.push(item);
return true;
}
return false;
}
function toBool(s, defValue) {
if (typeof s === "undefined") {
return typeof defValue !== "undefined" ? defValue : false;
}
return "false" !== s;
}
if (typeof String.prototype.endsWith !== 'function') {
String.prototype.endsWith = function (suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
}
if (typeof String.prototype.startsWith !== 'function') {
String.prototype.startsWith = function (str) {
return this.indexOf(str) == 0;
};
}
jQuery.fn.reverse = [].reverse;
/* ------ */
var groupData = { groupSize:0, zip:null, log:[], errors:0, files:[]};
var fileReaderOpts = {
dragClass: "drag", readAsDefault: "Text", on: {
load: function (e, file) {
if (groupData.groupSize == 1) {
loadFile(e, file, false)
} else {
groupData.files.push({e: e, file: file});
}
},
groupstart: function (g) {
resetGroupData();
groupData.zip = new JSZip();
groupData.groupSize = g.files.length;
},
groupend: function (g) {
//Multiple files
if (groupData.groupSize > 1) {
groupData.groupSize = 0;
var dlg = $('#dlg-files');
var btnPrimary = dlg.find(".btn-primary");
refreshSettings();
dlg.find("#files-count").text(groupData.files.length);
btnPrimary.text("Export");
dlg.modal().on();
btnPrimary.removeClass("disabled");
btnPrimary.unbind("click");
btnPrimary.on("click", function () {
if (btnPrimary.hasClass("disabled")) return;
btnPrimary.addClass("disabled");
btnPrimary.text("Please wait ...");
//To prevent UI lag
setTimeout(function () {
for (var i = 0; i < groupData.files.length; i++) {
var f = groupData.files[i];
loadFile(f.e, f.file, true);
}
groupData.log = "
Files converted: " + (groupData.files.length - groupData.errors) + " / " + groupData.files.length + "
" + groupData.log;
groupData.zip.file("log.html", groupData.log);
saveAs(groupData.zip.generate({type: "blob"}), "export.zip");
dlg.modal("hide");
}, 250);
});
dlg.unbind("hidden.bs.modal");
dlg.on("hidden.bs.modal", function () {
resetGroupData();
})
}
}
}
};
if (typeof FileReader === "undefined") {
$('#dropzone, #dropzone-dialog').hide();
$('#compat-error').show();
} else {
$('#dropzone, #dropzone-dialog').fileReaderJS(fileReaderOpts);
}
if(navigator.userAgent.toLowerCase().indexOf('firefox') > -1){
localStorage.bakeTransforms = false;
$(".bake-transforms").prop("disabled", true);
alert("Sorry but svg2android doesn't work well on Firefox, please use Google Chrome or other browser for now.");
}
//Copy settings to dialog
var dlg = $('#dlg-files');
dlg.find('.modal-body').html($("#settings-area").clone());
//Clipboard paste event
$("body").bind("paste", function(e) {
var pastedData = e.originalEvent.clipboardData.getData('text');
if (pastedData.length > 0) {
groupData.groupSize = 1;
refreshSettings();
parseSingleFile(pastedData);
}
});
$("#deprecation-text").on("click", function (ev) {
ev.stopPropagation();
});
showLastUpdate("svg2android");
/* ------ */
var DRAW_LINE = "l"; //used as default parameter when no found in path
var START_PATH = "M";
var END_PATH = "Z";
var INDENT = " ";
var pathsParsedCount = 0;
var generatedOutput = "";
var lastFileName = "";
var lastFileData;
var warnings = [];
var svgStyles = {};
var globalSvg;
var clipPathEnabled = false;
var clipPathItemsCount = 0;
var clipPathMerged = [];
function loadFile(e, file, multipleFiles) {
lastFileName = file.name;
refreshSettings();
if (multipleFiles) {
parseMultipleFiles(e.target.result)
} else {
parseSingleFile(e.target.result);
}
}
function resetGroupData() {
groupData.zip = new JSZip();
groupData.log = [];
groupData.files = [];
groupData.errors = 0;
groupData.groupSize = 0;
}
function refreshSettings() {
$(".opt-id-as-name").prop("checked", toBool(localStorage.useIdAsName));
$(".bake-transforms").prop("checked", toBool(localStorage.bakeTransforms));
$(".clear-groups").prop("checked", toBool(localStorage.clearGroups, true));
$(".wordwrap-pathdata").prop("checked", toBool(localStorage.wordWrapPathData, false));
}
function extractFileNameWithoutExt(filename) {
var dotIndex = filename.lastIndexOf(".");
if (dotIndex > -1) {
filename = filename.substr(0, dotIndex);
}
filename = filename.toLowerCase();
filename = filename.replace(/[^a-z0-9]/gi, '_');
return filename;
}
//Main parse & convert logic
function recursiveTreeWalk(parent, groupLevel, clipPath) {
parent.children().each(function () {
var current = $(this);
if (current.is("a") && current.children().length > 0) {
recursiveTreeWalk(current, groupLevel, clipPath);
} else if (current.is("g") && current.children().length > 0) { //Group tag, ignore empty groups
var group = parseGroup(current);
var ignoreGroup = !(toBool(localStorage.clearGroups, true) && !group.isSet);
if (ignoreGroup) printGroupStart(group, groupLevel);
if (ignoreGroup) groupLevel++;
recursiveTreeWalk(current, groupLevel, clipPath);
if (ignoreGroup) groupLevel--;
if (ignoreGroup) printGroupEnd(groupLevel);
} else if (current.is("path")) {
var pathD = parsePathD(current);
if (pathD != null) {
printPath(pathD, getStyles(current), groupLevel, clipPath);
} else {
pushUnique(warnings, "found path(s) without data (empty or invalid parameter d)");
}
} else if (current.is("line")) {
printPath(ShapeConverter.convertLine(current), getStyles(current), groupLevel, clipPath);
} else if (current.is("rect")) {
printPath(ShapeConverter.convertRect(current), getStyles(current), groupLevel, clipPath);
} else if (current.is("circle")) {
printPath(ShapeConverter.convertCircle(current), getStyles(current), groupLevel, clipPath);
} else if (current.is("ellipse")) {
printPath(ShapeConverter.convertEllipse(current), getStyles(current), groupLevel, clipPath);
} else if (current.is("polyline")) {
printPath(ShapeConverter.convertPolygon(current, true), getStyles(current), groupLevel, clipPath);
} else if (current.is("polygon")) {
printPath(ShapeConverter.convertPolygon(current, false), getStyles(current), groupLevel, clipPath);
} else if (current.is("text")) {
pushUnique(warnings, "text element is not supported, export all text into path");
} else if (current.is("image")) {
pushUnique(warnings, "image element is not supported, you must vectorize raster image");
}
});
}
function preprocessReferences(svg) {
svg.find("use").each(function () {
var current = $(this);
substituteUseRef(svg, current);
});
}
function getStyles(el) {
var styles = parseStyles(el);
var parentStyles = null;
//Inherit all parent group styles in reversed order (to override them correctly)
el.parents("g").reverse().each(function () {
var current = $(this);
if (parentStyles == null) {
parentStyles = [];
}
jQuery.extend(parentStyles, parseStyles(current));
});
//Do not propagate id from group to childrens
if (parentStyles != null && typeof parentStyles["id"] !== "undefined") {
parentStyles["id"] = undefined;
}
return [styles, parentStyles];
}
function substituteUseRef(parent, current) {
var href = current.attr("xlink:href");
if (typeof href !== "undefined") {
href = href.trim();
//Check if valid href
if (href.length > 1 && href.startsWith("#")) {
//Find definition in svg
var defs = $(parent).find("[id='" + href.substr(1) + "']");
if (defs.length) {
defs = defs.clone();
//Copy overriding attributes into children
$.each(current.prop("attributes"), function () {
defs.attr(this.name, this.value);
});
current.replaceWith(defs);
} else {
console.warn("Found