QR-Plugins.EmbedMedia

plugins for Kaskus-QR embed media, eg SoundCloud, Vimeo

  1. // ==UserScript==
  2. // @name QR-Plugins.EmbedMedia
  3. // @namespace http://userscripts.org/scripts/show/180813
  4. // @include *.kaskus.co.id/thread/*
  5. // @include *.kaskus.co.id/lastpost/*
  6. // @include *.kaskus.co.id/post/*
  7. // @include *.kaskus.co.id/group/discussion/*
  8. // @include *.kaskus.co.id/show_post/*
  9. // @version 0.1
  10. // @dtversion 1310280001
  11. // @timestamp 1382899161074
  12. // @qrversion 4.0.9+
  13. // @description plugins for Kaskus-QR embed media, eg SoundCloud, Vimeo
  14. // @author tuxie.forte;
  15. // @license (CC) by-nc-sa 3.0
  16. //
  17. // -!--latestupdate
  18. //
  19. // v0.1 - 2013-10-27
  20. // init
  21. //
  22. // -/!latestupdate---
  23. // ==/UserScript==
  24. //
  25.  
  26. (function(){
  27. // Initialize Global Variables
  28. var gvar=function() {};
  29.  
  30. /*
  31. window.alert(new Date().getTime());
  32. */
  33. //========-=-=-=-=--=========
  34. gvar.__DEBUG__ = false; // development
  35. //========-=-=-=-=--=========
  36.  
  37.  
  38. // this is where we re-initialize before we trigger start_Main()
  39. // any huge global var or loading any saved value may start in here too
  40. function init_start(){
  41.  
  42. gvar.B = rSRC.getSetOf('button');
  43. gvar.tID = "reply-messsage";
  44.  
  45. start_Main();
  46. }
  47. // =====
  48. // START
  49. function start_Main(){
  50. var el, Attr, par = gID(gvar.qr_identity);
  51.  
  52. if( par ){
  53. Attr = {'src':gvar.B.soundcloud_ico, style:'vertical-align:bottom;', alt:'[soundcloud]', title:'Embedding Soundcloud'};
  54. el = createEl('img',Attr);
  55. _o('click', el, function(e){return handleClick(e)} );
  56.  
  57. Dom.add(el, par);
  58.  
  59.  
  60. Attr = {'src':gvar.B.vimeo_png, style:'vertical-align:bottom;', alt:'[vimeo]', title:'Embedding Vimeo'};
  61. el = createEl('img',Attr);
  62. _o('click', el, function(e){return handleClick(e)} );
  63.  
  64. Dom.add(el, par);
  65. }
  66. }
  67.  
  68. var endFocus = function(){ _TEXT.focus(); return};
  69.  
  70. function handleClick(e){
  71. var vBText = _TEXT.init();
  72. if(!vBText) return;
  73.  
  74. var el = e.target || e;
  75. var mode = String(el.getAttribute('alt')).replace(/[\[\]]+/gi, '');
  76. var text = fn = null;
  77.  
  78. switch(mode){
  79. case "soundcloud":
  80. text = prompt('Please enter Soundcloud Widget Code or Track ID or API_URL containing track ID.\neg.https:/'+'/api.soundcloud.com/tracks/#######', '');
  81. text && (fn = soundcloud);
  82. break;
  83. case "vimeo":
  84. text = prompt('Please enter Vimeo URL Link, \nhttps:/'+'/vimeo.com/#######', '');
  85. text && (fn = vimeo);
  86. break;
  87. }
  88.  
  89.  
  90. if(text==null) return endFocus();
  91.  
  92. var innertext = null;
  93. if("undefined" != typeof fn)
  94. innertext = fn(trimStr(text));
  95.  
  96. if( !innertext ){
  97. return endFocus();
  98. }else{
  99. var tagname = mode.toUpperCase();
  100. var prehead = [('['+tagname+']').length, 0];
  101. prehead[1] = (prehead[0]+innertext.length);
  102. _TEXT.setValue( '['+tagname+']'+innertext+'[/'+tagname+']', prehead );
  103. }
  104. _TEXT.pracheck();
  105. }
  106.  
  107.  
  108. /*=========
  109. # embedmedia functionality
  110. # =========
  111. */
  112.  
  113. // soundcloud
  114. // The end-objective return the id of the tracks
  115. // sample-input eg.:
  116. // https://api.soundcloud.com/tracks/30511512
  117. // <iframe width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/30511512"></iframe>
  118. // [soundcloud url="https://api.soundcloud.com/tracks/30511512" width="100%" height="166" iframe="true" /]
  119. function soundcloud(text){
  120. var text_parser = function(text_){
  121. var ret_ = '';
  122. if( /^[\d\w]+$/.test(text_) ){
  123. ret_ = text_;
  124. }else{
  125. var cucok = /\bsoundcloud\.com\/tracks\/(\d+)/i.exec(text_);
  126. if( cucok )
  127. ret_ = cucok[1];
  128. else
  129. ret_ = null;
  130. }
  131. return ret_;
  132. };
  133. return text_parser(text);
  134. }
  135.  
  136. // vimeo
  137. // sample-input:
  138. // http://vimeo.com/54736141
  139. //
  140. function vimeo(text){
  141. var text_parser = function(text_){
  142. var ret_ = '';
  143. if( /^[\d\w]+$/.test(text_) ){
  144. ret_ = text_;
  145. }else{
  146. var cucok = /\bvimeo\.com\/(\d+)/i.exec(text_);
  147. if( cucok )
  148. ret_ = cucok[1];
  149. else
  150. ret_ = null;
  151. }
  152. return ret_;
  153. };
  154. return text_parser(text);
  155. }
  156.  
  157.  
  158.  
  159. // -
  160. // -
  161. // -
  162. // -
  163. //=========
  164. // code below should adapting current QR Engine for this plugins works
  165. // leave code below as wot it is, as long you know what todo
  166. //========= Common Functions && Global Var Init ====
  167. // static routine
  168. function isDefined(x) { return !(x == null && x !== null); }
  169. function isUndefined(x) { return x == null && x !== null; }
  170. function isString(x) { return (typeof(x)!='object' && typeof(x)!='function'); }
  171. function trimStr(x) { return x.replace(/^\s+|\s+$/g,""); };
  172.  
  173. function _o(m,e,f){Dom.Ev(e,m,function(e){typeof(f)=='function'?f(e):void(0)});}
  174. function gID(x) { return document.getElementById(x) }
  175.  
  176. function addClass(cName, Obj){
  177. if(cName=="") return;
  178. var neocls = (Obj.className ? Obj.className : '');
  179. if(neocls.indexOf(cName)!=-1) return;
  180. neocls+=(neocls!=''?' ':'')+cName;
  181. Obj.setAttribute('class', neocls);
  182. }
  183. function removeClass(cName, Obj){
  184. if(cName=="") return;
  185. var neocls = (Obj.className ? Obj.className : '');
  186. neocls = trimStr ( neocls.replace(cName,"") ); // replace and trim
  187. Obj.setAttribute('class', neocls);
  188. }
  189. function SimulateMouse(elem,event,preventDef) {
  190. if(typeof(elem)!='object') return;
  191. var evObj = document.createEvent('MouseEvents');
  192. preventDef=(isDefined(preventDef) && preventDef ? true : false);
  193. evObj.initEvent(event, preventDef, true);
  194. try{elem.dispatchEvent(evObj);}
  195. catch(e){}
  196. }
  197. function createEl(type, attrArray, html){
  198. var node = document.createElement(type);
  199. for (var attr in attrArray)
  200. if (attrArray.hasOwnProperty(attr))
  201. node.setAttribute(attr, attrArray[attr]);
  202. if(html) node.innerHTML = html;
  203. return node;
  204. }
  205.  
  206. // Get Elements
  207. var $D=function (q, root, single) {
  208. if (root && typeof root == 'string') {
  209. root = $D(root, null, true);
  210. if (!root) { return null; }
  211. }
  212. if( !q ) return false;
  213. if ( typeof q == 'object') return q;
  214. root = root || document;
  215. if (q[0]=='/' || (q[0]=='.' && q[1]=='/')) {
  216. if (single) { return document.evaluate(q, root, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; }
  217. return document.evaluate(q, root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  218. }
  219. else if (q[0]=='.') { return root.getElementsByClassName(q.substr(1)); }
  220. else { return root.getElementById( (q[0]=='#' ? q.substr(1):q.substr(0)) ); }
  221. return root.getElementsByTagName(q);
  222. };
  223. // utk add - remove element
  224. var Dom = {
  225. g: function(el) {
  226. if(!el) return false;
  227. return ( isString(el) ? document.getElementById(el) : el );
  228. },
  229. add: function(el, dest) {
  230. var el = this.g(el);
  231. var dest = this.g(dest);
  232. if(el && dest) dest.appendChild(el);
  233. },
  234. remove: function(el) {
  235. var el = this.g(el);
  236. if(el && el.parentNode)
  237. el.parentNode.removeChild(el);
  238. },
  239. Ev: function() {
  240. if (window.addEventListener) {
  241. return function(el, type, fn, ph) {
  242. if(typeof(el)=='object')
  243. this.g(el).addEventListener(type, function(e){fn(e);}, (isUndefined(ph) ? false : ph));
  244. };
  245. }else if (window.attachEvent) {
  246. return function(el, type, fn) {
  247. var f = function() { fn.call(this.g(el), window.event); };
  248. this.g(el).attachEvent('on' + type, f);
  249. };
  250. }
  251. }()
  252. };
  253.  
  254. var _TEXT = {
  255. e : null, eNat : null,
  256. content : "",
  257. cursorPos : [],
  258. last_scrollTop: 0,
  259. init: function() {
  260. this.eNat = gID(gvar.tID);
  261. this.content = this.eNat.value;
  262. this.cursorPos = _TEXT.rearmPos(); // [start, end]
  263. this.last_scrollTop = gID(gvar.tID).scrollTop; // last scrolltop pos
  264. return this;
  265. },
  266. rearmPos: function(){ return [this.getCaretPos(), gID(gvar.tID).selectionEnd]; },
  267. subStr: function(start, end){ return this.content.substring(start, end);},
  268. set: function(value){
  269. gID(gvar.tID).value = this.content = value;
  270. _TEXT.setRows_Elastic();
  271. _TEXT.init();
  272.  
  273. },
  274. wrapValue : function(tag, title){
  275. var st2, start=this.cursorPos[0], end=this.cursorPos[1],bufValue;
  276. tag = tag.toUpperCase();
  277. bufValue = this.subStr(0, start) +
  278. '['+tag+(title?'='+title:'')+']' +
  279. (start==end ? '' : this.subStr(start, end)) +
  280. '[/'+tag+']' + this.subStr(end, this.content.length);
  281. this.set(bufValue);
  282. st2 = (start + ('['+tag+(title?'='+title:'')+']').length);
  283. this.setCaretPos( st2, st2 + this.subStr(start, end).length );
  284. if(this.overflow!='hidden') gID(gvar.tID).scrollTop = (this.last_scrollTop+1);
  285. return bufValue;
  286. },
  287. add: function(text){ // used on fetch post only
  288. var newline = '\n\n';
  289. if( gID(gvar.tID).value != "" )
  290. this.content+= newline;
  291. gID(gvar.tID).value = ( this.content + text );
  292. setTimeout(function(){
  293. _TEXT.lastfocus();
  294. }, 200);
  295. },
  296. // ptpos stand to puretext position [start, end]
  297. setValue : function(text, ptpos){
  298. var start=this.cursorPos[0], end=this.cursorPos[1];
  299. if(isUndefined(ptpos)) ptpos=[text.length,text.length];
  300. if(start!=end) {
  301. this.replaceSelected(text,ptpos);
  302. return;
  303. }
  304. var bufValue = this.subStr(0, start) + text + this.subStr(start, this.content.length);
  305. this.set(bufValue);
  306. // fix chrome weird
  307. this.setCaretPos( (start + ptpos[0]), (start+ptpos[1]) );
  308. if(_TEXT.overflow!='hidden') gID(gvar.tID).scrollTop = (this.last_scrollTop+1);
  309. return bufValue;
  310. },
  311. replaceSelected : function(text, ptpos){
  312. var start=this.cursorPos[0], end=this.cursorPos[1];
  313. if(start==end) return;
  314. var bufValue = this.subStr(0, start) + text + this.subStr(end, this.content.length);
  315. this.set(bufValue);
  316. this.setCaretPos( (start + ptpos[0]), (start+ptpos[1]) );
  317. if( _TEXT.overflow!='hidden') gID(gvar.tID).scrollTop = (this.last_scrollTop+1);
  318. },
  319. pracheck: function(foc){
  320. if( isUndefined(foc) )
  321. foc = true;
  322. //_TEXT.setElastic(gvar.maxH_editor);
  323. if( gID(gvar.tID).value !="" )
  324. gID('clear_text').style.setProperty('display', 'block');
  325. else
  326. gID('clear_text').style.setProperty('display', 'none');
  327. if(foc) setTimeout(function(){
  328. _TEXT.focus();
  329. }, 200);
  330. },
  331. focus: function(){
  332. gID(gvar.tID).focus()
  333. },
  334. lastfocus: function (){
  335. var eText, nl, pos, txt = String(gID(gvar.tID).value); // use the actual content
  336. pos = txt.length;
  337. nl = txt.split('\n');
  338. nl = nl.length;
  339. pos+= (nl * 2);
  340. eText = gID(gvar.tID);
  341. if( eText.setSelectionRange ) {
  342. _TEXT.focus();
  343. eText.setSelectionRange(pos,pos);
  344. }
  345. setTimeout(function(){ _TEXT.focus() } , 310);
  346. },
  347. getSelectedText : function() {
  348. return (this.cursorPos[0]==this.cursorPos[1]? '': this.subStr(this.cursorPos[0], this.cursorPos[1]) );
  349. },
  350. getCaretPos : function() {
  351. var CaretPos = 0;
  352. //Mozilla/Firefox/Netscape 7+ support
  353. if(gID(gvar.tID))
  354. if (gID(gvar.tID).selectionStart || gID(gvar.tID).selectionStart == '0')
  355. CaretPos = gID(gvar.tID).selectionStart;
  356. return CaretPos;
  357. },
  358. setCaretPos : function (pos,end){
  359. if(isUndefined(end)) end = pos;
  360. if(gID(gvar.tID).setSelectionRange) { // Firefox, Opera and Safari
  361. this.focus();
  362. gID(gvar.tID).setSelectionRange(pos,end);
  363. }
  364. },
  365. setElastic: function(max,winrez){
  366. var a, tid=gvar.tID;
  367. function setCols_Elastic(max){
  368. var a=gID(tid); a.setAttribute("cols", Math.floor(a.clientWidth/7));
  369. var w = Math.floor(a.clientWidth/7);
  370. _TEXT.setRows_Elastic(max)
  371. }
  372. a= gID(tid) || gID(gvar.tID);
  373. _TEXT.oflow='hidden';
  374. a.setAttribute('style','visibility:hidden; overflow:'+_TEXT.oflow+';letter-spacing:0;line-height:14pt;'+(max?'max-height:'+(max-130)+'pt;':''));
  375. if( !winrez ) gID(gvar.tID).keyup(function(){ setCols_Elastic(max) });
  376. setCols_Elastic(max);
  377. },
  378. setRows_Elastic: function(max){
  379. var a = gID(gvar.tID), c=a.cols, b=a.value.toString(), h;
  380. b=b.replace(/(?:\r\n|\r|\n)/g,"\n");
  381. for(var d=2,e=0,f=0;f<b.length;f++){
  382. var g=b.charAt(f);e++;if(g=="\n"||e==c){d++;e=0}
  383. }
  384. h=(d*14); a.setAttribute("rows",d); a.style.height=h+"pt";
  385. _TEXT.oflow = (max && (d*14>(max-130)) ? 'auto':'hidden');
  386. a.style.setProperty('overflow', _TEXT.oflow, 'important');
  387. gID(gvar.tID).style.setProperty('visibility', 'visible');
  388. }
  389. };
  390.  
  391. // ----my ge-debug--------
  392. function show_alert(msg, force) {
  393. if(arguments.callee.counter) { arguments.callee.counter++; } else { arguments.callee.counter=1; }
  394. GM_log('('+arguments.callee.counter+') '+msg);
  395. if(force==0) { return; }
  396. }
  397. function clog(msg) {
  398. if(!gvar.__DEBUG__) return;
  399. show_alert(msg);
  400. }
  401.  
  402.  
  403.  
  404. // main resource
  405. var rSRC = {
  406. getSetOf: function(type){
  407. if(isUndefined(type)) return false;
  408. switch(type){
  409. case "button":
  410. return {
  411. soundcloud_ico : ""
  412. +"data:image/vnd.microsoft.icon;base64,AAABAAEAEBAAAAEAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8DSf8EPP4EPP4EPP4EPP4EPP4EPP4EPP4EPP4EPP4EPP4EPP4EPP4DSf4AZv8AZv4HQf4HQP0HQP0HQPwHQPwHQPwHQPwHQPsHQPsHQPsHQPwHQPwHQP0HQf4AZv4AZv4KR/0KR/wKR/sKR/oKR/oKRvkKRvkKRvgKRvgKRvgKRvgKRvkKR/sKR/wAZf0AZf0OTvwOTfoZVflKefkiW/dUgfgkXfY7bvY9b/U9b/U9cPY2afcOTfgOTvsAZfwAZf0SVfuYtfyduPzH1/2duPrH1vydt/nx9f7///////////////+rwvwSVPkAZfwAZfwWXfu6z/2fu/vI2Pyfu/nI2Pufuvnx9f7///////////////////8bX/gAZPsAZf0aZPt6pfugvvvJ2vygvvnJ2vugvvnx9v7////////////////Z5f0ZY/gAZPsAZf0dbPsca/l3pvrK3PyiwfrJ2/uhwfny9v7///////////98qPg8f/Yca/kAZfwAZv4hdf0gdPsgc/ktevdvo/nK3fyjxPny9/7////////C2PsgcfQgc/ggdPsAZf0AZv4lff4lfP0ke/ske/okevgzgvcsffXD2vzT5P2qy/szgvYkevgke/olfPwAZv4AZv8pg/4pg/4pg/0pgvwogvsogfoogPgogPgogPcogPgogfkogvspgvwpg/4AZv4AZv8si/8si/8siv4siv4siv0rifwrifsrifsrifsrifsrifwsiv0siv4siv4AZv8AZv8vkP8vkP8vkP8vkP8vj/4vj/4vj/4vj/0vj/0vj/0vj/4vj/4vkP8vkP8AZv8AZv8liv8xlf8xlf8xlf8xlf8xlf8xlf8xlf8xlf8xlf8xlf8xlf8xlf8liv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv8AZv+AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAA",
  413. vimeo_png: ""
  414. +"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAfRJREFUOMuNk7FrU1EYxX/n5iVpYrQSUmKhuOhS0HSIFsRJHJwEJwcX/wr7F4jov+HmLoKCipKprRB0UIeADtLGokmMtclL+j6Hd2/ew8m73MfHeed89zvfEUBr2/YEwh8DW3wrLSjcHmdg7ze1qta27ckQSosCGVhgWLD6ujNf8nhnqYolqapmhh0mKYEyIIcJSQw2OiYJeAOcMhxzsIfnOdW9RPNOk6r5XtdrRLttmp8us9q7wplmOf1PAod/b1HoeYvGzTrVWgG3dZaT4zlWcujJOo3TUSrkMN1eoWLCzFICBOq0WVkrEwXCAmitQuF6nfLLIUfZOGROSH5IDiA27F6P0cYu+/m5XThB9PSAyd2PDCbJwhl1RsR+RnIGRIK3A6azBDq/mIYuNmoUC4IbdZaWHALsW8z8zZCpd8Kccr0VHbwaMAmlq8uUB3OSR+dY9qTa6jGqpWTCwPmlEd6WFykBABerlHbaNBuRFQA9/s7v7piZVzSU2WiBcX9K0p9xHEiaJQog+3zE7P4XxlFuM1MX8qsGVBx6Pcy6AOjHJLc+8KOiHHrhghEcsUDy4Cvj4ZwE4NlP/lzrclAWlhcLoYjIBydbem2+ox8bVnO4onyOUjFTDhz5ZRDClGlY1aGq35MQMoQpITwky8u/cf6fE+L8F1j/0uRvBF3LAAAAAElFTkSuQmCC"
  415.  
  416. };
  417. break;
  418. }
  419. }
  420. };
  421. // -end static
  422. //=========
  423.  
  424. function init(){
  425. gvar.qr_identity= 'qr_plugins_container';
  426. gvar.try_wait = 0;
  427. gvar.try_max = 20;
  428. gvar.sITry_wait= null;
  429.  
  430. wait_for_qr();
  431. }
  432.  
  433. // make sure QR DOM is finished loaded
  434. function wait_for_qr(){
  435. if( gvar.try_wait<gvar.try_max ){
  436. if( !gID(gvar.qr_identity) ){
  437. clog('waiting..');
  438. gvar.try_wait++;
  439. gvar.sITry_wait = window.setTimeout(function() { wait_for_qr() }, 500);
  440. }else{
  441. clearTimeout( gvar.sITry_wait );
  442. init_start();
  443. }
  444. }
  445. }
  446.  
  447. // ------
  448. init();
  449. // ------
  450.  
  451. })()
  452. /* Mod By Idx. */

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址