diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2012-11-16 03:46:43 -0800 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2012-11-16 03:46:43 -0800 |
commit | b339c747a9943e9961239a234dcd6e16566a53e1 (patch) | |
tree | f933d5d04aa155fb55941c5bc9175dbb6eacc917 | |
parent | c7aeb5127e3e7e852ed76096ad90a68ebd1195fa (diff) | |
parent | 245544a9d9807c6875eb7b3d63ab6d76468464d6 (diff) | |
download | gitlab-ce-b339c747a9943e9961239a234dcd6e16566a53e1.tar.gz |
Merge pull request #1937 from riyad/add-file-line-links
Add file line links
-rw-r--r-- | Gemfile | 2 | ||||
-rw-r--r-- | Gemfile.lock | 14 | ||||
-rw-r--r-- | app/assets/javascripts/application.js | 1 | ||||
-rw-r--r-- | app/assets/javascripts/tree.js.coffee | 19 | ||||
-rw-r--r-- | app/assets/stylesheets/gitlab_bootstrap/files.scss | 88 | ||||
-rw-r--r-- | app/assets/stylesheets/highlight/dark.scss | 61 | ||||
-rw-r--r-- | app/assets/stylesheets/highlight/white.scss | 194 | ||||
-rw-r--r-- | app/views/tree/blob/_text.html.haml | 2 | ||||
-rw-r--r-- | vendor/assets/javascripts/jquery.scrollto.js | 225 |
9 files changed, 409 insertions, 197 deletions
@@ -33,7 +33,7 @@ gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref gem "gitolite", '1.1.0' # Syntax highlighter -gem "pygments.rb", "0.3.1" +gem "pygments.rb", git: "https://github.com/gitlabhq/pygments.rb.git", ref: '4db80c599067e2d5f23c5c243bf85b8ca0368ad4' # Language detection gem "github-linguist", "~> 2.3.4" , require: "linguist" diff --git a/Gemfile.lock b/Gemfile.lock index 76e92cd9d2f..3c1fa68dcb1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -42,6 +42,15 @@ GIT rubyntlm (~> 0.1.1) GIT + remote: https://github.com/gitlabhq/pygments.rb.git + revision: 4db80c599067e2d5f23c5c243bf85b8ca0368ad4 + ref: 4db80c599067e2d5f23c5c243bf85b8ca0368ad4 + specs: + pygments.rb (0.3.2) + posix-spawn (~> 0.3.6) + yajl-ruby (~> 1.1.0) + +GIT remote: https://github.com/gitlabhq/yaml_db.git revision: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd ref: 98e9a5dca43e3fedd3268c76a73af40d1bdf1dfd @@ -271,9 +280,6 @@ GEM coderay (~> 1.0.5) method_source (~> 0.7.1) slop (>= 2.4.4, < 3) - pygments.rb (0.3.1) - posix-spawn (~> 0.3.6) - yajl-ruby (~> 1.1.0) pyu-ruby-sasl (0.0.3.3) quiet_assets (1.0.1) railties (~> 3.1) @@ -470,7 +476,7 @@ DEPENDENCIES pg poltergeist pry - pygments.rb (= 0.3.1) + pygments.rb! quiet_assets (= 1.0.1) rack-mini-profiler rails (= 3.2.9) diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index c4e9a1b027d..49effdf9c15 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -13,6 +13,7 @@ //= require jquery.history //= require jquery.waitforimages //= require jquery.atwho +//= require jquery.scrollto //= require bootstrap //= require modernizr //= require chosen-jquery diff --git a/app/assets/javascripts/tree.js.coffee b/app/assets/javascripts/tree.js.coffee index 37adef70f35..8ef41e16853 100644 --- a/app/assets/javascripts/tree.js.coffee +++ b/app/assets/javascripts/tree.js.coffee @@ -35,3 +35,22 @@ $ -> state = History.getState() window.ajaxGet(state.url) )(window) + + # See if there are lines selected + # "#L12" and "#L34-56" supported + highlightBlobLines = -> + if window.location.hash isnt "" + matches = window.location.hash.match /\#L(\d+)(\-(\d+))?/ + first_line = parseInt matches[1] + last_line = parseInt matches[3] + + unless isNaN first_line + last_line = first_line if isNaN last_line + $("#tree-content-holder .highlight .line").removeClass("hll") + $("#LC#{line}").addClass("hll") for line in [first_line..last_line] + $("#L#{first_line}").ScrollTo() + + # Highlight the correct lines on load + highlightBlobLines() + # Highlight the correct lines when the hash part of the URL changes + $(window).on 'hashchange', highlightBlobLines diff --git a/app/assets/stylesheets/gitlab_bootstrap/files.scss b/app/assets/stylesheets/gitlab_bootstrap/files.scss index 580b74238ab..4887d1c9402 100644 --- a/app/assets/stylesheets/gitlab_bootstrap/files.scss +++ b/app/assets/stylesheets/gitlab_bootstrap/files.scss @@ -132,39 +132,73 @@ * Code file */ &.code { - padding:0; - td.code { - width: 100%; - .highlight { - margin-left: 55px; - overflow:auto; - overflow-y:hidden; - } - } - .highlight pre { - white-space: pre; - word-wrap:normal; - } + padding: 0; - table.highlighttable { + table.lines { border: none; - } - body.project-page table.highlighttable td { border: none } - table.highlighttable tr:hover { background:none;} + box-shadow: none; + margin: 0px; + padding: 0px; + table-layout: fixed; - table.highlighttable pre{ - line-height:16px !important; - font-size:12px !important; - } + pre { + background: none; + border: none; + font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; + font-size: 12px !important; + line-height: 16px !important; + margin: 0; + padding: 10px 0; + } + td { + border: none; + margin: 0; + padding: 0; + vertical-align: top; + + &:first-child { + background: #eee; + width: 50px; + } + &:last-child { + } + } + tr:hover { + background: none; + } - table.highlighttable .linenodiv { - a { + pre.line_numbers { color: #666; - } - pre { + padding: 10px 6px 10px 0; text-align: right; - padding-right: 4px; - color:#666; + + a { + color: #666; + + i { + display: none; + font-size: 14px; + line-height: 14px; + } + &:hover i { + display: inherit; + } + } + } + + .highlight { + border-left: 1px solid #DEE2E3; + overflow: auto; + overflow-y: hidden; + + pre { + white-space: pre; + word-wrap: normal; + + .line { + padding: 0 10px; + } + } } } } diff --git a/app/assets/stylesheets/highlight/dark.scss b/app/assets/stylesheets/highlight/dark.scss index 97c57835b75..0996cc772f4 100644 --- a/app/assets/stylesheets/highlight/dark.scss +++ b/app/assets/stylesheets/highlight/dark.scss @@ -1,9 +1,8 @@ -.black .highlighttable { - td.linenos { border:none; } - pre { color: #eee } - .highlight { background: #333; border-left:1px solid #555; } +.black .lines .highlight { + background: #333; + pre { color: #eee; } - .hll { background-color: #ffffff } + .hll { display: block; background-color: darken($hover, 65%) } .c { color: #888888; font-style: italic } /* Comment */ .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .k { color: #CDA869; font-weight: bold } /* Keyword */ @@ -22,43 +21,43 @@ .gs { font-weight: bold } /* Generic.Strong */ .gu { color: #606060 } /* Generic.Subheading */ .gt { color: #aa0000 } /* Generic.Traceback */ - .highlight .kc{font-weight:bold;} /* Keyword.Constant */ - .highlight .kd{font-weight:bold;} /* Keyword.Declaration */ - .highlight .kn{font-weight:bold;} /* Keyword.Namespace */ - .highlight .kp{font-weight:bold;} /* Keyword.Pseudo */ - .highlight .kr{font-weight:bold;} /* Keyword.Reserved */ - .highlight .kt{color:#458;font-weight:bold;} /* Keyword.Type */ + .kc{font-weight:bold;} /* Keyword.Constant */ + .kd{font-weight:bold;} /* Keyword.Declaration */ + .kn{font-weight:bold;} /* Keyword.Namespace */ + .kp{font-weight:bold;} /* Keyword.Pseudo */ + .kr{font-weight:bold;} /* Keyword.Reserved */ + .kt{color:#458;font-weight:bold;} /* Keyword.Type */ .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .p { color: #eee; } .s { color: #0AD; background-color: transparent } /* Literal.String */ - .highlight .na{color:#008080;} /* Name.Attribute */ - .highlight .nb{color:#0086B3;} /* Name.Builtin */ - .highlight .nc{color:#ccc;font-weight:bold;} /* Name.Class */ - .highlight .no{color:turquoise;} /* Name.Constant */ - .highlight .ni{color:#800080;} - .highlight .ne{color:#900;font-weight:bold;} /* Name.Exception */ - .highlight .nf{color:#ccc;font-weight:bold;} /* Name.Function */ - .highlight .nn{color:#79C3E0;font-weight:bold;} /* Name.Namespace */ - .highlight .nt{color:#fc5;} /* Name.Tag */ - .highlight .nv{color:#FA4;} /* Name.Variable */ + .na{color:#008080;} /* Name.Attribute */ + .nb{color:#0086B3;} /* Name.Builtin */ + .nc{color:#ccc;font-weight:bold;} /* Name.Class */ + .no{color:turquoise;} /* Name.Constant */ + .ni{color:#800080;} + .ne{color:#900;font-weight:bold;} /* Name.Exception */ + .nf{color:#ccc;font-weight:bold;} /* Name.Function */ + .nn{color:#79C3E0;font-weight:bold;} /* Name.Namespace */ + .nt{color:#fc5;} /* Name.Tag */ + .nv{color:#FA4;} /* Name.Variable */ .py { color: #336699; font-weight: bold } /* Name.Property */ .ow { color: #008800 } /* Operator.Word */ .w { color: #bbbbbb } /* Text.Whitespace */ .mf { color: #7AC; font-weight: bold } /* Literal.Number.Float */ .mh { color: #7AC; font-weight: bold } /* Literal.Number.Hex */ - .highlight .mi {color:#099;} /* Literal.Number.Integer */ + .mi {color:#099;} /* Literal.Number.Integer */ .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .sb { color: #dd2200; background-color: transparent; } /* Literal.String.Backtick */ - .highlight .sc{color:#d14;} /* Literal.String.Char */ + .sc{color:#d14;} /* Literal.String.Char */ .sd { color: #dd2200; background-color: transparent; } /* Literal.String.Doc */ - .highlight .s2{color:orange;} /* Literal.String.Double */ - .highlight .se{color:orange;} /* Literal.String.Escape */ - .highlight .sh{color:orange;} /* Literal.String.Heredoc */ - .highlight .si{color:orange;} /* Literal.String.Interpol */ - .highlight .sx{color:orange;} /* Literal.String.Other */ - .highlight .sr{color:orange;} /* Literal.String.Regex */ - .highlight .s1{color:orange;} /* Literal.String.Single */ - .highlight .ss{color:orange;} /* Literal.String.Symbol */ + .s2{color:orange;} /* Literal.String.Double */ + .se{color:orange;} /* Literal.String.Escape */ + .sh{color:orange;} /* Literal.String.Heredoc */ + .si{color:orange;} /* Literal.String.Interpol */ + .sx{color:orange;} /* Literal.String.Other */ + .sr{color:orange;} /* Literal.String.Regex */ + .s1{color:orange;} /* Literal.String.Single */ + .ss{color:orange;} /* Literal.String.Symbol */ .bp { color: #D58 } /* Name.Builtin.Pseudo */ .vc { color: #336699 } /* Name.Variable.Class */ .vg { color: #dd7700 } /* Name.Variable.Global */ diff --git a/app/assets/stylesheets/highlight/white.scss b/app/assets/stylesheets/highlight/white.scss index 9b003b8ace5..d6792b37e9c 100644 --- a/app/assets/stylesheets/highlight/white.scss +++ b/app/assets/stylesheets/highlight/white.scss @@ -1,141 +1,69 @@ -table.highlighttable { - margin:0px; - padding:0px; - font-size:12px; - table-layout:fixed; - background: #EEE; - box-shadow: none; - border: none; - td.linenos { - background:#eee; - border-left:none; - } - td.code { - border-right:none; - } -} - - -td.code, -td.linenos{ - padding:0; - margin:0; - border-top:0; - vertical-align:top; -} - -.highlighttable .highlight{ - background:none; - padding:10px 0px 0px 10px; - margin-left:0px; - border-left: 1px solid #DEE2E3; +.white .lines .highlight { background: white; -} - -.linenodiv pre, -.highlighttable .highlight pre{ - margin:0; - padding:0; - background:none; - border:none; -} + pre { color: #333; } -.linenodiv pre { - white-space:pre-line; + .hll { display: block; background-color: $hover } + .c { color: #888888; font-style: italic } /* Comment */ + .err { color: #a61717; background-color: #e3d2d2 } /* Error */ + .k { color: #000000; font-weight: bold } /* Keyword */ + .cm { color: #888888 } /* Comment.Multiline */ + .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ + .c1 { color: #888888 } /* Comment.Single */ + .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ + .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ + .ge { font-style: italic } /* Generic.Emph */ + .gr { color: #aa0000 } /* Generic.Error */ + .gh { color: #303030 } /* Generic.Heading */ + .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ + .go { color: #888888 } /* Generic.Output */ + .gp { color: #555555 } /* Generic.Prompt */ + .gs { font-weight: bold } /* Generic.Strong */ + .gu { color: #606060 } /* Generic.Subheading */ + .gt { color: #aa0000 } /* Generic.Traceback */ + .kc{font-weight:bold;} /* Keyword.Constant */ + .kd{font-weight:bold;} /* Keyword.Declaration */ + .kn{font-weight:bold;} /* Keyword.Namespace */ + .kp{font-weight:bold;} /* Keyword.Pseudo */ + .kr{font-weight:bold;} /* Keyword.Reserved */ + .kt{color:#458;font-weight:bold;} /* Keyword.Type */ + .m { color: #0000DD; font-weight: bold } /* Literal.Number */ + .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ + .na{color:#008080;} /* Name.Attribute */ + .nb{color:#0086B3;} /* Name.Builtin */ + .nc{color:#458;font-weight:bold;} /* Name.Class */ + .no{color:#008080;} /* Name.Constant */ + .ni{color:#800080;} + .ne{color:#900;font-weight:bold;} /* Name.Exception */ + .nf{color:#900;font-weight:bold;} /* Name.Function */ + .nn{color:#005;font-weight:bold;} /* Name.Namespace */ + .nt{color:#000080;} /* Name.Tag */ + .nv{color:#008080;} /* Name.Variable */ + .py { color: #336699; font-weight: bold } /* Name.Property */ + .ow { color: #008800 } /* Operator.Word */ + .w { color: #bbbbbb } /* Text.Whitespace */ + .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ + .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ + .mi {color:#099;} /* Literal.Number.Integer */ + .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ + .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ + .sc{color:#d14;} /* Literal.String.Char */ + .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ + .s2{color:#d14;} /* Literal.String.Double */ + .se{color:#d14;} /* Literal.String.Escape */ + .sh{color:#d14;} /* Literal.String.Heredoc */ + .si{color:#d14;} /* Literal.String.Interpol */ + .sx{color:#d14;} /* Literal.String.Other */ + .sr{color:#d14;} /* Literal.String.Regex */ + .s1{color:#d14;} /* Literal.String.Single */ + .ss{color:#d14;} /* Literal.String.Symbol */ + .bp { color: #003388 } /* Name.Builtin.Pseudo */ + .vc { color: #336699 } /* Name.Variable.Class */ + .vg { color: #dd7700 } /* Name.Variable.Global */ + .vi { color: #3333bb } } -td.linenos { - /*background:#F7F7F7;*/ - color:#666; - padding:10px 0px 0px 10px; - float:left; - width:45px; - border-right: 1px solid #ccc; - -} - -td.code .highlight { - overflow: auto; -} -table.highlighttable pre{ - padding:0; - margin:0; - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; - color: #333; - text-align:left; -} - -.git-empty .highlight { - pre{ - padding:15px; - line-height:2.0; - margin:0; - font-family: 'Menlo', 'Liberation Mono', 'Consolas', 'Courier New', 'andale mono','lucida console',monospace; - color: #333; - text-align:left;} - } - -.shadow{ +.shadow { -webkit-box-shadow:0 5px 15px #000; -moz-box-shadow:0 5px 15px #000; box-shadow:0 5px 15px #000; } - -.hll { background-color: #ffffff } -.c { color: #888888; font-style: italic } /* Comment */ -.err { color: #a61717; background-color: #e3d2d2 } /* Error */ -.k { color: #000000; font-weight: bold } /* Keyword */ -.cm { color: #888888 } /* Comment.Multiline */ -.cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ -.c1 { color: #888888 } /* Comment.Single */ -.cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ -.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ -.ge { font-style: italic } /* Generic.Emph */ -.gr { color: #aa0000 } /* Generic.Error */ -.gh { color: #303030 } /* Generic.Heading */ -.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ -.go { color: #888888 } /* Generic.Output */ -.gp { color: #555555 } /* Generic.Prompt */ -.gs { font-weight: bold } /* Generic.Strong */ -.gu { color: #606060 } /* Generic.Subheading */ -.gt { color: #aa0000 } /* Generic.Traceback */ -.highlight .kc{font-weight:bold;} /* Keyword.Constant */ -.highlight .kd{font-weight:bold;} /* Keyword.Declaration */ -.highlight .kn{font-weight:bold;} /* Keyword.Namespace */ -.highlight .kp{font-weight:bold;} /* Keyword.Pseudo */ -.highlight .kr{font-weight:bold;} /* Keyword.Reserved */ -.highlight .kt{color:#458;font-weight:bold;} /* Keyword.Type */ -.m { color: #0000DD; font-weight: bold } /* Literal.Number */ -.s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ -.highlight .na{color:#008080;} /* Name.Attribute */ -.highlight .nb{color:#0086B3;} /* Name.Builtin */ -.highlight .nc{color:#458;font-weight:bold;} /* Name.Class */ -.highlight .no{color:#008080;} /* Name.Constant */ -.highlight .ni{color:#800080;} -.highlight .ne{color:#900;font-weight:bold;} /* Name.Exception */ -.highlight .nf{color:#900;font-weight:bold;} /* Name.Function */ -.highlight .nn{color:#005;font-weight:bold;} /* Name.Namespace */ -.highlight .nt{color:#000080;} /* Name.Tag */ -.highlight .nv{color:#008080;} /* Name.Variable */ -.py { color: #336699; font-weight: bold } /* Name.Property */ -.ow { color: #008800 } /* Operator.Word */ -.w { color: #bbbbbb } /* Text.Whitespace */ -.mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ -.mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ -.highlight .mi {color:#099;} /* Literal.Number.Integer */ -.mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ -.sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ -.highlight .sc{color:#d14;} /* Literal.String.Char */ -.sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ -.highlight .s2{color:#d14;} /* Literal.String.Double */ -.highlight .se{color:#d14;} /* Literal.String.Escape */ -.highlight .sh{color:#d14;} /* Literal.String.Heredoc */ -.highlight .si{color:#d14;} /* Literal.String.Interpol */ -.highlight .sx{color:#d14;} /* Literal.String.Other */ -.highlight .sr{color:#d14;} /* Literal.String.Regex */ -.highlight .s1{color:#d14;} /* Literal.String.Single */ -.highlight .ss{color:#d14;} /* Literal.String.Symbol */ -.bp { color: #003388 } /* Name.Builtin.Pseudo */ -.vc { color: #336699 } /* Name.Variable.Class */ -.vg { color: #dd7700 } /* Name.Variable.Global */ -.vi { color: #3333bb } diff --git a/app/views/tree/blob/_text.html.haml b/app/views/tree/blob/_text.html.haml index 3b7f293a35c..9e0f4bc4bc1 100644 --- a/app/views/tree/blob/_text.html.haml +++ b/app/views/tree/blob/_text.html.haml @@ -10,6 +10,6 @@ - unless blob.empty? %div{class: current_user.dark_scheme ? "black" : "white"} = preserve do - = raw blob.colorize(options: { linenos: true, lineanchors: :line, anchorlinenos: true }) + = raw blob.colorize(formatter: :gitlab) - else %h4.nothing_here_message Empty file diff --git a/vendor/assets/javascripts/jquery.scrollto.js b/vendor/assets/javascripts/jquery.scrollto.js new file mode 100644 index 00000000000..7f10b7f1082 --- /dev/null +++ b/vendor/assets/javascripts/jquery.scrollto.js @@ -0,0 +1,225 @@ +/** + * @depends jquery + * @name jquery.scrollto + * @package jquery-scrollto {@link http://balupton.com/projects/jquery-scrollto} + */ + +/** + * jQuery Aliaser + */ +(function(window,undefined){ + // Prepare + var jQuery, $, ScrollTo; + jQuery = $ = window.jQuery; + + /** + * jQuery ScrollTo (balupton edition) + * @version 1.2.0 + * @date July 9, 2012 + * @since 0.1.0, August 27, 2010 + * @package jquery-scrollto {@link http://balupton.com/projects/jquery-scrollto} + * @author Benjamin "balupton" Lupton {@link http://balupton.com} + * @copyright (c) 2010 Benjamin Arthur Lupton {@link http://balupton.com} + * @license MIT License {@link http://creativecommons.org/licenses/MIT/} + */ + ScrollTo = $.ScrollTo = $.ScrollTo || { + /** + * The Default Configuration + */ + config: { + duration: 400, + easing: 'swing', + callback: undefined, + durationMode: 'each', + offsetTop: 0, + offsetLeft: 0 + }, + + /** + * Configure ScrollTo + */ + configure: function(options){ + // Apply Options to Config + $.extend(ScrollTo.config, options||{}); + + // Chain + return this; + }, + + /** + * Perform the Scroll Animation for the Collections + * We use $inline here, so we can determine the actual offset start for each overflow:scroll item + * Each collection is for each overflow:scroll item + */ + scroll: function(collections, config){ + // Prepare + var collection, $container, container, $target, $inline, position, + containerScrollTop, containerScrollLeft, + containerScrollTopEnd, containerScrollLeftEnd, + startOffsetTop, targetOffsetTop, targetOffsetTopAdjusted, + startOffsetLeft, targetOffsetLeft, targetOffsetLeftAdjusted, + scrollOptions, + callback; + + // Determine the Scroll + collection = collections.pop(); + $container = collection.$container; + container = $container.get(0); + $target = collection.$target; + + // Prepare the Inline Element of the Container + $inline = $('<span/>').css({ + 'position': 'absolute', + 'top': '0px', + 'left': '0px' + }); + position = $container.css('position'); + + // Insert the Inline Element of the Container + $container.css('position','relative'); + $inline.appendTo($container); + + // Determine the top offset + startOffsetTop = $inline.offset().top; + targetOffsetTop = $target.offset().top; + targetOffsetTopAdjusted = targetOffsetTop - startOffsetTop - parseInt(config.offsetTop,10); + + // Determine the left offset + startOffsetLeft = $inline.offset().left; + targetOffsetLeft = $target.offset().left; + targetOffsetLeftAdjusted = targetOffsetLeft - startOffsetLeft - parseInt(config.offsetLeft,10); + + // Determine current scroll positions + containerScrollTop = container.scrollTop; + containerScrollLeft = container.scrollLeft; + + // Reset the Inline Element of the Container + $inline.remove(); + $container.css('position',position); + + // Prepare the scroll options + scrollOptions = {}; + + // Prepare the callback + callback = function(event){ + // Check + if ( collections.length === 0 ) { + // Callback + if ( typeof config.callback === 'function' ) { + config.callback.apply(this,[event]); + } + } + else { + // Recurse + ScrollTo.scroll(collections,config); + } + // Return true + return true; + }; + + // Handle if we only want to scroll if we are outside the viewport + if ( config.onlyIfOutside ) { + // Determine current scroll positions + containerScrollTopEnd = containerScrollTop + $container.height(); + containerScrollLeftEnd = containerScrollLeft + $container.width(); + + // Check if we are in the range of the visible area of the container + if ( containerScrollTop < targetOffsetTopAdjusted && targetOffsetTopAdjusted < containerScrollTopEnd ) { + targetOffsetTopAdjusted = containerScrollTop; + } + if ( containerScrollLeft < targetOffsetLeftAdjusted && targetOffsetLeftAdjusted < containerScrollLeftEnd ) { + targetOffsetLeftAdjusted = containerScrollLeft; + } + } + + // Determine the scroll options + if ( targetOffsetTopAdjusted !== containerScrollTop ) { + scrollOptions.scrollTop = targetOffsetTopAdjusted; + } + if ( targetOffsetLeftAdjusted !== containerScrollLeft ) { + scrollOptions.scrollLeft = targetOffsetLeftAdjusted; + } + + // Perform the scroll + if ( $.browser.safari && container === document.body ) { + window.scrollTo(scrollOptions.scrollLeft, scrollOptions.scrollTop); + callback(); + } + else if ( scrollOptions.scrollTop || scrollOptions.scrollLeft ) { + $container.animate(scrollOptions, config.duration, config.easing, callback); + } + else { + callback(); + } + + // Return true + return true; + }, + + /** + * ScrollTo the Element using the Options + */ + fn: function(options){ + // Prepare + var collections, config, $container, container; + collections = []; + + // Prepare + var $target = $(this); + if ( $target.length === 0 ) { + // Chain + return this; + } + + // Handle Options + config = $.extend({},ScrollTo.config,options); + + // Fetch + $container = $target.parent(); + container = $container.get(0); + + // Cycle through the containers + while ( ($container.length === 1) && (container !== document.body) && (container !== document) ) { + // Check Container for scroll differences + var scrollTop, scrollLeft; + scrollTop = $container.css('overflow-y') !== 'visible' && container.scrollHeight !== container.clientHeight; + scrollLeft = $container.css('overflow-x') !== 'visible' && container.scrollWidth !== container.clientWidth; + if ( scrollTop || scrollLeft ) { + // Push the Collection + collections.push({ + '$container': $container, + '$target': $target + }); + // Update the Target + $target = $container; + } + // Update the Container + $container = $container.parent(); + container = $container.get(0); + } + + // Add the final collection + collections.push({ + '$container': $( + ($.browser.msie || $.browser.mozilla) ? 'html' : 'body' + ), + '$target': $target + }); + + // Adjust the Config + if ( config.durationMode === 'all' ) { + config.duration /= collections.length; + } + + // Handle + ScrollTo.scroll(collections,config); + + // Chain + return this; + } + }; + + // Apply our jQuery Prototype Function + $.fn.ScrollTo = $.ScrollTo.fn; + +})(window); |