skip to content
usubeni fantasy logo Usubeni Fantasy

TyranoScript Tutorial Part 6: Page Creation

/ 4 min read

This Post is Available In: CN EN

One day, my boss said we needed a brand new UI, but luckily, I was prepared for it.

I’ve complained before that writing settings, CG, and other pages using TyranoScript is hard to understand, and it’s difficult to manage the page hierarchy. It would be better to just write it in HTML. So today, let’s analyze how to create a new page using HTML.

We’ll start with an existing “non-script” page, such as the default Load page, which can be found by doing a global search for displayLoad in the kag.menu.js file.

this.kag.html("load", { array_save: array, novel: $.novel }, function (html_str) {
var layer_menu = that.kag.layer.getMenuLayer();
var j_save = $(html_str);
j_save.find(".save_list").css("font-family", that.kag.config.userFace);
j_save.find(".save_display_area").each(function () {
$(this).click(function (e) {
var num = $(this).attr("data-num");
that.snap = null;
that.loadGame(num);
var layer_menu = that.kag.layer.getMenuLayer();
layer_menu.hide();
layer_menu.empty();
var layer_title = that.kag.layer.getTitleLayer();
layer_title.hide();
layer_title.empty();
if (that.kag.stat.visible_menu_button == true) $(".button_menu").show();
});
});
j_save.find(".button_smart").hide();
if ($.userenv() != "pc") {
j_save.find(".button_smart").show();
j_save.find(".button_arrow_up").click(function () {
var now = j_save.find(".area_save_list").scrollTop();
var pos = now - 160;
layer_menu.find(".area_save_list").animate({ scrollTop: pos }, { queue: false });
});
j_save.find(".button_arrow_down").click(function () {
var now = j_save.find(".area_save_list").scrollTop();
var pos = now + 160;
j_save.find(".area_save_list").animate({ scrollTop: pos }, { queue: false });
});
}
that.setMenu(j_save);
});

The core of creating a new page is the kag.html function, which can be found in kag.js:

{
html: function(html_file_name, data, callback) {
var that = this
data = data || {}
if (this.cache_html[html_file_name]) {
if (callback) {
var tmpl = $.templates(this.cache_html[html_file_name])
var html = tmpl.render(data)
callback($(html))
}
} else {
if (!this.kag.stat.sysview) {
this.kag.stat.sysview = {
save: './tyrano/html/save.html',
load: './tyrano/html/load.html',
backlog: './tyrano/html/backlog.html',
menu: './tyrano/html/menu.html',
}
}
var path_html = this.kag.stat.sysview[html_file_name]
$.loadText(path_html, function(text_str) {
var tmpl = $.templates(text_str)
var html = tmpl.render(data)
that.cache_html[html_file_name] = text_str
if (callback) callback($(html))
})
}
}
}

The parameters of the html function are:

  • File name
  • Data passed in
  • Callback function

Observing displayLoad, it can be seen that loading the load page requires passing the page name load, an object containing archived content, and a callback function with HTML file content as a parameter. There is a flaw here, as the $(html) passed into the callback is not simply a “str” but an object processed by jQuery.

In the html function, $.loadText is used to fetch the local html file using Ajax, while functions such as $.templates and tmpl.render come from the open-source rendering engine jsrender.

In the load.html, we can see the use of a template:

<div class="save_list">
{{for array_save}}
<div class="save_display_area save_list_item" data-num="{{:num}}">
<span class="save_list_item_thumb">
{{if img_data != ""}}
<img class="pic" src="{{:img_data}}" />
{{/if}}
</span>
<span class="save_list_item_thumb">
{{if img_data == ""}}
<div class="pic">No data</div>
{{/if}}
</span>
<div class="save_list_item_area">
<div class="save_list_item_date">{{:save_date}}</div>
<div class="save_list_item_text">{{:title}}</div>
</div>
</div>
{{/for}}
</div>

However, I don’t intend to use jsrender as a template engine because I also want to incorporate Vue and take advantage of MVVM conveniently.

So, we can rewrite a simpler html function:

{
htmlPure: function(html_file_name, data, callback) {
var that = this
data = data || {}
if (this.cache_html[html_file_name]) {
if (callback) {
callback(this.cache_html[html_file_name])
}
} else {
var path_html = this.kag.stat.sysview[html_file_name]
$.loadText(path_html, function(text_str) {
that.cache_html[html_file_name] = text_str
if (callback) callback(text_str)
})
}
},
}

The htmlPure function eliminates the template engine rendering and directly passes the html string to the callback function. (You can choose to keep jsrender, but in order to avoid conflicts with Vue’s template, you need to modify Vue’s delimiters)

After adding the htmlPure function, we also need to create a new tag for creating the new page, which is named showExtendPage:

tyrano.plugin.kag.tag.showExtendPage = {
pm: {},
start: function (pm) {
var that = this;
this.kag.stat.is_skip = false;
this.kag.htmlPure(pm.name, null, function (html_str) {
var extendPage = $(html_str);
var layer_extend = that.kag.layer.layer_extend;
layer_extend[0].style.zIndex = pm.zindex || 9999999999;
layer_extend[0].innerHTML = "";
layer_extend.fadeIn();
layer_extend.append(extendPage);
});
this.kag.ftag.nextOrder();
},
};

This is the approach to using custom pages. After replacing the script file with an html file, I felt liberated as I no longer need to worry about script callback navigation and hierarchy clearing, just call the showExtendPage tag to fade the page in.

评论组件加载中……