![](https://seccdn.libravatar.org/avatar/e2145bc5cf53dda95c308a3c75e8fef3.jpg?s=120&d=mm&r=g)
Hello community, here is the log from the commit of package rubygem-turbolinks for openSUSE:Factory checked in at 2015-02-11 16:44:13 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-turbolinks (Old) and /work/SRC/openSUSE:Factory/.rubygem-turbolinks.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "rubygem-turbolinks" Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-turbolinks/rubygem-turbolinks.changes 2014-10-19 19:29:18.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.rubygem-turbolinks.new/rubygem-turbolinks.changes 2015-02-11 16:44:14.000000000 +0100 @@ -1,0 +2,5 @@ +Tue Feb 10 07:58:48 UTC 2015 - coolo@suse.com + +- updated to version 2.5.3, no changelog + +------------------------------------------------------------------- Old: ---- turbolinks-2.4.0.gem New: ---- turbolinks-2.5.3.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-turbolinks.spec ++++++ --- /var/tmp/diff_new_pack.KTu7Hb/_old 2015-02-11 16:44:15.000000000 +0100 +++ /var/tmp/diff_new_pack.KTu7Hb/_new 2015-02-11 16:44:15.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package rubygem-turbolinks # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -24,7 +24,7 @@ # Name: rubygem-turbolinks -Version: 2.4.0 +Version: 2.5.3 Release: 0 %define mod_name turbolinks %define mod_full_name %{mod_name}-%{version} ++++++ turbolinks-2.4.0.gem -> turbolinks-2.5.3.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/README.md new/README.md --- old/README.md 1970-01-01 01:00:00.000000000 +0100 +++ new/README.md 2014-12-08 15:17:40.000000000 +0100 @@ -68,7 +68,13 @@ $(document).on("page:receive", stopSpinner); ``` -DOM transformations that are idempotent are best. If you have transformations that are not, hook them to happen only on `page:load` instead of `page:change` (as that would run them again on the cached pages). +DOM transformations that are idempotent are best. If you have transformations that are not, bind them to `page:load` (in addition to the initial page load) instead of `page:change` (as that would run them again on the cached pages): + +```javascript +// using jQuery for simplicity + +$(document).on("ready page:load", nonIdempotentFunction); +``` Transition Cache: A Speed Boost ------------------------------- @@ -82,10 +88,32 @@ Turbolinks.enableTransitionCache(); ``` -The one drawback is that dramatic differences in appearence between a cached copy and new copy may lead to a jarring affect for the end-user. This will be especially true for pages that have many moving parts (expandable sections, sortable tables, infinite scrolling, etc.). +The one drawback is that dramatic differences in appearance between a cached copy and new copy may lead to a jarring affect for the end-user. This will be especially true for pages that have many moving parts (expandable sections, sortable tables, infinite scrolling, etc.). If you find that a page is causing problems, you can have Turbolinks skip displaying the cached copy by adding `data-no-transition-cache` to any DOM element on the offending page. +Progress Bar +------------ + +Because Turbolinks skips the traditional full page reload, browsers won't display their native progress bar when changing pages. To fill this void, Turbolinks offers an optional JavaScript-and-CSS-based progress bar to display page loading progress. + +To enable the progress bar, include the following in your JavaScript: +```javascript +Turbolinks.enableProgressBar(); +``` + +The progress bar is implemented on the `<html>` element's pseudo `:before` element and can be **customized** by including CSS with higher specificity than the included styles. For example: + +```css +html.turbolinks-progress-bar::before { + background-color: red !important; + height: 5px !important; +} +``` + +In Turbolinks 3.0, the progress bar will be turned on by default. + + Initialization -------------- @@ -127,7 +155,7 @@ jquery.turbolinks ----------------- -If you have a lot of existing JavaScript that binds elements on jQuery.ready(), you can pull the [jquery.turbolinks](https://github.com/kossnocorp/jquery.turbolinks) library into your project that will trigger ready() when Turbolinks triggers the the `page:load` event. It may restore functionality of some libraries. +If you have a lot of existing JavaScript that binds elements on jQuery.ready(), you can pull the [jquery.turbolinks](https://github.com/kossnocorp/jquery.turbolinks) library into your project that will trigger ready() when Turbolinks triggers the `page:load` event. It may restore functionality of some libraries. Add the gem to your project, then add the following line to your JavaScript manifest file, after `jquery.js` but before `turbolinks.js`: @@ -205,6 +233,7 @@ * [ASP.NET MVC Turbolinks](https://github.com/kazimanzurrashid/aspnetmvcturbolinks) * [PHP Turbolinks Component](https://github.com/helthe/Turbolinks) (Symfony Component) * [PHP Turbolinks Package](https://github.com/frenzyapp/turbolinks) (Laravel Package) +* [Grails Turbolinks](http://grails.org/plugin/turbolinks) (Grails Plugin) Credits ------- Files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/assets/javascripts/turbolinks.js.coffee new/lib/assets/javascripts/turbolinks.js.coffee --- old/lib/assets/javascripts/turbolinks.js.coffee 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/assets/javascripts/turbolinks.js.coffee 2014-12-08 15:17:40.000000000 +0100 @@ -1,13 +1,13 @@ pageCache = {} cacheSize = 10 transitionCacheEnabled = false +progressBar = null currentState = null loadedAssets = null referer = null -createDocument = null xhr = null EVENTS = @@ -26,10 +26,11 @@ rememberReferer() cacheCurrentPage() + progressBar?.start() if transitionCacheEnabled and cachedPage = transitionCacheFor(url.absolute) fetchHistory cachedPage - fetchReplacement url + fetchReplacement url, null, false else fetchReplacement url, resetScrollPosition @@ -40,7 +41,15 @@ enableTransitionCache = (enable = true) -> transitionCacheEnabled = enable -fetchReplacement = (url, onLoadFunction = =>) -> +enableProgressBar = (enable = true) -> + return unless browserSupportsTurbolinks + if enable + progressBar ?= new ProgressBar 'html' + else + progressBar?.uninstall() + progressBar = null + +fetchReplacement = (url, onLoadFunction, showProgressBar = true) -> triggerEvent EVENTS.FETCH, url: url.absolute xhr?.abort() @@ -54,13 +63,21 @@ if doc = processResponse() reflectNewUrl url + reflectRedirectedUrl() changePage extractTitleAndBody(doc)... manuallyTriggerHashChangeForFirefox() - reflectRedirectedUrl() - onLoadFunction() + onLoadFunction?() triggerEvent EVENTS.LOAD else - document.location.href = url.absolute + document.location.href = crossOriginRedirect() or url.absolute + + if progressBar and showProgressBar + xhr.onprogress = (event) => + percent = if event.lengthComputable + event.loaded / event.total * 100 + else + progressBar.value + (100 - progressBar.value) / 10 + progressBar.advanceTo(percent) xhr.onloadend = -> xhr = null xhr.onerror = -> document.location.href = url.absolute @@ -110,6 +127,7 @@ setAutofocusElement() executeScriptTags() if runScripts currentState = window.history.state + progressBar?.done() triggerEvent EVENTS.CHANGE triggerEvent EVENTS.UPDATE @@ -134,7 +152,7 @@ autofocusElement = (list = document.querySelectorAll 'input[autofocus], textarea[autofocus]')[list.length - 1] if autofocusElement and document.activeElement isnt autofocusElement autofocusElement.focus() - + reflectNewUrl = (url) -> if (url = new ComponentUrl url).absolute isnt referer window.history.pushState { turbolinks: true, url: url.absolute }, '', url.absolute @@ -143,7 +161,10 @@ if location = xhr.getResponseHeader 'X-XHR-Redirected-To' location = new ComponentUrl location preservedHash = if location.hasNoHash() then document.location.hash else '' - window.history.replaceState currentState, '', location.href + preservedHash + window.history.replaceState window.history.state, '', location.href + preservedHash + +crossOriginRedirect = -> + redirect if (redirect = xhr.getResponseHeader('Location'))? and (new ComponentUrl(redirect)).crossOrigin() rememberReferer = -> referer = document.location.href @@ -204,7 +225,7 @@ 400 <= xhr.status < 600 validContent = -> - (contentType = xhr.getResponseHeader('Content-Type'))? and + (contentType = xhr.getResponseHeader('Content-Type'))? and contentType.match /^(?:text\/html|application\/xhtml\+xml|application\/xml)(?:;|$)/ extractTrackAssets = (doc) -> @@ -239,74 +260,18 @@ if current.token? and latest? and current.token isnt latest current.node.setAttribute 'content', latest -browserCompatibleDocumentParser = -> - createDocumentUsingParser = (html) -> - (new DOMParser).parseFromString html, 'text/html' - - createDocumentUsingDOM = (html) -> - doc = document.implementation.createHTMLDocument '' - doc.documentElement.innerHTML = html - doc - - createDocumentUsingWrite = (html) -> - doc = document.implementation.createHTMLDocument '' - doc.open 'replace' - doc.write html - doc.close() - doc - - createDocumentUsingFragment = (html) -> - head = html.match(/
]*>([\s\S.]*)<\/head>/i)?[0] or '<head></head>' - body = html.match(/]*>([\s\S.]*)<\/body>/i)?[0] or '<body></body>' - htmlWrapper = document.createElement 'html' - htmlWrapper.innerHTML = head + body - doc = document.createDocumentFragment() - doc.appendChild htmlWrapper - doc - - # Use createDocumentUsingParser if DOMParser is defined and natively - # supports 'text/html' parsing (Firefox 12+, IE 10) - # - # Use createDocumentUsingDOM if createDocumentUsingParser throws an exception - # due to unsupported type 'text/html' (Firefox < 12, Opera) - # - # Use createDocumentUsingWrite if: - # - DOMParser isn't defined - # - createDocumentUsingParser returns null due to unsupported type 'text/html' (Chrome, Safari) - # - createDocumentUsingDOM doesn't create a valid HTML document (safeguarding against potential edge cases) - # - # Use createDocumentUsingFragment if the previously selected parser does not - # correctly parse <form> tags. (Safari 7.1+ - see github.com/rails/turbolinks/issues/408) - buildTestsUsing = (createMethod) -> - buildTest = (fallback, passes) -> - passes: passes() - fallback: fallback - - structureTest = buildTest createDocumentUsingWrite, => - (createMethod '<html><body><p>test')?.body?.childNodes.length is 1 - - formNestingTest = buildTest createDocumentUsingFragment, => - (createMethod '<html><body><form></form><div></div></body></html>')?.body?.childNodes.length is 2 - - [structureTest, formNestingTest] - - try - if window.DOMParser - docTests = buildTestsUsing createDocumentUsingParser - createDocumentUsingParser - catch e - docTests = buildTestsUsing createDocumentUsingDOM - createDocumentUsingDOM - finally - for docTest in docTests - return docTest.fallback unless docTest.passes - +createDocument = (html) -> + doc = document.documentElement.cloneNode() + doc.innerHTML = html + doc.head = doc.querySelector 'head' + doc.body = doc.querySelector 'body' + doc # The ComponentUrl class converts a basic URL string into an object -# that behaves similarly to document.location. +# that behaves similarly to document.location. # -# If an instance is created from a relative URL, the current document -# is used to fill in the missing attributes (protocol, host, port). +# If an instance is created from a relative URL, the current document +# is used to fill in the missing attributes (protocol, host, port). class ComponentUrl constructor: (@original = document.location.href) -> return @original if @original.constructor is ComponentUrl @@ -319,6 +284,9 @@ hasNoHash: -> @hash.length is 0 + crossOrigin: -> + @origin isnt (new ComponentUrl).origin + _parse: -> (@link ?= document.createElement 'a').href = @original { @href, @protocol, @host, @hostname, @port, @pathname, @search, @hash } = @link @@ -345,15 +313,12 @@ super shouldIgnore: -> - @_crossOrigin() or - @_anchored() or - @_nonHtml() or - @_optOut() or + @crossOrigin() or + @_anchored() or + @_nonHtml() or + @_optOut() or @_target() - _crossOrigin: -> - @origin isnt (new ComponentUrl).origin - _anchored: -> (@hash.length > 0 or @href.charAt(@href.length - 1) is '#') and (@withoutHash() is (new ComponentUrl).withoutHash()) @@ -373,9 +338,9 @@ # The Click class handles clicked links, verifying if Turbolinks should -# take control by inspecting both the event and the link. If it should, -# the page change process is initiated. If not, control is passed back -# to the browser for default functionality. +# take control by inspecting both the event and the link. If it should, +# the page change process is initiated. If not, control is passed back +# to the browser for default functionality. class Click @installHandlerLast: (event) -> unless event.defaultPrevented @@ -390,7 +355,7 @@ @_extractLink() if @_validForTurbolinks() visit @link.href unless pageChangePrevented(@link.absolute) - @event.preventDefault() + @event.preventDefault() _extractLink: -> link = @event.target @@ -401,13 +366,113 @@ @link? and not (@link.shouldIgnore() or @_nonStandardClick()) _nonStandardClick: -> - @event.which > 1 or - @event.metaKey or - @event.ctrlKey or - @event.shiftKey or + @event.which > 1 or + @event.metaKey or + @event.ctrlKey or + @event.shiftKey or @event.altKey +class ProgressBar + className = 'turbolinks-progress-bar' + + constructor: (@elementSelector) -> + @value = 0 + @content = '' + @speed = 300 + # Setting the opacity to a value < 1 fixes a display issue in Safari 6 and + # iOS 6 where the progress bar would fill the entire page. + @opacity = 0.99 + @install() + + install: -> + @element = document.querySelector(@elementSelector) + @element.classList.add(className) + @styleElement = document.createElement('style') + document.head.appendChild(@styleElement) + @_updateStyle() + + uninstall: -> + @element.classList.remove(className) + document.head.removeChild(@styleElement) + + start: -> + @advanceTo(5) + + advanceTo: (value) -> + if value > @value <= 100 + @value = value + @_updateStyle() + + if @value is 100 + @_stopTrickle() + else if @value > 0 + @_startTrickle() + + done: -> + if @value > 0 + @advanceTo(100) + @_reset() + + _reset: -> + originalOpacity = @opacity + + setTimeout => + @opacity = 0 + @_updateStyle() + , @speed / 2 + + setTimeout => + @value = 0 + @opacity = originalOpacity + @_withSpeed(0, => @_updateStyle(true)) + , @speed + + _startTrickle: -> + return if @trickling + @trickling = true + setTimeout(@_trickle, @speed) + + _stopTrickle: -> + delete @trickling + + _trickle: => + return unless @trickling + @advanceTo(@value + Math.random() / 2) + setTimeout(@_trickle, @speed) + + _withSpeed: (speed, fn) -> + originalSpeed = @speed + @speed = speed + result = fn() + @speed = originalSpeed + result + + _updateStyle: (forceRepaint = false) -> + @_changeContentToForceRepaint() if forceRepaint + @styleElement.textContent = @_createCSSRule() + + _changeContentToForceRepaint: -> + @content = if @content is '' then ' ' else '' + + _createCSSRule: -> + """ + #{@elementSelector}.#{className}::before { + content: '#{@content}'; + position: fixed; + top: 0; + left: 0; + z-index: 2000; + background-color: #0076ff; + height: 3px; + opacity: #{@opacity}; + width: #{@value}%; + transition: width #{@speed}ms ease-out, opacity #{@speed / 2}ms ease-in; + transform: translate3d(0,0,0); + } + """ + + # Delay execution of function long enough to miss the popstate event # some browsers fire on the initial page load. bypassOnLoadPopstate = (fn) -> @@ -436,7 +501,6 @@ initializeTurbolinks = -> rememberCurrentUrl() rememberCurrentState() - createDocument = browserCompatibleDocumentParser() document.addEventListener 'click', Click.installHandlerLast, true @@ -487,7 +551,8 @@ visit, pagesCached, enableTransitionCache, + enableProgressBar, allowLinkExtensions: Link.allowExtensions, supported: browserSupportsTurbolinks, EVENTS: clone(EVENTS) -} \ No newline at end of file +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/turbolinks/version.rb new/lib/turbolinks/version.rb --- old/lib/turbolinks/version.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/lib/turbolinks/version.rb 2014-12-08 15:17:40.000000000 +0100 @@ -1,3 +1,3 @@ module Turbolinks - VERSION = '2.4.0' -end \ No newline at end of file + VERSION = '2.5.3' +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 1970-01-01 01:00:00.000000000 +0100 +++ new/metadata 2014-12-08 15:17:40.000000000 +0100 @@ -1,27 +1,27 @@ --- !ruby/object:Gem::Specification name: turbolinks version: !ruby/object:Gem::Version - version: 2.4.0 + version: 2.5.3 platform: ruby authors: - David Heinemeier Hansson autorequire: bindir: bin cert_chain: [] -date: 2014-10-03 00:00:00.000000000 Z +date: 2014-12-08 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: coffee-rails requirement: !ruby/object:Gem::Requirement requirements: - - - '>=' + - - ">=" - !ruby/object:Gem::Version version: '0' type: :runtime prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - - '>=' + - - ">=" - !ruby/object:Gem::Version version: '0' description: @@ -30,6 +30,8 @@ extensions: [] extra_rdoc_files: [] files: +- MIT-LICENSE +- README.md - lib/assets/javascripts/turbolinks.js.coffee - lib/turbolinks.rb - lib/turbolinks/cookies.rb @@ -38,14 +40,14 @@ - lib/turbolinks/x_domain_blocker.rb - lib/turbolinks/xhr_headers.rb - lib/turbolinks/xhr_url_for.rb -- README.md -- MIT-LICENSE - test/config.ru - test/dummy.gif - test/index.html - test/manifest.appcache - test/offline.html - test/other.html +- test/redirect1.html +- test/redirect2.html - test/reload.html - test/withoutextension homepage: https://github.com/rails/turbolinks/ @@ -58,20 +60,19 @@ - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - - '>=' + - - ">=" - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - - '>=' + - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: -rubygems_version: 2.0.3 +rubygems_version: 2.2.2 signing_key: specification_version: 4 summary: Turbolinks makes following links in your web application faster (use with Rails Asset Pipeline) test_files: [] -has_rdoc: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/config.ru new/test/config.ru --- old/test/config.ru 1970-01-01 01:00:00.000000000 +0100 +++ new/test/config.ru 2014-12-08 15:17:40.000000000 +0100 @@ -7,6 +7,29 @@ env.append_path File.join(Root, "lib", "assets", "javascripts") end +class SlowResponse + CHUNKS = ['<html><body>', '.'*50, '.'*20, '<a href="/index.html">Home</a></body></html>'] + + def call(env) + [200, headers, self] + end + + def each + CHUNKS.each do |part| + sleep rand(0.3..0.8) + yield part + end + end + + def length + CHUNKS.join.length + end + + def headers + { "Content-Length" => length.to_s, "Content-Type" => "text/html", "Cache-Control" => "no-cache, no-store, must-revalidate" } + end +end + map "/js" do run Assets end @@ -19,6 +42,14 @@ run Rack::File.new(File.join(Root, "test", "withoutextension"), "Content-Type" => "text/html") end +map "/slow-response" do + run SlowResponse.new +end + +map "/bounce" do + run Proc.new{ [200, { "X-XHR-Redirected-To" => "redirect1.html", "Content-Type" => "text/html" }, File.open( File.join( Root, "test", "redirect1.html" ) ) ] } +end + map "/" do run Rack::Directory.new(File.join(Root, "test")) end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/index.html new/test/index.html --- old/test/index.html 1970-01-01 01:00:00.000000000 +0100 +++ new/test/index.html 2014-12-08 15:17:40.000000000 +0100 @@ -5,6 +5,8 @@ <title>Home</title> <script type="text/javascript" src="/js/turbolinks.js"></script> <script type="text/javascript"> + Turbolinks.enableProgressBar(); + document.addEventListener("page:change", function() { console.log("page changed"); }); @@ -19,8 +21,9 @@ </script> </head> <body class="page-index"> - <ul style="margin-top:200px;"> + <ul style="margin-top:20px;"> <li><a href="/other.html">Other page</a></li> + <li><a href="/slow-response">Slow loading page for progress bar</a></li> <li><a href="/other.html"><span>Wrapped link</span></a></li> <li><a href="/withoutextension">Without extension</a></li> <li><a href="/withoutextension?sort=user.name">Without extension with query params</a></li> @@ -28,6 +31,7 @@ <li><a href="/other.html" onclick="if(!confirm('follow link?')) { return false}">Confirm Fire Order</a></li> <li><a href="/reload.html"><span>New assets track </span></a></li> <li><a href="/dummy.gif?12345">Query Param Image Link</a></li> + <li><a href="/bounce">Redirect</a></li> <li><a href="#">Hash link</a></li> <li><a href="/reload.html#foo">New assets track with hash link</a></li> <li><h5>If you stop the server or go into airplane/offline mode</h5></li> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/redirect1.html new/test/redirect1.html --- old/test/redirect1.html 1970-01-01 01:00:00.000000000 +0100 +++ new/test/redirect1.html 2014-12-08 15:17:40.000000000 +0100 @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>Home</title> + <script type="text/javascript" src="/js/turbolinks.js"></script> +</head> +<body class="page-other"> + Should show /redirect1.html as path + <ul> + <li>Click <a href="/redirect2.html">Redirect 2</a></li> + </ul> + +</body> +</html> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/test/redirect2.html new/test/redirect2.html --- old/test/redirect2.html 1970-01-01 01:00:00.000000000 +0100 +++ new/test/redirect2.html 2014-12-08 15:17:40.000000000 +0100 @@ -0,0 +1,11 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="utf-8"> + <title>Home</title> + <script type="text/javascript" src="/js/turbolinks.js"></script> +</head> +<body class="page-other"> + Hit back button twice. It should go back to home page. +</body> +</html> -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org