diff --git a/README.md b/README.md index 3b67a3e..c37db8a 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,39 @@ +## Important note +In november 2019, publiq vzw (formerly known as CultuurNet) starts the End of Support phase of the Culturefeed Drupal 7 module suite. This means that you can continue to use Culturefeed, but publiq vzw will not invest anymore in this Drupal 7 module suite. + +As an exception, critical security updates will still be provided if needed. + +The End of Life (EOL) date of the module suite is set to the same date as the EOL of Drupal 7 core, ie. November 2021 (https://www.drupal.org/psa-2019-02-25). + +We built this final 4.0 release, which contains a major security update, and some incompatible changes compared to the latest 3.10.2 release. Some less used modules are moved to a separate repository. If you update to this version please check & should you use one of these modules, reinstall them from a separate repository. After that all things should work as usual. +- https://github.com/cultuurnet/culturefeed_pages [DEPRECATED] + +- https://github.com/cultuurnet/culturefeed_roles [DEPRECATED] + +- https://github.com/cultuurnet/culturefeed_messages [DEPRECATED] + +- https://github.com/cultuurnet/culturefeed_calendar [DEPRECATED] + +- https://github.com/cultuurnet/culturefeed_uitpas + +- https://github.com/cultuurnet/culturefeed_social + +- https://github.com/cultuurnet/culturefeed_userpoints_ui [DEPRECATED] + +- https://github.com/cultuurnet/culturefeed_entry_ui [DEPRECATED] + +### Alternatives + +As an alternative for the Culturefeed Drupal 7 module suite, publiq vzw focused on: + +- A new, easy to use API in a developer-friendly Json format: https://projectaanvraag.uitdatabank.be/#!/integrations#api + +- An even easier to use widget platform: https://projectaanvraag.uitdatabank.be/#!/integrations#widgets + +We also have a Drupal 8 version on https://github.com/cultuurnet/culturefeed_d8 with the most commonly used modules culturefeed_agenda, culturefeed_content, culturefeed_search, culturefeed_search_api and culturefeed_user. + +However, these modules will not contain the full functionality as was provided in the Drupal 7 edition, and it will not be heavily extended by publiq the same way we did this for the Drupal 7 edition. We are still happy to review and accept pull requests from external developers or partners, though. + # How to use this theme? ### culturefeed_bootstrap: diff --git a/culturefeed_bootstrap.info b/culturefeed_bootstrap.info index ab1358b..be638d3 100644 --- a/culturefeed_bootstrap.info +++ b/culturefeed_bootstrap.info @@ -40,6 +40,7 @@ scripts[] = 'js/culturefeed-bootstrap.js' scripts[] = 'js/jquery.blueimp-gallery.js' scripts[] = 'js/bootstrap-gallery.js' scripts[] = 'bootstrap/js/modal.js' +scripts[] = 'js/mobile-detect.min.js' ;********************************** ; METHOD 1: Bootstrap Source Files diff --git a/img/error.png b/img/error.png new file mode 100755 index 0000000..a5577c3 Binary files /dev/null and b/img/error.png differ diff --git a/img/error.svg b/img/error.svg new file mode 100755 index 0000000..184206a --- /dev/null +++ b/img/error.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/img/loading.gif b/img/loading.gif new file mode 100755 index 0000000..90f28cb Binary files /dev/null and b/img/loading.gif differ diff --git a/img/museumpas.png b/img/museumpas.png new file mode 100644 index 0000000..8ddd60a Binary files /dev/null and b/img/museumpas.png differ diff --git a/img/play-pause.png b/img/play-pause.png new file mode 100755 index 0000000..ece6cfb Binary files /dev/null and b/img/play-pause.png differ diff --git a/img/play-pause.svg b/img/play-pause.svg new file mode 100755 index 0000000..a7f1f50 --- /dev/null +++ b/img/play-pause.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/img/video-play.png b/img/video-play.png new file mode 100755 index 0000000..353e3a5 Binary files /dev/null and b/img/video-play.png differ diff --git a/img/video-play.svg b/img/video-play.svg new file mode 100755 index 0000000..b5ea206 --- /dev/null +++ b/img/video-play.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/js/culturefeed-bootstrap.js b/js/culturefeed-bootstrap.js index 9c85416..9b353d1 100644 --- a/js/culturefeed-bootstrap.js +++ b/js/culturefeed-bootstrap.js @@ -1,14 +1,41 @@ (function ($) { - $(document).ready(function() { + function getScrollOffset() { + var offset = $('.navbar-header').height(); + var adminMenu = $('#admin-menu'); + + // drupal logged-in menu + if (adminMenu) { + offset += adminMenu.height(); + } + + return offset; + } + + $(document).ready(function () { // Init popovers $("a[data-toggle=popover]") .popover() - .click(function(e) { + .click(function (e) { e.preventDefault() }) + // skip-link focus + $("a[href^='#']").click(function () { + $("#" + $(this).attr("href").slice(1) + "").focus(); + }); + + // Temp adding aria-expanded to dropdown untill base bootstrap is updated + $('.dropdown-toggle').click(function () { + var status = $(this).attr('aria-expanded'); + if (status == 'false') { + $(this).attr('aria-expanded', 'true'); + } else { + $(this).attr('aria-expanded', 'false'); + } + }); + // popover - authentication required if (!Drupal.settings.culturefeed || !Drupal.settings.culturefeed.isCultureFeedUser) { @@ -22,11 +49,11 @@ html: true, placement: 'top', trigger: 'manual', - content: function() { + content: function () { // see custom culturefeed-ui-connect-hover.tpl.php return $(".popover-login").html(); } - }).click(function(e) { + }).click(function (e) { $(this).popover('show'); clickedAway = false isVisible = true @@ -34,14 +61,11 @@ }); // hide popover - $(document).click(function(e) { - if (isVisible && clickedAway) - { + $(document).click(function (e) { + if (isVisible && clickedAway) { $popoverLogin.popover('hide') isVisible = clickedAway = false - } - else - { + } else { clickedAway = true } }); @@ -53,15 +77,15 @@ $("span[data-toggle=tooltip]").tooltip(); // Init the map if this toggles a map. - $(".map-toggle").click(function() { + $(".map-toggle").click(function () { Drupal.CultureFeed.Agenda.initializeMap(); }); // Count characters input field - limit 400 characters - $(function(){ - $('#limit-400').keyup(function(){ - limitChars('limit-400', 400, 'charlimitinfo'); - }) + $(function () { + $('#limit-400').keyup(function () { + limitChars('limit-400', 400, 'charlimitinfo'); + }) }); // Remove agenda tab from page timeline block if agenda block is not available @@ -72,22 +96,18 @@ }) // Count characters input field - limit - general - function limitChars(textid, limit, infodiv) - { - var text = $('#'+textid).val(); - text=text.replace(/[\n\r\n]+/g, ' '); - var textlength = text.length; - if(textlength > limit) - { - $('#' + infodiv).html('Maximum '+limit+' karakters!'); - $('#'+textid).val(text.substr(0,limit)); - return false; - } - else - { - $('#' + infodiv).html('Nog '+ (limit - textlength) +' resterende karakters'); - return true; - } + function limitChars(textid, limit, infodiv) { + var text = $('#' + textid).val(); + text = text.replace(/[\n\r\n]+/g, ' '); + var textlength = text.length; + if (textlength > limit) { + $('#' + infodiv).html('Maximum ' + limit + ' karakters!'); + $('#' + textid).val(text.substr(0, limit)); + return false; + } else { + $('#' + infodiv).html('Nog ' + (limit - textlength) + ' resterende karakters'); + return true; + } } /** @@ -96,7 +116,7 @@ Drupal.behaviors.fileValidateAutoAttach = { attach: function (context, settings) { if (settings.file && settings.file.elements) { - $.each(settings.file.elements, function(selector) { + $.each(settings.file.elements, function (selector) { var extensions = settings.file.elements[selector]; $(selector, context).once('validate', function () { $(this).bind('change', {extensions: extensions}, Drupal.file.validateExtension); @@ -106,7 +126,7 @@ }, detach: function (context, settings) { if (settings.file && settings.file.elements) { - $.each(settings.file.elements, function(selector) { + $.each(settings.file.elements, function (selector) { $(selector, context).unbind('change', Drupal.file.validateExtension); }); } @@ -117,8 +137,8 @@ * Add click events on the read more link. */ Drupal.behaviors.culturefeedPushMoreInfoToUitId = { - attach: function(context, settings) { - $('a.moreinfo-link', context).bind('click', function(e) { + attach: function (context, settings) { + $('a.moreinfo-link', context).bind('click', function (e) { e.preventDefault(); $.ajax($(this).prop('rel')); $('#cf-longdescription').toggle(); @@ -126,6 +146,21 @@ } }; + /** + * Add smooth scroll on the anchor links. + */ + Drupal.behaviors.scrollToAnchorLinks = { + attach: function (context, settings) { + $(context).find(".scroll-to-anchor").once().click(function (e) { + e.preventDefault(); + + $([document.documentElement, document.body]).animate({ + scrollTop: $($(this).attr('href')).offset().top - getScrollOffset() + }, 300); + }); + } + } + if (Drupal.file) { /** @@ -163,73 +198,70 @@ if (Drupal.ajax) { - if (typeof Drupal.ajax.prototype != "undefined") { + /** + * Handler for the form redirection error. + * Custom override: Don't show an error when people are navigation away of the site. + */ + Drupal.ajax.prototype.error = function (response, uri) { - /** - * Handler for the form redirection error. - * Custom override: Don't show an error when people are navigation away of the site. - */ - Drupal.ajax.prototype.error = function (response, uri) { - - if (!response.status) { - return; - } - - alert(Drupal.ajaxError(response, uri)); - // Remove the progress element. - if (this.progress.element) { - $(this.progress.element).remove(); - } - if (this.progress.object) { - this.progress.object.stopMonitoring(); - } - // Undo hide. - $(this.wrapper).show(); - // Re-enable the element. - $(this.element).removeClass('progress-disabled').removeAttr('disabled'); - // Reattach behaviors, if they were detached in beforeSerialize(). - if (this.form) { - var settings = response.settings || this.settings || Drupal.settings; - Drupal.attachBehaviors(this.form, settings); - } - }; - - /** - * Command to provide a bootstrap modal with drupal ajax support. - */ - Drupal.ajax.prototype.commands.bootstrapModal = function (ajax, response, status) { - - // Support for jquery datepicker. See http://stackoverflow.com/questions/21059598/implementing-jquery-datepicker-in-bootstrap-modal - var enforceModalFocusFn = $.fn.modal.Constructor.prototype.enforceFocus; - $.fn.modal.Constructor.prototype.enforceFocus = function() {}; - $('#bootstrap-modal-container').on('hidden', function() { - $.fn.modal.Constructor.prototype.enforceFocus = enforceModalFocusFn; - }); - - var wrapper = $('#bootstrap-modal-container').find('.modal-content'); - var settings = response.settings || ajax.settings || Drupal.settings; - Drupal.detachBehaviors(wrapper, settings); - - var new_content = $('
').html(response.data); - $('#bootstrap-modal-container').find('.modal-content').html(new_content); - $('#bootstrap-modal-container').modal({show : true}); - Drupal.attachBehaviors(new_content, settings); - + if (!response.status) { + return; + } + + alert(Drupal.ajaxError(response, uri)); + // Remove the progress element. + if (this.progress.element) { + $(this.progress.element).remove(); + } + if (this.progress.object) { + this.progress.object.stopMonitoring(); + } + // Undo hide. + $(this.wrapper).show(); + // Re-enable the element. + $(this.element).removeClass('progress-disabled').removeAttr('disabled'); + // Reattach behaviors, if they were detached in beforeSerialize(). + if (this.form) { + var settings = response.settings || this.settings || Drupal.settings; + Drupal.attachBehaviors(this.form, settings); + } + }; + + /** + * Command to provide a bootstrap modal with drupal ajax support. + */ + Drupal.ajax.prototype.commands.bootstrapModal = function (ajax, response, status) { + + // Support for jquery datepicker. See http://stackoverflow.com/questions/21059598/implementing-jquery-datepicker-in-bootstrap-modal + var enforceModalFocusFn = $.fn.modal.Constructor.prototype.enforceFocus; + $.fn.modal.Constructor.prototype.enforceFocus = function () { }; + $('#bootstrap-modal-container').on('hidden', function () { + $.fn.modal.Constructor.prototype.enforceFocus = enforceModalFocusFn; + }); - /** - * Command to reload current page. - */ - Drupal.ajax.prototype.commands.culturefeedGoto = function (ajax, response, status) { - - if (ajax.progress.element) { - $(ajax.element).addClass('progress-disabled').attr('disabled', 'disabled'); - $(ajax.element).append(ajax.progress.element); - } - - window.location.href = response.url; + var wrapper = $('#bootstrap-modal-container').find('.modal-content'); + var settings = response.settings || ajax.settings || Drupal.settings; + Drupal.detachBehaviors(wrapper, settings); + + var new_content = $('
').html(response.data); + $('#bootstrap-modal-container').find('.modal-content').html(new_content); + $('#bootstrap-modal-container').modal({show: true}); + Drupal.attachBehaviors(new_content, settings); + + }; + + /** + * Command to reload current page. + */ + Drupal.ajax.prototype.commands.culturefeedGoto = function (ajax, response, status) { + + if (ajax.progress.element) { + $(ajax.element).addClass('progress-disabled').attr('disabled', 'disabled'); + $(ajax.element).append(ajax.progress.element); } + window.location.href = response.url; } } @@ -294,7 +326,7 @@ if ($.custom && $.custom.categorisedAutocomplete) { // Take over the search function. - $.custom.categorisedAutocomplete.prototype.search = function(value, event) { + $.custom.categorisedAutocomplete.prototype.search = function (value, event) { var $throbber = $('.glyphicon-refresh', $(this.element).parent()); $throbber.addClass('glyphicon-spin'); @@ -304,11 +336,11 @@ // always save the actual value, not the one passed as an argument this.term = this._value(); - if ( value.length < this.options.minLength ) { - return this.close( event ); + if (value.length < this.options.minLength) { + return this.close(event); } - if ( this._trigger( "search", event ) === false ) { + if (this._trigger("search", event) === false) { return; } @@ -317,23 +349,23 @@ } // Take over the render menu function. - $.custom.categorisedAutocomplete.prototype._renderMenu = function(ul, items) { + $.custom.categorisedAutocomplete.prototype._renderMenu = function (ul, items) { var $throbber = $('.glyphicon-refresh', $(this.element).parent()); $throbber.removeClass('glyphicon-spin'); var that = this, - currentCategory = ""; - $.each(items, function(index, item) { + currentCategory = ""; + $.each(items, function (index, item) { var li; if (!item.label) { if (item.category != currentCategory) { - ul.append("
  • " + item.category + "
  • "); + ul.append("
  • " + item.category + "
  • "); currentCategory = item.category; } } else { if (item.category != currentCategory) { - ul.append("
  • " + item.category + "
  • "); + ul.append("
  • " + item.category + "
  • "); currentCategory = item.category; } li = that._renderItemData(ul, item); @@ -351,10 +383,127 @@ * Prevents the form from submitting if the suggestions popup is open * and closes the suggestions popup when doing so. */ - Drupal.autocompleteSubmit = function () { - return $('.form-autocomplete > .dropdown').each(function () { - this.owner.hidePopup(); - }).length == 0; - }; + Drupal.autocompleteSubmit = function () { + return $('.form-autocomplete > .dropdown').each(function () { + this.owner.hidePopup(); + }).length == 0; + }; + + /** + * Add mobile detect helper classes to the body tag. + */ + Drupal.behaviors.culturefeedMobileDetect = { + attach: function (context, settings) { + var bodyClasses = []; + var md = new MobileDetect(window.navigator.userAgent); + + if (md.mobile() !== null) { + if (md.tablet() !== null) { + bodyClasses.push('is-tablet'); + } else { + bodyClasses.push('is-phone'); + } + } else { + bodyClasses.push('is-computer'); + } + + if (md.os() === 'AndroidOS') { + bodyClasses.push('is-android'); + } + if (md.os() === 'iOS') { + bodyClasses.push('is-ios'); + } + + $.each(bodyClasses, function (key, value) { + $('body').addClass(value); + }); + + // Format phones for mobile. + // Contact phone + if (Drupal.settings.culturefeed_agenda) { + if (Drupal.settings.culturefeed_agenda.contact) { + if (Drupal.settings.culturefeed_agenda.contact.phones) { + var phones = Drupal.settings.culturefeed_agenda.contact.phones; + + if (md.mobile()) { + var linkPhones = Array(); + phones = phones.split(', '); + + $.each(phones, function (key, phone) { + linkPhones[key] = '' + phone + ''; + }); + phones = linkPhones.join(', '); + $('.phone-placeholder').html(phones); + } + } + } + + // Reservation phone + if (Drupal.settings.culturefeed_agenda.reservation) { + if (Drupal.settings.culturefeed_agenda.reservation.phones) { + var resPhones = Drupal.settings.culturefeed_agenda.reservation.phones; + + if (md.mobile()) { + var linkResPhones = Array(); + resPhones = resPhones.split(', '); + + $.each(resPhones, function (key, phone) { + linkResPhones[key] = '' + phone + ''; + }); + resPhones = linkResPhones.join(', '); + $('.reservation-phone-placeholder').html(resPhones); + } + } + } + } + } + }; + + /** + * Add the right links for maps and phones depending on the device. + */ + function validate_phone(rawPhone) { + var phone = rawPhone.replace(new RegExp(' ', 'g'), '-'); + return phone.replace(new RegExp(/[^0-9+()]/, 'g'), ''); + } + + Drupal.behaviors.culturefeedAddMapLink = { + attach: function (context, settings) { + if (Drupal.settings.culturefeed_map) { + var md = new MobileDetect(window.navigator.userAgent); + var title = Drupal.settings.culturefeed_map.title; + // Map + if (Drupal.settings.culturefeed_map.info.location) { + var zip = Drupal.settings.culturefeed_map.info.location.zip; + var city = Drupal.settings.culturefeed_map.info.location.city; + var street = Drupal.settings.culturefeed_map.info.location.street; + var lat = (Drupal.settings.culturefeed_map.info.coordinates.lat) ? Drupal.settings.culturefeed_map.info.coordinates.lat : '0'; + var lng = (Drupal.settings.culturefeed_map.info.coordinates.lng) ? Drupal.settings.culturefeed_map.info.coordinates.lng : '0'; + var querystring = title; + var mapLink = ''; + + if (zip) { + querystring = querystring + '+' + zip; + } + if (city) { + querystring = querystring + '+' + city; + } + if (street) { + querystring = querystring + '+' + street; + } + + if (md.os() === 'iOS') { + mapLink = '' + Drupal.t('Open map') + ''; + } else if (md.os() === 'AndroidOS') { + mapLink = '' + Drupal.t('Open map') + ''; + } else { + mapLink = ''; + } + + $('.map-js-link').html(mapLink); + } + } + } + }; })(jQuery); diff --git a/js/daterangepicker-bind.js b/js/daterangepicker-bind.js index 2f2230d..d4ad892 100644 --- a/js/daterangepicker-bind.js +++ b/js/daterangepicker-bind.js @@ -137,8 +137,15 @@ Drupal.CulturefeedSearch = Drupal.CulturefeedSearch || {}; scrollTop: offset.top - 120, scrollLeft: offset.left - 120 }); + // move focus to first field for anysurfer + $('.daterangepicker input[name="daterangepicker_start"]').focus(); e.preventDefault(); }); + + pickerlink.on('cancel.daterangepicker', function (ev, picker) { + // move focus back to triggerlink after cancel for anysurfer + pickerlink.focus(); + }); }; })(jQuery); diff --git a/js/mobile-detect.min.js b/js/mobile-detect.min.js new file mode 100755 index 0000000..8ce8464 --- /dev/null +++ b/js/mobile-detect.min.js @@ -0,0 +1,3 @@ +/*!@license Copyright 2013, Heinrich Goebl, License: MIT, see https://github.com/hgoebl/mobile-detect.js*/ +!function(a,b){a(function(){"use strict";function a(a,b){return null!=a&&null!=b&&a.toLowerCase()===b.toLowerCase()}function c(a,b){var c,d,e=a.length;if(!e||!b)return!1;for(c=b.toLowerCase(),d=0;d=0&&(c=c.substring(0,j)+"([\\w._\\+]+)"+c.substring(j+5)),b[e]=new RegExp(c,"i");k.props[a]=b}d(k.oss),d(k.phones),d(k.tablets),d(k.uas),d(k.utils),k.oss0={WindowsPhoneOS:k.oss.WindowsPhoneOS,WindowsMobileOS:k.oss.WindowsMobileOS}}(),f.findMatch=function(a,b){for(var c in a)if(h.call(a,c)&&a[c].test(b))return c;return null},f.findMatches=function(a,b){var c=[];for(var d in a)h.call(a,d)&&a[d].test(b)&&c.push(d);return c},f.getVersionStr=function(a,b){var c,d,e,g,i=f.mobileDetectRules.props;if(h.call(i,a))for(c=i[a],e=c.length,d=0;d1&&(a=b[0]+".",b.shift(),a+=b.join("")),Number(a)},f.isMobileFallback=function(a){return f.detectMobileBrowsers.fullPattern.test(a)||f.detectMobileBrowsers.shortPattern.test(a.substr(0,4))},f.isTabletFallback=function(a){return f.detectMobileBrowsers.tabletPattern.test(a)},f.prepareDetectionCache=function(a,c,d){if(a.mobile===b){var g,h,i;return(h=f.findMatch(f.mobileDetectRules.tablets,c))?(a.mobile=a.tablet=h,void(a.phone=null)):(g=f.findMatch(f.mobileDetectRules.phones,c))?(a.mobile=a.phone=g,void(a.tablet=null)):void(f.isMobileFallback(c)?(i=e.isPhoneSized(d),i===b?(a.mobile=f.FALLBACK_MOBILE,a.tablet=a.phone=null):i?(a.mobile=a.phone=f.FALLBACK_PHONE,a.tablet=null):(a.mobile=a.tablet=f.FALLBACK_TABLET,a.phone=null)):f.isTabletFallback(c)?(a.mobile=a.tablet=f.FALLBACK_TABLET,a.phone=null):a.mobile=a.tablet=a.phone=null)}},f.mobileGrade=function(a){var b=null!==a.mobile();return a.os("iOS")&&a.version("iPad")>=4.3||a.os("iOS")&&a.version("iPhone")>=3.1||a.os("iOS")&&a.version("iPod")>=3.1||a.version("Android")>2.1&&a.is("Webkit")||a.version("Windows Phone OS")>=7||a.is("BlackBerry")&&a.version("BlackBerry")>=6||a.match("Playbook.*Tablet")||a.version("webOS")>=1.4&&a.match("Palm|Pre|Pixi")||a.match("hp.*TouchPad")||a.is("Firefox")&&a.version("Firefox")>=12||a.is("Chrome")&&a.is("AndroidOS")&&a.version("Android")>=4||a.is("Skyfire")&&a.version("Skyfire")>=4.1&&a.is("AndroidOS")&&a.version("Android")>=2.3||a.is("Opera")&&a.version("Opera Mobi")>11&&a.is("AndroidOS")||a.is("MeeGoOS")||a.is("Tizen")||a.is("Dolfin")&&a.version("Bada")>=2||(a.is("UC Browser")||a.is("Dolfin"))&&a.version("Android")>=2.3||a.match("Kindle Fire")||a.is("Kindle")&&a.version("Kindle")>=3||a.is("AndroidOS")&&a.is("NookTablet")||a.version("Chrome")>=11&&!b||a.version("Safari")>=5&&!b||a.version("Firefox")>=4&&!b||a.version("MSIE")>=7&&!b||a.version("Opera")>=10&&!b?"A":a.os("iOS")&&a.version("iPad")<4.3||a.os("iOS")&&a.version("iPhone")<3.1||a.os("iOS")&&a.version("iPod")<3.1||a.is("Blackberry")&&a.version("BlackBerry")>=5&&a.version("BlackBerry")<6||a.version("Opera Mini")>=5&&a.version("Opera Mini")<=6.5&&(a.version("Android")>=2.3||a.is("iOS"))||a.match("NokiaN8|NokiaC7|N97.*Series60|Symbian/3")||a.version("Opera Mobi")>=11&&a.is("SymbianOS")?"B":(a.version("BlackBerry")<5||a.match("MSIEMobile|Windows CE.*Mobile")||a.version("Windows Mobile")<=5.2,"C")},f.detectOS=function(a){return f.findMatch(f.mobileDetectRules.oss0,a)||f.findMatch(f.mobileDetectRules.oss,a)},f.getDeviceSmallerSide=function(){return window.screen.width"; new_content += "'; $output .= '