Skip to content
This repository has been archived by the owner on Jul 21, 2024. It is now read-only.

feat: load hierarchy from saved file #143

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 40 additions & 3 deletions weditor/static/js/common.js
Original file line number Diff line number Diff line change
@@ -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) {
Expand Down Expand Up @@ -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) {

}
}
83 changes: 71 additions & 12 deletions weditor/static/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand All @@ -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);

Expand Down
7 changes: 7 additions & 0 deletions weditor/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@
<el-switch v-model="liveScreen" active-text="实时" inactive-text="静态">
</el-switch>
</template>
<input type="file" id="load_hierarchy" name="load_hierarchy" accept="*" @change="(e) => {loadHierarchy(e.target.files)}" multiple style="display: none;"/>
<el-tooltip :open-delay="500" content="Load screenshot (or/and) source json" placement="bottom">
<label class="btn btn-default" for="load_hierarchy" v-if="platform == 'iOS'">
<i class="fa fa-upload" :class='{"fa-spin": dumping}'></i> Load Hierarchy
</label>
</el-tooltip>
</form>
<ul class="nav navbar-nav navbar-right">
<!-- <li><a href="#">Link</a></li> -->
Expand Down Expand Up @@ -292,6 +298,7 @@ <h4 class="modal-title">
</div>
</body>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/uuidv4.min.js"></script>
<script src="/cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<script src="/cdn.jsdelivr.net/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="/cdn.jsdelivr.net/bootstrap.select/1.12.2/js/bootstrap-select.min.js"></script>
Expand Down