mirror of https://github.com/mindoc-org/mindoc.git
添加iframe支持(conf `enable_iframe`)
parent
8515abcd9d
commit
b624fea255
|
@ -263,6 +263,12 @@ func RegisterFunction() {
|
||||||
logs.Error("注册函数 urlfor 出错 ->", err)
|
logs.Error("注册函数 urlfor 出错 ->", err)
|
||||||
os.Exit(-1)
|
os.Exit(-1)
|
||||||
}
|
}
|
||||||
|
//读取配置值(未作任何转换)
|
||||||
|
err = web.AddFuncMap("conf", conf.CONF)
|
||||||
|
if err != nil {
|
||||||
|
logs.Error("注册函数 conf 出错 ->", err)
|
||||||
|
os.Exit(-1)
|
||||||
|
}
|
||||||
err = web.AddFuncMap("date_format", func(t time.Time, format string) string {
|
err = web.AddFuncMap("date_format", func(t time.Time, format string) string {
|
||||||
return t.Local().Format(format)
|
return t.Local().Format(format)
|
||||||
})
|
})
|
||||||
|
|
|
@ -8,6 +8,7 @@ sessionon = true
|
||||||
sessionname = mindoc_id
|
sessionname = mindoc_id
|
||||||
copyrequestbody = true
|
copyrequestbody = true
|
||||||
enablexsrf = "${MINDOC_ENABLE_XSRF||false}"
|
enablexsrf = "${MINDOC_ENABLE_XSRF||false}"
|
||||||
|
enable_iframe = "${MINDOC_ENABLE_IFRAME||false}"
|
||||||
|
|
||||||
#系统完整URL(http://doc.iminho.me),如果该项不设置,会从请求头中获取地址。
|
#系统完整URL(http://doc.iminho.me),如果该项不设置,会从请求头中获取地址。
|
||||||
baseurl="${MINDOC_BASE_URL}"
|
baseurl="${MINDOC_BASE_URL}"
|
||||||
|
|
|
@ -152,6 +152,11 @@ func GetEnableExport() bool {
|
||||||
return web.AppConfig.DefaultBool("enable_export", true)
|
return web.AppConfig.DefaultBool("enable_export", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//是否启用iframe
|
||||||
|
func GetEnableIframe() bool {
|
||||||
|
return web.AppConfig.DefaultBool("enable_iframe", false)
|
||||||
|
}
|
||||||
|
|
||||||
//同一项目导出线程的并发数
|
//同一项目导出线程的并发数
|
||||||
func GetExportProcessNum() int {
|
func GetExportProcessNum() int {
|
||||||
exportProcessNum := web.AppConfig.DefaultInt("export_process_num", 1)
|
exportProcessNum := web.AppConfig.DefaultInt("export_process_num", 1)
|
||||||
|
@ -208,6 +213,15 @@ func IsAllowUploadFileExt(ext string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//读取配置文件值
|
||||||
|
func CONF(key string, value ...string) string {
|
||||||
|
defaultValue := ""
|
||||||
|
if len(value) > 0 {
|
||||||
|
defaultValue = value[0]
|
||||||
|
}
|
||||||
|
return web.AppConfig.DefaultString(key, defaultValue)
|
||||||
|
}
|
||||||
|
|
||||||
//重写生成URL的方法,加上完整的域名
|
//重写生成URL的方法,加上完整的域名
|
||||||
func URLFor(endpoint string, values ...interface{}) string {
|
func URLFor(endpoint string, values ...interface{}) string {
|
||||||
baseUrl := web.AppConfig.DefaultString("baseurl", "")
|
baseUrl := web.AppConfig.DefaultString("baseurl", "")
|
||||||
|
|
|
@ -1,11 +1,82 @@
|
||||||
package routers
|
package routers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httputil"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/beego/beego/v2/core/logs"
|
||||||
"github.com/beego/beego/v2/server/web"
|
"github.com/beego/beego/v2/server/web"
|
||||||
|
"github.com/beego/beego/v2/server/web/context"
|
||||||
|
"github.com/mindoc-org/mindoc/conf"
|
||||||
"github.com/mindoc-org/mindoc/controllers"
|
"github.com/mindoc-org/mindoc/controllers"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func rt(req *http.Request) (*http.Response, error) {
|
||||||
|
log.Printf("request received. url=%s", req.URL)
|
||||||
|
// req.Header.Set("Host", "httpbin.org") // <--- I set it here as well
|
||||||
|
defer log.Printf("request complete. url=%s", req.URL)
|
||||||
|
|
||||||
|
return http.DefaultTransport.RoundTrip(req)
|
||||||
|
}
|
||||||
|
|
||||||
|
// roundTripper makes func signature a http.RoundTripper
|
||||||
|
type roundTripper func(*http.Request) (*http.Response, error)
|
||||||
|
|
||||||
|
func (f roundTripper) RoundTrip(req *http.Request) (*http.Response, error) { return f(req) }
|
||||||
|
|
||||||
|
type CorsTransport struct {
|
||||||
|
http.RoundTripper
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *CorsTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
|
||||||
|
// refer:
|
||||||
|
// - https://stackoverflow.com/questions/31535569/golang-how-to-read-response-body-of-reverseproxy/31536962#31536962
|
||||||
|
// - https://gist.github.com/simon-cj/b4da0b2bca793ec3b8a5abe04c8fca41
|
||||||
|
resp, err = t.RoundTripper.RoundTrip(req)
|
||||||
|
logs.Debug(resp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
resp.Header.Del("Access-Control-Request-Method")
|
||||||
|
resp.Header.Set("Access-Control-Allow-Origin", "*")
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
web.Any("/cors-anywhere", func(ctx *context.Context) {
|
||||||
|
u, _ := url.PathUnescape(ctx.Input.Query("url"))
|
||||||
|
logs.Error("ReverseProxy: ", u)
|
||||||
|
if len(u) > 0 && strings.HasPrefix(u, "http") {
|
||||||
|
if strings.TrimRight(conf.BaseUrl, "/") == ctx.Input.Site() {
|
||||||
|
ctx.Redirect(302, u)
|
||||||
|
} else {
|
||||||
|
target, _ := url.Parse(u)
|
||||||
|
logs.Debug("target: ", target)
|
||||||
|
|
||||||
|
proxy := &httputil.ReverseProxy{
|
||||||
|
Transport: roundTripper(rt),
|
||||||
|
Director: func(req *http.Request) {
|
||||||
|
req.Header = ctx.Request.Header
|
||||||
|
req.URL.Scheme = target.Scheme
|
||||||
|
req.URL.Host = target.Host
|
||||||
|
req.URL.Path = target.Path
|
||||||
|
req.Header.Set("Host", target.Host)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
|
||||||
|
proxy.ServeHTTP(ctx.ResponseWriter, ctx.Request)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx.ResponseWriter.WriteHeader(http.StatusBadRequest)
|
||||||
|
ctx.Output.Body([]byte("400 Bad Request"))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
web.Router("/", &controllers.HomeController{}, "*:Index")
|
web.Router("/", &controllers.HomeController{}, "*:Index")
|
||||||
|
|
||||||
web.Router("/login", &controllers.AccountController{}, "*:Login")
|
web.Router("/login", &controllers.AccountController{}, "*:Login")
|
||||||
|
|
|
@ -3,6 +3,10 @@ $(function () {
|
||||||
js : window.katex.js,
|
js : window.katex.js,
|
||||||
css : window.katex.css
|
css : window.katex.css
|
||||||
};
|
};
|
||||||
|
var htmlDecodeList = ["style","script","title","onmouseover","onmouseout","style"];
|
||||||
|
if (!window.IS_ENABLE_IFRAME) {
|
||||||
|
htmlDecodeList.unshift("iframe");
|
||||||
|
}
|
||||||
window.editor = editormd("docEditor", {
|
window.editor = editormd("docEditor", {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
|
@ -18,8 +22,8 @@ $(function () {
|
||||||
taskList: true,
|
taskList: true,
|
||||||
flowChart: true,
|
flowChart: true,
|
||||||
mermaid: true,
|
mermaid: true,
|
||||||
htmlDecode: "style,script,iframe,title,onmouseover,onmouseout,style",
|
htmlDecode: htmlDecodeList.join(','),
|
||||||
lineNumbers: false,
|
lineNumbers: true,
|
||||||
sequenceDiagram: true,
|
sequenceDiagram: true,
|
||||||
highlightStyle: window.highlightStyle ? window.highlightStyle : "github",
|
highlightStyle: window.highlightStyle ? window.highlightStyle : "github",
|
||||||
tocStartLevel: 1,
|
tocStartLevel: 1,
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
!function(P,H,k){"use strict";if(1==P.importNode.length&&!H.get("ungap-li")){var D="extends";try{var e={extends:"li"},t=HTMLLIElement,n=function(){return Reflect.construct(t,[],n)};if(n.prototype=k.create(t.prototype),H.define("ungap-li",n,e),!/is="ungap-li"/.test((new n).outerHTML))throw e}catch(e){!function(){var l="attributeChangedCallback",n="connectedCallback",r="disconnectedCallback",e=Element.prototype,i=k.assign,t=k.create,o=k.defineProperties,a=k.getOwnPropertyDescriptor,s=k.setPrototypeOf,u=H.define,c=H.get,f=H.upgrade,p=H.whenDefined,v=t(null),d=new WeakMap,g={childList:!0,subtree:!0};Reflect.ownKeys(self).filter(function(e){return"string"==typeof e&&/^HTML(?!Element)/.test(e)}).forEach(function(e){function t(){}var n=self[e];s(t,n),(t.prototype=n.prototype).constructor=t,(n={})[e]={value:t},o(self,n)}),new MutationObserver(m).observe(P,g),O(Document.prototype,"importNode"),O(Node.prototype,"cloneNode"),o(H,{define:{value:function(e,t,n){if(e=e.toLowerCase(),n&&D in n){v[e]=i({},n,{Class:t});for(var e=n[D]+'[is="'+e+'"]',r=P.querySelectorAll(e),o=0,a=r.length;o<a;o++)A(r[o])}else u.apply(H,arguments)}},get:{value:function(e){return e in v?v[e].Class:c.call(H,e)}},upgrade:{value:function(e){var t=L(e);!t||e instanceof t.Class?f.call(H,e):N(e,t)}},whenDefined:{value:function(e){return e in v?Promise.resolve():p.call(H,e)}}});var h=P.createElement;o(P,{createElement:{value:function(e,t){e=h.call(P,e);return t&&"is"in t&&(e.setAttribute("is",t.is),H.upgrade(e)),e}}});var b=a(e,"attachShadow").value,y=a(e,"innerHTML");function m(e){for(var t=0,n=e.length;t<n;t++){for(var r=e[t],o=r.addedNodes,a=r.removedNodes,i=0,l=o.length;i<l;i++)A(o[i]);for(i=0,l=a.length;i<l;i++)C(a[i])}}function w(e){for(var t=0,n=e.length;t<n;t++){var r=e[t],o=r.attributeName,a=r.oldValue,i=r.target,r=i.getAttribute(o);l in i&&(a!=r||null!=r)&&i[l](o,a,i.getAttribute(o),null)}}function C(e){var t;1===e.nodeType&&((t=L(e))&&e instanceof t.Class&&r in e&&d.get(e)!==r&&(d.set(e,r),Promise.resolve(e).then(T)),E(e,C))}function L(e){e=e.getAttribute("is");return e&&(e=e.toLowerCase())in v?v[e]:null}function M(e){e[n]()}function T(e){e[r]()}function N(e,t){var t=t.Class,n=t.observedAttributes||[];if(s(e,t.prototype),n.length){new MutationObserver(w).observe(e,{attributes:!0,attributeFilter:n,attributeOldValue:!0});for(var r=[],o=0,a=n.length;o<a;o++)r.push({attributeName:n[o],oldValue:null,target:e});w(r)}}function A(e){var t;1===e.nodeType&&((t=L(e))&&(e instanceof t.Class||N(e,t),n in e&&e.isConnected&&d.get(e)!==n&&(d.set(e,n),Promise.resolve(e).then(M))),E(e,A))}function E(e,t){for(var n=e.content,r=(n&&11==n.nodeType?n:e).querySelectorAll("[is]"),o=0,a=r.length;o<a;o++)t(r[o])}function O(e,t){var n=e[t],r={};r[t]={value:function(){var e=n.apply(this,arguments);switch(e.nodeType){case 1:case 11:E(e,A)}return e}},o(e,r)}o(e,{attachShadow:{value:function(){var e=b.apply(this,arguments);return new MutationObserver(m).observe(e,g),e}},innerHTML:{get:y.get,set:function(e){y.set.call(this,e),/\bis=("|')?[a-z0-9_-]+\1/i.test(e)&&E(this,A)}}})}()}}}(document,customElements,Object);
|
|
@ -54,7 +54,10 @@ $(function () {
|
||||||
remark: 'Remark',
|
remark: 'Remark',
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
var htmlDecodeList = ["style","script","title","onmouseover","onmouseout","style"];
|
||||||
|
if (!window.IS_ENABLE_IFRAME) {
|
||||||
|
htmlDecodeList.unshift("iframe");
|
||||||
|
}
|
||||||
window.editor = editormd("docEditor", {
|
window.editor = editormd("docEditor", {
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "100%",
|
height: "100%",
|
||||||
|
@ -69,8 +72,8 @@ $(function () {
|
||||||
fileUploadURL: window.fileUploadURL,
|
fileUploadURL: window.fileUploadURL,
|
||||||
taskList: true,
|
taskList: true,
|
||||||
flowChart: true,
|
flowChart: true,
|
||||||
htmlDecode: "style,script,iframe,title,onmouseover,onmouseout,style",
|
htmlDecode: htmlDecodeList.join(','),
|
||||||
lineNumbers: false,
|
lineNumbers: true,
|
||||||
sequenceDiagram: true,
|
sequenceDiagram: true,
|
||||||
tocStartLevel: 1,
|
tocStartLevel: 1,
|
||||||
tocm: true,
|
tocm: true,
|
||||||
|
@ -193,7 +196,7 @@ $(function () {
|
||||||
} else {
|
} else {
|
||||||
var action = window.editor.toolbarHandlers[name];
|
var action = window.editor.toolbarHandlers[name];
|
||||||
|
|
||||||
if (action !== "undefined") {
|
if (!!action && action !== "undefined") {
|
||||||
$.proxy(action, window.editor)();
|
$.proxy(action, window.editor)();
|
||||||
window.editor.focus();
|
window.editor.focus();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
customElements.define('x-frame-bypass', class extends HTMLIFrameElement {
|
||||||
|
static get observedAttributes() {
|
||||||
|
return ['src']
|
||||||
|
}
|
||||||
|
constructor () {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
attributeChangedCallback () {
|
||||||
|
this.load(this.src)
|
||||||
|
}
|
||||||
|
connectedCallback () {
|
||||||
|
this.sandbox = '' + this.sandbox || 'allow-forms allow-modals allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-presentation allow-same-origin allow-scripts allow-top-navigation-by-user-activation' // all except allow-top-navigation
|
||||||
|
}
|
||||||
|
load (url, options) {
|
||||||
|
if (!url || !url.startsWith('http'))
|
||||||
|
throw new Error(`X-Frame-Bypass src ${url} does not start with http(s)://`)
|
||||||
|
console.log('X-Frame-Bypass loading:', url)
|
||||||
|
this.srcdoc = `<html>
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
.loader {
|
||||||
|
position: absolute;
|
||||||
|
top: calc(50% - 25px);
|
||||||
|
left: calc(50% - 25px);
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #333;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: loader 1s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
@keyframes loader {
|
||||||
|
0% {
|
||||||
|
transform: scale(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scale(1);
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="loader"></div>
|
||||||
|
</body>
|
||||||
|
</html>`
|
||||||
|
this.fetchProxy(url, options, 0).then(res => res.text()).then(data => {
|
||||||
|
if (data)
|
||||||
|
this.srcdoc = data.replace(/<head([^>]*)>/i, `<head$1>
|
||||||
|
<base href="${url}">
|
||||||
|
<script>
|
||||||
|
// X-Frame-Bypass navigation event handlers
|
||||||
|
document.addEventListener('click', e => {
|
||||||
|
if (frameElement && document.activeElement && document.activeElement.href) {
|
||||||
|
e.preventDefault()
|
||||||
|
frameElement.load(document.activeElement.href)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
document.addEventListener('submit', e => {
|
||||||
|
if (frameElement && document.activeElement && document.activeElement.form && document.activeElement.form.action) {
|
||||||
|
e.preventDefault()
|
||||||
|
if (document.activeElement.form.method === 'post')
|
||||||
|
frameElement.load(document.activeElement.form.action, {method: 'post', body: new FormData(document.activeElement.form)})
|
||||||
|
else
|
||||||
|
frameElement.load(document.activeElement.form.action + '?' + new URLSearchParams(new FormData(document.activeElement.form)))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
</script>`)
|
||||||
|
}).catch(e => console.error('Cannot load X-Frame-Bypass:', e))
|
||||||
|
}
|
||||||
|
fetchProxy (url, options, i) {
|
||||||
|
const proxies = (options || {}).proxies || [
|
||||||
|
window.BASE_URL + 'cors-anywhere?url=',
|
||||||
|
'https://cors-anywhere.herokuapp.com/',
|
||||||
|
'https://yacdn.org/proxy/',
|
||||||
|
'https://api.codetabs.com/v1/proxy/?quest='
|
||||||
|
]
|
||||||
|
return fetch(proxies[i] + url, options).then(res => {
|
||||||
|
if (!res.ok)
|
||||||
|
throw new Error(`${res.status} ${res.statusText}`);
|
||||||
|
return res
|
||||||
|
}).catch(error => {
|
||||||
|
if (i === proxies.length - 1)
|
||||||
|
throw error
|
||||||
|
return this.fetchProxy(url, options, i + 1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, {extends: 'iframe'})
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/mindoc-org/mindoc/conf"
|
"github.com/mindoc-org/mindoc/conf"
|
||||||
)
|
)
|
||||||
|
|
||||||
func StripTags(s string) string {
|
func StripTags(s string) string {
|
||||||
|
|
||||||
//将HTML标签全转换成小写
|
//将HTML标签全转换成小写
|
||||||
re, _ := regexp.Compile("\\<[\\S\\s]+?\\>")
|
re, _ := regexp.Compile("\\<[\\S\\s]+?\\>")
|
||||||
|
@ -33,8 +33,9 @@ func StripTags(s string) string {
|
||||||
|
|
||||||
return src
|
return src
|
||||||
}
|
}
|
||||||
|
|
||||||
//自动提取文章摘要
|
//自动提取文章摘要
|
||||||
func AutoSummary(body string,l int) string {
|
func AutoSummary(body string, l int) string {
|
||||||
|
|
||||||
//匹配图片,如果图片语法是在代码块中,这里同样会处理
|
//匹配图片,如果图片语法是在代码块中,这里同样会处理
|
||||||
re := regexp.MustCompile(`<p>(.*?)</p>`)
|
re := regexp.MustCompile(`<p>(.*?)</p>`)
|
||||||
|
@ -42,11 +43,11 @@ func AutoSummary(body string,l int) string {
|
||||||
contents := re.FindAllString(body, -1)
|
contents := re.FindAllString(body, -1)
|
||||||
|
|
||||||
if len(contents) <= 0 {
|
if len(contents) <= 0 {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
content := ""
|
content := ""
|
||||||
for _,s := range contents {
|
for _, s := range contents {
|
||||||
b := strings.Replace(StripTags(s),"\n","", -1)
|
b := strings.Replace(StripTags(s), "\n", "", -1)
|
||||||
|
|
||||||
if l <= 0 {
|
if l <= 0 {
|
||||||
break
|
break
|
||||||
|
@ -70,7 +71,9 @@ func SafetyProcessor(html string) string {
|
||||||
docQuery.Find("applet").Remove()
|
docQuery.Find("applet").Remove()
|
||||||
docQuery.Find("frame").Remove()
|
docQuery.Find("frame").Remove()
|
||||||
docQuery.Find("meta").Remove()
|
docQuery.Find("meta").Remove()
|
||||||
docQuery.Find("iframe").Remove()
|
if !conf.GetEnableIframe() {
|
||||||
|
docQuery.Find("iframe").Remove()
|
||||||
|
}
|
||||||
docQuery.Find("*").Each(func(i int, selection *goquery.Selection) {
|
docQuery.Find("*").Each(func(i int, selection *goquery.Selection) {
|
||||||
|
|
||||||
if href, ok := selection.Attr("href"); ok && strings.HasPrefix(href, "javascript:") {
|
if href, ok := selection.Attr("href"); ok && strings.HasPrefix(href, "javascript:") {
|
||||||
|
@ -117,9 +120,8 @@ func SafetyProcessor(html string) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if html, err := docQuery.Html(); err == nil {
|
if html, err := docQuery.Html(); err == nil {
|
||||||
return strings.TrimSuffix(strings.TrimPrefix(strings.TrimSpace(html), "<html><head></head><body>"), "</body></html>")
|
return strings.TrimSuffix(strings.TrimPrefix(strings.TrimSpace(html), "<html><head></head><body>"), "</body></html>")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return html
|
return html
|
||||||
|
|
|
@ -29,6 +29,10 @@
|
||||||
<link href="{{cdncss "/static/katex/katex.min.css"}}" rel="stylesheet">
|
<link href="{{cdncss "/static/katex/katex.min.css"}}" rel="stylesheet">
|
||||||
<link href="{{cdncss "/static/css/print.css" "version"}}" media="print" rel="stylesheet">
|
<link href="{{cdncss "/static/css/print.css" "version"}}" media="print" rel="stylesheet">
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.IS_ENABLE_IFRAME = '{{conf "enable_iframe" }}' === 'true';
|
||||||
|
window.BASE_URL = '{{urlfor "HomeController.Index" }}';
|
||||||
|
</script>
|
||||||
<script type="text/javascript">window.book={"identify":"{{.Model.Identify}}"};</script>
|
<script type="text/javascript">window.book={"identify":"{{.Model.Identify}}"};</script>
|
||||||
<style>
|
<style>
|
||||||
.btn-mobile {
|
.btn-mobile {
|
||||||
|
@ -251,6 +255,8 @@
|
||||||
<script src="{{cdnjs "/static/js/jquery.highlight.js"}}" type="text/javascript"></script>
|
<script src="{{cdnjs "/static/js/jquery.highlight.js"}}" type="text/javascript"></script>
|
||||||
<script src="{{cdnjs "/static/js/kancloud.js" "version"}}" type="text/javascript"></script>
|
<script src="{{cdnjs "/static/js/kancloud.js" "version"}}" type="text/javascript"></script>
|
||||||
<script src="{{cdnjs "/static/js/splitbar.js" "version"}}" type="text/javascript"></script>
|
<script src="{{cdnjs "/static/js/splitbar.js" "version"}}" type="text/javascript"></script>
|
||||||
|
<script src="{{cdnjs "/static/js/custom-elements-builtin-0.6.5.min.js"}}" type="text/javascript"></script>
|
||||||
|
<script src="{{cdnjs "/static/js/x-frame-bypass-1.0.2.js"}}" type="text/javascript"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(function () {
|
$(function () {
|
||||||
$("#searchList").on("click","a",function () {
|
$("#searchList").on("click","a",function () {
|
||||||
|
|
|
@ -92,6 +92,10 @@
|
||||||
border: 1px solid #357ebd;
|
border: 1px solid #357ebd;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.IS_ENABLE_IFRAME = '{{conf "enable_iframe" }}' === 'true';
|
||||||
|
window.BASE_URL = '{{urlfor "HomeController.Index" }}';
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="auth_form">
|
<div class="auth_form">
|
||||||
|
@ -109,6 +113,8 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script src="{{cdnjs "/static/js/custom-elements-builtin-0.6.5.min.js"}}" type="text/javascript"></script>
|
||||||
|
<script src="{{cdnjs "/static/js/x-frame-bypass-1.0.2.js"}}" type="text/javascript"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$("#auth_form").ajaxForm({
|
$("#auth_form").ajaxForm({
|
||||||
beforeSerialize: function () {
|
beforeSerialize: function () {
|
||||||
|
|
|
@ -11,7 +11,10 @@
|
||||||
color: #44B036 !important;
|
color: #44B036 !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.IS_ENABLE_IFRAME = '{{conf "enable_iframe" }}' === 'true';
|
||||||
|
window.BASE_URL = '{{urlfor "HomeController.Index" }}';
|
||||||
|
</script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.editor = null;
|
window.editor = null;
|
||||||
window.imageUploadURL = "{{urlfor "DocumentController.Upload" "identify" .Model.Identify}}";
|
window.imageUploadURL = "{{urlfor "DocumentController.Upload" "identify" .Model.Identify}}";
|
||||||
|
@ -207,6 +210,8 @@
|
||||||
<script src="{{cdnjs "/static/js/jquery.form.js"}}" type="text/javascript"></script>
|
<script src="{{cdnjs "/static/js/jquery.form.js"}}" type="text/javascript"></script>
|
||||||
<script src="{{cdnjs "/static/js/editor.js"}}" type="text/javascript"></script>
|
<script src="{{cdnjs "/static/js/editor.js"}}" type="text/javascript"></script>
|
||||||
<script src="{{cdnjs "/static/js/html-editor.js"}}" type="text/javascript"></script>
|
<script src="{{cdnjs "/static/js/html-editor.js"}}" type="text/javascript"></script>
|
||||||
|
<script src="{{cdnjs "/static/js/custom-elements-builtin-0.6.5.min.js"}}" type="text/javascript"></script>
|
||||||
|
<script src="{{cdnjs "/static/js/x-frame-bypass-1.0.2.js"}}" type="text/javascript"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(function () {
|
$(function () {
|
||||||
lang = {{i18n $.Lang "common.js_lang"}};
|
lang = {{i18n $.Lang "common.js_lang"}};
|
||||||
|
|
|
@ -19,6 +19,10 @@
|
||||||
<script src="/static/html5shiv/3.7.3/html5shiv.min.js"></script>
|
<script src="/static/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||||
<script src="/static/respond.js/1.4.2/respond.min.js"></script>
|
<script src="/static/respond.js/1.4.2/respond.min.js"></script>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.IS_ENABLE_IFRAME = '{{conf "enable_iframe" }}' === 'true';
|
||||||
|
window.BASE_URL = '{{urlfor "HomeController.Index" }}';
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="m-manual manual-reader">
|
<div class="m-manual manual-reader">
|
||||||
|
@ -173,6 +177,8 @@
|
||||||
<script src="{{cdnjs "/static/bootstrap/js/bootstrap.min.js"}}"></script>
|
<script src="{{cdnjs "/static/bootstrap/js/bootstrap.min.js"}}"></script>
|
||||||
<script src="{{cdnjs "/static/jstree/3.3.4/jstree.min.js"}}" type="text/javascript"></script>
|
<script src="{{cdnjs "/static/jstree/3.3.4/jstree.min.js"}}" type="text/javascript"></script>
|
||||||
<script src="{{cdnjs "/static/jquery/plugins/imgbox/jquery.imgbox.pack.js"}}"></script>
|
<script src="{{cdnjs "/static/jquery/plugins/imgbox/jquery.imgbox.pack.js"}}"></script>
|
||||||
|
<script src="{{cdnjs "/static/js/custom-elements-builtin-0.6.5.min.js"}}" type="text/javascript"></script>
|
||||||
|
<script src="{{cdnjs "/static/js/x-frame-bypass-1.0.2.js"}}" type="text/javascript"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(function () {
|
$(function () {
|
||||||
$("#sidebar").jstree({
|
$("#sidebar").jstree({
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<title>{{i18n .Lang "doc.edit_doc"}} - Powered by MinDoc</title>
|
<title>{{i18n .Lang "doc.edit_doc"}} - Powered by MinDoc</title>
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.IS_ENABLE_IFRAME = '{{conf "enable_iframe" }}' === 'true';
|
||||||
|
window.BASE_URL = '{{urlfor "HomeController.Index" }}';
|
||||||
|
</script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.treeCatalog = null;
|
window.treeCatalog = null;
|
||||||
window.baseUrl = "{{.BaseUrl}}";
|
window.baseUrl = "{{.BaseUrl}}";
|
||||||
|
@ -452,6 +456,8 @@
|
||||||
<script src="{{cdnjs "/static/js/array.js" "version"}}" type="text/javascript"></script>
|
<script src="{{cdnjs "/static/js/array.js" "version"}}" type="text/javascript"></script>
|
||||||
<script src="{{cdnjs "/static/js/editor.js" "version"}}" type="text/javascript"></script>
|
<script src="{{cdnjs "/static/js/editor.js" "version"}}" type="text/javascript"></script>
|
||||||
<script src="{{cdnjs "/static/js/markdown.js" "version"}}" type="text/javascript"></script>
|
<script src="{{cdnjs "/static/js/markdown.js" "version"}}" type="text/javascript"></script>
|
||||||
|
<script src="{{cdnjs "/static/js/custom-elements-builtin-0.6.5.min.js"}}" type="text/javascript"></script>
|
||||||
|
<script src="{{cdnjs "/static/js/x-frame-bypass-1.0.2.js"}}" type="text/javascript"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(function () {
|
$(function () {
|
||||||
editLangPath = {{cdnjs "/static/editor.md/languages/"}} + lang
|
editLangPath = {{cdnjs "/static/editor.md/languages/"}} + lang
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
<title>{{i18n .Lang "doc.edit_doc"}} - Powered by MinDoc</title>
|
<title>{{i18n .Lang "doc.edit_doc"}} - Powered by MinDoc</title>
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.IS_ENABLE_IFRAME = '{{conf "enable_iframe" }}' === 'true';
|
||||||
|
window.BASE_URL = '{{urlfor "HomeController.Index" }}';
|
||||||
|
</script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
window.editor = null;
|
window.editor = null;
|
||||||
window.imageUploadURL = "{{urlfor "DocumentController.Upload" "identify" .Model.Identify}}";
|
window.imageUploadURL = "{{urlfor "DocumentController.Upload" "identify" .Model.Identify}}";
|
||||||
|
@ -384,6 +388,8 @@
|
||||||
<script src="{{cdnjs "/static/js/array.js" "version"}}" type="text/javascript"></script>
|
<script src="{{cdnjs "/static/js/array.js" "version"}}" type="text/javascript"></script>
|
||||||
<script src="{{cdnjs "/static/js/editor.js"}}" type="text/javascript"></script>
|
<script src="{{cdnjs "/static/js/editor.js"}}" type="text/javascript"></script>
|
||||||
<script src="{{cdnjs "/static/js/quill.js"}}" type="text/javascript"></script>
|
<script src="{{cdnjs "/static/js/quill.js"}}" type="text/javascript"></script>
|
||||||
|
<script src="{{cdnjs "/static/js/custom-elements-builtin-0.6.5.min.js"}}" type="text/javascript"></script>
|
||||||
|
<script src="{{cdnjs "/static/js/x-frame-bypass-1.0.2.js"}}" type="text/javascript"></script>
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$(function () {
|
$(function () {
|
||||||
lang = {{i18n $.Lang "common.js_lang"}};
|
lang = {{i18n $.Lang "common.js_lang"}};
|
||||||
|
|
Loading…
Reference in New Issue