From 6a89eeedf3e2130031ac75b8329037424f936013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20San=20Juli=C3=A1n?= Date: Mon, 3 Aug 2015 21:27:07 +0200 Subject: [PATCH 1/2] browser supports copy detection --- .gopmfile | 2 ++ modules/middleware/repo.go | 26 ++++++++++++++++++++++++++ templates/ng/base/head.tmpl | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/.gopmfile b/.gopmfile index 0a70cccee..d4cd97017 100644 --- a/.gopmfile +++ b/.gopmfile @@ -33,6 +33,8 @@ golang.org/x/net = commit:937a34c9de13 golang.org/x/text = commit:5b2527008a4c gopkg.in/ini.v1 = commit:caf3f03ad9 gopkg.in/redis.v2 = commit:e617904962 +github.com/hashicorp/go-version = commit:999359b6b7 +github.com/mssola/user_agent = commit:f659b98638 [res] include = etc|public|scripts|templates diff --git a/modules/middleware/repo.go b/modules/middleware/repo.go index a200d6d66..e8a362bd4 100644 --- a/modules/middleware/repo.go +++ b/modules/middleware/repo.go @@ -16,6 +16,14 @@ import ( "github.com/gogits/gogs/modules/git" "github.com/gogits/gogs/modules/log" "github.com/gogits/gogs/modules/setting" + + "github.com/hashicorp/go-version" + "github.com/mssola/user_agent" +) + +const ( + FIREFOX_COPY_SUPPORT = "41.0" + CHROME_COPY_SUPPORT = "43.0.2356" ) func ApiRepoAssignment() macaron.Handler { @@ -345,6 +353,24 @@ func RepoAssignment(redirect bool, args ...bool) macaron.Handler { ctx.Data["BranchName"] = ctx.Repo.BranchName ctx.Data["CommitId"] = ctx.Repo.CommitId + + userAgent := ctx.Req.Header.Get("User-Agent") + ua := user_agent.New(userAgent); + browserName, browserVer := ua.Browser() + + sliceVer := strings.Split(browserVer, ".") + var max int + if max = len(sliceVer); 3 < max { + max = 3 + } + browserVer = strings.Join(sliceVer[:max], ".") + + browserVersion, err := version.NewVersion(browserVer) + chromeConstraint, err := version.NewConstraint(">= " + CHROME_COPY_SUPPORT) + firefoxConstraint, err := version.NewConstraint(">= " + FIREFOX_COPY_SUPPORT) + + ctx.Data["BrowserSupportsCopy"] = (browserName == "Chrome" && chromeConstraint.Check(browserVersion)) || (browserName == "Firefox" && firefoxConstraint.Check(browserVersion)) + } } diff --git a/templates/ng/base/head.tmpl b/templates/ng/base/head.tmpl index 6d5001a9c..faafef563 100644 --- a/templates/ng/base/head.tmpl +++ b/templates/ng/base/head.tmpl @@ -1,5 +1,5 @@ - + From eebcbf9d3438a9910dee56fd76ab624726eb207c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fernando=20San=20Juli=C3=A1n?= Date: Mon, 3 Aug 2015 21:27:15 +0200 Subject: [PATCH 2/2] add clipboard API support --- public/js/app.js | 78 +++++++++++++++++++++++++++++--------------- public/ng/js/gogs.js | 68 ++++++++++++++++++++++++++------------ 2 files changed, 100 insertions(+), 46 deletions(-) diff --git a/public/js/app.js b/public/js/app.js index 6208dbedc..3dbf29c14 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -269,36 +269,62 @@ var Gogits = {}; if ($(selector).hasClass('js-copy-bind')) { return; } - $(selector).zclip({ - path: "/js/ZeroClipboard.swf", - copy: function () { - var t = $(this).data("copy-val"); - var to = $($(this).data("copy-from")); - var str = ""; - if (t == "txt") { - str = to.text(); - } - if (t == 'val') { - str = to.val(); - } - if (t == 'html') { - str = to.html(); - } - return str; - }, - afterCopy: function () { + + if ( document.documentElement.classList.contains("is-copy-enabled") ) { + + $(selector).click(function(event) { var $this = $(this); - $this.tooltip('hide') - .attr('data-original-title', 'Copied OK'); + + var cfrom = $this.attr('data-copy-from'); + $(cfrom).select(); + document.execCommand('copy'); + getSelection().removeAllRanges(); + + $this.tipsy("hide").attr('original-title', $this.data('after-title')); setTimeout(function () { - $this.tooltip("show"); + $this.tipsy("show"); }, 200); setTimeout(function () { - $this.tooltip('hide') - .attr('data-original-title', 'Copy to Clipboard'); - }, 3000); - } - }).addClass("js-copy-bind"); + $this.tipsy('hide').attr('original-title', $this.data('original-title')); + }, 2000); + + this.blur(); + return; + }); + + $(selector).addClass("js-copy-bind"); + + } else { + + $(selector).zclip({ + path: Gogs.AppSubUrl + "/js/ZeroClipboard.swf", + copy: function () { + var t = $(this).data("copy-val"); + var to = $($(this).data("copy-from")); + var str = ""; + if (t == "txt") { + str = to.text(); + } + if (t == 'val') { + str = to.val(); + } + if (t == 'html') { + str = to.html(); + } + return str; + }, + afterCopy: function () { + var $this = $(this); + $this.tipsy("hide").attr('original-title', $this.data('after-title')); + setTimeout(function () { + $this.tipsy("show"); + }, 200); + setTimeout(function () { + $this.tipsy('hide').attr('original-title', $this.data('original-title')); + }, 2000); + } + }).addClass("js-copy-bind"); + } } // api working diff --git a/public/ng/js/gogs.js b/public/ng/js/gogs.js index 7ffef8af8..38b34c615 100644 --- a/public/ng/js/gogs.js +++ b/public/ng/js/gogs.js @@ -333,25 +333,17 @@ var Gogs = {}; if ($(selector).hasClass('js-copy-bind')) { return; } - $(selector).zclip({ - path: Gogs.AppSubUrl + "/js/ZeroClipboard.swf", - copy: function () { - var t = $(this).data("copy-val"); - var to = $($(this).data("copy-from")); - var str = ""; - if (t == "txt") { - str = to.text(); - } - if (t == 'val') { - str = to.val(); - } - if (t == 'html') { - str = to.html(); - } - return str; - }, - afterCopy: function () { + + if ( document.documentElement.classList.contains("is-copy-enabled") ) { + + $(selector).click(function(event) { var $this = $(this); + + var cfrom = $this.attr('data-copy-from'); + $(cfrom).select(); + document.execCommand('copy'); + getSelection().removeAllRanges(); + $this.tipsy("hide").attr('original-title', $this.data('after-title')); setTimeout(function () { $this.tipsy("show"); @@ -359,8 +351,44 @@ var Gogs = {}; setTimeout(function () { $this.tipsy('hide').attr('original-title', $this.data('original-title')); }, 2000); - } - }).addClass("js-copy-bind"); + + this.blur(); + return; + }); + + $(selector).addClass("js-copy-bind"); + + } else { + + $(selector).zclip({ + path: Gogs.AppSubUrl + "/js/ZeroClipboard.swf", + copy: function () { + var t = $(this).data("copy-val"); + var to = $($(this).data("copy-from")); + var str = ""; + if (t == "txt") { + str = to.text(); + } + if (t == 'val') { + str = to.val(); + } + if (t == 'html') { + str = to.html(); + } + return str; + }, + afterCopy: function () { + var $this = $(this); + $this.tipsy("hide").attr('original-title', $this.data('after-title')); + setTimeout(function () { + $this.tipsy("show"); + }, 200); + setTimeout(function () { + $this.tipsy('hide').attr('original-title', $this.data('original-title')); + }, 2000); + } + }).addClass("js-copy-bind"); + } } })(jQuery);