diff --git a/at_core/inc/forms/settings.menutoggle.inc b/at_core/inc/forms/settings.menutoggle.inc index 7266780629cd3ca71b4096f8f50fcd17ebb4a8c0..d80e9500a091e7dd42e2ec075ce3375cdc42599a 100755 --- a/at_core/inc/forms/settings.menutoggle.inc +++ b/at_core/inc/forms/settings.menutoggle.inc @@ -9,7 +9,7 @@ function at_core_menu_toggle_form(&$form) { '#type' => 'fieldset', '#title' => t('Mobile Menu Toggle'), '#weight' => 30, - '#description' => t('

Menu Toggle for Mobile

The Menu Toggle will hide the main menu (either a block in the Menu bar region, or the Main menu) and a single clickable link will appear. Clicking this link toggles the menu open and closed - suitable for mobile devices.

Superfish: if you start using the Superfish module you should re-save the theme settings so this will work correctly (extra CSS is added only if the module is enabled). Also enable the sf-Touchscreen plugin, which is a setting in the block configuration for your Superfish menu block.

Smalltouch/smartphone breakpoints are supported by default, you can select additional devices/breakpoints.'), + '#description' => t('

Menu Toggle for Mobile

The Menu Toggle will hide selected menus and a single clickable link will appear. Clicking this link toggles the menu open and closed - suitable for mobile devices. Smalltouch/smartphone breakpoints are supported by default.

Superfish: if you start using the Superfish module you should re-save the theme settings. Also enable the sf-Touchscreen plugin for your Superfish menu block.

Polyfills: for this to work in older browsers and Adroid 2 you need to enable the matchMedia polyfill (see the Polyfills tab).

'), ); // Select additional breakpoints diff --git a/at_core/inc/forms/settings.polyfills.inc b/at_core/inc/forms/settings.polyfills.inc index 404ddd618e6b9da93a86b4f3f40c617d2a18889a..6c7002effb32e9e8cb51b8b4559bf0eb5771dfb4 100755 --- a/at_core/inc/forms/settings.polyfills.inc +++ b/at_core/inc/forms/settings.polyfills.inc @@ -26,12 +26,20 @@ function at_core_polyfills_form(&$form, $theme_name) { '#default_value' => at_get_setting('load_html5js'), ); + // matchMedia polyfill: https://github.com/paulirish/matchMedia.js + $form['at-settings']['polyfills']['fills']['load_matchmediajs'] = array( + '#type' => 'checkbox', + '#title' => t('matchMedia.js Polyfill'), + '#description' => t('Backport matchMedia support to unsupporting browsers - see github.com/paulirish/matchMedia. If using the Menu Toggle extension you need this if supporting Android 2.3 or earlier is important. Do not enable this if you are using respond.js (see Media query support for IE6-8, below) or Modernizr. A number of other libraries load this polyfill also - it\'s worth checking, although its also a very small polyfill.', array('!matchmedia_link' => '//github.com/paulirish/matchMedia.js')), + '#default_value' => at_get_setting('load_matchmediajs'), + ); + // OnMediaQuery.js $script_filepath = '/' . $theme_name . '/scripts/media_queries.js'; $form['at-settings']['polyfills']['fills']['load_onmediaqueryjs'] = array( '#type' => 'checkbox', - '#title' => t('Responsive JavaScript beta'), - '#description' => t('Load the JS Media Queries plugin to enable responsive JavaScript. See @script_filepath for instructions on how to use. This is an alternative to using matchMedia and hard coding breakpoints in JavaScript. This is bleeding edge and must be considered beta, but its wickedly cool, and useful.', array('!onmediaquery_link' => '//github.com/JoshBarr/js-media-queries', '@script_filepath' => $script_filepath)), + '#title' => t('Responsive JavaScript (deprecated)'), + '#description' => t('This is deprecated because AT Core now loads it\'s media queries into Drupals JS settings - see menu-toggle.js in the core theme for an example of how this can be used with matchMedia. This legacy feature loads the JS Media Queries plugin to enable responsive JavaScript. See @script_filepath for instructions on how to use. This is an alternative to using matchMedia.', array('!onmediaquery_link' => '//github.com/JoshBarr/js-media-queries', '@script_filepath' => $script_filepath)), '#default_value' => at_get_setting('load_onmediaqueryjs'), ); @@ -46,7 +54,7 @@ function at_core_polyfills_form(&$form, $theme_name) { // Respond.js $form['at-settings']['polyfills']['fills']['load_respondjs'] = array( '#type' => 'checkbox', - '#title' => t('Media query support for IE6-8'), + '#title' => t('Media query support for IE6-8 (respond.js)'), '#description' => t('By checking this setting IE6, 7 and 8 will rely on respond.js to set the layout.', array('!respondjs_link' => '//github.com/scottjehl/Respond')), '#default_value' => at_get_setting('load_respondjs'), '#states' => array( @@ -58,7 +66,7 @@ function at_core_polyfills_form(&$form, $theme_name) { $form['at-settings']['polyfills']['fills']['load_scalefixjs'] = array( '#type' => 'checkbox', '#title' => t('Scalefix for iOS'), - '#description' => t('Fixes the iOS Orientationchange zoom bug.'), + '#description' => t('Fixes the iOS Orientationchange zoom bug. See github.com/scottjehl/iOS-Orientationchange-Fix.', array('!scalefix_link' => 'https://github.com/scottjehl/iOS-Orientationchange-Fix')), '#default_value' => at_get_setting('load_scalefixjs'), '#states' => array( 'invisible' => array('input[name="disable_responsive_styles"]' => array('checked' => TRUE)), diff --git a/at_core/inc/load.inc b/at_core/inc/load.inc index 59d46e3348b6a417b5f9dab01e246b0eb6bb37a5..60800298686cbe246cb74fa54f98224a214a520d 100755 --- a/at_core/inc/load.inc +++ b/at_core/inc/load.inc @@ -340,6 +340,10 @@ function at_load_polyfills($theme_name) { if (at_get_setting('load_onmediaqueryjs') === 1) { $polyfills_array['all'][] = 'scripts/onmediaquery.js'; } + if (at_get_setting('load_matchmediajs') === 1) { + $polyfills_array['all'][] = 'scripts/matchMedia.addListener.js'; + $polyfills_array['all'][] = 'scripts/matchMedia.js'; + } // Load Polyfills if (!empty($polyfills_array)) { @@ -700,6 +704,7 @@ function at_load_menu_toggle($path, $theme_name) { 'type' => 'file', 'scope' => 'header', 'group' => JS_THEME, + 'weight'=> 999, 'preprocess' => TRUE, 'cache' => TRUE, ) diff --git a/at_core/inc/preprocess.inc b/at_core/inc/preprocess.inc index cce40abb1aa2a9ee75fb48bd030915402c662ab4..c2da3d3f357eb2ac28fb1078c2671a06e10a1d67 100755 --- a/at_core/inc/preprocess.inc +++ b/at_core/inc/preprocess.inc @@ -793,13 +793,20 @@ function adaptivetheme_preprocess_comment(&$vars) { } $vars['links_attributes_array']['class'][] = 'clearfix'; - // Build the submitted by and time elements + // Build the submitted by, permalink, title and time elements $uri = entity_uri('comment', $vars['comment']); $uri['options'] += array('attributes' => array('rel' => 'bookmark')); $vars['title'] = l($vars['comment']->subject, $uri['path'], $uri['options']); - $vars['permalink'] = l(t('Permalink'), $uri['path'], $uri['options']); // Permalinks are embedded in the time element, aka Wordpress + + // Don't rebuild the permalink variable if Advanced Forum is enabled + if (!module_exists('advanced_forum')) { + $vars['permalink'] = l(t('Permalink'), $uri['path'], $uri['options']); + } + $vars['created'] = '' . l($vars['created'], $uri['path'], $uri['options']) . ''; + $vars['datetime'] = format_date($vars['comment']->created, 'custom', 'Y-m-d\TH:i:s\Z'); // Generate the timestamp, PHP "c" format is wrong + $vars['submitted'] = t('Submitted by !username on !datetime', array( '!username' => $vars['author'], diff --git a/at_core/scripts/matchMedia.addListener.js b/at_core/scripts/matchMedia.addListener.js new file mode 100755 index 0000000000000000000000000000000000000000..2c61b3969c9331fdc7e932649d498faa78065003 --- /dev/null +++ b/at_core/scripts/matchMedia.addListener.js @@ -0,0 +1,47 @@ +/*! matchMedia() polyfill addListener/removeListener extension. Author & copyright (c) 2012: Scott Jehl. Dual MIT/BSD license */ +(function(){ + // monkeypatch unsupported addListener/removeListener with polling + if( !window.matchMedia( "" ).addListener ){ + var oldMM = window.matchMedia; + + window.matchMedia = function( q ){ + var ret = oldMM( q ), + listeners = [], + last = false, + timer, + check = function(){ + var list = oldMM( q ), + unmatchToMatch = list.matches && !last, + matchToUnmatch = !list.matches && last; + + //fire callbacks only if transitioning to or from matched state + if( unmatchToMatch || matchToUnmatch ){ + for( var i =0, il = listeners.length; i< il; i++ ){ + listeners[ i ].call( ret, list ); + } + } + last = list.matches; + }; + + ret.addListener = function( cb ){ + listeners.push( cb ); + if( !timer ){ + timer = setInterval( check, 1000 ); + } + }; + + ret.removeListener = function( cb ){ + for( var i =0, il = listeners.length; i< il; i++ ){ + if( listeners[ i ] === cb ){ + listeners.splice( i, 1 ); + } + } + if( !listeners.length && timer ){ + clearInterval( timer ); + } + }; + + return ret; + }; + } +}()); diff --git a/at_core/scripts/matchMedia.js b/at_core/scripts/matchMedia.js new file mode 100755 index 0000000000000000000000000000000000000000..c680c4baf4246dbee84c38fba759caf29d1ef001 --- /dev/null +++ b/at_core/scripts/matchMedia.js @@ -0,0 +1,36 @@ +/*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ + +window.matchMedia = window.matchMedia || (function( doc, undefined ) { + + "use strict"; + + var bool, + docElem = doc.documentElement, + refNode = docElem.firstElementChild || docElem.firstChild, + // fakeBody required for + fakeBody = doc.createElement( "body" ), + div = doc.createElement( "div" ); + + div.id = "mq-test-1"; + div.style.cssText = "position:absolute;top:-100em"; + fakeBody.style.background = "none"; + fakeBody.appendChild(div); + + return function(q){ + + div.innerHTML = "­"; + + docElem.insertBefore( fakeBody, refNode ); + bool = div.offsetWidth === 42; + docElem.removeChild( fakeBody ); + + return { + matches: bool, + media: q + }; + + }; + +}( document )); + + diff --git a/at_core/scripts/respond.js b/at_core/scripts/respond.js index 21437ba0b0b657291028a8bbfd99a9a33abe6d6a..31ebe0183563e2dae8da09616782ef986e7af00c 100755 --- a/at_core/scripts/respond.js +++ b/at_core/scripts/respond.js @@ -1,6 +1,6 @@ /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ -window.matchMedia=window.matchMedia||(function(e,f){var c,a=e.documentElement,b=a.firstElementChild||a.firstChild,d=e.createElement("body"),g=e.createElement("div");g.id="mq-test-1";g.style.cssText="position:absolute;top:-100em";d.style.background="none";d.appendChild(g);return function(h){g.innerHTML='­';a.insertBefore(d,b);c=g.offsetWidth==42;a.removeChild(d);return{matches:c,media:h}}})(document); +window.matchMedia=window.matchMedia||function(a){"use strict";var c,d=a.documentElement,e=d.firstElementChild||d.firstChild,f=a.createElement("body"),g=a.createElement("div");return g.id="mq-test-1",g.style.cssText="position:absolute;top:-100em",f.style.background="none",f.appendChild(g),function(a){return g.innerHTML='­',d.insertBefore(f,e),c=42===g.offsetWidth,d.removeChild(f),{matches:c,media:a}}}(document); /*! Respond.js v1.1.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ -(function(e){e.respond={};respond.update=function(){};respond.mediaQueriesSupported=e.matchMedia&&e.matchMedia("only all").matches;if(respond.mediaQueriesSupported){return}var w=e.document,s=w.documentElement,i=[],k=[],q=[],o={},h=30,f=w.getElementsByTagName("head")[0]||s,g=w.getElementsByTagName("base")[0],b=f.getElementsByTagName("link"),d=[],a=function(){var D=b,y=D.length,B=0,A,z,C,x;for(;B-1,minw:F.match(/\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:F.match(/\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}}j()},l,r,v=function(){var z,A=w.createElement("div"),x=w.body,y=false;A.style.cssText="position:absolute;font-size:1em;width:1em";if(!x){x=y=w.createElement("body");x.style.background="none"}x.appendChild(A);s.insertBefore(x,s.firstChild);z=A.offsetWidth;if(y){s.removeChild(x)}else{x.removeChild(A)}z=p=parseFloat(z);return z},p,j=function(I){var x="clientWidth",B=s[x],H=w.compatMode==="CSS1Compat"&&B||w.body[x]||B,D={},G=b[b.length-1],z=(new Date()).getTime();if(I&&l&&z-l-1?(p||v()):1)}if(!!J){J=parseFloat(J)*(J.indexOf(y)>-1?(p||v()):1)}if(!K.hasquery||(!A||!L)&&(A||H>=C)&&(L||H<=J)){if(!D[K.media]){D[K.media]=[]}D[K.media].push(k[K.rules])}}for(var E in q){if(q[E]&&q[E].parentNode===f){f.removeChild(q[E])}}for(var E in D){var M=w.createElement("style"),F=D[E].join("\n");M.type="text/css";M.media=E;f.insertBefore(M,G.nextSibling);if(M.styleSheet){M.styleSheet.cssText=F}else{M.appendChild(w.createTextNode(F))}q.push(M)}},n=function(x,z){var y=c();if(!y){return}y.open("GET",x,true);y.onreadystatechange=function(){if(y.readyState!=4||y.status!=200&&y.status!=304){return}z(y.responseText)};if(y.readyState==4){return}y.send(null)},c=(function(){var x=false;try{x=new XMLHttpRequest()}catch(y){x=new ActiveXObject("Microsoft.XMLHTTP")}return function(){return x}})();a();respond.update=a;function t(){j(true)}if(e.addEventListener){e.addEventListener("resize",t,false)}else{if(e.attachEvent){e.attachEvent("onresize",t)}}})(this); \ No newline at end of file +(function(a){"use strict";function x(){u(!0)}var b={};if(a.respond=b,b.update=function(){},b.mediaQueriesSupported=a.matchMedia&&a.matchMedia("only all").matches,!b.mediaQueriesSupported){var q,r,t,c=a.document,d=c.documentElement,e=[],f=[],g=[],h={},i=30,j=c.getElementsByTagName("head")[0]||d,k=c.getElementsByTagName("base")[0],l=j.getElementsByTagName("link"),m=[],n=function(){for(var b=0;l.length>b;b++){var c=l[b],d=c.href,e=c.media,f=c.rel&&"stylesheet"===c.rel.toLowerCase();d&&f&&!h[d]&&(c.styleSheet&&c.styleSheet.rawCssText?(p(c.styleSheet.rawCssText,d,e),h[d]=!0):(!/^([a-zA-Z:]*\/\/)/.test(d)&&!k||d.replace(RegExp.$1,"").split("/")[0]===a.location.host)&&m.push({href:d,media:e}))}o()},o=function(){if(m.length){var a=m.shift();v(a.href,function(b){p(b,a.href,a.media),h[a.href]=!0,setTimeout(function(){o()},0)})}},p=function(a,b,c){var d=a.match(/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi),g=d&&d.length||0;b=b.substring(0,b.lastIndexOf("/"));var h=function(a){return a.replace(/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,"$1"+b+"$2$3")},i=!g&&c;b.length&&(b+="/"),i&&(g=1);for(var j=0;g>j;j++){var k,l,m,n;i?(k=c,f.push(h(a))):(k=d[j].match(/@media *([^\{]+)\{([\S\s]+?)$/)&&RegExp.$1,f.push(RegExp.$2&&h(RegExp.$2))),m=k.split(","),n=m.length;for(var o=0;n>o;o++)l=m[o],e.push({media:l.split("(")[0].match(/(only\s+)?([a-zA-Z]+)\s?/)&&RegExp.$2||"all",rules:f.length-1,hasquery:l.indexOf("(")>-1,minw:l.match(/\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:l.match(/\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}u()},s=function(){var a,b=c.createElement("div"),e=c.body,f=!1;return b.style.cssText="position:absolute;font-size:1em;width:1em",e||(e=f=c.createElement("body"),e.style.background="none"),e.appendChild(b),d.insertBefore(e,d.firstChild),a=b.offsetWidth,f?d.removeChild(e):e.removeChild(b),a=t=parseFloat(a)},u=function(a){var b="clientWidth",h=d[b],k="CSS1Compat"===c.compatMode&&h||c.body[b]||h,m={},n=l[l.length-1],o=(new Date).getTime();if(a&&q&&i>o-q)return clearTimeout(r),r=setTimeout(u,i),void 0;q=o;for(var p in e)if(e.hasOwnProperty(p)){var v=e[p],w=v.minw,x=v.maxw,y=null===w,z=null===x,A="em";w&&(w=parseFloat(w)*(w.indexOf(A)>-1?t||s():1)),x&&(x=parseFloat(x)*(x.indexOf(A)>-1?t||s():1)),v.hasquery&&(y&&z||!(y||k>=w)||!(z||x>=k))||(m[v.media]||(m[v.media]=[]),m[v.media].push(f[v.rules]))}for(var B in g)g.hasOwnProperty(B)&&g[B]&&g[B].parentNode===j&&j.removeChild(g[B]);for(var C in m)if(m.hasOwnProperty(C)){var D=c.createElement("style"),E=m[C].join("\n");D.type="text/css",D.media=C,j.insertBefore(D,n.nextSibling),D.styleSheet?D.styleSheet.cssText=E:D.appendChild(c.createTextNode(E)),g.push(D)}},v=function(a,b){var c=w();c&&(c.open("GET",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},w=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject("Microsoft.XMLHTTP")}return function(){return b}}();n(),b.update=n,a.addEventListener?a.addEventListener("resize",x,!1):a.attachEvent&&a.attachEvent("onresize",x)}})(this); \ No newline at end of file diff --git a/at_core/scripts/scalefix.js b/at_core/scripts/scalefix.js index 711472cadd8c7c344cb49e9098107d88e8199605..616a0b7ba25e243373072ad7acfa5f518bac66a6 100755 --- a/at_core/scripts/scalefix.js +++ b/at_core/scripts/scalefix.js @@ -1,24 +1,56 @@ -// Optimized scalefix by jdalton: https://gist.github.com/903131 -// Prevents iOS from overscaling the page on orientation change. -// 1) won't restrict viewport if JS is disabled -// 2) uses capture phase -// 3) assumes last viewport meta is the one to edit (incase for some odd reason there is more than one) -// 4) feature inference (no sniffs, behavior should be ignored on other enviros) -// 5) removes event handler after fired -!function(doc) { - var addEvent = 'addEventListener', - type = 'gesturestart', - qsa = 'querySelectorAll', - scales = [1, 1], - meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : []; - - function fix() { - meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1]; - doc.removeEventListener(type, fix, !0); - } - if ((meta = meta[meta.length - 1]) && addEvent in doc) { - fix(); - scales = [.25, 1.6]; - doc[addEvent](type, fix, !0); - } -}(document); +/*! A fix for the iOS orientationchange zoom bug. + Script by @scottjehl, rebound by @wilto. + MIT / GPLv2 License. +*/ +(function(w){ + + // This fix addresses an iOS bug, so return early if the UA claims it's something else. + var ua = navigator.userAgent; + if( !( /iPhone|iPad|iPod/.test( navigator.platform ) && /OS [1-5]_[0-9_]* like Mac OS X/i.test(ua) && ua.indexOf( "AppleWebKit" ) > -1 ) ){ + return; + } + + var doc = w.document; + + if( !doc.querySelector ){ return; } + + var meta = doc.querySelector( "meta[name=viewport]" ), + initialContent = meta && meta.getAttribute( "content" ), + disabledZoom = initialContent + ",maximum-scale=1", + enabledZoom = initialContent + ",maximum-scale=10", + enabled = true, + x, y, z, aig; + + if( !meta ){ return; } + + function restoreZoom(){ + meta.setAttribute( "content", enabledZoom ); + enabled = true; + } + + function disableZoom(){ + meta.setAttribute( "content", disabledZoom ); + enabled = false; + } + + function checkTilt( e ){ + aig = e.accelerationIncludingGravity; + x = Math.abs( aig.x ); + y = Math.abs( aig.y ); + z = Math.abs( aig.z ); + + // If portrait orientation and in one of the danger zones + if( (!w.orientation || w.orientation === 180) && ( x > 7 || ( ( z > 6 && y < 8 || z < 8 && y > 6 ) && x > 5 ) ) ){ + if( enabled ){ + disableZoom(); + } + } + else if( !enabled ){ + restoreZoom(); + } + } + + w.addEventListener( "orientationchange", restoreZoom, false ); + w.addEventListener( "devicemotion", checkTilt, false ); + +})( this ); \ No newline at end of file