Tagged “javascript”

Logout from HTTP auth using Apache

Published by cybso on

This is a post from my original site, which was hosted by the former blog service of the University of Osnabrück. I have moved it to the new site for archiving. Pages linked in this article may no longer work today, and the blog comments under the article no longer exist. Opinions expressed in this article reflect the point of view of the time of publication and do not necessarily reflect my opinion today.

Since there is no mechanism defined to log the user out of a HTTP authenticated session you have to use a workaround. Most browsers forget their login data once they received a 403 response. The problem is, that the user have to return to the normal starting page manually.

Update 2017-02-22: It seems that this technique doesn't work anymore in recent Firefox and Chrome browsers.

The following code, which can be embedded into an Apache VHost declaration, uses a cookie to send a 403 response to the browser the first time he requests "/logout", and redirects it to "/" on the second time. So the user can immediately login again if he want to.

Please note that the order of the declarations does matter! The Location-Block must be the last block which requires a user or group.

RewriteCond %{HTTP_COOKIE} ^.*logout=1.*$
RewriteRule ^/logout$ / [R,L,co=logout:0:%{HTTP_HOST}:0:/logout]                                                                                                         
RewriteRule ^/logout$ - [R,L,co=logout:1:%{HTTP_HOST}:0:/logout]
<Location /logout>
    Require user nonexistinguser
</Location>

Introducing: Nested Scroll

Published by cybso on

Nested Scroll is a Javascript library that allows you to scroll
selected elements into the viewport. You can define if the element should be aligned to the upper, lower, left or right
boundary, or let Nested Scroll automatically decide depending on the shortest path.

Additionally, it is possible to define some animation methods, respect the element's border and margin
and add extra margins on each side when scrolling.

But what makes this library unique compared to other libraries I've looked into is that it that it
not only works with vertical but also with horizontal scrollbars, with nested scrollable DIVs
and with fixed elements!

Usage

  // Scroll with default options
  var target = document.getElementById('target-element');
  nestedScroll(target);

  // Scroll with additional parameters
  var options = {
    // See section options
    animationMethod: 'easeInOut',
    animationTimeout: 500,
    force: true,
    align: 'auto',
    withCssMargins: true,
    marginTop: 10,
    marginLeft: 10,
    marginRight: 10,
    marginBottom: 10
  };
  nestedScroll(target, options);

  // Define a global option
  nestesScroll.defaultOptions['animationMethod'] = 'easeIn';

Download

Download the library on github.

Disclamer: This is tested on Vivaldi 1.10, Firefox 52 and Chromium 59. Edge should also work, but I had some problems using the example file with IE11. Maybe I'll fix this later, or somebody as does ;-)

QtWebEngine: Be careful when doing periodic WebChannel requests

Published by cybso on

Today I had to resolve a mysterious bug in a PyQt5 / QtWebEngine application. After the user unlocked his session, the application hangs for a while before resuming to normal activity. I've added an JavaScript interval that prints the current time once a second onto the console, but even through the timestamps were OK it seems that something had freezed the application while the screen was locked.

To make it short, the application requested a status update via WebChannel once a second. While the Javascript kept active, the event loop of QApplication was blocked, so that the WebChannel events were put into a queue. (The reason for the block was the change to a new VT by the light-locker lock screen - I was able emulate it by manually switching to VT1 after the application has been started). When the application got active again, Qt started to empty the queue before any new events were processed.

My solution was to omit the periodic status updates when the webchannel isn't idle.

Make Android's Pinch Zoom-Feature more Accessible

Published by cybso on

Since I'm getting older I often need to pinch zoom into web pages to make the text more readable.
However, Android (or Chrome) has the annoying "feature" to enlarge the whole viewport when zooming into a web page, forcing the user to scroll horizontally through the page to read the text:

Screenshot of an article from this blog, with pinch zoom enabled. The text is croped on the right side.

Currently it seems that there is no way to disable this behaviour from the developer's side using CSS or HTML. Although Chrome as a so-called reading mode I see this only as a workaround, since the user must know about this mode and must enable it manually for each single website – and does not work on all pages.

So I experimented a bit and found a JavaScript-based solution that is pretty simple. You need some sort of container for that you want to re-flow the text on pinch zoom (in this example the HTML element main), and it should have no margins when in mobile view. I also suggest to add overflow-wrap: break-word; to your CSS, since otherwise long URLs might break the layout.

Then insert the following JavaScript code at the end of your HTML file:

<script>
// Force Android's browsers to reflow content on pinch zoom
if (navigator.userAgent.match(/android/i) && window.visualViewport && window.visualViewport.scale) {
  let scaleTimeoutId = undefined
  window.visualViewport.addEventListener("resize", (() => {
    if (scaleTimeoutId != undefined) {
      window.clearTimeout(scaleTimeoutId)
    }

    // Apply changes if the value has not changed for more than 250ms to prevent flickering
    scaleTimeoutId = window.setTimeout(() => {
      scaleTimeoutId = undefined
      var scaleFactor = window.visualViewport.scale

      var main = document.getElementsByTagName('main')[0]
      if (scaleFactor > 1) {
        main.style.maxWidth = "" + Math.round(100/scaleFactor) + "%"
        // Add a CSS class that allows to do modifications on default styles,
        // like removing 'margin: auto'.
        main.classList.add('pinchzoom')
      } else {
        main.style.maxWidth = ''
        main.classList.remove('pinchzoom')
      }
    }, 250)
  }))
}
</script>

This uses the VisualViewport's scale property to set the maximum width of the container element to the scale factor's inverse value and thus force the browser to wrap the text along the actual viewport's size:

Screenshot of the same site as above, but now the text is wrapped on the screen borders

An issue of this method is that since the text gets rearranged it might flow out of the visual viewport. I've tried to workaround this problem by identifying the centered element of the visual viewport and scroll this into view after the 'max-width' style had been applied, but due to limitations on scrollIntoView() this is far from being perfect. See /js/reflow.js for the current full version if this code.

I don't know if this works on all Browsers, and if it does not have any other side effects, so I would be happy to get some feedback!