diff --git a/weditor/static/js/common.js b/weditor/static/js/common.js
index 3c0ebca..df4d18e 100644
--- a/weditor/static/js/common.js
+++ b/weditor/static/js/common.js
@@ -1,9 +1,9 @@
-// Copies a string to the clipboard. Must be called from within an
+// Copies a string to the clipboard. Must be called from within an
// event handler such as click. May return false if it failed, but
-// this is not always possible. Browser support for Chrome 43+,
+// this is not always possible. Browser support for Chrome 43+,
// Firefox 42+, Safari 10+, Edge and IE 10+.
// IE: The clipboard feature may be disabled by an administrator. By
-// default a prompt is shown the first time the clipboard is
+// default a prompt is shown the first time the clipboard is
// used (per session).
function copyToClipboard(text) {
if (window.clipboardData && window.clipboardData.setData) {
@@ -72,4 +72,41 @@ function b64toBlob(b64Data, contentType, sliceSize) {
return new Blob(byteArrays, {
type: contentType
});
+}
+
+var dumplib = {
+ parseIosJson: function(json, screenshotWidth) {
+ var node = JSON.parse(json);
+ // get 414, 736 from {{0, 0}, {414, 736}}
+ var windowSize = /\{\{(.+)\}, \{(.+)\}\}/.exec(node.frame)[2].split(',').map(v => parseInt(v, 10))
+ var scale = screenshotWidth ? screenshotWidth / windowSize[0] : 1
+
+ function travel(node) {
+ node['_id'] = node['_id'] || uuidv4();
+ node['_type'] = node['type'] || null;
+ if (node['rect']) {
+ let rect = node['rect'];
+ let nrect = {};
+ for (let k in rect) {
+ nrect[k] = rect[k] * scale;
+ }
+ node['rect'] = nrect;
+ }
+
+ if (node['children']) {
+ node['children'].forEach(child => {
+ travel(child);
+ });
+ }
+ return node;
+ }
+
+ return {
+ jsonHierarchy: travel(node),
+ windowSize
+ }
+ },
+ parseAndroidJson: function(json) {
+
+ }
}
\ No newline at end of file
diff --git a/weditor/static/js/index.js b/weditor/static/js/index.js
index cf0daf0..1b051ff 100644
--- a/weditor/static/js/index.js
+++ b/weditor/static/js/index.js
@@ -775,27 +775,87 @@ window.vm = new Vue({
return this.screenRefresh().then(this.dumpHierarchy)
}
},
+ setHierarchy: function (ret) {
+ localStorage.setItem("xmlHierarchy", ret.xmlHierarchy);
+ localStorage.setItem('jsonHierarchy', JSON.stringify(ret.jsonHierarchy));
+ localStorage.setItem("activity", ret.activity);
+ localStorage.setItem("packageName", ret.packageName);
+ localStorage.setItem("windowSize", ret.windowSize);
+ this.activity = ret.activity; // only for android
+ this.packageName = ret.packageName;
+ this.drawAllNodeFromSource(ret.jsonHierarchy);
+ this.nodeSelected = null;
+ },
dumpHierarchy: function () { // v2
this.dumping = true
return $.getJSON(LOCAL_URL + 'api/v2/devices/' + encodeURIComponent(this.deviceId || '-') + '/hierarchy')
.fail((ret) => {
this.showAjaxError(ret);
})
- .then((ret) => {
- localStorage.setItem("xmlHierarchy", ret.xmlHierarchy);
- localStorage.setItem('jsonHierarchy', JSON.stringify(ret.jsonHierarchy));
- localStorage.setItem("activity", ret.activity);
- localStorage.setItem("packageName", ret.packageName);
- localStorage.setItem("windowSize", ret.windowSize);
- this.activity = ret.activity; // only for android
- this.packageName = ret.packageName;
- this.drawAllNodeFromSource(ret.jsonHierarchy);
- this.nodeSelected = null;
- })
+ .then(this.setHierarchy)
.always(() => {
this.dumping = false
})
},
+ loadHierarchy: function (files) {
+ if (!files || files.length == 0) {
+ return;
+ }
+ const loadSource = () => {
+ var source = Array.from(files).find(function (file) {
+ return file.type.indexOf('image/') === -1
+ })
+ this.loadHierarchySource(source);
+ this.dumping = false
+ }
+
+ this.dumping = true
+ var screenshot = Array.from(files).find(function (file) {
+ return file.type.indexOf('image/') > -1
+ })
+ // screenshot or source can be uploaded separately
+ // if (!screenshot) {
+ // alert('screenshot file is required')
+ // return;
+ // }
+
+ if (screenshot) {
+ this.loadScreenshot(screenshot).then(loadSource);
+ } else {
+ loadSource()
+ }
+
+ // if (!screenshot && !source) {
+ // alert('screenshot or source file is required')
+ // return;
+ // }
+ },
+ loadScreenshot: function (screenshot) {
+ if (!screenshot) {
+ return;
+ }
+ console.debug('screenshot', screenshot)
+ return this.drawBlobImageToScreen(screenshot);
+ },
+
+ loadHierarchySource: function (source) {
+ if (!source) {
+ return;
+ }
+
+ var screenshotWidth = this.canvas.bg.width || 0;
+
+ var reader = new FileReader();
+ reader.readAsText(source, "UTF-8");
+ reader.onload = (evt) => {
+ var ret = dumplib.parseIosJson(evt.target.result, screenshotWidth)
+ this.setHierarchy(ret)
+ }
+ reader.onerror = function (evt) {
+ console.warn('hierarchy load error', evt)
+ alert('hierarchy load error')
+ }
+ },
screenRefresh: function () {
return $.getJSON(LOCAL_URL + 'api/v1/devices/' + encodeURIComponent(this.deviceId || '-') + '/screenshot')
.fail((err) => {
@@ -822,7 +882,6 @@ window.vm = new Vue({
fgcanvas.width = bgcanvas.width = img.width
fgcanvas.height = bgcanvas.height = img.height
-
ctx.drawImage(img, 0, 0, img.width, img.height);
self.resizeScreen(img);
diff --git a/weditor/templates/index.html b/weditor/templates/index.html
index 07512a5..18866dc 100644
--- a/weditor/templates/index.html
+++ b/weditor/templates/index.html
@@ -62,6 +62,12 @@