Advertisement
rccharles

ASC Pagination

Aug 24th, 2016
265
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name        ASC Pagination Changing: e -- August 24, 2016
  3. // @namespace   ASCPaginationGoto
  4. // @description script functions
  5. // @include     https://discussions.apple.com/message/*
  6. // @include     https://discussions.apple.com/thread/*
  7. // @version     1
  8. // @grant       none
  9. // ==/UserScript==
  10.  
  11.  
  12. /*
  13.     Add pagination to the top of Apple Support Communities board web page
  14.     system introduced in 2016-06
  15.  
  16.     Copyright  2016 rccharles    
  17.      
  18.     GNU General Public License      
  19.      
  20.     This program is free software: you can redistribute it and/or modify      
  21.     it under the terms of the GNU General Public License as published by      
  22.     the Free Software Foundation,  version 3      
  23.      
  24.     This program is distributed in the hope that it will be useful,      
  25.     but WITHOUT ANY WARRANTY; without even the implied warranty of      
  26.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      
  27.     GNU General Public License for more details.      
  28.      
  29.     For a copy of the GNU General Public License      
  30.     see <http://www.gnu.org/licenses/>.        
  31.      
  32.     For more information on how to install this script and  see:      
  33.     https://discussions.apple.com      
  34.    
  35.  
  36.     v0.99
  37.         - Beta
  38.     v0.50
  39.         - Alpha
  40.         - Alpha testing by ccc
  41.  
  42.  
  43.     written by rccharles, August 2016
  44.    
  45. */
  46.  
  47. // In case of a serious bug, run in the web console on the page you want to change.
  48.  
  49. //  Command+]  to indent a highlighted block of text or conversely Command+[ to unindent
  50.  
  51. /*
  52.    document.getElementById("intro");
  53.    document.getElementsByTagName("p");
  54.    This example finds the element with id="main", and then finds all <p> elements inside "main":
  55.      Example
  56.        var x = document.getElementById("main");
  57.        var y = x.getElementsByTagName("p");
  58.    document.getElementsByClassName("intro");
  59.    document.querySelectorAll("p.intro");
  60.    document.getElementById("demo").innerHTML = text;
  61. */
  62.  
  63. /*
  64.   if (typeof variable === 'undefined') {
  65.     // variable is undefined
  66. }
  67.  
  68. The typeof operator, unlike the other operators, doesn't throw a ReferenceError exception when used with an undeclared variable.
  69.  
  70. However, do note that typeof null will return "object". We have to be careful to avoid the mistake of initializing a variable to null. To be safe, this is what we could use instead:
  71.  
  72. if (typeof variable === 'undefined' || variable === null) {
  73.     // variable is undefined or null
  74. }
  75.  
  76. */
  77.  
  78.   // What the "from" htlm looks like.
  79.  
  80.   //    <div class="all-replies-container">
  81.   //      <!-- BEGIN pagination-->
  82.   //      <span class="j-pagination pagination top">  
  83.   //          <a href="/thread/7632418?start=0&amp;tstart=0"
  84.   //               title="global.first" class="js-pagination-first"
  85.   //               onclick="jspaginate.init('first'); return false;">first
  86.   //          </a>
  87.   //          <a href="/thread/7632418?start=15&amp;tstart=0"
  88.   //               title="Select to go to the previous page"                      
  89.   //               class="js-pagination-prev  icon icon-standalone icon-chevronleft"
  90.   //               onclick="jspaginate.init('prev'); return false;" >
  91.   //               <span class="a11y">Previous
  92.   //               </span>
  93.   //          </a>
  94.   //          <span class="current-page">
  95.   //               Page
  96.   //               <!--<a href="/thread/7632418?start=30&amp;tstart=0"
  97.   //                   class="j-pagination-current current-page-target font-color-normal" 3 </a>-->
  98.   //               3
  99.   //               of                    
  100.   //               3              
  101.   //               <!--<a href="/thread/7632418?start=30&amp;tstart=0"
  102.   //                    class="j-pagination-current font-color-normal">-->
  103.   //               <!--3-->
  104.   //               <!--</a>-->
  105.   //           </span>
  106.   //       </span>
  107.   //       <!-- END pagination -->      
  108.  
  109.  
  110.   // What the "to" html looks like.
  111.  
  112.   //    <ul class="apple-social-actions-toolbar" role="toolbar" aria-label="Social Actions">      
  113.   //        <li class="j-js-follow-controls"
  114.   //            data-streamsassoc="2"
  115.   //            data-location="jive-macros"
  116.   //            aria-live="polite" aria-atomic="true"> ... </li>      
  117.   //        <li class="apple-actions"
  118.   //            role="toolbar"
  119.   //            aria-labelledby="jive-action-sidebar-tab-header_thread-actions-tab"> ... </li>
  120.   //    </ul>
  121.  
  122. // ------------------------------------------
  123. // Modify web page downloaded function
  124. function cloneGotoChange()
  125. {
  126.   var debug = 0;
  127.  
  128. // alter updateUI
  129.  
  130. /* document.getElementById('tag-id').innerHTML = '<ol><li>html data</li></ol>'; */
  131.  
  132. // Find where to insert the code
  133. // We place the code at the beginning of the function
  134. var stringed = jspaginate["updateUI"].toString();
  135. var position = stringed.indexOf("{");
  136. position += 1;
  137. /* blank lines before and after so to avoid any abuttle problems */
  138. newCode = (`
  139.  
  140. /* very strange, copying data seems to avoid firefox javascript abnormality.
  141.    What a pain to find.
  142.     This will be run evertime the user click on a change page icon.*/
  143. var passData = data;
  144. var rc = cloneGotoUpate(passData);
  145. if (rc) {console.log("-->  updateUI returning from cloneGotoUpate rc = " + rc);}
  146.  
  147. `);
  148.  
  149. /* Heavy work of doing the change */
  150. var changedCode = stringed.substr(0, position)
  151.     + newCode
  152.     + stringed.substr(position);
  153. if ( debug ) console.log ("--> cloneGotoChange: new code:\n" + changedCode);
  154.  
  155. // Inject the changed code
  156. //   need to use the eval function to make a function assignment instead of a string assignment
  157. eval( 'jspaginate["updateUI"] =' + changedCode);
  158.  
  159. if ( debug ) console.log("--> updateUI:\n"+jspaginate["updateUI"].toString() );
  160.  
  161. /*  Template for changing a function.
  162. // ...............................
  163. newCode = (`
  164.  
  165. `);
  166.  
  167. // Inject the changed code
  168. //   need to use the eval function to make a function assignment instead of a string assignment
  169. eval( 'jspaginate["getData"] =' + newCode);
  170.   if ( debug ) console.log("--> igetData:\n"+window.jspaginate["init"].toString() );
  171. */
  172.  
  173. if ( debug ) console.log("--> cloneGotoChange returning. ");
  174. }   // end of function cloneGotoChange
  175.  
  176. // ------------------------------------------
  177. // Inject the script functions into the web page.
  178. function cloneGoto()
  179. {
  180.     var debug = 0;
  181.   // Create first <script> code
  182.   var firstScript = document.createElement("script");  
  183.  
  184.   // This is goint to be a little confusing since there is code inside of the quote marks.
  185.   // begin embeded code ------->
  186.   var nodeScript = document.createTextNode(`
  187. /*
  188.    Javascript strips out line ends, so:
  189.    Must not use // for comments
  190.    Must end all statements with ;
  191. */
  192.  
  193. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  194. /* Inject the pagination html */    
  195. function cloneGotoInsert()
  196. {
  197. var debug = 0;
  198. var aDate = new Date();
  199. console.log ("--> cloneGotoInsert: building pagination block " + aDate );
  200. /*  pageinations are after the original post and after the last post.
  201.     They only appear when there is more than one page. */
  202. try
  203.   {
  204.     if ( debug) console.log ("looking for pagination");
  205.     var item = document.getElementsByClassName("j-pagination pagination top")[0];
  206.   }
  207. catch(err)
  208.   {
  209.     /* Something otherthan pagination not found. */
  210.      alert("==> cloneGotoInsert # 11: " + err.message );
  211.      console.log ("--> cloneGotoInsert # 11: found an error ");
  212.      console.log (err);
  213.     return 11; /* Sad goodbye */
  214.   }
  215. if ( debug ) console.log ("something returned. pagination");
  216.  
  217. /*
  218.    Some uncertainty over what is the best way.  All work. :
  219.      if ( item === undefined ||  item === null)
  220.      if (typeof  item==='undefined' ||  item===null)
  221.      if ( item == null)
  222. */
  223.  
  224. /* See if we found a discussion with one page which happens when no paginatin exists */
  225. if ( item == null)
  226.   {
  227.     if ( debug) console.log ("no pagination");
  228.     return 0;  /* We are done. Nothing to do. Are we sure? Needs checkingout.  */
  229.   }
  230.  
  231. if ( debug) console.log ("assume pagination");
  232.  
  233.  
  234.    
  235.   /* Copy the <span> element and its child nodes */
  236.   var clone = item.cloneNode(true);
  237.  
  238.   cloneGotoInsertCommon(clone);
  239.  
  240. }  /* end of cloneGotoInsert     */                        
  241.  
  242. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  243. /* Inject the pagination html */    
  244. function cloneGotoInsertCommon(htmlToInsert)
  245. {
  246. try
  247. {
  248.     var debug = 0;
  249.   if ( debug ) console.log ("--> starting cloneGotoInsertCommon");
  250.  
  251.   /* Buid data structure
  252.      Create first <li> note */
  253.   var firstLi = document.createElement("lI");
  254.   /* \u00A0 is &nbsp; */
  255.   var node = document.createTextNode(" \u00A0\u00A0\u00A0\u00A0 ");
  256.   firstLi.appendChild(node);
  257.  
  258.   /* within div with the same name */
  259.   var firstDiv = document.createElement("DIV");
  260.  
  261.   /* supply an id so this div is easier to find */
  262.   firstDiv.setAttribute("id","ASCPaginationGotoIcons");
  263.  
  264.   /* Append pagination
  265.      End with three paginations on a multipage document page */
  266.   firstDiv.appendChild(htmlToInsert);                      
  267.  
  268.   /* Create second <li> node */
  269.   var secondLi = document.createElement("LI");  
  270.   /* combine */
  271.   secondLi.appendChild(firstDiv);    
  272.    
  273.   /* so we need a new place to append when person isn't logged in :-( */
  274.   if ( debug ) console.log ("--> cloneGotoInsertCommon: choice");
  275.  
  276.   /* Note: always returns a array.  Nothing found, first element will be
  277.      undefined */
  278.   var whereTo = document.getElementsByClassName("apple-social-actions-toolbar")
  279.   if ( whereTo[0] == null)
  280.   {
  281.     if ( debug ) console.log ("--> user not signed in");
  282.     /* user not signed in.  We have to find a different place to put. jive-breadcrumb*/
  283.     var signedOutId = document.getElementById("menubar");
  284.     if ( signedOutId == null)
  285.     {
  286.       alert("==> cloneGotoInsert # 16: no place found for not signed in." );
  287.       console.log ("--> cloneGotoInsert #16: no place found for not signed in. ");
  288.       return 0;  /* We are done. Nothing to do. */
  289.     }
  290.    
  291.     if ( debug ) console.log ("found place to put pagination info when user not signed in");
  292.     // firstDiv.setAttribute("style","margin-bottom: -120px !important;"); */
  293.     /* Append the cloned <span> element to follow [pulldown] */
  294.     signedOutId.appendChild(secondLi);    
  295.   }
  296.   else
  297.   {
  298.     if ( debug ) console.log ("signed");
  299.     /* Logged in path */
  300.     whereTo[0].appendChild(firstLi);
  301.      
  302.     /* Append the cloned <span> element to follow [pulldown] */
  303.     whereTo[0].appendChild(secondLi);
  304.  
  305.   }
  306.  
  307.  
  308. }  /* end of try */
  309. /* avoid repeated errors at least
  310.    first get will fail when there is only one page. */
  311. catch(err)
  312.   {
  313.      alert("==> cloneGotoInsert # 12: " + err.message );
  314.      console.log ("--> cloneGotoInsert #12: found an error ");
  315.      console.log (err);
  316.      return 12;  /* Sad goodbye */
  317.   }
  318. } // end of function cloneGotoInsertCommon
  319.  
  320. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  321. /* called when user click on a pagination icon */
  322. function cloneGotoUpate(htmlToInsert)
  323. {
  324. var debug = 0;
  325. var aDate = new Date();
  326. console.log ("--> cloneGotoUpdate: building pagination block " + aDate );
  327.  
  328. /* remove old pagination html */
  329. try
  330.   {
  331.                 var whereTo = document.getElementById("ASCPaginationGotoIcons")
  332.                 if ( whereTo )
  333.                         {
  334.                                 if ( debug ) console.log ("--> cloneGotoUpdate: found pagination");
  335.                                 /* Remove top of page pagination */
  336.                                 whereTo.parentNode.removeChild(whereTo);    
  337.                                 if ( debug ) console.log ("--> cloneGotoUpdate: pagination removed");
  338.                         }
  339.                         else
  340.                         {
  341.                                 if ( debug )  console.log ("--> cloneGotoUpdate: no pagination found");
  342.                         }
  343.  
  344.   }
  345. catch(err)
  346.   {
  347.      alert("==> cloneGotoUpdate # 17: " + err.message );
  348.      console.log ("--> cloneGotoUpdate #17: found an error ");
  349.      console.log (err);
  350.      return 17;  /* Sad goodbye */
  351.   }
  352.  
  353. /* htmlToInsert contains a little extra data, like the whole bottom of the page.
  354.    strip off after:
  355.    <!-- END pagination -->
  356. */
  357. var position = htmlToInsert.indexOf("<!-- END pagination -->");
  358.   if ( debug ) console.log ("--> cloneGotoUpdate: ending start of line position " + position);
  359. position = htmlToInsert.indexOf("-->",position);
  360.   if ( debug ) console.log ("--> cloneGotoUpdate: near ending line position " + position);
  361. position += 3;
  362.   if ( debug ) console.log ("--> cloneGotoUpdate: ending line position " + position);
  363.  
  364.   if ( debug ) console.log ("--> cloneGotoUpdate: htmlToInsert typeof = " + typeof htmlToInsert);
  365.   if ( debug ) console.log("running data = "+htmlToInsert);
  366. var justPaginate = htmlToInsert.substr(0, position);
  367.   if ( debug ) console.log ("--> cloneGotoUpdate: justPaginate typeof = " + typeof justPaginate);
  368.   if ( debug ) console.log("running data = "+justPaginate);
  369.  
  370. /* example:
  371.      document.getElementById('tag-id').innerHTML = '<ol><li>html data</li></ol>'; */
  372. var firstSpan = document.createElement("span");
  373. firstSpan.innerHTML = justPaginate;
  374.  
  375.  
  376.  
  377. /* add back the pagination.  Assumed we end up with an updated pagination */
  378. var rc = cloneGotoInsertCommon(firstSpan);
  379. if (rc) {console.log("--> cloneGotoUpdate: returned from cloneGotoInsert rc = " + rc);}
  380.  
  381. return 0;
  382.  
  383. } /* End of cloneGotoUpate */        
  384.                                  
  385.        `);
  386.        
  387.    // <----------- end embedded code.
  388.      
  389.    // Were back to normal run of the mill code that will ultimately insert the above code
  390.    firstScript.appendChild(nodeScript);
  391.    
  392.    // Insert the script text
  393.    try
  394.    {
  395.      var isASC = document.getElementById("body-apple");  
  396.      if ( isASC == null)
  397.      {
  398.       console.log ("--> cloneGotoInsert # 13: Does not have the layout of an ASC web page.");
  399.       return 0;  /* We are done. Ignore non ASC web page.  Greasemonkey shouldn't have called us. */
  400.      }
  401.      
  402.      /* Found a ASC web page  */
  403.      isASC.appendChild(firstScript);
  404.    }
  405.    catch (err)
  406.    {
  407.      alert ("==> cloneGotoInsert # 14: " + err.message);    
  408.      console.log("--> cloneGotoInsert # 14: Got some odd error when looking for script insertion point. ");
  409.      console.log("--> " + err.message)
  410.      console.log(err);
  411.      return 14;  // Sad goodbye
  412.    }
  413. if ( debug ) console.log("--> cloneGotoInsert proceeding ");  
  414.    try
  415.    {
  416.      // Now that we moved the script inline, run it
  417.      // Insert pagination at the top of the page.
  418.      var cloneGotoInsertRc = cloneGotoInsert();
  419.      if (cloneGotoInsertRc) {
  420.          console.log("-->  cloneGotoInsert rc = " + clonecloneGotoInsertRc);
  421.        }
  422.    }  
  423.    // avoid repeated errors at least
  424.    // first get will fail when there is only one page.
  425.    catch(err)
  426.    {
  427.      alert("==> cloneGotoInsert # 15: When inserting pagination, received this message \n"
  428.            + err.message );
  429.      console.log ("--> cloneGotoInsert # 15: found an error when inserting pagination");
  430.      console.log (err);
  431.      return 15;  // Sad goodbye
  432.    }
  433.  
  434.    if (debug) {console.log("-->  cloneGoto calling cloneGotoChange()");}
  435.    // Now all we have to do is modify jspaginate.init so we can fix up out added
  436.    // paginate information at the top right of the page
  437.    // Has a tap bit of a side effect.
  438.    cloneGotoChange();
  439.    if ( debug ) console.log("returning from cloneGoto");
  440.    return 0;
  441.  
  442. }  // end of function cloneGoto
  443.  
  444.  
  445. // ----------------------------- Start of running code --------------------------------------------
  446. var debug = 0;
  447.  
  448. if ( debug ) console.log ("--> : starting ... ");
  449. // collect rc.
  450. var rc = cloneGoto();
  451. if (rc) {console.log("--> Last rc = " + rc);}
  452. if ( debug ) console.log ("--> : all ... done");
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement