├── CHANGELOG.md ├── LICENSE ├── composer.json ├── extend.php ├── js ├── dist │ ├── forum.js │ └── forum.js.map ├── forum.js ├── package.json ├── src │ └── forum │ │ └── index.js └── webpack.config.js └── less └── forum.less /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [1.2.0](https://github.com/flarum/embed/compare/v1.1.0...v1.2.0) 4 | 5 | No changes. 6 | 7 | ## [1.1.0](https://github.com/flarum/embed/compare/v1.0.0...v1.1.0) 8 | 9 | No changes. 10 | 11 | ## [1.0.0](https://github.com/flarum/embed/compare/v0.1.0-beta.16...v1.0.0) 12 | 13 | ### Changed 14 | - Compatibility with Flarum v1.0.0. 15 | 16 | ## [0.1.0-beta.16](https://github.com/flarum/embed/compare/v0.1.0-beta.15...v0.1.0-beta.16) 17 | 18 | ### Changed 19 | - Replaced `app()` helper with `resolve()`. 20 | 21 | ## [0.1.0-beta.15](https://github.com/flarum/embed/compare/v0.1.0-beta.14...v0.1.0-beta.15) 22 | 23 | ### Changed 24 | - Updated composer.json and admin javascript for new admin area. 25 | 26 | ## [0.1.0-beta.14](https://github.com/flarum/embed/compare/v0.1.0-beta.13...v0.1.0-beta.14) 27 | 28 | ### Changed 29 | - Updated mithril to version 2 30 | - Updated JS dependencies 31 | 32 | ## [0.1.0-beta.13](https://github.com/flarum/embed/compare/v0.1.0-beta.12...v0.1.0-beta.13) 33 | 34 | ### Changed 35 | - Updated JS dependencies 36 | 37 | ## [0.1.0-beta.10](https://github.com/flarum/embed/compare/v0.1.0-beta.9...v0.1.0-beta.10) 38 | 39 | ### Fixed 40 | - JavaScript code was not compiled (#6) 41 | - Icon was not updated for FontAwesome 5 (#6) 42 | 43 | ## [0.1.0-beta.9](https://github.com/flarum/embed/compare/v0.1.0-beta.8...v0.1.0-beta.9) 44 | 45 | ### Fixed 46 | - JS: Vulnerable lodash dependency ([1a1a724](https://github.com/flarum/embed/commit/1a1a72477bfa1eec5da3a09aaf70a5942616d65d)) 47 | 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019-2024 Stichting Flarum (Flarum Foundation) 4 | Copyright (c) 2014-2019 Toby Zerner (toby.zerner@gmail.com) 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flarum/embed", 3 | "description": "Embed Flarum discussions as comments for your blog.", 4 | "type": "flarum-extension", 5 | "keywords": [ 6 | "discussion" 7 | ], 8 | "license": "MIT", 9 | "support": { 10 | "issues": "https://github.com/flarum/framework/issues", 11 | "source": "https://github.com/flarum/embed", 12 | "forum": "https://discuss.flarum.org" 13 | }, 14 | "homepage": "https://flarum.org", 15 | "funding": [ 16 | { 17 | "type": "website", 18 | "url": "https://flarum.org/donate/" 19 | } 20 | ], 21 | "require": { 22 | "flarum/core": "^2.0.0-beta.3" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "Flarum\\Embed\\": "src/" 27 | } 28 | }, 29 | "extra": { 30 | "branch-alias": { 31 | "dev-main": "2.x-dev" 32 | }, 33 | "flarum-extension": { 34 | "title": "Embed", 35 | "category": "feature", 36 | "icon": { 37 | "name": "fas fa-code", 38 | "backgroundColor": "#B9D233", 39 | "color": "#fff" 40 | } 41 | }, 42 | "flarum-cli": { 43 | "modules": { 44 | "admin": false, 45 | "forum": true, 46 | "js": true, 47 | "jsCommon": false, 48 | "css": true, 49 | "gitConf": true, 50 | "githubActions": true, 51 | "prettier": true, 52 | "typescript": false, 53 | "bundlewatch": false, 54 | "backendTesting": false, 55 | "editorConfig": true, 56 | "styleci": true 57 | } 58 | } 59 | }, 60 | "repositories": [ 61 | { 62 | "type": "path", 63 | "url": "../../*/*" 64 | } 65 | ], 66 | "minimum-stability": "dev", 67 | "prefer-stable": true 68 | } 69 | -------------------------------------------------------------------------------- /extend.php: -------------------------------------------------------------------------------- 1 | route( 17 | '/embed/{id:\d+(?:-[^/]*)?}[/{near:[^/]*}]', 18 | 'embed.discussion', 19 | function (Document $document, Request $request) { 20 | // Add the discussion content to the document so that the 21 | // payload will be included on the page and the JS app will be 22 | // able to render the discussion immediately. 23 | resolve(Flarum\Forum\Content\Discussion::class)($document, $request); 24 | 25 | resolve(Flarum\Frontend\Content\Assets::class)->forFrontend('embed')($document, $request); 26 | } 27 | ), 28 | 29 | (new Extend\Frontend('embed')) 30 | ->js(__DIR__.'/js/dist/forum.js') 31 | ->css(__DIR__.'/less/forum.less') 32 | ]; 33 | -------------------------------------------------------------------------------- /js/dist/forum.js: -------------------------------------------------------------------------------- 1 | (()=>{var e={424:e=>{!function(t){if("undefined"!=typeof window){var n=!0,o="",i=0,r="",a=null,c="",s=!1,u={resize:1,click:1},d=128,l=!0,m=1,f="bodyOffset",p=f,g=!0,h="",v={},y=32,w=null,b=!1,T=!1,E="[iFrameSizer]",O="",S={max:1,min:1,bodyScroll:1,documentElementScroll:1},M="child",I=window.parent,N="*",x=0,A=!1,C=null,k=16,z=1,R="scroll",P=R,F=window,L=function(){ie("onMessage function not defined")},D=function(){},j=function(){},q={height:function(){return ie("Custom height calculation function not defined"),document.documentElement.offsetHeight},width:function(){return ie("Custom width calculation function not defined"),document.body.scrollWidth}},H={},W=!1;try{var B=Object.create({},{passive:{get:function(){W=!0}}});window.addEventListener("test",Z,B),window.removeEventListener("test",Z,B)}catch(e){}var J,U,_,V,X,Y,K,Q={bodyOffset:function(){return document.body.offsetHeight+ge("marginTop")+ge("marginBottom")},offset:function(){return Q.bodyOffset()},bodyScroll:function(){return document.body.scrollHeight},custom:function(){return q.height()},documentElementOffset:function(){return document.documentElement.offsetHeight},documentElementScroll:function(){return document.documentElement.scrollHeight},max:function(){return Math.max.apply(null,ve(Q))},min:function(){return Math.min.apply(null,ve(Q))},grow:function(){return Q.max()},lowestElement:function(){return Math.max(Q.bodyOffset()||Q.documentElementOffset(),he("bottom",we()))},taggedElement:function(){return ye("bottom","data-iframe-height")}},$={bodyScroll:function(){return document.body.scrollWidth},bodyOffset:function(){return document.body.offsetWidth},custom:function(){return q.width()},documentElementScroll:function(){return document.documentElement.scrollWidth},documentElementOffset:function(){return document.documentElement.offsetWidth},scroll:function(){return Math.max($.bodyScroll(),$.documentElementScroll())},max:function(){return Math.max.apply(null,ve($))},min:function(){return Math.min.apply(null,ve($))},rightMostElement:function(){return he("right",we())},taggedElement:function(){return ye("right","data-iframe-width")}},G=(J=be,X=null,Y=0,K=function(){Y=Date.now(),X=null,V=J.apply(U,_),X||(U=_=null)},function(){var e=Date.now();Y||(Y=e);var t=k-(e-Y);return U=this,_=arguments,t<=0||t>k?(X&&(clearTimeout(X),X=null),Y=e,V=J.apply(U,_),X||(U=_=null)):X||(X=setTimeout(K,t)),V});"iframeResizer"in window||(window.iframeChildListener=function(e){Ie({data:e,sameDomian:!0})},ee(window,"message",Ie),ee(window,"readystatechange",Ne),Ne())}function Z(){}function ee(e,t,n,o){e.addEventListener(t,n,!!W&&(o||{}))}function te(e){return e.charAt(0).toUpperCase()+e.slice(1)}function ne(e){return E+"["+O+"] "+e}function oe(e){b&&"object"==typeof window.console&&console.log(ne(e))}function ie(e){"object"==typeof window.console&&console.warn(ne(e))}function re(){var e,u;!function(){function e(e){return"true"===e}var a=h.slice(13).split(":");O=a[0],i=t===a[1]?i:Number(a[1]),s=t===a[2]?s:e(a[2]),b=t===a[3]?b:e(a[3]),y=t===a[4]?y:Number(a[4]),n=t===a[6]?n:e(a[6]),r=a[7],p=t===a[8]?p:a[8],o=a[9],c=a[10],x=t===a[11]?x:Number(a[11]),v.enable=t!==a[12]&&e(a[12]),M=t===a[13]?M:a[13],P=t===a[14]?P:a[14],T=t===a[15]?T:e(a[15])}(),oe("Initialising iFrame ("+window.location.href+")"),function(){function e(e,t){return"function"==typeof e&&(oe("Setup custom "+t+"CalcMethod"),q[t]=e,e="custom"),e}var t;"iFrameResizer"in window&&Object===window.iFrameResizer.constructor&&(t=window.iFrameResizer,oe("Reading data from page: "+JSON.stringify(t)),Object.keys(t).forEach(ae,t),L="onMessage"in t?t.onMessage:L,D="onReady"in t?t.onReady:D,N="targetOrigin"in t?t.targetOrigin:N,p="heightCalculationMethod"in t?t.heightCalculationMethod:p,P="widthCalculationMethod"in t?t.widthCalculationMethod:P,p=e(p,"height"),P=e(P,"width")),oe("TargetOrigin for parent set to: "+N)}(),t===r&&(r=i+"px"),ce("margin",(-1!==(u=r).indexOf("-")&&(ie("Negative CSS value ignored for margin"),u=""),u)),ce("background",o),ce("padding",c),(e=document.createElement("div")).style.clear="both",e.style.display="block",e.style.height="0",document.body.appendChild(e),le(),me(),document.documentElement.style.height="",document.body.style.height="",oe('HTML & body height set to "auto"'),oe("Enable public methods"),F.parentIFrame={autoResize:function(e){return!0===e&&!1===n?(n=!0,fe()):!1===e&&!0===n&&(n=!1,ue("remove"),null!==a&&a.disconnect(),clearInterval(w)),Me(0,0,"autoResize",JSON.stringify(n)),n},close:function(){Me(0,0,"close")},getId:function(){return O},getPageInfo:function(e){"function"==typeof e?(j=e,Me(0,0,"pageInfo")):(j=function(){},Me(0,0,"pageInfoStop"))},moveToAnchor:function(e){v.findTarget(e)},reset:function(){Se("parentIFrame.reset")},scrollTo:function(e,t){Me(t,e,"scrollTo")},scrollToOffset:function(e,t){Me(t,e,"scrollToOffset")},sendMessage:function(e,t){Me(0,0,"message",JSON.stringify(e),t)},setHeightCalculationMethod:function(e){p=e,le()},setWidthCalculationMethod:function(e){P=e,me()},setTargetOrigin:function(e){oe("Set targetOrigin: "+e),N=e},size:function(e,t){Te("size","parentIFrame.size("+(e||"")+(t?","+t:"")+")",e,t)}},function(){function e(e){Me(0,0,e.type,e.screenY+":"+e.screenX)}function t(t,n){oe("Add event listener: "+n),ee(window.document,t,e)}!0===T&&(t("mouseenter","Mouse Enter"),t("mouseleave","Mouse Leave"))}(),fe(),v=function(){function e(e){var n=e.getBoundingClientRect(),o={x:window.pageXOffset===t?document.documentElement.scrollLeft:window.pageXOffset,y:window.pageYOffset===t?document.documentElement.scrollTop:window.pageYOffset};return{x:parseInt(n.left,10)+parseInt(o.x,10),y:parseInt(n.top,10)+parseInt(o.y,10)}}function n(n){var o=n.split("#")[1]||n,i=decodeURIComponent(o),r=document.getElementById(i)||document.getElementsByName(i)[0];t===r?(oe("In page link (#"+o+") not found in iFrame, so sending to parent"),Me(0,0,"inPageLink","#"+o)):function(t){var n=e(t);oe("Moving to in page link (#"+o+") at x: "+n.x+" y: "+n.y),Me(n.y,n.x,"scrollToOffset")}(r)}function o(){var e=window.location.hash,t=window.location.href;""!==e&&"#"!==e&&n(t)}return v.enable?Array.prototype.forEach&&document.querySelectorAll?(oe("Setting up location.hash handlers"),Array.prototype.forEach.call(document.querySelectorAll('a[href^="#"]'),(function(e){"#"!==e.getAttribute("href")&&ee(e,"click",(function(e){e.preventDefault(),n(this.getAttribute("href"))}))})),ee(window,"hashchange",o),setTimeout(o,d)):ie("In page linking not fully supported in this browser! (See README.md for IE8 workaround)"):oe("In page linking not enabled"),{findTarget:n}}(),Te("init","Init message from host page"),D()}function ae(e){var t=e.split("Callback");if(2===t.length){var n="on"+t[0].charAt(0).toUpperCase()+t[0].slice(1);this[n]=this[e],delete this[e],ie("Deprecated: '"+e+"' has been renamed '"+n+"'. The old method will be removed in the next major version.")}}function ce(e,n){t!==n&&""!==n&&"null"!==n&&(document.body.style[e]=n,oe("Body "+e+' set to "'+n+'"'))}function se(e){var t={add:function(t){function n(){Te(e.eventName,e.eventType)}H[t]=n,ee(window,t,n,{passive:!0})},remove:function(e){var t,n,o=H[e];delete H[e],t=e,n=o,window.removeEventListener(t,n,!1)}};e.eventNames&&Array.prototype.map?(e.eventName=e.eventNames[0],e.eventNames.map(t[e.method])):t[e.method](e.eventName),oe(te(e.method)+" event listener: "+e.eventType)}function ue(e){se({method:e,eventType:"Animation Start",eventNames:["animationstart","webkitAnimationStart"]}),se({method:e,eventType:"Animation Iteration",eventNames:["animationiteration","webkitAnimationIteration"]}),se({method:e,eventType:"Animation End",eventNames:["animationend","webkitAnimationEnd"]}),se({method:e,eventType:"Input",eventName:"input"}),se({method:e,eventType:"Mouse Up",eventName:"mouseup"}),se({method:e,eventType:"Mouse Down",eventName:"mousedown"}),se({method:e,eventType:"Orientation Change",eventName:"orientationchange"}),se({method:e,eventType:"Print",eventNames:["afterprint","beforeprint"]}),se({method:e,eventType:"Ready State Change",eventName:"readystatechange"}),se({method:e,eventType:"Touch Start",eventName:"touchstart"}),se({method:e,eventType:"Touch End",eventName:"touchend"}),se({method:e,eventType:"Touch Cancel",eventName:"touchcancel"}),se({method:e,eventType:"Transition Start",eventNames:["transitionstart","webkitTransitionStart","MSTransitionStart","oTransitionStart","otransitionstart"]}),se({method:e,eventType:"Transition Iteration",eventNames:["transitioniteration","webkitTransitionIteration","MSTransitionIteration","oTransitionIteration","otransitioniteration"]}),se({method:e,eventType:"Transition End",eventNames:["transitionend","webkitTransitionEnd","MSTransitionEnd","oTransitionEnd","otransitionend"]}),"child"===M&&se({method:e,eventType:"IFrame Resized",eventName:"resize"})}function de(e,t,n,o){return t!==e&&(e in n||(ie(e+" is not a valid option for "+o+"CalculationMethod."),e=t),oe(o+' calculation method set to "'+e+'"')),e}function le(){p=de(p,f,Q,"height")}function me(){P=de(P,R,$,"width")}function fe(){var e;!0===n?(ue("add"),e=0>y,window.MutationObserver||window.WebKitMutationObserver?e?pe():a=function(){function e(e){function t(e){!1===e.complete&&(oe("Attach listeners to "+e.src),e.addEventListener("load",o,!1),e.addEventListener("error",i,!1),a.push(e))}"attributes"===e.type&&"src"===e.attributeName?t(e.target):"childList"===e.type&&Array.prototype.forEach.call(e.target.querySelectorAll("img"),t)}function t(e){oe("Remove listeners from "+e.src),e.removeEventListener("load",o,!1),e.removeEventListener("error",i,!1),function(e){a.splice(a.indexOf(e),1)}(e)}function n(e,n,o){t(e.target),Te(n,o+": "+e.target.src)}function o(e){n(e,"imageLoad","Image loaded")}function i(e){n(e,"imageLoadFailed","Image load failed")}function r(t){Te("mutationObserver","mutationObserver: "+t[0].target+" "+t[0].type),t.forEach(e)}var a=[],c=window.MutationObserver||window.WebKitMutationObserver,s=function(){var e=document.querySelector("body");return s=new c(r),oe("Create body MutationObserver"),s.observe(e,{attributes:!0,attributeOldValue:!1,characterData:!0,characterDataOldValue:!1,childList:!0,subtree:!0}),s}();return{disconnect:function(){"disconnect"in s&&(oe("Disconnect body MutationObserver"),s.disconnect(),a.forEach(t))}}}():(oe("MutationObserver not supported in this browser!"),pe())):oe("Auto Resize disabled")}function pe(){0!==y&&(oe("setInterval: "+y+"ms"),w=setInterval((function(){Te("interval","setInterval: "+y)}),Math.abs(y)))}function ge(e,t){var n=0;return t=t||document.body,n=null===(n=document.defaultView.getComputedStyle(t,null))?0:n[e],parseInt(n,10)}function he(e,t){for(var n=t.length,o=0,i=0,r=te(e),a=Date.now(),c=0;ci&&(i=o);return a=Date.now()-a,oe("Parsed "+n+" HTML elements"),oe("Element position calculated in "+a+"ms"),function(e){e>k/2&&oe("Event throttle increased to "+(k=2*e)+"ms")}(a),i}function ve(e){return[e.bodyOffset(),e.bodyScroll(),e.documentElementOffset(),e.documentElementScroll()]}function ye(e,t){var n=document.querySelectorAll("["+t+"]");return 0===n.length&&(ie("No tagged elements ("+t+") found on page"),document.querySelectorAll("body *")),he(e,n)}function we(){return document.querySelectorAll("body *")}function be(e,n,o,i){var r,a;!function(){function e(e,t){return!(Math.abs(e-t)<=x)}return r=t===o?Q[p]():o,a=t===i?$[P]():i,e(m,r)||s&&e(z,a)}()&&"init"!==e?!(e in{init:1,interval:1,size:1})&&(p in S||s&&P in S)?Se(n):e in{interval:1}||oe("No change in size detected"):(Ee(),Me(m=r,z=a,e))}function Te(e,t,n,o){A&&e in u?oe("Trigger event cancelled: "+e):(e in{reset:1,resetPage:1,init:1}||oe("Trigger event: "+t),"init"===e?be(e,t,n,o):G(e,t,n,o))}function Ee(){A||(A=!0,oe("Trigger event lock on")),clearTimeout(C),C=setTimeout((function(){A=!1,oe("Trigger event lock off"),oe("--")}),d)}function Oe(e){m=Q[p](),z=$[P](),Me(m,z,e)}function Se(e){var t=p;p=f,oe("Reset trigger event: "+e),Ee(),Oe("reset"),p=t}function Me(e,n,o,i,r){var a;t===r?r=N:oe("Message targetOrigin: "+r),oe("Sending message to host page ("+(a=O+":"+e+":"+n+":"+o+(t===i?"":":"+i))+")"),I.postMessage(E+a,r)}function Ie(n){var o,i={init:function(){h=n.data,I=n.source,re(),l=!1,setTimeout((function(){g=!1}),d)},reset:function(){g?oe("Page reset ignored by init"):(oe("Page size reset by host page"),Oe("resetPage"))},resize:function(){Te("resizeParent","Parent window requested size check")},moveToAnchor:function(){v.findTarget(a())},inPageLink:function(){this.moveToAnchor()},pageInfo:function(){var e=a();oe("PageInfoFromParent called from parent: "+e),j(JSON.parse(e)),oe(" --")},message:function(){var e=a();oe("onMessage called from parent: "+e),L(JSON.parse(e)),oe(" --")}};function r(){return n.data.split("]")[1].split(":")[0]}function a(){return n.data.slice(n.data.indexOf(":")+1)}function c(){return n.data.split(":")[2]in{true:1,false:1}}E===(""+n.data).slice(0,13)&&(!1===l?(o=r())in i?i[o]():!e.exports&&"iFrameResize"in window||window.jQuery!==t&&"iFrameResize"in window.jQuery.prototype||c()||ie("Unexpected message ("+n.data+")"):c()?i.init():oe('Ignored message of type "'+r()+'". Received before initialization.'))}function Ne(){"loading"!==document.readyState&&window.parent.postMessage("[iFrameResizerChild]Ready","*")}}()}},t={};function n(o){flarum.reg._webpack_runtimes["flarum-embed"]||=n;var i=t[o];if(void 0!==i)return i.exports;var r=t[o]={exports:{}};return e[o](r,r.exports,n),r.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var o in t)n.o(t,o)&&!n.o(e,o)&&Object.defineProperty(e,o,{enumerable:!0,get:t[o]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{"use strict";n(424);const e=flarum.reg.get("core","common/extend"),t=flarum.reg.get("core","forum/app");var o=n.n(t);const i=flarum.reg.get("core","common/utils/Stream");var r=n.n(i);const a=flarum.reg.get("core","forum/ForumApplication");var c=n.n(a);const s=flarum.reg.get("core","common/components/ModalManager");var u=n.n(s);const d=flarum.reg.get("core","forum/components/PostMeta");var l=n.n(d);const f=flarum.reg.get("core","forum/components/DiscussionPage");var p=n.n(f);(0,e.extend)(c().prototype,"mount",(function(){m.route.param("hideFirstPost")&&(0,e.extend)("flarum/forum/components/PostStream","view",(e=>{1===e.children[0].attrs["data-number"]&&e.children.splice(0,1)}))})),(0,e.override)(m.route.Link,"view",(function(e,t){return t.attrs.href=t.attrs.href.replace("/embed","/d"),t.attrs.target="_blank",e(t)})),(0,e.override)(l().prototype,"getPermalink",((e,t)=>e(t).replace("/embed","/d"))),o().pageInfo=r()({});const g=function(){const e=o().pageInfo();this.$().css("top",Math.max(0,e.scrollTop-e.offsetTop))};(0,e.extend)(u().prototype,"show",g),(0,e.extend)("flarum/forum/components/Composer","show",g),window.iFrameResizer={readyCallback:function(){window.parentIFrame.getPageInfo(o().pageInfo)}},(0,e.extend)("flarum/forum/components/PostStream","goToNumber",(function(e,t){if("reply"===t&&"parentIFrame"in window&&o().composer.isFullScreen()){const e=this.$(".PostStream-item:last").offset().top;window.parentIFrame.scrollToOffset(0,e)}})),(0,e.extend)(p().prototype,"sidebarItems",(function(e){e.remove("scrubber");const t=this.discussion.replyCount();e.add("replies",m("h3",null,m("a",{route:o().route.discussion(this.discussion).replace("/embed","/d")},t," comment",1==t?"":"s")),100);const n=e.get("controls").attrs;n.className=n.className.replace("App-primaryControl","")})),o().routes.discussion={path:"/embed/:id",component:p()},o().routes["discussion.near"]={path:"/embed/:id/:near",component:p()}})(),module.exports={}})(); 2 | //# sourceMappingURL=forum.js.map -------------------------------------------------------------------------------- /js/dist/forum.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"file":"forum.js","mappings":"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","sources":["webpack://@flarum/embed/../../../node_modules/iframe-resizer/js/iframeResizer.contentWindow.js","webpack://@flarum/embed/webpack/bootstrap","webpack://@flarum/embed/webpack/runtime/compat get default export","webpack://@flarum/embed/webpack/runtime/define property getters","webpack://@flarum/embed/webpack/runtime/hasOwnProperty shorthand","webpack://@flarum/embed/external root \"flarum.reg.get('core', 'common/extend')\"","webpack://@flarum/embed/external root \"flarum.reg.get('core', 'forum/app')\"","webpack://@flarum/embed/external root \"flarum.reg.get('core', 'common/utils/Stream')\"","webpack://@flarum/embed/external root \"flarum.reg.get('core', 'forum/ForumApplication')\"","webpack://@flarum/embed/external root \"flarum.reg.get('core', 'common/components/ModalManager')\"","webpack://@flarum/embed/external root \"flarum.reg.get('core', 'forum/components/PostMeta')\"","webpack://@flarum/embed/external root \"flarum.reg.get('core', 'forum/components/DiscussionPage')\"","webpack://@flarum/embed/./src/forum/index.js"],"sourcesContent":["/*\n * File: iframeResizer.contentWindow.js\n * Desc: Include this file in any page being loaded into an iframe\n * to force the iframe to resize to the content size.\n * Requires: iframeResizer.js on host page.\n * Doc: https://iframe-resizer.com\n * Author: David J. Bradshaw - info@iframe-resizer.com\n *\n */\n\n// eslint-disable-next-line sonarjs/cognitive-complexity, no-shadow-restricted-names\n;(function (undefined) {\n if (typeof window === 'undefined') return // don't run for server side render\n\n var autoResize = true,\n base = 10,\n bodyBackground = '',\n bodyMargin = 0,\n bodyMarginStr = '',\n bodyObserver = null,\n bodyPadding = '',\n calculateWidth = false,\n doubleEventList = { resize: 1, click: 1 },\n eventCancelTimer = 128,\n firstRun = true,\n height = 1,\n heightCalcModeDefault = 'bodyOffset',\n heightCalcMode = heightCalcModeDefault,\n initLock = true,\n initMsg = '',\n inPageLinks = {},\n interval = 32,\n intervalTimer = null,\n logging = false,\n mouseEvents = false,\n msgID = '[iFrameSizer]', // Must match host page msg ID\n msgIdLen = msgID.length,\n myID = '',\n resetRequiredMethods = {\n max: 1,\n min: 1,\n bodyScroll: 1,\n documentElementScroll: 1\n },\n resizeFrom = 'child',\n sendPermit = true,\n target = window.parent,\n targetOriginDefault = '*',\n tolerance = 0,\n triggerLocked = false,\n triggerLockedTimer = null,\n throttledTimer = 16,\n width = 1,\n widthCalcModeDefault = 'scroll',\n widthCalcMode = widthCalcModeDefault,\n win = window,\n onMessage = function () {\n warn('onMessage function not defined')\n },\n onReady = function () {},\n onPageInfo = function () {},\n customCalcMethods = {\n height: function () {\n warn('Custom height calculation function not defined')\n return document.documentElement.offsetHeight\n },\n width: function () {\n warn('Custom width calculation function not defined')\n return document.body.scrollWidth\n }\n },\n eventHandlersByName = {},\n passiveSupported = false\n\n function noop() {}\n\n try {\n var options = Object.create(\n {},\n {\n passive: {\n // eslint-disable-next-line getter-return\n get: function () {\n passiveSupported = true\n }\n }\n }\n )\n window.addEventListener('test', noop, options)\n window.removeEventListener('test', noop, options)\n } catch (error) {\n /* */\n }\n\n function addEventListener(el, evt, func, options) {\n el.addEventListener(evt, func, passiveSupported ? options || {} : false)\n }\n\n function removeEventListener(el, evt, func) {\n el.removeEventListener(evt, func, false)\n }\n\n function capitalizeFirstLetter(string) {\n return string.charAt(0).toUpperCase() + string.slice(1)\n }\n\n // Based on underscore.js\n function throttle(func) {\n var context,\n args,\n result,\n timeout = null,\n previous = 0,\n later = function () {\n previous = Date.now()\n timeout = null\n result = func.apply(context, args)\n if (!timeout) {\n // eslint-disable-next-line no-multi-assign\n context = args = null\n }\n }\n\n return function () {\n var now = Date.now()\n\n if (!previous) {\n previous = now\n }\n\n var remaining = throttledTimer - (now - previous)\n\n context = this\n args = arguments\n\n if (remaining <= 0 || remaining > throttledTimer) {\n if (timeout) {\n clearTimeout(timeout)\n timeout = null\n }\n\n previous = now\n result = func.apply(context, args)\n\n if (!timeout) {\n // eslint-disable-next-line no-multi-assign\n context = args = null\n }\n } else if (!timeout) {\n timeout = setTimeout(later, remaining)\n }\n\n return result\n }\n }\n\n function formatLogMsg(msg) {\n return msgID + '[' + myID + '] ' + msg\n }\n\n function log(msg) {\n if (logging && 'object' === typeof window.console) {\n // eslint-disable-next-line no-console\n console.log(formatLogMsg(msg))\n }\n }\n\n function warn(msg) {\n if ('object' === typeof window.console) {\n // eslint-disable-next-line no-console\n console.warn(formatLogMsg(msg))\n }\n }\n\n function init() {\n readDataFromParent()\n log('Initialising iFrame (' + window.location.href + ')')\n readDataFromPage()\n setMargin()\n setBodyStyle('background', bodyBackground)\n setBodyStyle('padding', bodyPadding)\n injectClearFixIntoBodyElement()\n checkHeightMode()\n checkWidthMode()\n stopInfiniteResizingOfIFrame()\n setupPublicMethods()\n setupMouseEvents()\n startEventListeners()\n inPageLinks = setupInPageLinks()\n sendSize('init', 'Init message from host page')\n onReady()\n }\n\n function readDataFromParent() {\n function strBool(str) {\n return 'true' === str\n }\n\n var data = initMsg.slice(msgIdLen).split(':')\n\n myID = data[0]\n bodyMargin = undefined === data[1] ? bodyMargin : Number(data[1]) // For V1 compatibility\n calculateWidth = undefined === data[2] ? calculateWidth : strBool(data[2])\n logging = undefined === data[3] ? logging : strBool(data[3])\n interval = undefined === data[4] ? interval : Number(data[4])\n autoResize = undefined === data[6] ? autoResize : strBool(data[6])\n bodyMarginStr = data[7]\n heightCalcMode = undefined === data[8] ? heightCalcMode : data[8]\n bodyBackground = data[9]\n bodyPadding = data[10]\n tolerance = undefined === data[11] ? tolerance : Number(data[11])\n inPageLinks.enable = undefined === data[12] ? false : strBool(data[12])\n resizeFrom = undefined === data[13] ? resizeFrom : data[13]\n widthCalcMode = undefined === data[14] ? widthCalcMode : data[14]\n mouseEvents = undefined === data[15] ? mouseEvents : strBool(data[15])\n }\n\n function depricate(key) {\n var splitName = key.split('Callback')\n\n if (splitName.length === 2) {\n var name =\n 'on' + splitName[0].charAt(0).toUpperCase() + splitName[0].slice(1)\n this[name] = this[key]\n delete this[key]\n warn(\n \"Deprecated: '\" +\n key +\n \"' has been renamed '\" +\n name +\n \"'. The old method will be removed in the next major version.\"\n )\n }\n }\n\n function readDataFromPage() {\n function readData() {\n var data = window.iFrameResizer\n\n log('Reading data from page: ' + JSON.stringify(data))\n Object.keys(data).forEach(depricate, data)\n\n onMessage = 'onMessage' in data ? data.onMessage : onMessage\n onReady = 'onReady' in data ? data.onReady : onReady\n targetOriginDefault =\n 'targetOrigin' in data ? data.targetOrigin : targetOriginDefault\n heightCalcMode =\n 'heightCalculationMethod' in data\n ? data.heightCalculationMethod\n : heightCalcMode\n widthCalcMode =\n 'widthCalculationMethod' in data\n ? data.widthCalculationMethod\n : widthCalcMode\n }\n\n function setupCustomCalcMethods(calcMode, calcFunc) {\n if ('function' === typeof calcMode) {\n log('Setup custom ' + calcFunc + 'CalcMethod')\n customCalcMethods[calcFunc] = calcMode\n calcMode = 'custom'\n }\n\n return calcMode\n }\n\n if (\n 'iFrameResizer' in window &&\n Object === window.iFrameResizer.constructor\n ) {\n readData()\n heightCalcMode = setupCustomCalcMethods(heightCalcMode, 'height')\n widthCalcMode = setupCustomCalcMethods(widthCalcMode, 'width')\n }\n\n log('TargetOrigin for parent set to: ' + targetOriginDefault)\n }\n\n function chkCSS(attr, value) {\n if (-1 !== value.indexOf('-')) {\n warn('Negative CSS value ignored for ' + attr)\n value = ''\n }\n return value\n }\n\n function setBodyStyle(attr, value) {\n if (undefined !== value && '' !== value && 'null' !== value) {\n document.body.style[attr] = value\n log('Body ' + attr + ' set to \"' + value + '\"')\n }\n }\n\n function setMargin() {\n // If called via V1 script, convert bodyMargin from int to str\n if (undefined === bodyMarginStr) {\n bodyMarginStr = bodyMargin + 'px'\n }\n\n setBodyStyle('margin', chkCSS('margin', bodyMarginStr))\n }\n\n function stopInfiniteResizingOfIFrame() {\n document.documentElement.style.height = ''\n document.body.style.height = ''\n log('HTML & body height set to \"auto\"')\n }\n\n function manageTriggerEvent(options) {\n var listener = {\n add: function (eventName) {\n function handleEvent() {\n sendSize(options.eventName, options.eventType)\n }\n\n eventHandlersByName[eventName] = handleEvent\n\n addEventListener(window, eventName, handleEvent, { passive: true })\n },\n remove: function (eventName) {\n var handleEvent = eventHandlersByName[eventName]\n delete eventHandlersByName[eventName]\n\n removeEventListener(window, eventName, handleEvent)\n }\n }\n\n if (options.eventNames && Array.prototype.map) {\n options.eventName = options.eventNames[0]\n options.eventNames.map(listener[options.method])\n } else {\n listener[options.method](options.eventName)\n }\n\n log(\n capitalizeFirstLetter(options.method) +\n ' event listener: ' +\n options.eventType\n )\n }\n\n function manageEventListeners(method) {\n manageTriggerEvent({\n method: method,\n eventType: 'Animation Start',\n eventNames: ['animationstart', 'webkitAnimationStart']\n })\n manageTriggerEvent({\n method: method,\n eventType: 'Animation Iteration',\n eventNames: ['animationiteration', 'webkitAnimationIteration']\n })\n manageTriggerEvent({\n method: method,\n eventType: 'Animation End',\n eventNames: ['animationend', 'webkitAnimationEnd']\n })\n manageTriggerEvent({\n method: method,\n eventType: 'Input',\n eventName: 'input'\n })\n manageTriggerEvent({\n method: method,\n eventType: 'Mouse Up',\n eventName: 'mouseup'\n })\n manageTriggerEvent({\n method: method,\n eventType: 'Mouse Down',\n eventName: 'mousedown'\n })\n manageTriggerEvent({\n method: method,\n eventType: 'Orientation Change',\n eventName: 'orientationchange'\n })\n manageTriggerEvent({\n method: method,\n eventType: 'Print',\n eventNames: ['afterprint', 'beforeprint']\n })\n manageTriggerEvent({\n method: method,\n eventType: 'Ready State Change',\n eventName: 'readystatechange'\n })\n manageTriggerEvent({\n method: method,\n eventType: 'Touch Start',\n eventName: 'touchstart'\n })\n manageTriggerEvent({\n method: method,\n eventType: 'Touch End',\n eventName: 'touchend'\n })\n manageTriggerEvent({\n method: method,\n eventType: 'Touch Cancel',\n eventName: 'touchcancel'\n })\n manageTriggerEvent({\n method: method,\n eventType: 'Transition Start',\n eventNames: [\n 'transitionstart',\n 'webkitTransitionStart',\n 'MSTransitionStart',\n 'oTransitionStart',\n 'otransitionstart'\n ]\n })\n manageTriggerEvent({\n method: method,\n eventType: 'Transition Iteration',\n eventNames: [\n 'transitioniteration',\n 'webkitTransitionIteration',\n 'MSTransitionIteration',\n 'oTransitionIteration',\n 'otransitioniteration'\n ]\n })\n manageTriggerEvent({\n method: method,\n eventType: 'Transition End',\n eventNames: [\n 'transitionend',\n 'webkitTransitionEnd',\n 'MSTransitionEnd',\n 'oTransitionEnd',\n 'otransitionend'\n ]\n })\n if ('child' === resizeFrom) {\n manageTriggerEvent({\n method: method,\n eventType: 'IFrame Resized',\n eventName: 'resize'\n })\n }\n }\n\n function checkCalcMode(calcMode, calcModeDefault, modes, type) {\n if (calcModeDefault !== calcMode) {\n if (!(calcMode in modes)) {\n warn(\n calcMode + ' is not a valid option for ' + type + 'CalculationMethod.'\n )\n calcMode = calcModeDefault\n }\n log(type + ' calculation method set to \"' + calcMode + '\"')\n }\n\n return calcMode\n }\n\n function checkHeightMode() {\n heightCalcMode = checkCalcMode(\n heightCalcMode,\n heightCalcModeDefault,\n getHeight,\n 'height'\n )\n }\n\n function checkWidthMode() {\n widthCalcMode = checkCalcMode(\n widthCalcMode,\n widthCalcModeDefault,\n getWidth,\n 'width'\n )\n }\n\n function startEventListeners() {\n if (true === autoResize) {\n manageEventListeners('add')\n setupMutationObserver()\n } else {\n log('Auto Resize disabled')\n }\n }\n\n // function stopMsgsToParent() {\n // log('Disable outgoing messages')\n // sendPermit = false\n // }\n\n // function removeMsgListener() {\n // log('Remove event listener: Message')\n // removeEventListener(window, 'message', receiver)\n // }\n\n function disconnectMutationObserver() {\n if (null !== bodyObserver) {\n /* istanbul ignore next */ // Not testable in PhantonJS\n bodyObserver.disconnect()\n }\n }\n\n function stopEventListeners() {\n manageEventListeners('remove')\n disconnectMutationObserver()\n clearInterval(intervalTimer)\n }\n\n // function teardown() {\n // stopMsgsToParent()\n // removeMsgListener()\n // if (true === autoResize) stopEventListeners()\n // }\n\n function injectClearFixIntoBodyElement() {\n var clearFix = document.createElement('div')\n clearFix.style.clear = 'both'\n // Guard against the following having been globally redefined in CSS.\n clearFix.style.display = 'block'\n clearFix.style.height = '0'\n document.body.appendChild(clearFix)\n }\n\n function setupInPageLinks() {\n function getPagePosition() {\n return {\n x:\n window.pageXOffset === undefined\n ? document.documentElement.scrollLeft\n : window.pageXOffset,\n y:\n window.pageYOffset === undefined\n ? document.documentElement.scrollTop\n : window.pageYOffset\n }\n }\n\n function getElementPosition(el) {\n var elPosition = el.getBoundingClientRect(),\n pagePosition = getPagePosition()\n\n return {\n x: parseInt(elPosition.left, 10) + parseInt(pagePosition.x, 10),\n y: parseInt(elPosition.top, 10) + parseInt(pagePosition.y, 10)\n }\n }\n\n function findTarget(location) {\n function jumpToTarget(target) {\n var jumpPosition = getElementPosition(target)\n\n log(\n 'Moving to in page link (#' +\n hash +\n ') at x: ' +\n jumpPosition.x +\n ' y: ' +\n jumpPosition.y\n )\n sendMsg(jumpPosition.y, jumpPosition.x, 'scrollToOffset') // X&Y reversed at sendMsg uses height/width\n }\n\n var hash = location.split('#')[1] || location, // Remove # if present\n hashData = decodeURIComponent(hash),\n target =\n document.getElementById(hashData) ||\n document.getElementsByName(hashData)[0]\n\n if (undefined === target) {\n log(\n 'In page link (#' +\n hash +\n ') not found in iFrame, so sending to parent'\n )\n sendMsg(0, 0, 'inPageLink', '#' + hash)\n } else {\n jumpToTarget(target)\n }\n }\n\n function checkLocationHash() {\n var hash = window.location.hash\n var href = window.location.href\n\n if ('' !== hash && '#' !== hash) {\n findTarget(href)\n }\n }\n\n function bindAnchors() {\n function setupLink(el) {\n function linkClicked(e) {\n e.preventDefault()\n\n /* jshint validthis:true */\n findTarget(this.getAttribute('href'))\n }\n\n if ('#' !== el.getAttribute('href')) {\n addEventListener(el, 'click', linkClicked)\n }\n }\n\n Array.prototype.forEach.call(\n document.querySelectorAll('a[href^=\"#\"]'),\n setupLink\n )\n }\n\n function bindLocationHash() {\n addEventListener(window, 'hashchange', checkLocationHash)\n }\n\n function initCheck() {\n // Check if page loaded with location hash after init resize\n setTimeout(checkLocationHash, eventCancelTimer)\n }\n\n function enableInPageLinks() {\n /* istanbul ignore else */ // Not testable in phantonJS\n if (Array.prototype.forEach && document.querySelectorAll) {\n log('Setting up location.hash handlers')\n bindAnchors()\n bindLocationHash()\n initCheck()\n } else {\n warn(\n 'In page linking not fully supported in this browser! (See README.md for IE8 workaround)'\n )\n }\n }\n\n if (inPageLinks.enable) {\n enableInPageLinks()\n } else {\n log('In page linking not enabled')\n }\n\n return {\n findTarget: findTarget\n }\n }\n\n function setupMouseEvents() {\n if (mouseEvents !== true) return\n\n function sendMouse(e) {\n sendMsg(0, 0, e.type, e.screenY + ':' + e.screenX)\n }\n\n function addMouseListener(evt, name) {\n log('Add event listener: ' + name)\n addEventListener(window.document, evt, sendMouse)\n }\n\n addMouseListener('mouseenter', 'Mouse Enter')\n addMouseListener('mouseleave', 'Mouse Leave')\n }\n\n function setupPublicMethods() {\n log('Enable public methods')\n\n win.parentIFrame = {\n autoResize: function autoResizeF(resize) {\n if (true === resize && false === autoResize) {\n autoResize = true\n startEventListeners()\n } else if (false === resize && true === autoResize) {\n autoResize = false\n stopEventListeners()\n }\n sendMsg(0, 0, 'autoResize', JSON.stringify(autoResize))\n return autoResize\n },\n\n close: function closeF() {\n sendMsg(0, 0, 'close')\n // teardown()\n },\n\n getId: function getIdF() {\n return myID\n },\n\n getPageInfo: function getPageInfoF(callback) {\n if ('function' === typeof callback) {\n onPageInfo = callback\n sendMsg(0, 0, 'pageInfo')\n } else {\n onPageInfo = function () {}\n sendMsg(0, 0, 'pageInfoStop')\n }\n },\n\n moveToAnchor: function moveToAnchorF(hash) {\n inPageLinks.findTarget(hash)\n },\n\n reset: function resetF() {\n resetIFrame('parentIFrame.reset')\n },\n\n scrollTo: function scrollToF(x, y) {\n sendMsg(y, x, 'scrollTo') // X&Y reversed at sendMsg uses height/width\n },\n\n scrollToOffset: function scrollToF(x, y) {\n sendMsg(y, x, 'scrollToOffset') // X&Y reversed at sendMsg uses height/width\n },\n\n sendMessage: function sendMessageF(msg, targetOrigin) {\n sendMsg(0, 0, 'message', JSON.stringify(msg), targetOrigin)\n },\n\n setHeightCalculationMethod: function setHeightCalculationMethodF(\n heightCalculationMethod\n ) {\n heightCalcMode = heightCalculationMethod\n checkHeightMode()\n },\n\n setWidthCalculationMethod: function setWidthCalculationMethodF(\n widthCalculationMethod\n ) {\n widthCalcMode = widthCalculationMethod\n checkWidthMode()\n },\n\n setTargetOrigin: function setTargetOriginF(targetOrigin) {\n log('Set targetOrigin: ' + targetOrigin)\n targetOriginDefault = targetOrigin\n },\n\n size: function sizeF(customHeight, customWidth) {\n var valString =\n '' + (customHeight || '') + (customWidth ? ',' + customWidth : '')\n sendSize(\n 'size',\n 'parentIFrame.size(' + valString + ')',\n customHeight,\n customWidth\n )\n }\n }\n }\n\n function initInterval() {\n if (0 !== interval) {\n log('setInterval: ' + interval + 'ms')\n intervalTimer = setInterval(function () {\n sendSize('interval', 'setInterval: ' + interval)\n }, Math.abs(interval))\n }\n }\n\n // Not testable in PhantomJS\n /* istanbul ignore next */\n function setupBodyMutationObserver() {\n function addImageLoadListners(mutation) {\n function addImageLoadListener(element) {\n if (false === element.complete) {\n log('Attach listeners to ' + element.src)\n element.addEventListener('load', imageLoaded, false)\n element.addEventListener('error', imageError, false)\n elements.push(element)\n }\n }\n\n if (mutation.type === 'attributes' && mutation.attributeName === 'src') {\n addImageLoadListener(mutation.target)\n } else if (mutation.type === 'childList') {\n Array.prototype.forEach.call(\n mutation.target.querySelectorAll('img'),\n addImageLoadListener\n )\n }\n }\n\n function removeFromArray(element) {\n elements.splice(elements.indexOf(element), 1)\n }\n\n function removeImageLoadListener(element) {\n log('Remove listeners from ' + element.src)\n element.removeEventListener('load', imageLoaded, false)\n element.removeEventListener('error', imageError, false)\n removeFromArray(element)\n }\n\n function imageEventTriggered(event, type, typeDesc) {\n removeImageLoadListener(event.target)\n sendSize(type, typeDesc + ': ' + event.target.src)\n }\n\n function imageLoaded(event) {\n imageEventTriggered(event, 'imageLoad', 'Image loaded')\n }\n\n function imageError(event) {\n imageEventTriggered(event, 'imageLoadFailed', 'Image load failed')\n }\n\n function mutationObserved(mutations) {\n sendSize(\n 'mutationObserver',\n 'mutationObserver: ' + mutations[0].target + ' ' + mutations[0].type\n )\n\n // Deal with WebKit / Blink asyncing image loading when tags are injected into the page\n mutations.forEach(addImageLoadListners)\n }\n\n function createMutationObserver() {\n var target = document.querySelector('body'),\n config = {\n attributes: true,\n attributeOldValue: false,\n characterData: true,\n characterDataOldValue: false,\n childList: true,\n subtree: true\n }\n\n observer = new MutationObserver(mutationObserved)\n\n log('Create body MutationObserver')\n observer.observe(target, config)\n\n return observer\n }\n\n var elements = [],\n MutationObserver =\n window.MutationObserver || window.WebKitMutationObserver,\n observer = createMutationObserver()\n\n return {\n disconnect: function () {\n if ('disconnect' in observer) {\n log('Disconnect body MutationObserver')\n observer.disconnect()\n elements.forEach(removeImageLoadListener)\n }\n }\n }\n }\n\n function setupMutationObserver() {\n var forceIntervalTimer = 0 > interval\n\n // Not testable in PhantomJS\n /* istanbul ignore if */ if (\n window.MutationObserver ||\n window.WebKitMutationObserver\n ) {\n if (forceIntervalTimer) {\n initInterval()\n } else {\n bodyObserver = setupBodyMutationObserver()\n }\n } else {\n log('MutationObserver not supported in this browser!')\n initInterval()\n }\n }\n\n // document.documentElement.offsetHeight is not reliable, so\n // we have to jump through hoops to get a better value.\n function getComputedStyle(prop, el) {\n var retVal = 0\n el = el || document.body // Not testable in phantonJS\n\n retVal = document.defaultView.getComputedStyle(el, null)\n retVal = null === retVal ? 0 : retVal[prop]\n\n return parseInt(retVal, base)\n }\n\n function chkEventThottle(timer) {\n if (timer > throttledTimer / 2) {\n throttledTimer = 2 * timer\n log('Event throttle increased to ' + throttledTimer + 'ms')\n }\n }\n\n // Idea from https://github.com/guardian/iframe-messenger\n function getMaxElement(side, elements) {\n var elementsLength = elements.length,\n elVal = 0,\n maxVal = 0,\n Side = capitalizeFirstLetter(side),\n timer = Date.now()\n\n for (var i = 0; i < elementsLength; i++) {\n elVal =\n elements[i].getBoundingClientRect()[side] +\n getComputedStyle('margin' + Side, elements[i])\n if (elVal > maxVal) {\n maxVal = elVal\n }\n }\n\n timer = Date.now() - timer\n\n log('Parsed ' + elementsLength + ' HTML elements')\n log('Element position calculated in ' + timer + 'ms')\n\n chkEventThottle(timer)\n\n return maxVal\n }\n\n function getAllMeasurements(dimensions) {\n return [\n dimensions.bodyOffset(),\n dimensions.bodyScroll(),\n dimensions.documentElementOffset(),\n dimensions.documentElementScroll()\n ]\n }\n\n function getTaggedElements(side, tag) {\n function noTaggedElementsFound() {\n warn('No tagged elements (' + tag + ') found on page')\n return document.querySelectorAll('body *')\n }\n\n var elements = document.querySelectorAll('[' + tag + ']')\n\n if (elements.length === 0) noTaggedElementsFound()\n\n return getMaxElement(side, elements)\n }\n\n function getAllElements() {\n return document.querySelectorAll('body *')\n }\n\n var getHeight = {\n bodyOffset: function getBodyOffsetHeight() {\n return (\n document.body.offsetHeight +\n getComputedStyle('marginTop') +\n getComputedStyle('marginBottom')\n )\n },\n\n offset: function () {\n return getHeight.bodyOffset() // Backwards compatibility\n },\n\n bodyScroll: function getBodyScrollHeight() {\n return document.body.scrollHeight\n },\n\n custom: function getCustomWidth() {\n return customCalcMethods.height()\n },\n\n documentElementOffset: function getDEOffsetHeight() {\n return document.documentElement.offsetHeight\n },\n\n documentElementScroll: function getDEScrollHeight() {\n return document.documentElement.scrollHeight\n },\n\n max: function getMaxHeight() {\n return Math.max.apply(null, getAllMeasurements(getHeight))\n },\n\n min: function getMinHeight() {\n return Math.min.apply(null, getAllMeasurements(getHeight))\n },\n\n grow: function growHeight() {\n return getHeight.max() // Run max without the forced downsizing\n },\n\n lowestElement: function getBestHeight() {\n return Math.max(\n getHeight.bodyOffset() || getHeight.documentElementOffset(),\n getMaxElement('bottom', getAllElements())\n )\n },\n\n taggedElement: function getTaggedElementsHeight() {\n return getTaggedElements('bottom', 'data-iframe-height')\n }\n },\n getWidth = {\n bodyScroll: function getBodyScrollWidth() {\n return document.body.scrollWidth\n },\n\n bodyOffset: function getBodyOffsetWidth() {\n return document.body.offsetWidth\n },\n\n custom: function getCustomWidth() {\n return customCalcMethods.width()\n },\n\n documentElementScroll: function getDEScrollWidth() {\n return document.documentElement.scrollWidth\n },\n\n documentElementOffset: function getDEOffsetWidth() {\n return document.documentElement.offsetWidth\n },\n\n scroll: function getMaxWidth() {\n return Math.max(getWidth.bodyScroll(), getWidth.documentElementScroll())\n },\n\n max: function getMaxWidth() {\n return Math.max.apply(null, getAllMeasurements(getWidth))\n },\n\n min: function getMinWidth() {\n return Math.min.apply(null, getAllMeasurements(getWidth))\n },\n\n rightMostElement: function rightMostElement() {\n return getMaxElement('right', getAllElements())\n },\n\n taggedElement: function getTaggedElementsWidth() {\n return getTaggedElements('right', 'data-iframe-width')\n }\n }\n\n function sizeIFrame(\n triggerEvent,\n triggerEventDesc,\n customHeight,\n customWidth\n ) {\n function resizeIFrame() {\n height = currentHeight\n width = currentWidth\n\n sendMsg(height, width, triggerEvent)\n }\n\n function isSizeChangeDetected() {\n function checkTolarance(a, b) {\n var retVal = Math.abs(a - b) <= tolerance\n return !retVal\n }\n\n currentHeight =\n undefined === customHeight ? getHeight[heightCalcMode]() : customHeight\n currentWidth =\n undefined === customWidth ? getWidth[widthCalcMode]() : customWidth\n\n return (\n checkTolarance(height, currentHeight) ||\n (calculateWidth && checkTolarance(width, currentWidth))\n )\n }\n\n function isForceResizableEvent() {\n return !(triggerEvent in { init: 1, interval: 1, size: 1 })\n }\n\n function isForceResizableCalcMode() {\n return (\n heightCalcMode in resetRequiredMethods ||\n (calculateWidth && widthCalcMode in resetRequiredMethods)\n )\n }\n\n function logIgnored() {\n log('No change in size detected')\n }\n\n function checkDownSizing() {\n if (isForceResizableEvent() && isForceResizableCalcMode()) {\n resetIFrame(triggerEventDesc)\n } else if (!(triggerEvent in { interval: 1 })) {\n logIgnored()\n }\n }\n\n var currentHeight, currentWidth\n\n if (isSizeChangeDetected() || 'init' === triggerEvent) {\n lockTrigger()\n resizeIFrame()\n } else {\n checkDownSizing()\n }\n }\n\n var sizeIFrameThrottled = throttle(sizeIFrame)\n\n function sendSize(triggerEvent, triggerEventDesc, customHeight, customWidth) {\n function recordTrigger() {\n if (!(triggerEvent in { reset: 1, resetPage: 1, init: 1 })) {\n log('Trigger event: ' + triggerEventDesc)\n }\n }\n\n function isDoubleFiredEvent() {\n return triggerLocked && triggerEvent in doubleEventList\n }\n\n if (isDoubleFiredEvent()) {\n log('Trigger event cancelled: ' + triggerEvent)\n } else {\n recordTrigger()\n if (triggerEvent === 'init') {\n sizeIFrame(triggerEvent, triggerEventDesc, customHeight, customWidth)\n } else {\n sizeIFrameThrottled(\n triggerEvent,\n triggerEventDesc,\n customHeight,\n customWidth\n )\n }\n }\n }\n\n function lockTrigger() {\n if (!triggerLocked) {\n triggerLocked = true\n log('Trigger event lock on')\n }\n clearTimeout(triggerLockedTimer)\n triggerLockedTimer = setTimeout(function () {\n triggerLocked = false\n log('Trigger event lock off')\n log('--')\n }, eventCancelTimer)\n }\n\n function triggerReset(triggerEvent) {\n height = getHeight[heightCalcMode]()\n width = getWidth[widthCalcMode]()\n\n sendMsg(height, width, triggerEvent)\n }\n\n function resetIFrame(triggerEventDesc) {\n var hcm = heightCalcMode\n heightCalcMode = heightCalcModeDefault\n\n log('Reset trigger event: ' + triggerEventDesc)\n lockTrigger()\n triggerReset('reset')\n\n heightCalcMode = hcm\n }\n\n function sendMsg(height, width, triggerEvent, msg, targetOrigin) {\n function setTargetOrigin() {\n if (undefined === targetOrigin) {\n targetOrigin = targetOriginDefault\n } else {\n log('Message targetOrigin: ' + targetOrigin)\n }\n }\n\n function sendToParent() {\n var size = height + ':' + width,\n message =\n myID +\n ':' +\n size +\n ':' +\n triggerEvent +\n (undefined === msg ? '' : ':' + msg)\n\n log('Sending message to host page (' + message + ')')\n target.postMessage(msgID + message, targetOrigin)\n }\n\n if (true === sendPermit) {\n setTargetOrigin()\n sendToParent()\n }\n }\n\n function receiver(event) {\n var processRequestFromParent = {\n init: function initFromParent() {\n initMsg = event.data\n target = event.source\n\n init()\n firstRun = false\n setTimeout(function () {\n initLock = false\n }, eventCancelTimer)\n },\n\n reset: function resetFromParent() {\n if (initLock) {\n log('Page reset ignored by init')\n } else {\n log('Page size reset by host page')\n triggerReset('resetPage')\n }\n },\n\n resize: function resizeFromParent() {\n sendSize('resizeParent', 'Parent window requested size check')\n },\n\n moveToAnchor: function moveToAnchorF() {\n inPageLinks.findTarget(getData())\n },\n inPageLink: function inPageLinkF() {\n this.moveToAnchor()\n }, // Backward compatibility\n\n pageInfo: function pageInfoFromParent() {\n var msgBody = getData()\n log('PageInfoFromParent called from parent: ' + msgBody)\n onPageInfo(JSON.parse(msgBody))\n log(' --')\n },\n\n message: function messageFromParent() {\n var msgBody = getData()\n\n log('onMessage called from parent: ' + msgBody)\n // eslint-disable-next-line sonarjs/no-extra-arguments\n onMessage(JSON.parse(msgBody))\n log(' --')\n }\n }\n\n function isMessageForUs() {\n return msgID === ('' + event.data).slice(0, msgIdLen) // ''+ Protects against non-string messages\n }\n\n function getMessageType() {\n return event.data.split(']')[1].split(':')[0]\n }\n\n function getData() {\n return event.data.slice(event.data.indexOf(':') + 1)\n }\n\n function isMiddleTier() {\n return (\n (!(typeof module !== 'undefined' && module.exports) &&\n 'iFrameResize' in window) ||\n (window.jQuery !== undefined &&\n 'iFrameResize' in window.jQuery.prototype)\n )\n }\n\n function isInitMsg() {\n // Test if this message is from a child below us. This is an ugly test, however, updating\n // the message format would break backwards compatibility.\n return event.data.split(':')[2] in { true: 1, false: 1 }\n }\n\n function callFromParent() {\n var messageType = getMessageType()\n\n if (messageType in processRequestFromParent) {\n processRequestFromParent[messageType]()\n } else if (!isMiddleTier() && !isInitMsg()) {\n warn('Unexpected message (' + event.data + ')')\n }\n }\n\n function processMessage() {\n if (false === firstRun) {\n callFromParent()\n } else if (isInitMsg()) {\n processRequestFromParent.init()\n } else {\n log(\n 'Ignored message of type \"' +\n getMessageType() +\n '\". Received before initialization.'\n )\n }\n }\n\n if (isMessageForUs()) {\n processMessage()\n }\n }\n\n // Normally the parent kicks things off when it detects the iFrame has loaded.\n // If this script is async-loaded, then tell parent page to retry init.\n function chkLateLoaded() {\n if ('loading' !== document.readyState) {\n window.parent.postMessage('[iFrameResizerChild]Ready', '*')\n }\n }\n\n // Setup if not already running\n if (!('iframeResizer' in window)) {\n window.iframeChildListener = function (data) {\n receiver({ data, sameDomian: true })\n }\n addEventListener(window, 'message', receiver)\n addEventListener(window, 'readystatechange', chkLateLoaded)\n chkLateLoaded()\n }\n\n \n})()\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\tflarum.reg._webpack_runtimes[\"flarum-embed\"] ||= __webpack_require__;// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.reg.get('core', 'common/extend');","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.reg.get('core', 'forum/app');","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.reg.get('core', 'common/utils/Stream');","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.reg.get('core', 'forum/ForumApplication');","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.reg.get('core', 'common/components/ModalManager');","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.reg.get('core', 'forum/components/PostMeta');","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.reg.get('core', 'forum/components/DiscussionPage');","import 'iframe-resizer/js/iframeResizer.contentWindow.js';\nimport { override, extend } from 'flarum/common/extend';\nimport app from 'flarum/forum/app';\nimport Stream from 'flarum/common/utils/Stream';\nimport ForumApplication from 'flarum/forum/ForumApplication';\nimport ModalManager from 'flarum/common/components/ModalManager';\nimport PostMeta from 'flarum/forum/components/PostMeta';\nimport DiscussionPage from 'flarum/forum/components/DiscussionPage';\nextend(ForumApplication.prototype, 'mount', function () {\n if (m.route.param('hideFirstPost')) {\n extend('flarum/forum/components/PostStream', 'view', vdom => {\n if (vdom.children[0].attrs['data-number'] === 1) {\n vdom.children.splice(0, 1);\n }\n });\n }\n});\noverride(m.route.Link, 'view', function (original, vnode) {\n vnode.attrs.href = vnode.attrs.href.replace('/embed', '/d');\n vnode.attrs.target = '_blank';\n // TODO: If href leads to a post within this discussion that we have\n // already loaded, then scroll to it?\n return original(vnode);\n});\n\n// Trim the /embed prefix off of post permalinks\noverride(PostMeta.prototype, 'getPermalink', (original, post) => {\n return original(post).replace('/embed', '/d');\n});\napp.pageInfo = Stream({});\nconst reposition = function () {\n const info = app.pageInfo();\n this.$().css('top', Math.max(0, info.scrollTop - info.offsetTop));\n};\nextend(ModalManager.prototype, 'show', reposition);\nextend('flarum/forum/components/Composer', 'show', reposition);\nwindow.iFrameResizer = {\n readyCallback: function () {\n window.parentIFrame.getPageInfo(app.pageInfo);\n }\n};\nextend('flarum/forum/components/PostStream', 'goToNumber', function (promise, number) {\n if (number === 'reply' && 'parentIFrame' in window && app.composer.isFullScreen()) {\n const itemTop = this.$('.PostStream-item:last').offset().top;\n window.parentIFrame.scrollToOffset(0, itemTop);\n }\n});\nextend(DiscussionPage.prototype, 'sidebarItems', function (items) {\n items.remove('scrubber');\n const count = this.discussion.replyCount();\n items.add('replies', m(\"h3\", null, m(\"a\", {\n route: app.route.discussion(this.discussion).replace('/embed', '/d')\n }, count, \" comment\", count == 1 ? '' : 's')), 100);\n const attrs = items.get('controls').attrs;\n attrs.className = attrs.className.replace('App-primaryControl', '');\n});\napp.routes['discussion'] = {\n path: '/embed/:id',\n component: DiscussionPage\n};\napp.routes['discussion.near'] = {\n path: '/embed/:id/:near',\n component: DiscussionPage\n};"],"names":["undefined","window","autoResize","bodyBackground","bodyMargin","bodyMarginStr","bodyObserver","bodyPadding","calculateWidth","doubleEventList","resize","click","eventCancelTimer","firstRun","height","heightCalcModeDefault","heightCalcMode","initLock","initMsg","inPageLinks","interval","intervalTimer","logging","mouseEvents","msgID","myID","resetRequiredMethods","max","min","bodyScroll","documentElementScroll","resizeFrom","target","parent","targetOriginDefault","tolerance","triggerLocked","triggerLockedTimer","throttledTimer","width","widthCalcModeDefault","widthCalcMode","win","onMessage","warn","onReady","onPageInfo","customCalcMethods","document","documentElement","offsetHeight","body","scrollWidth","eventHandlersByName","passiveSupported","options","Object","create","passive","get","addEventListener","noop","removeEventListener","error","func","context","args","result","timeout","previous","later","getHeight","bodyOffset","getComputedStyle","offset","scrollHeight","custom","documentElementOffset","Math","apply","getAllMeasurements","grow","lowestElement","getMaxElement","getAllElements","taggedElement","getTaggedElements","getWidth","offsetWidth","scroll","rightMostElement","sizeIFrameThrottled","sizeIFrame","Date","now","remaining","this","arguments","clearTimeout","setTimeout","iframeChildListener","data","receiver","sameDomian","chkLateLoaded","el","evt","capitalizeFirstLetter","string","charAt","toUpperCase","slice","formatLogMsg","msg","log","console","init","clearFix","value","strBool","str","split","Number","enable","readDataFromParent","location","href","setupCustomCalcMethods","calcMode","calcFunc","iFrameResizer","constructor","JSON","stringify","keys","forEach","depricate","targetOrigin","heightCalculationMethod","widthCalculationMethod","readDataFromPage","setBodyStyle","indexOf","createElement","style","clear","display","appendChild","checkHeightMode","checkWidthMode","parentIFrame","startEventListeners","manageEventListeners","disconnect","clearInterval","sendMsg","close","getId","getPageInfo","callback","moveToAnchor","hash","findTarget","reset","resetIFrame","scrollTo","x","y","scrollToOffset","sendMessage","setHeightCalculationMethod","setWidthCalculationMethod","setTargetOrigin","size","customHeight","customWidth","sendSize","sendMouse","e","type","screenY","screenX","addMouseListener","name","setupMouseEvents","getElementPosition","elPosition","getBoundingClientRect","pagePosition","pageXOffset","scrollLeft","pageYOffset","scrollTop","parseInt","left","top","hashData","decodeURIComponent","getElementById","getElementsByName","jumpPosition","jumpToTarget","checkLocationHash","Array","prototype","querySelectorAll","call","getAttribute","preventDefault","setupInPageLinks","key","splitName","length","attr","manageTriggerEvent","listener","add","eventName","handleEvent","eventType","remove","eventNames","map","method","checkCalcMode","calcModeDefault","modes","forceIntervalTimer","MutationObserver","WebKitMutationObserver","initInterval","addImageLoadListners","mutation","addImageLoadListener","element","complete","src","imageLoaded","imageError","elements","push","attributeName","removeImageLoadListener","splice","removeFromArray","imageEventTriggered","event","typeDesc","mutationObserved","mutations","observer","querySelector","observe","attributes","attributeOldValue","characterData","characterDataOldValue","childList","subtree","createMutationObserver","setupBodyMutationObserver","setInterval","abs","prop","retVal","defaultView","side","elementsLength","elVal","maxVal","Side","timer","i","chkEventThottle","dimensions","tag","triggerEvent","triggerEventDesc","currentHeight","currentWidth","checkTolarance","a","b","isSizeChangeDetected","lockTrigger","resetPage","triggerReset","hcm","message","postMessage","messageType","processRequestFromParent","source","getData","inPageLink","pageInfo","msgBody","parse","getMessageType","isInitMsg","true","false","module","exports","jQuery","readyState","__webpack_module_cache__","__webpack_require__","moduleId","flarum","reg","_webpack_runtimes","cachedModule","__webpack_modules__","n","getter","__esModule","d","definition","o","defineProperty","enumerable","obj","hasOwnProperty","extend","m","route","param","vdom","children","attrs","override","Link","original","vnode","replace","post","reposition","info","$","css","offsetTop","readyCallback","promise","number","isFullScreen","itemTop","items","count","discussion","replyCount","className","path","component"],"sourceRoot":""} -------------------------------------------------------------------------------- /js/forum.js: -------------------------------------------------------------------------------- 1 | export * from './src/forum'; 2 | -------------------------------------------------------------------------------- /js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "name": "@flarum/embed", 4 | "version": "0.0.0", 5 | "prettier": "@flarum/prettier-config", 6 | "dependencies": { 7 | "iframe-resizer": "^4.3.2" 8 | }, 9 | "devDependencies": { 10 | "prettier": "^2.5.1", 11 | "flarum-webpack-config": "^3.0.0", 12 | "webpack": "^5.76.0", 13 | "webpack-cli": "^4.9.1", 14 | "@flarum/prettier-config": "^1.0.0" 15 | }, 16 | "scripts": { 17 | "dev": "webpack --mode development --watch", 18 | "build": "webpack --mode production", 19 | "format": "prettier --write src", 20 | "format-check": "prettier --check src", 21 | "analyze": "cross-env ANALYZER=true yarn run build" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /js/src/forum/index.js: -------------------------------------------------------------------------------- 1 | import 'iframe-resizer/js/iframeResizer.contentWindow.js'; 2 | 3 | import { override, extend } from 'flarum/common/extend'; 4 | import app from 'flarum/forum/app'; 5 | import Stream from 'flarum/common/utils/Stream'; 6 | import ForumApplication from 'flarum/forum/ForumApplication'; 7 | import ModalManager from 'flarum/common/components/ModalManager'; 8 | import PostMeta from 'flarum/forum/components/PostMeta'; 9 | 10 | import DiscussionPage from 'flarum/forum/components/DiscussionPage'; 11 | 12 | extend(ForumApplication.prototype, 'mount', function () { 13 | if (m.route.param('hideFirstPost')) { 14 | extend('flarum/forum/components/PostStream', 'view', (vdom) => { 15 | if (vdom.children[0].attrs['data-number'] === 1) { 16 | vdom.children.splice(0, 1); 17 | } 18 | }); 19 | } 20 | }); 21 | 22 | override(m.route.Link, 'view', function (original, vnode) { 23 | vnode.attrs.href = vnode.attrs.href.replace('/embed', '/d'); 24 | vnode.attrs.target = '_blank'; 25 | // TODO: If href leads to a post within this discussion that we have 26 | // already loaded, then scroll to it? 27 | return original(vnode); 28 | }); 29 | 30 | // Trim the /embed prefix off of post permalinks 31 | override(PostMeta.prototype, 'getPermalink', (original, post) => { 32 | return original(post).replace('/embed', '/d'); 33 | }); 34 | 35 | app.pageInfo = Stream({}); 36 | 37 | const reposition = function () { 38 | const info = app.pageInfo(); 39 | this.$().css('top', Math.max(0, info.scrollTop - info.offsetTop)); 40 | }; 41 | 42 | extend(ModalManager.prototype, 'show', reposition); 43 | extend('flarum/forum/components/Composer', 'show', reposition); 44 | 45 | window.iFrameResizer = { 46 | readyCallback: function () { 47 | window.parentIFrame.getPageInfo(app.pageInfo); 48 | }, 49 | }; 50 | 51 | extend('flarum/forum/components/PostStream', 'goToNumber', function (promise, number) { 52 | if (number === 'reply' && 'parentIFrame' in window && app.composer.isFullScreen()) { 53 | const itemTop = this.$('.PostStream-item:last').offset().top; 54 | window.parentIFrame.scrollToOffset(0, itemTop); 55 | } 56 | }); 57 | 58 | extend(DiscussionPage.prototype, 'sidebarItems', function (items) { 59 | items.remove('scrubber'); 60 | 61 | const count = this.discussion.replyCount(); 62 | 63 | items.add( 64 | 'replies', 65 |

66 | 67 | {count} comment{count == 1 ? '' : 's'} 68 | 69 |

, 70 | 100 71 | ); 72 | 73 | const attrs = items.get('controls').attrs; 74 | attrs.className = attrs.className.replace('App-primaryControl', ''); 75 | }); 76 | 77 | app.routes['discussion'] = { path: '/embed/:id', component: DiscussionPage }; 78 | app.routes['discussion.near'] = { path: '/embed/:id/:near', component: DiscussionPage }; 79 | -------------------------------------------------------------------------------- /js/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = require('flarum-webpack-config')(); 2 | -------------------------------------------------------------------------------- /less/forum.less: -------------------------------------------------------------------------------- 1 | .container { 2 | width: auto; 3 | padding: 0 20px; 4 | 5 | @media @phone { 6 | padding: 0; 7 | } 8 | } 9 | .App { 10 | padding-top: 0; 11 | min-height: 0; 12 | overflow: hidden; 13 | 14 | &:before { 15 | display: none; 16 | } 17 | } 18 | .App-content { 19 | border-top: 0; 20 | min-height: 0; 21 | } 22 | .Composer { 23 | margin-left: 0 !important; 24 | margin-right: 0 !important; 25 | } 26 | .DiscussionHero { 27 | display: none; 28 | } 29 | .DiscussionPage-nav { 30 | width: auto; 31 | float: none; 32 | 33 | @media @tablet-up { 34 | height: 70px; 35 | } 36 | 37 | > ul { 38 | .header-background(); 39 | border-bottom: 0; 40 | height: auto !important; 41 | list-style: none; 42 | padding: 15px 0; 43 | margin: 0; 44 | width: auto; 45 | 46 | @media @phone { 47 | position: static; 48 | } 49 | @media @tablet-up { 50 | padding: 15px 15px; 51 | 52 | .scrolled & { 53 | box-shadow: 0 2px 6px var(--shadow-color); 54 | } 55 | } 56 | 57 | > li { 58 | margin: 0 15px 0 0; 59 | display: inline-block; 60 | } 61 | .item-replies { 62 | @media @phone { 63 | display: block; 64 | margin-bottom: 10px; 65 | } 66 | 67 | h3 { 68 | font-weight: normal; 69 | margin: 0; 70 | 71 | &, a { 72 | color: var(--muted-color); 73 | } 74 | } 75 | } 76 | } 77 | .ButtonGroup { 78 | &, .Button { 79 | width: auto !important; 80 | } 81 | .Dropdown-toggle { 82 | width: 36px !important; 83 | } 84 | } 85 | } 86 | .DiscussionPage-stream { 87 | margin-right: 0; 88 | } 89 | .Post-stream { 90 | margin-top: 0; 91 | } 92 | 93 | @media @phone { 94 | .Dropdown .Dropdown-menu { 95 | position: absolute; 96 | bottom: auto; 97 | top: auto; 98 | right: auto !important; 99 | padding-bottom: 0 !important; 100 | .transition(none); 101 | 102 | &.Dropdown-menu--right { 103 | left: auto !important; 104 | right: 0 !important; 105 | } 106 | } 107 | .Composer:not(.minimized) { 108 | height: 400px !important; 109 | } 110 | } 111 | --------------------------------------------------------------------------------